diff options
author | Merov Linden <merov@lindenlab.com> | 2010-10-22 17:39:03 -0700 |
---|---|---|
committer | Merov Linden <merov@lindenlab.com> | 2010-10-22 17:39:03 -0700 |
commit | a0714f01804a2a2220bd72c3adf06f097ad21b73 (patch) | |
tree | db304a8eca349020b48ae927fd8a534264a6ed83 /indra | |
parent | e3ecffc180ae50a0e8b726a061ec39cbe591326e (diff) | |
parent | de6f7e19c44d267d3224c56941c2ab27677c406f (diff) |
Merge with viewer-development
Diffstat (limited to 'indra')
476 files changed, 13380 insertions, 5548 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 261c0b17e2..8d4969a49e 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -123,6 +123,8 @@ if (SERVER) endif (WINDOWS) endif (SERVER) -# Define after the custom viewer and server targets are created so individual -# apps can add themselves as dependencies -add_subdirectory(${INTEGRATION_TESTS_PREFIX}integration_tests) +if (LL_TESTS) + # Define after the custom viewer and server targets are created so + # individual apps can add themselves as dependencies + add_subdirectory(${INTEGRATION_TESTS_PREFIX}integration_tests) +endif (LL_TESTS) diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 4fc25dcc24..6470836286 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -26,6 +26,7 @@ set(cmake_SOURCE_FILES FindBerkeleyDB.cmake FindCARes.cmake FindELFIO.cmake + FindFMOD.cmake FindGooglePerfTools.cmake FindMono.cmake FindMT.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 95ed5d6bc8..e852cf463c 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -55,9 +55,10 @@ if(WINDOWS) set(release_files ${release_files} libtcmalloc_minimal.dll) endif(USE_GOOGLE_PERFTOOLS) - if (FMOD_SDK_DIR) - set(fmod_files fmod.dll) - endif (FMOD_SDK_DIR) + if (FMOD) + set(debug_files ${debug_files} fmod.dll) + set(release_files ${release_files} fmod.dll) + endif (FMOD) #******************************* # LLKDU @@ -237,9 +238,9 @@ elseif(LINUX) libssl.so.0.9.7 ) - if (FMOD_SDK_DIR) - set(fmod_files "libfmod-3.75.so") - endif (FMOD_SDK_DIR) + if (FMOD) + set(release_files ${release_files} "libfmod-3.75.so") + endif (FMOD) #******************************* # LLKDU @@ -333,30 +334,6 @@ copy_if_different( ) set(third_party_targets ${third_party_targets} ${out_targets}) -if (FMOD_SDK_DIR) - copy_if_different( - ${FMOD_SDK_DIR} - "${CMAKE_CURRENT_BINARY_DIR}/Debug" - out_targets - ${fmod_files} - ) - set(all_targets ${all_targets} ${out_targets}) - copy_if_different( - ${FMOD_SDK_DIR} - "${CMAKE_CURRENT_BINARY_DIR}/Release" - out_targets - ${fmod_files} - ) - set(all_targets ${all_targets} ${out_targets}) - copy_if_different( - ${FMOD_SDK_DIR} - "${CMAKE_CURRENT_BINARY_DIR}/RelWithDbgInfo" - out_targets - ${fmod_files} - ) - set(all_targets ${all_targets} ${out_targets}) -endif (FMOD_SDK_DIR) - #******************************* # LLKDU set(internal_llkdu_path "${CMAKE_SOURCE_DIR}/llkdu") diff --git a/indra/cmake/FMOD.cmake b/indra/cmake/FMOD.cmake index 759b8f1340..dcf44cd642 100644 --- a/indra/cmake/FMOD.cmake +++ b/indra/cmake/FMOD.cmake @@ -1,64 +1,26 @@ # -*- cmake -*- -include(Linking) - -if(INSTALL_PROPRIETARY) - include(Prebuilt) - use_prebuilt_binary(fmod) -endif(INSTALL_PROPRIETARY) - -find_library(FMOD_LIBRARY_RELEASE - NAMES fmod fmodvc fmod-3.75 - PATHS - ${ARCH_PREBUILT_DIRS_RELEASE} - ) - -find_library(FMOD_LIBRARY_DEBUG - NAMES fmod fmodvc fmod-3.75 - PATHS - ${ARCH_PREBUILT_DIRS_DEBUG} - ) - -if (FMOD_LIBRARY_RELEASE AND FMOD_LIBRARY_DEBUG) - set(FMOD_LIBRARY - debug ${FMOD_LIBRARY_DEBUG} - optimized ${FMOD_LIBRARY_RELEASE}) -elseif (FMOD_LIBRARY_RELEASE) - set(FMOD_LIBRARY ${FMOD_LIBRARY_RELEASE}) -endif (FMOD_LIBRARY_RELEASE AND FMOD_LIBRARY_DEBUG) - -if (NOT FMOD_LIBRARY) - set(FMOD_SDK_DIR CACHE PATH "Path to the FMOD SDK.") - if (FMOD_SDK_DIR) - find_library(FMOD_LIBRARY - NAMES fmodvc fmod-3.75 fmod - PATHS - ${FMOD_SDK_DIR}/api/lib - ${FMOD_SDK_DIR}/api - ${FMOD_SDK_DIR}/lib - ${FMOD_SDK_DIR} - ) - endif (FMOD_SDK_DIR) -endif (NOT FMOD_LIBRARY) - -find_path(FMOD_INCLUDE_DIR fmod.h - ${LIBS_PREBUILT_DIR}/include - ${FMOD_SDK_DIR}/api/inc - ${FMOD_SDK_DIR}/inc - ${FMOD_SDK_DIR} - ) - -if (FMOD_LIBRARY AND FMOD_INCLUDE_DIR) - set(FMOD ON CACHE BOOL "Use closed source FMOD sound library.") -else (FMOD_LIBRARY AND FMOD_INCLUDE_DIR) - set(FMOD_LIBRARY "") - set(FMOD_INCLUDE_DIR "") - if (FMOD) - message(STATUS "No support for FMOD audio (need to set FMOD_SDK_DIR?)") - endif (FMOD) - set(FMOD OFF CACHE BOOL "Use closed source FMOD sound library.") -endif (FMOD_LIBRARY AND FMOD_INCLUDE_DIR) +set(FMOD ON CACHE BOOL "Use FMOD sound library.") if (FMOD) - message(STATUS "Building with FMOD audio support") + if (STANDALONE) + set(FMOD_FIND_REQUIRED ON) + include(FindFMOD) + else (STANDALONE) + if (INSTALL_PROPRIETARY) + include(Prebuilt) + use_prebuilt_binary(fmod) + endif (INSTALL_PROPRIETARY) + + if (WINDOWS) + set(FMOD_LIBRARY fmod) + elseif (DARWIN) + set(FMOD_LIBRARY fmod) + elseif (LINUX) + set(FMOD_LIBRARY fmod-3.75) + endif (WINDOWS) + + SET(FMOD_LIBRARIES ${FMOD_LIBRARY}) + set(FMOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) + endif (STANDALONE) endif (FMOD) diff --git a/indra/cmake/FindFMOD.cmake b/indra/cmake/FindFMOD.cmake new file mode 100644 index 0000000000..e60b386027 --- /dev/null +++ b/indra/cmake/FindFMOD.cmake @@ -0,0 +1,44 @@ +# -*- cmake -*- + +# - Find FMOD +# Find the FMOD includes and library +# This module defines +# FMOD_INCLUDE_DIR, where to find fmod.h and fmod_errors.h +# FMOD_LIBRARIES, the libraries needed to use FMOD. +# FMOD, If false, do not try to use FMOD. +# also defined, but not for general use are +# FMOD_LIBRARY, where to find the FMOD library. + +FIND_PATH(FMOD_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod) + +SET(FMOD_NAMES ${FMOD_NAMES} fmod fmodvc fmod-3.75) +FIND_LIBRARY(FMOD_LIBRARY + NAMES ${FMOD_NAMES} + PATH_SUFFIXES fmod + ) + +IF (FMOD_LIBRARY AND FMOD_INCLUDE_DIR) + SET(FMOD_LIBRARIES ${FMOD_LIBRARY}) + SET(FMOD_FOUND "YES") +ELSE (FMOD_LIBRARY AND FMOD_INCLUDE_DIR) + SET(FMOD_FOUND "NO") +ENDIF (FMOD_LIBRARY AND FMOD_INCLUDE_DIR) + +IF (FMOD_FOUND) + IF (NOT FMOD_FIND_QUIETLY) + MESSAGE(STATUS "Found FMOD: ${FMOD_LIBRARIES}") + ENDIF (NOT FMOD_FIND_QUIETLY) +ELSE (FMOD_FOUND) + IF (FMOD_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find FMOD library") + ENDIF (FMOD_FIND_REQUIRED) +ENDIF (FMOD_FOUND) + +# Deprecated declarations. +SET (NATIVE_FMOD_INCLUDE_PATH ${FMOD_INCLUDE_DIR} ) +GET_FILENAME_COMPONENT (NATIVE_FMOD_LIB_PATH ${FMOD_LIBRARY} PATH) + +MARK_AS_ADVANCED( + FMOD_LIBRARY + FMOD_INCLUDE_DIR + ) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index a6a7989955..79c3bb7da2 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -256,6 +256,10 @@ MACRO(SET_TEST_PATH LISTVAR) set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib) ELSE(WINDOWS) # Linux uses a single staging directory anyway. - set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib) + IF (STANDALONE) + set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib) + ELSE (STANDALONE) + set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib) + ENDIF (STANDALONE) ENDIF(WINDOWS) ENDMACRO(SET_TEST_PATH) diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index e377aeef48..37aa75e364 100644 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -24,7 +24,7 @@ myprog somearg otherarg $LicenseInfo:firstyear=2009&license=viewerlgpl$ Second Life Viewer Source Code -Copyright (C) 2010, Linden Research, Inc. +Copyright (C) 2009-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 diff --git a/indra/lib/python/indra/__init__.py b/indra/lib/python/indra/__init__.py index e010741c1c..0c5053cf49 100644 --- a/indra/lib/python/indra/__init__.py +++ b/indra/lib/python/indra/__init__.py @@ -4,7 +4,7 @@ $LicenseInfo:firstyear=2006&license=viewerlgpl$ Second Life Viewer Source Code -Copyright (C) 2010, Linden Research, Inc. +Copyright (C) 2006-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 diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index e869b9717c..21ec622819 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -14,7 +14,6 @@ include(LLVFS) include_directories( ${LLAUDIO_INCLUDE_DIRS} - ${FMOD_INCLUDE_DIR} ${LLCOMMON_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} @@ -45,6 +44,10 @@ set(llaudio_HEADER_FILES ) if (FMOD) + include_directories( + ${FMOD_INCLUDE_DIR} + ) + list(APPEND llaudio_SOURCE_FILES llaudioengine_fmod.cpp lllistener_fmod.cpp diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 0dfc540f54..a6f07f9600 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -33,6 +33,7 @@ set(llcommon_SOURCE_FILES llapp.cpp llapr.cpp llassettype.cpp + llavatarname.cpp llbase32.cpp llbase64.cpp llcommon.cpp @@ -116,6 +117,7 @@ set(llcommon_HEADER_FILES llallocator.h llallocator_heap_profile.h llagentconstants.h + llavatarname.h llapp.h llapr.h llassettype.h @@ -254,8 +256,15 @@ set_source_files_properties(${llcommon_HEADER_FILES} list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) if(LLCOMMON_LINK_SHARED) - add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) - ll_stage_sharedlib(llcommon) + add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) + if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) + endif(NOT WORD_SIZE EQUAL 32) + ll_stage_sharedlib(llcommon) else(LLCOMMON_LINK_SHARED) add_library (llcommon ${llcommon_SOURCE_FILES}) endif(LLCOMMON_LINK_SHARED) diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp new file mode 100644 index 0000000000..b1ec9e9875 --- /dev/null +++ b/indra/llcommon/llavatarname.cpp @@ -0,0 +1,113 @@ +/** + * @file llavatarname.cpp + * @brief Represents name-related data for an avatar, such as the + * username/SLID ("bobsmith123" or "james.linden") and the display + * name ("James Cook") + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "linden_common.h" + +#include "llavatarname.h" + +#include "lldate.h" +#include "llsd.h" + +// Store these in pre-built std::strings to avoid memory allocations in +// LLSD map lookups +static const std::string USERNAME("username"); +static const std::string DISPLAY_NAME("display_name"); +static const std::string LEGACY_FIRST_NAME("legacy_first_name"); +static const std::string LEGACY_LAST_NAME("legacy_last_name"); +static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default"); +static const std::string DISPLAY_NAME_EXPIRES("display_name_expires"); +static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update"); + +LLAvatarName::LLAvatarName() +: mUsername(), + mDisplayName(), + mLegacyFirstName(), + mLegacyLastName(), + mIsDisplayNameDefault(false), + mIsDummy(false), + mExpires(F64_MAX), + mNextUpdate(0.0) +{ } + +bool LLAvatarName::operator<(const LLAvatarName& rhs) const +{ + if (mUsername == rhs.mUsername) + return mDisplayName < rhs.mDisplayName; + else + return mUsername < rhs.mUsername; +} + +LLSD LLAvatarName::asLLSD() const +{ + LLSD sd; + sd[USERNAME] = mUsername; + sd[DISPLAY_NAME] = mDisplayName; + sd[LEGACY_FIRST_NAME] = mLegacyFirstName; + sd[LEGACY_LAST_NAME] = mLegacyLastName; + sd[IS_DISPLAY_NAME_DEFAULT] = mIsDisplayNameDefault; + sd[DISPLAY_NAME_EXPIRES] = LLDate(mExpires); + sd[DISPLAY_NAME_NEXT_UPDATE] = LLDate(mNextUpdate); + return sd; +} + +void LLAvatarName::fromLLSD(const LLSD& sd) +{ + mUsername = sd[USERNAME].asString(); + mDisplayName = sd[DISPLAY_NAME].asString(); + mLegacyFirstName = sd[LEGACY_FIRST_NAME].asString(); + mLegacyLastName = sd[LEGACY_LAST_NAME].asString(); + mIsDisplayNameDefault = sd[IS_DISPLAY_NAME_DEFAULT].asBoolean(); + LLDate expires = sd[DISPLAY_NAME_EXPIRES]; + mExpires = expires.secondsSinceEpoch(); + LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE]; + mNextUpdate = next_update.secondsSinceEpoch(); +} + +std::string LLAvatarName::getCompleteName() const +{ + std::string name; + if (!mUsername.empty()) + { + name = mDisplayName + " (" + mUsername + ")"; + } + else + { + // ...display names are off, legacy name is in mDisplayName + name = mDisplayName; + } + return name; +} + +std::string LLAvatarName::getLegacyName() const +{ + std::string name; + name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() ); + name = mLegacyFirstName; + name += " "; + name += mLegacyLastName; + return name; +} diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h new file mode 100644 index 0000000000..145aeccd35 --- /dev/null +++ b/indra/llcommon/llavatarname.h @@ -0,0 +1,95 @@ +/** + * @file llavatarname.h + * @brief Represents name-related data for an avatar, such as the + * username/SLID ("bobsmith123" or "james.linden") and the display + * name ("James Cook") + * + * $LicenseInfo:firstyear=2010&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 LLAVATARNAME_H +#define LLAVATARNAME_H + +#include <string> + +class LLSD; + +class LL_COMMON_API LLAvatarName +{ +public: + LLAvatarName(); + + bool operator<(const LLAvatarName& rhs) const; + + LLSD asLLSD() const; + + void fromLLSD(const LLSD& sd); + + // For normal names, returns "James Linden (james.linden)" + // When display names are disabled returns just "James Linden" + std::string getCompleteName() const; + + // Returns "James Linden" or "bobsmith123 Resident" for backwards + // compatibility with systems like voice and muting + // *TODO: Eliminate this in favor of username only + std::string getLegacyName() const; + + // "bobsmith123" or "james.linden", US-ASCII only + std::string mUsername; + + // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode + // Contains data whether or not user has explicitly set + // a display name; may duplicate their username. + std::string mDisplayName; + + // For "James Linden", "James" + // For "bobsmith123", "bobsmith123" + // Used to communicate with legacy systems like voice and muting which + // rely on old-style names. + // *TODO: Eliminate this in favor of username only + std::string mLegacyFirstName; + + // For "James Linden", "Linden" + // For "bobsmith123", "Resident" + // see above for rationale + std::string mLegacyLastName; + + // If true, both display name and SLID were generated from + // a legacy first and last name, like "James Linden (james.linden)" + bool mIsDisplayNameDefault; + + // Under error conditions, we may insert "dummy" records with + // names like "???" into caches as placeholders. These can be + // shown in UI, but are not serialized. + bool mIsDummy; + + // Names can change, so need to keep track of when name was + // last checked. + // Unix time-from-epoch seconds for efficiency + F64 mExpires; + + // You can only change your name every N hours, so record + // when the next update is allowed + // Unix time-from-epoch seconds + F64 mNextUpdate; +}; + +#endif diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h index 52b85c7bba..87c2d6775b 100644 --- a/indra/llcommon/llchat.h +++ b/indra/llcommon/llchat.h @@ -28,7 +28,6 @@ #ifndef LL_LLCHAT_H #define LL_LLCHAT_H -#include "llstring.h" #include "lluuid.h" #include "v3math.h" @@ -71,7 +70,7 @@ typedef enum e_chat_style class LLChat { public: - LLChat(const std::string& text = LLStringUtil::null) + LLChat(const std::string& text = std::string()) : mText(text), mFromName(), mFromID(), diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h index a8cd03b42a..131b819c99 100644 --- a/indra/llcommon/lldarray.h +++ b/indra/llcommon/lldarray.h @@ -51,7 +51,7 @@ public: LLDynamicArray(S32 size=0) : std::vector<Type>(size) { if (size < BlockSize) std::vector<Type>::reserve(BlockSize); } - void reset() { std::vector<Type>::resize(0); } + void reset() { std::vector<Type>::clear(); } // ACCESSORS const Type& get(S32 index) const { return std::vector<Type>::operator[](index); } diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index ae7e624a1a..f3b48b0156 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -731,14 +731,17 @@ void LLStringOps::setupDatetimeInfo (bool daylight) nowT = time (NULL); - tmpT = localtime (&nowT); - localT = mktime (tmpT); - tmpT = gmtime (&nowT); gmtT = mktime (tmpT); + tmpT = localtime (&nowT); + localT = mktime (tmpT); + sLocalTimeOffset = (long) (gmtT - localT); - + if (tmpT->tm_isdst) + { + sLocalTimeOffset -= 60 * 60; // 1 hour + } sPacificDaylightTime = daylight; sPacificTimeOffset = (sPacificDaylightTime? 7 : 8 ) * 60 * 60; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index bd65ce8573..b209e4aa38 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -28,10 +28,14 @@ #define LL_LLVERSIONVIEWER_H const S32 LL_VERSION_MAJOR = 2; -const S32 LL_VERSION_MINOR = 2; -const S32 LL_VERSION_PATCH = 1; +const S32 LL_VERSION_MINOR = 4; +const S32 LL_VERSION_PATCH = 0; const S32 LL_VERSION_BUILD = 0; const char * const LL_CHANNEL = "Second Life Developer"; +#if LL_DARWIN +const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.snowglobe.viewer"; +#endif + #endif diff --git a/indra/llcommon/roles_constants.h b/indra/llcommon/roles_constants.h index 70bca821c7..effd15ea72 100644 --- a/indra/llcommon/roles_constants.h +++ b/indra/llcommon/roles_constants.h @@ -52,7 +52,6 @@ enum LLRoleChangeType // // KNOWN HOLES: use these for any single bit powers you need -// bit 0x1 << 41 // bit 0x1 << 46 // bit 0x1 << 49 and above @@ -103,6 +102,8 @@ const U64 GP_LAND_ALLOW_FLY = 0x1 << 24; // Bypass Fly Restriction const U64 GP_LAND_ALLOW_CREATE = 0x1 << 25; // Bypass Create/Edit Objects Restriction const U64 GP_LAND_ALLOW_LANDMARK = 0x1 << 26; // Bypass Landmark Restriction const U64 GP_LAND_ALLOW_SET_HOME = 0x1 << 28; // Bypass Set Home Point Restriction +const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land + // Parcel Access const U64 GP_LAND_MANAGE_ALLOWED = 0x1 << 29; // Manage Allowed List diff --git a/indra/llinventory/lltransactionflags.cpp b/indra/llinventory/lltransactionflags.cpp index 8f7eeb8efa..ee0e6ae26c 100644 --- a/indra/llinventory/lltransactionflags.cpp +++ b/indra/llinventory/lltransactionflags.cpp @@ -108,6 +108,9 @@ std::string build_transfer_message_to_source( std::ostringstream ostr; if(dest_id.isNull()) { + // *NOTE: Do not change these strings! The viewer matches + // them in llviewermessage.cpp to perform localization. + // If you need to make changes, add a new, localizable message. JC ostr << "You paid L$" << amount; switch(transaction_type) { @@ -154,6 +157,9 @@ std::string build_transfer_message_to_destination( return description; } std::ostringstream ostr; + // *NOTE: Do not change these strings! The viewer matches + // them in llviewermessage.cpp to perform localization. + // If you need to make changes, add a new, localizable message. JC ostr << source_name << " paid you L$" << amount; append_reason(ostr, transaction_type, description); ostr << "."; diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 1f8ee26716..1cad0f6d22 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -25,6 +25,7 @@ set(llmessage_SOURCE_FILES llares.cpp llareslistener.cpp llassetstorage.cpp + llavatarnamecache.cpp llblowfishcipher.cpp llbuffer.cpp llbufferstream.cpp @@ -110,6 +111,7 @@ set(llmessage_HEADER_FILES llares.h llareslistener.h llassetstorage.h + llavatarnamecache.h llblowfishcipher.h llbuffer.h llbufferstream.h @@ -248,6 +250,7 @@ if (LL_TESTS) "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py" ) + LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llpartdata "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llxfer_file "" "${test_libs}") diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp new file mode 100644 index 0000000000..2f2d9099a3 --- /dev/null +++ b/indra/llmessage/llavatarnamecache.cpp @@ -0,0 +1,822 @@ +/** + * @file llavatarnamecache.cpp + * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names + * ("James Cook") from avatar UUIDs. + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ +#include "linden_common.h" + +#include "llavatarnamecache.h" + +#include "llcachename.h" // we wrap this system +#include "llframetimer.h" +#include "llhttpclient.h" +#include "llsd.h" +#include "llsdserialize.h" + +#include <boost/tokenizer.hpp> + +#include <map> +#include <set> + +namespace LLAvatarNameCache +{ + use_display_name_signal_t mUseDisplayNamesSignal; + + // Manual override for display names - can disable even if the region + // supports it. + bool sUseDisplayNames = true; + + // Cache starts in a paused state until we can determine if the + // current region supports display names. + bool sRunning = false; + + // Base lookup URL for name service. + // On simulator, loaded from indra.xml + // On viewer, usually a simulator capability (at People API team's request) + // Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/" + std::string sNameLookupURL; + + // accumulated agent IDs for next query against service + typedef std::set<LLUUID> ask_queue_t; + ask_queue_t sAskQueue; + + // agent IDs that have been requested, but with no reply + // maps agent ID to frame time request was made + typedef std::map<LLUUID, F64> pending_queue_t; + pending_queue_t sPendingQueue; + + // Callbacks to fire when we received a name. + // May have multiple callbacks for a single ID, which are + // represented as multiple slots bound to the signal. + // Avoid copying signals via pointers. + typedef std::map<LLUUID, callback_signal_t*> signal_map_t; + signal_map_t sSignalMap; + + // names we know about + typedef std::map<LLUUID, LLAvatarName> cache_t; + cache_t sCache; + + // Send bulk lookup requests a few times a second at most + // only need per-frame timing resolution + LLFrameTimer sRequestTimer; + + // Periodically clean out expired entries from the cache + //LLFrameTimer sEraseExpiredTimer; + + //----------------------------------------------------------------------- + // Internal methods + //----------------------------------------------------------------------- + + // Handle name response off network. + // Optionally skip adding to cache, used when this is a fallback to the + // legacy name system. + void processName(const LLUUID& agent_id, + const LLAvatarName& av_name, + bool add_to_cache); + + void requestNamesViaCapability(); + + // Legacy name system callback + void legacyNameCallback(const LLUUID& agent_id, + const std::string& full_name, + bool is_group); + + void requestNamesViaLegacy(); + + // Fill in an LLAvatarName with the legacy name data + void buildLegacyName(const std::string& full_name, + LLAvatarName* av_name); + + // Do a single callback to a given slot + void fireSignal(const LLUUID& agent_id, + const callback_slot_t& slot, + const LLAvatarName& av_name); + + // Is a request in-flight over the network? + bool isRequestPending(const LLUUID& agent_id); + + // Erase expired names from cache + void eraseExpired(); + + bool expirationFromCacheControl(LLSD headers, F64 *expires); +} + +/* Sample response: +<?xml version="1.0"?> +<llsd> + <map> + <key>agents</key> + <array> + <map> + <key>display_name_next_update</key> + <date>2010-04-16T21:34:02+00:00Z</date> + <key>display_name_expires</key> + <date>2010-04-16T21:32:26.142178+00:00Z</date> + <key>display_name</key> + <string>MickBot390 LLQABot</string> + <key>sl_id</key> + <string>mickbot390.llqabot</string> + <key>id</key> + <string>0012809d-7d2d-4c24-9609-af1230a37715</string> + <key>is_display_name_default</key> + <boolean>false</boolean> + </map> + <map> + <key>display_name_next_update</key> + <date>2010-04-16T21:34:02+00:00Z</date> + <key>display_name_expires</key> + <date>2010-04-16T21:32:26.142178+00:00Z</date> + <key>display_name</key> + <string>Bjork Gudmundsdottir</string> + <key>sl_id</key> + <string>sardonyx.linden</string> + <key>id</key> + <string>3941037e-78ab-45f0-b421-bd6e77c1804d</string> + <key>is_display_name_default</key> + <boolean>true</boolean> + </map> + </array> + </map> +</llsd> +*/ + +class LLAvatarNameResponder : public LLHTTPClient::Responder +{ +private: + // need to store agent ids that are part of this request in case of + // an error, so we can flag them as unavailable + std::vector<LLUUID> mAgentIDs; + + // Need the headers to look up Expires: and Retry-After: + LLSD mHeaders; + +public: + LLAvatarNameResponder(const std::vector<LLUUID>& agent_ids) + : mAgentIDs(agent_ids), + mHeaders() + { } + + /*virtual*/ void completedHeader(U32 status, const std::string& reason, + const LLSD& headers) + { + mHeaders = headers; + } + + /*virtual*/ void result(const LLSD& content) + { + // Pull expiration out of headers if available + F64 expires = LLAvatarNameCache::nameExpirationFromHeaders(mHeaders); + + LLSD agents = content["agents"]; + LLSD::array_const_iterator it = agents.beginArray(); + for ( ; it != agents.endArray(); ++it) + { + const LLSD& row = *it; + LLUUID agent_id = row["id"].asUUID(); + + LLAvatarName av_name; + av_name.fromLLSD(row); + + // Use expiration time from header + av_name.mExpires = expires; + + // Some avatars don't have explicit display names set + if (av_name.mDisplayName.empty()) + { + av_name.mDisplayName = av_name.mUsername; + } + + // cache it and fire signals + LLAvatarNameCache::processName(agent_id, av_name, true); + } + + // Same logic as error response case + LLSD unresolved_agents = content["bad_ids"]; + if (unresolved_agents.size() > 0) + { + const std::string DUMMY_NAME("\?\?\?"); + LLAvatarName av_name; + av_name.mUsername = DUMMY_NAME; + av_name.mDisplayName = DUMMY_NAME; + av_name.mIsDisplayNameDefault = false; + av_name.mIsDummy = true; + av_name.mExpires = expires; + + it = unresolved_agents.beginArray(); + for ( ; it != unresolved_agents.endArray(); ++it) + { + const LLUUID& agent_id = *it; + // cache it and fire signals + LLAvatarNameCache::processName(agent_id, av_name, true); + } + } + } + + /*virtual*/ void error(U32 status, const std::string& reason) + { + // We're going to construct a dummy record and cache it for a while, + // either briefly for a 503 Service Unavailable, or longer for other + // errors. + F64 retry_timestamp = errorRetryTimestamp(status); + + // *NOTE: "??" starts trigraphs in C/C++, escape the question marks. + const std::string DUMMY_NAME("\?\?\?"); + LLAvatarName av_name; + av_name.mUsername = DUMMY_NAME; + av_name.mDisplayName = DUMMY_NAME; + av_name.mIsDisplayNameDefault = false; + av_name.mIsDummy = true; + av_name.mExpires = retry_timestamp; + + // Add dummy records for all agent IDs in this request + std::vector<LLUUID>::const_iterator it = mAgentIDs.begin(); + for ( ; it != mAgentIDs.end(); ++it) + { + const LLUUID& agent_id = *it; + // cache it and fire signals + LLAvatarNameCache::processName(agent_id, av_name, true); + } + } + + // Return time to retry a request that generated an error, based on + // error type and headers. Return value is seconds-since-epoch. + F64 errorRetryTimestamp(S32 status) + { + F64 now = LLFrameTimer::getTotalSeconds(); + + // Retry-After takes priority + LLSD retry_after = mHeaders["retry-after"]; + if (retry_after.isDefined()) + { + // We only support the delta-seconds type + S32 delta_seconds = retry_after.asInteger(); + if (delta_seconds > 0) + { + // ...valid delta-seconds + return now + F64(delta_seconds); + } + } + + // If no Retry-After, look for Cache-Control max-age + F64 expires = 0.0; + if (LLAvatarNameCache::expirationFromCacheControl(mHeaders, &expires)) + { + return expires; + } + + // No information in header, make a guess + if (status == 503) + { + // ...service unavailable, retry soon + const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min + return now + SERVICE_UNAVAILABLE_DELAY; + } + else + { + // ...other unexpected error + const F64 DEFAULT_DELAY = 3600.0; // 1 hour + return now + DEFAULT_DELAY; + } + } +}; + +void LLAvatarNameCache::processName(const LLUUID& agent_id, + const LLAvatarName& av_name, + bool add_to_cache) +{ + if (add_to_cache) + { + sCache[agent_id] = av_name; + } + + sPendingQueue.erase(agent_id); + + // signal everyone waiting on this name + signal_map_t::iterator sig_it = sSignalMap.find(agent_id); + if (sig_it != sSignalMap.end()) + { + callback_signal_t* signal = sig_it->second; + (*signal)(agent_id, av_name); + + sSignalMap.erase(agent_id); + + delete signal; + signal = NULL; + } +} + +void LLAvatarNameCache::requestNamesViaCapability() +{ + F64 now = LLFrameTimer::getTotalSeconds(); + + // URL format is like: + // http://pdp60.lindenlab.com:8000/agents/?ids=3941037e-78ab-45f0-b421-bd6e77c1804d&ids=0012809d-7d2d-4c24-9609-af1230a37715&ids=0019aaba-24af-4f0a-aa72-6457953cf7f0 + // + // Apache can handle URLs of 4096 chars, but let's be conservative + const U32 NAME_URL_MAX = 4096; + const U32 NAME_URL_SEND_THRESHOLD = 3000; + std::string url; + url.reserve(NAME_URL_MAX); + + std::vector<LLUUID> agent_ids; + agent_ids.reserve(128); + + ask_queue_t::const_iterator it = sAskQueue.begin(); + for ( ; it != sAskQueue.end(); ++it) + { + const LLUUID& agent_id = *it; + + if (url.empty()) + { + // ...starting new request + url += sNameLookupURL; + url += "?ids="; + } + else + { + // ...continuing existing request + url += "&ids="; + } + url += agent_id.asString(); + agent_ids.push_back(agent_id); + + // mark request as pending + sPendingQueue[agent_id] = now; + + if (url.size() > NAME_URL_SEND_THRESHOLD) + { + //llinfos << "requestNames " << url << llendl; + LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids)); + url.clear(); + agent_ids.clear(); + } + } + + if (!url.empty()) + { + //llinfos << "requestNames " << url << llendl; + LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids)); + url.clear(); + agent_ids.clear(); + } + + // We've moved all asks to the pending request queue + sAskQueue.clear(); +} + +void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id, + const std::string& full_name, + bool is_group) +{ + // Construct a dummy record for this name. By convention, SLID is blank + // Never expires, but not written to disk, so lasts until end of session. + LLAvatarName av_name; + buildLegacyName(full_name, &av_name); + + // Don't add to cache, the data already exists in the legacy name system + // cache and we don't want or need duplicate storage, because keeping the + // two copies in sync is complex. + processName(agent_id, av_name, false); +} + +void LLAvatarNameCache::requestNamesViaLegacy() +{ + F64 now = LLFrameTimer::getTotalSeconds(); + std::string full_name; + ask_queue_t::const_iterator it = sAskQueue.begin(); + for (; it != sAskQueue.end(); ++it) + { + const LLUUID& agent_id = *it; + + // Mark as pending first, just in case the callback is immediately + // invoked below. This should never happen in practice. + sPendingQueue[agent_id] = now; + + gCacheName->get(agent_id, false, // legacy compatibility + boost::bind(&LLAvatarNameCache::legacyNameCallback, + _1, _2, _3)); + } + + // We've either answered immediately or moved all asks to the + // pending queue + sAskQueue.clear(); +} + +void LLAvatarNameCache::initClass(bool running) +{ + sRunning = running; +} + +void LLAvatarNameCache::cleanupClass() +{ +} + +void LLAvatarNameCache::importFile(std::istream& istr) +{ + LLSD data; + S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr); + if (parse_count < 1) return; + + // by convention LLSD storage is a map + // we only store one entry in the map + LLSD agents = data["agents"]; + + LLUUID agent_id; + LLAvatarName av_name; + LLSD::map_const_iterator it = agents.beginMap(); + for ( ; it != agents.endMap(); ++it) + { + agent_id.set(it->first); + av_name.fromLLSD( it->second ); + sCache[agent_id] = av_name; + } + // entries may have expired since we last ran the viewer, just + // clean them out now + eraseExpired(); + llinfos << "loaded " << sCache.size() << llendl; +} + +void LLAvatarNameCache::exportFile(std::ostream& ostr) +{ + LLSD agents; + cache_t::const_iterator it = sCache.begin(); + for ( ; it != sCache.end(); ++it) + { + const LLUUID& agent_id = it->first; + const LLAvatarName& av_name = it->second; + if (!av_name.mIsDummy) + { + // key must be a string + agents[agent_id.asString()] = av_name.asLLSD(); + } + } + LLSD data; + data["agents"] = agents; + LLSDSerialize::toPrettyXML(data, ostr); +} + +void LLAvatarNameCache::setNameLookupURL(const std::string& name_lookup_url) +{ + sNameLookupURL = name_lookup_url; +} + +bool LLAvatarNameCache::hasNameLookupURL() +{ + return !sNameLookupURL.empty(); +} + +void LLAvatarNameCache::idle() +{ + // By convention, start running at first idle() call + sRunning = true; + + // *TODO: Possibly re-enabled this based on People API load measurements + // 100 ms is the threshold for "user speed" operations, so we can + // stall for about that long to batch up requests. + //const F32 SECS_BETWEEN_REQUESTS = 0.1f; + //if (!sRequestTimer.checkExpirationAndReset(SECS_BETWEEN_REQUESTS)) + //{ + // return; + //} + + // Must be large relative to above + + // No longer deleting expired entries, just re-requesting in the get + // this way first synchronous get call on an expired entry won't return + // legacy name. LF + + //const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds + //if (sEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT)) + //{ + // eraseExpired(); + //} + + if (sAskQueue.empty()) + { + return; + } + + if (useDisplayNames()) + { + requestNamesViaCapability(); + } + else + { + // ...fall back to legacy name cache system + requestNamesViaLegacy(); + } +} + +bool LLAvatarNameCache::isRequestPending(const LLUUID& agent_id) +{ + const F64 PENDING_TIMEOUT_SECS = 5.0 * 60.0; + F64 now = LLFrameTimer::getTotalSeconds(); + F64 expire_time = now - PENDING_TIMEOUT_SECS; + + pending_queue_t::const_iterator it = sPendingQueue.find(agent_id); + if (it != sPendingQueue.end()) + { + bool request_expired = (it->second < expire_time); + return !request_expired; + } + return false; +} + +void LLAvatarNameCache::eraseExpired() +{ + F64 now = LLFrameTimer::getTotalSeconds(); + cache_t::iterator it = sCache.begin(); + while (it != sCache.end()) + { + cache_t::iterator cur = it; + ++it; + const LLAvatarName& av_name = cur->second; + if (av_name.mExpires < now) + { + sCache.erase(cur); + } + } +} + +void LLAvatarNameCache::buildLegacyName(const std::string& full_name, + LLAvatarName* av_name) +{ + llassert(av_name); + av_name->mUsername = ""; + av_name->mDisplayName = full_name; + av_name->mIsDisplayNameDefault = true; + av_name->mIsDummy = true; + av_name->mExpires = F64_MAX; +} + +// fills in av_name if it has it in the cache, even if expired (can check expiry time) +// returns bool specifying if av_name was filled, false otherwise +bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +{ + if (sRunning) + { + // ...only do immediate lookups when cache is running + if (useDisplayNames()) + { + // ...use display names cache + std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id); + if (it != sCache.end()) + { + *av_name = it->second; + + // re-request name if entry is expired + if (av_name->mExpires < LLFrameTimer::getTotalSeconds()) + { + if (!isRequestPending(agent_id)) + { + sAskQueue.insert(agent_id); + } + } + + return true; + } + } + else + { + // ...use legacy names cache + std::string full_name; + if (gCacheName->getFullName(agent_id, full_name)) + { + buildLegacyName(full_name, av_name); + return true; + } + } + } + + if (!isRequestPending(agent_id)) + { + sAskQueue.insert(agent_id); + } + + return false; +} + +void LLAvatarNameCache::fireSignal(const LLUUID& agent_id, + const callback_slot_t& slot, + const LLAvatarName& av_name) +{ + callback_signal_t signal; + signal.connect(slot); + signal(agent_id, av_name); +} + +void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) +{ + if (sRunning) + { + // ...only do immediate lookups when cache is running + if (useDisplayNames()) + { + // ...use new cache + std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id); + if (it != sCache.end()) + { + const LLAvatarName& av_name = it->second; + + if (av_name.mExpires > LLFrameTimer::getTotalSeconds()) + { + // ...name already exists in cache, fire callback now + fireSignal(agent_id, slot, av_name); + + return; + } + } + } + else + { + // ...use old name system + std::string full_name; + if (gCacheName->getFullName(agent_id, full_name)) + { + LLAvatarName av_name; + buildLegacyName(full_name, &av_name); + fireSignal(agent_id, slot, av_name); + return; + } + } + } + + // schedule a request + if (!isRequestPending(agent_id)) + { + sAskQueue.insert(agent_id); + } + + // always store additional callback, even if request is pending + signal_map_t::iterator sig_it = sSignalMap.find(agent_id); + if (sig_it == sSignalMap.end()) + { + // ...new callback for this id + callback_signal_t* signal = new callback_signal_t(); + signal->connect(slot); + sSignalMap[agent_id] = signal; + } + else + { + // ...existing callback, bind additional slot + callback_signal_t* signal = sig_it->second; + signal->connect(slot); + } +} + + +void LLAvatarNameCache::setUseDisplayNames(bool use) +{ + if (use != sUseDisplayNames) + { + sUseDisplayNames = use; + // flush our cache + sCache.clear(); + + mUseDisplayNamesSignal(); + } +} + +bool LLAvatarNameCache::useDisplayNames() +{ + // Must be both manually set on and able to look up names. + return sUseDisplayNames && !sNameLookupURL.empty(); +} + +void LLAvatarNameCache::erase(const LLUUID& agent_id) +{ + sCache.erase(agent_id); +} + +void LLAvatarNameCache::fetch(const LLUUID& agent_id) +{ + // re-request, even if request is already pending + sAskQueue.insert(agent_id); +} + +void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_name) +{ + // *TODO: update timestamp if zero? + sCache[agent_id] = av_name; +} + +F64 LLAvatarNameCache::nameExpirationFromHeaders(LLSD headers) +{ + F64 expires = 0.0; + if (expirationFromCacheControl(headers, &expires)) + { + return expires; + } + else + { + // With no expiration info, default to an hour + const F64 DEFAULT_EXPIRES = 60.0 * 60.0; + F64 now = LLFrameTimer::getTotalSeconds(); + return now + DEFAULT_EXPIRES; + } +} + +bool LLAvatarNameCache::expirationFromCacheControl(LLSD headers, F64 *expires) +{ + // Allow the header to override the default + LLSD cache_control_header = headers["cache-control"]; + if (cache_control_header.isDefined()) + { + S32 max_age = 0; + std::string cache_control = cache_control_header.asString(); + if (max_age_from_cache_control(cache_control, &max_age)) + { + F64 now = LLFrameTimer::getTotalSeconds(); + *expires = now + (F64)max_age; + return true; + } + } + return false; +} + + +void LLAvatarNameCache::addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb) +{ + mUseDisplayNamesSignal.connect(cb); +} + + +static const std::string MAX_AGE("max-age"); +static const boost::char_separator<char> EQUALS_SEPARATOR("="); +static const boost::char_separator<char> COMMA_SEPARATOR(","); + +bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age) +{ + // Split the string on "," to get a list of directives + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + tokenizer directives(cache_control, COMMA_SEPARATOR); + + tokenizer::iterator token_it = directives.begin(); + for ( ; token_it != directives.end(); ++token_it) + { + // Tokens may have leading or trailing whitespace + std::string token = *token_it; + LLStringUtil::trim(token); + + if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0) + { + // ...this token starts with max-age, so let's chop it up by "=" + tokenizer subtokens(token, EQUALS_SEPARATOR); + tokenizer::iterator subtoken_it = subtokens.begin(); + + // Must have a token + if (subtoken_it == subtokens.end()) return false; + std::string subtoken = *subtoken_it; + + // Must exactly equal "max-age" + LLStringUtil::trim(subtoken); + if (subtoken != MAX_AGE) return false; + + // Must have another token + ++subtoken_it; + if (subtoken_it == subtokens.end()) return false; + subtoken = *subtoken_it; + + // Must be a valid integer + // *NOTE: atoi() returns 0 for invalid values, so we have to + // check the string first. + // *TODO: Do servers ever send "0000" for zero? We don't handle it + LLStringUtil::trim(subtoken); + if (subtoken == "0") + { + *max_age = 0; + return true; + } + S32 val = atoi( subtoken.c_str() ); + if (val > 0 && val < S32_MAX) + { + *max_age = val; + return true; + } + return false; + } + } + return false; +} + diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h new file mode 100644 index 0000000000..8f21ace96a --- /dev/null +++ b/indra/llmessage/llavatarnamecache.h @@ -0,0 +1,103 @@ +/** + * @file llavatarnamecache.h + * @brief Provides lookup of avatar SLIDs ("bobsmith123") and display names + * ("James Cook") from avatar UUIDs. + * + * $LicenseInfo:firstyear=2010&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 LLAVATARNAMECACHE_H +#define LLAVATARNAMECACHE_H + +#include "llavatarname.h" // for convenience + +#include <boost/signals2.hpp> + +class LLSD; +class LLUUID; + +namespace LLAvatarNameCache +{ + + typedef boost::signals2::signal<void (void)> use_display_name_signal_t; + + // Until the cache is set running, immediate lookups will fail and + // async lookups will be queued. This allows us to block requests + // until we know if the first region supports display names. + void initClass(bool running); + void cleanupClass(); + + void importFile(std::istream& istr); + void exportFile(std::ostream& ostr); + + // On the viewer, usually a simulator capabilitity + // If empty, name cache will fall back to using legacy name + // lookup system + void setNameLookupURL(const std::string& name_lookup_url); + + // Do we have a valid lookup URL, hence are we trying to use the + // new display name lookup system? + bool hasNameLookupURL(); + + // Periodically makes a batch request for display names not already in + // cache. Call once per frame. + void idle(); + + // If name is in cache, returns true and fills in provided LLAvatarName + // otherwise returns false + bool get(const LLUUID& agent_id, LLAvatarName *av_name); + + // Callback types for get() below + typedef boost::signals2::signal< + void (const LLUUID& agent_id, const LLAvatarName& av_name)> + callback_signal_t; + typedef callback_signal_t::slot_type callback_slot_t; + + // Fetches name information and calls callback. + // If name information is in cache, callback will be called immediately. + void get(const LLUUID& agent_id, callback_slot_t slot); + + // Allow display names to be explicitly disabled for testing. + void setUseDisplayNames(bool use); + bool useDisplayNames(); + + void erase(const LLUUID& agent_id); + + // Force a re-fetch of the most recent data, but keep the current + // data in cache + void fetch(const LLUUID& agent_id); + + void insert(const LLUUID& agent_id, const LLAvatarName& av_name); + + // Compute name expiration time from HTTP Cache-Control header, + // or return default value, in seconds from epoch. + F64 nameExpirationFromHeaders(LLSD headers); + + void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb); +} + +// Parse a cache-control header to get the max-age delta-seconds. +// Returns true if header has max-age param and it parses correctly. +// Exported here to ease unit testing. +bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age); + +#endif diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 379f390625..4a66a31c35 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -69,6 +69,8 @@ public: public: bool mIsGroup; U32 mCreateTime; // unix time_t + // IDEVO TODO collapse names to one field, which will eliminate + // many string compares on "Resident" std::string mFirstName; std::string mLastName; std::string mGroupName; @@ -214,7 +216,9 @@ public: Impl(LLMessageSystem* msg); ~Impl(); - + + BOOL getName(const LLUUID& id, std::string& first, std::string& last); + boost::signals2::connection addPending(const LLUUID& id, const LLCacheNameCallback& callback); void addPending(const LLUUID& id, const LLHost& host); @@ -300,89 +304,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback& return impl.mSignal.connect(callback); } -void LLCacheName::importFile(LLFILE* fp) -{ - S32 count = 0; - - const S32 BUFFER_SIZE = 1024; - char buffer[BUFFER_SIZE]; /*Flawfinder: ignore*/ - - // *NOTE: These buffer sizes are hardcoded into sscanf() below - char id_string[MAX_STRING]; /*Flawfinder: ignore*/ - char firstname[MAX_STRING]; /*Flawfinder: ignore*/ - char lastname[MAX_STRING]; /*Flawfinder: ignore*/ - U32 create_time; - - // This is OK if the first line is actually a name. We just don't load it. - char* valid = fgets(buffer, BUFFER_SIZE, fp); - if (!valid) return; - - // *NOTE: This buffer size is hardcoded into sscanf() below - char version_string[BUFFER_SIZE]; /*Flawfinder: ignore*/ - S32 version = 0; - S32 match = sscanf( /* Flawfinder: ignore */ - buffer, - "%1023s %d", - version_string, &version); - if ( match != 2 - || strcmp(version_string, "version") - || version != CN_FILE_VERSION) - { - llwarns << "Ignoring old cache name file format" << llendl; - return; - } - - // We'll expire entries more than a week old - U32 now = (U32)time(NULL); - const U32 SECS_PER_DAY = 60 * 60 * 24; - U32 delete_before_time = now - (7 * SECS_PER_DAY); - - while(!feof(fp)) - { - valid = fgets(buffer, BUFFER_SIZE, fp); - if (!valid) break; - - match = sscanf( /* Flawfinder: ignore */ - buffer, - "%254s %u %254s %254s", - id_string, - &create_time, - firstname, - lastname); - if (4 != match) continue; - - LLUUID id(id_string); - if (id.isNull()) continue; - - // undo trivial XOR - S32 i; - for (i = 0; i < UUID_BYTES; i++) - { - id.mData[i] ^= 0x33; - } - - // Don't load entries that are more than a week old - if (create_time < delete_before_time) continue; - - LLCacheNameEntry* entry = new LLCacheNameEntry(); - entry->mIsGroup = false; - entry->mCreateTime = create_time; - entry->mFirstName = firstname; - entry->mLastName = lastname; - impl.mCache[id] = entry; - std::string fullname = entry->mFirstName + " " + entry->mLastName; - impl.mReverseCache[fullname] = id; - - count++; - } - - llinfos << "LLCacheName loaded " << count << " names" << llendl; -} - bool LLCacheName::importFile(std::istream& istr) { LLSD data; - if(LLSDSerialize::fromXML(data, istr) < 1) + if(LLSDSerialize::fromXMLDocument(data, istr) < 1) return false; // We'll expire entries more than a week old @@ -408,7 +333,7 @@ bool LLCacheName::importFile(std::istream& istr) entry->mFirstName = agent[FIRST].asString(); entry->mLastName = agent[LAST].asString(); impl.mCache[id] = entry; - std::string fullname = entry->mFirstName + " " + entry->mLastName; + std::string fullname = buildFullName(entry->mFirstName, entry->mLastName); impl.mReverseCache[fullname] = id; ++count; @@ -457,6 +382,7 @@ void LLCacheName::exportFile(std::ostream& ostr) // store it LLUUID id = iter->first; std::string id_str = id.asString(); + // IDEVO TODO: Should we store SLIDs with last name "Resident" or not? if(!entry->mFirstName.empty() && !entry->mLastName.empty()) { data[AGENTS][id_str][FIRST] = entry->mFirstName; @@ -474,7 +400,7 @@ void LLCacheName::exportFile(std::ostream& ostr) } -BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& last) +BOOL LLCacheName::Impl::getName(const LLUUID& id, std::string& first, std::string& last) { if(id.isNull()) { @@ -483,7 +409,7 @@ BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& las return TRUE; } - LLCacheNameEntry* entry = get_ptr_in_map(impl.mCache, id ); + LLCacheNameEntry* entry = get_ptr_in_map(mCache, id ); if (entry) { first = entry->mFirstName; @@ -494,16 +420,17 @@ BOOL LLCacheName::getName(const LLUUID& id, std::string& first, std::string& las { first = sCacheName["waiting"]; last.clear(); - if (!impl.isRequestPending(id)) + if (!isRequestPending(id)) { - impl.mAskNameQueue.insert(id); + mAskNameQueue.insert(id); } return FALSE; } } + // static -void LLCacheName::LocalizeCacheName(std::string key, std::string value) +void LLCacheName::localizeCacheName(std::string key, std::string value) { if (key!="" && value!= "" ) sCacheName[key]=value; @@ -514,11 +441,13 @@ void LLCacheName::LocalizeCacheName(std::string key, std::string value) BOOL LLCacheName::getFullName(const LLUUID& id, std::string& fullname) { std::string first_name, last_name; - BOOL res = getName(id, first_name, last_name); - fullname = first_name + " " + last_name; + BOOL res = impl.getName(id, first_name, last_name); + fullname = buildFullName(first_name, last_name); return res; } + + BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) { if(id.isNull()) @@ -555,13 +484,13 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) BOOL LLCacheName::getUUID(const std::string& first, const std::string& last, LLUUID& id) { - std::string fullname = first + " " + last; - return getUUID(fullname, id); + std::string full_name = buildFullName(first, last); + return getUUID(full_name, id); } -BOOL LLCacheName::getUUID(const std::string& fullname, LLUUID& id) +BOOL LLCacheName::getUUID(const std::string& full_name, LLUUID& id) { - ReverseCache::iterator iter = impl.mReverseCache.find(fullname); + ReverseCache::iterator iter = impl.mReverseCache.find(full_name); if (iter != impl.mReverseCache.end()) { id = iter->second; @@ -573,6 +502,55 @@ BOOL LLCacheName::getUUID(const std::string& fullname, LLUUID& id) } } +//static +std::string LLCacheName::buildFullName(const std::string& first, const std::string& last) +{ + std::string fullname = first; + if (!last.empty() + && last != "Resident") + { + fullname += ' '; + fullname += last; + } + return fullname; +} + +//static +std::string LLCacheName::cleanFullName(const std::string& full_name) +{ + return full_name.substr(0, full_name.find(" Resident")); +} + +//static +std::string LLCacheName::buildUsername(const std::string& full_name) +{ + // rare, but handle hard-coded error names returned from server + if (full_name == "(\?\?\?) (\?\?\?)") + { + return "(\?\?\?)"; + } + + std::string::size_type index = full_name.find(' '); + + if (index != std::string::npos) + { + std::string username; + username = full_name.substr(0, index); + std::string lastname = full_name.substr(index+1); + + if (lastname != "Resident") + { + username = username + "." + lastname; + } + + LLStringUtil::toLower(username); + return username; + } + + // if the input wasn't a correctly formatted legacy name just return it unchanged + return full_name; +} + // This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer. // The reason it is a slot is so that the legacy get() function below can bind an old callback // and pass it as a slot. The reason it isn't a boost::function is so that trackable behavior @@ -580,7 +558,7 @@ BOOL LLCacheName::getUUID(const std::string& fullname, LLUUID& id) // we call it immediately. -Steve // NOTE: Even though passing first and last name is a bit of extra overhead, it eliminates the // potential need for any parsing should any code need to handle first and last name independently. -boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback) +boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) { boost::signals2::connection res; @@ -588,7 +566,7 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, co { LLCacheNameSignal signal; signal.connect(callback); - signal(id, sCacheName["nobody"], "", is_group); + signal(id, sCacheName["nobody"], is_group); return res; } @@ -600,11 +578,13 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, co // id found in map therefore we can call the callback immediately. if (entry->mIsGroup) { - signal(id, entry->mGroupName, "", entry->mIsGroup); + signal(id, entry->mGroupName, entry->mIsGroup); } else { - signal(id, entry->mFirstName, entry->mLastName, entry->mIsGroup); + std::string fullname = + buildFullName(entry->mFirstName, entry->mLastName); + signal(id, fullname, entry->mIsGroup); } } else @@ -626,9 +606,15 @@ boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, co return res; } -boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data) +boost::signals2::connection LLCacheName::getGroup(const LLUUID& group_id, + const LLCacheNameCallback& callback) +{ + return get(group_id, true, callback); +} + +boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data) { - return get(id, is_group, boost::bind(callback, _1, _2, _3, _4, user_data)); + return get(id, is_group, boost::bind(callback, _1, _2, _3, user_data)); } void LLCacheName::processPending() @@ -700,7 +686,7 @@ void LLCacheName::dump() { llinfos << iter->first << " = " - << entry->mFirstName << " " << entry->mLastName + << buildFullName(entry->mFirstName, entry->mLastName) << " @ " << entry->mCreateTime << llendl; } @@ -719,12 +705,24 @@ void LLCacheName::dumpStats() << llendl; } +void LLCacheName::clear() +{ + for_each(impl.mCache.begin(), impl.mCache.end(), DeletePairedPointer()); + impl.mCache.clear(); +} + //static std::string LLCacheName::getDefaultName() { return sCacheName["waiting"]; } +//static +std::string LLCacheName::getDefaultLastName() +{ + return "Resident"; +} + void LLCacheName::Impl::processPendingAsks() { LLMemType mt_ppa(LLMemType::MTYPE_CACHE_PROCESS_PENDING_ASKS); @@ -746,11 +744,13 @@ void LLCacheName::Impl::processPendingReplies() if (!entry->mIsGroup) { - (reply->mSignal)(reply->mID, entry->mFirstName, entry->mLastName, FALSE); + std::string fullname = + LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); + (reply->mSignal)(reply->mID, fullname, false); } else { - (reply->mSignal)(reply->mID, entry->mGroupName, "", TRUE); + (reply->mSignal)(reply->mID, entry->mGroupName, true); } } @@ -921,13 +921,27 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup) if (!isGroup) { - mSignal(id, entry->mFirstName, entry->mLastName, FALSE); - std::string fullname = entry->mFirstName + " " + entry->mLastName; - mReverseCache[fullname] = id; + // NOTE: Very occasionally the server sends down a full name + // in the first name field with an empty last name, for example, + // first = "Ladanie1 Resident", last = "". + // I cannot reproduce this, nor can I find a bug in the server code. + // Ensure "Resident" does not appear via cleanFullName, because + // buildFullName only checks last name. JC + std::string full_name; + if (entry->mLastName.empty()) + { + full_name = cleanFullName(entry->mFirstName); + } + else + { + full_name = LLCacheName::buildFullName(entry->mFirstName, entry->mLastName); + } + mSignal(id, full_name, false); + mReverseCache[full_name] = id; } else { - mSignal(id, entry->mGroupName, "", TRUE); + mSignal(id, entry->mGroupName, true); mReverseCache[entry->mGroupName] = id; } } @@ -956,4 +970,3 @@ void LLCacheName::Impl::handleUUIDGroupNameReply(LLMessageSystem* msg, void** us { ((LLCacheName::Impl*)userData)->processUUIDReply(msg, true); } - diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index ab65800cb0..b469803060 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -36,13 +36,12 @@ class LLUUID; typedef boost::signals2::signal<void (const LLUUID& id, - const std::string& first_name, - const std::string& last_name, - BOOL is_group)> LLCacheNameSignal; + const std::string& name, + bool is_group)> LLCacheNameSignal; typedef LLCacheNameSignal::slot_type LLCacheNameCallback; // Old callback with user data for compatability -typedef void (*old_callback_t)(const LLUUID&, const std::string&, const std::string&, BOOL, void*); +typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*); // Here's the theory: // If you request a name that isn't in the cache, it returns "waiting" @@ -65,24 +64,31 @@ public: boost::signals2::connection addObserver(const LLCacheNameCallback& callback); - // janky old format. Remove after a while. Phoenix. 2008-01-30 - void importFile(LLFILE* fp); - // storing cache on disk; for viewer, in name.cache bool importFile(std::istream& istr); void exportFile(std::ostream& ostr); - // If available, copies the first and last name into the strings provided. - // first must be at least DB_FIRST_NAME_BUF_SIZE characters. - // last must be at least DB_LAST_NAME_BUF_SIZE characters. + // If available, copies name ("bobsmith123" or "James Linden") into string // If not available, copies the string "waiting". // Returns TRUE iff available. - BOOL getName(const LLUUID& id, std::string& first, std::string& last); - BOOL getFullName(const LLUUID& id, std::string& fullname); - + BOOL getFullName(const LLUUID& id, std::string& full_name); + // Reverse lookup of UUID from name BOOL getUUID(const std::string& first, const std::string& last, LLUUID& id); BOOL getUUID(const std::string& fullname, LLUUID& id); + + // IDEVO Temporary code + // Clean up new-style "bobsmith123 Resident" names to "bobsmith123" for display + static std::string buildFullName(const std::string& first, const std::string& last); + + // Clean up legacy "bobsmith123 Resident" to "bobsmith123" + // If name does not contain "Resident" returns it unchanged. + static std::string cleanFullName(const std::string& full_name); + + // Converts a standard legacy name to a username + // "bobsmith123 Resident" -> "bobsmith" + // "Random Linden" -> "random.linden" + static std::string buildUsername(const std::string& name); // If available, this method copies the group name into the string // provided. The caller must allocate at least @@ -94,10 +100,15 @@ public: // If the data is currently available, may call the callback immediatly // otherwise, will request the data, and will call the callback when // available. There is no garuntee the callback will ever be called. - boost::signals2::connection get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback); - + boost::signals2::connection get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback); + + // Convenience method for looking up a group name, so you can + // tell the difference between avatar lookup and group lookup + // in global searches + boost::signals2::connection getGroup(const LLUUID& group_id, const LLCacheNameCallback& callback); + // LEGACY - boost::signals2::connection get(const LLUUID& id, BOOL is_group, old_callback_t callback, void* user_data); + boost::signals2::connection get(const LLUUID& id, bool is_group, old_callback_t callback, void* user_data); // This method needs to be called from time to time to send out // requests. void processPending(); @@ -108,9 +119,15 @@ public: // Debugging void dump(); // Dumps the contents of the cache void dumpStats(); // Dumps the sizes of the cache and associated queues. + void clear(); // Deletes all entries from the cache static std::string getDefaultName(); - static void LocalizeCacheName(std::string key, std::string value); + + // Returns "Resident", the default last name for SLID-based accounts + // that have no last name. + static std::string getDefaultLastName(); + + static void localizeCacheName(std::string key, std::string value); static std::map<std::string, std::string> sCacheName; private: diff --git a/indra/llmessage/mean_collision_data.h b/indra/llmessage/mean_collision_data.h index cf1063eb55..29de091603 100644 --- a/indra/llmessage/mean_collision_data.h +++ b/indra/llmessage/mean_collision_data.h @@ -55,7 +55,7 @@ public: LLMeanCollisionData(LLMeanCollisionData *mcd) : mVictim(mcd->mVictim), mPerp(mcd->mPerp), mTime(mcd->mTime), mType(mcd->mType), mMag(mcd->mMag), - mFirstName(mcd->mFirstName), mLastName(mcd->mLastName) + mFullName(mcd->mFullName) { } @@ -89,8 +89,7 @@ public: time_t mTime; EMeanCollisionType mType; F32 mMag; - std::string mFirstName; - std::string mLastName; + std::string mFullName; }; diff --git a/indra/llmessage/tests/llavatarnamecache_test.cpp b/indra/llmessage/tests/llavatarnamecache_test.cpp new file mode 100644 index 0000000000..ec6b65d483 --- /dev/null +++ b/indra/llmessage/tests/llavatarnamecache_test.cpp @@ -0,0 +1,102 @@ +/** + * @file llavatarnamecache_test.cpp + * @author James Cook + * @brief LLAvatarNameCache test cases. + * + * $LicenseInfo:firstyear=2010&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../llavatarnamecache.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct avatarnamecache_data + { + }; + typedef test_group<avatarnamecache_data> avatarnamecache_test; + typedef avatarnamecache_test::object avatarnamecache_object; + tut::avatarnamecache_test avatarnamecache_testcase("LLAvatarNameCache"); + + template<> template<> + void avatarnamecache_object::test<1>() + { + bool valid = false; + S32 max_age = 0; + + valid = max_age_from_cache_control("max-age=3600", &max_age); + ensure("typical input valid", valid); + ensure_equals("typical input parsed", max_age, 3600); + + valid = max_age_from_cache_control( + " max-age=600 , no-cache,private=\"stuff\" ", &max_age); + ensure("complex input valid", valid); + ensure_equals("complex input parsed", max_age, 600); + + valid = max_age_from_cache_control( + "no-cache, max-age = 123 ", &max_age); + ensure("complex input 2 valid", valid); + ensure_equals("complex input 2 parsed", max_age, 123); + } + + template<> template<> + void avatarnamecache_object::test<2>() + { + bool valid = false; + S32 max_age = -1; + + valid = max_age_from_cache_control("", &max_age); + ensure("empty input returns invalid", !valid); + ensure_equals("empty input doesn't change val", max_age, -1); + + valid = max_age_from_cache_control("no-cache", &max_age); + ensure("no max-age field returns invalid", !valid); + + valid = max_age_from_cache_control("max", &max_age); + ensure("just 'max' returns invalid", !valid); + + valid = max_age_from_cache_control("max-age", &max_age); + ensure("partial max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age=", &max_age); + ensure("longer partial max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age=FOO", &max_age); + ensure("invalid integer max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age 234", &max_age); + ensure("space separated max-age is invalid", !valid); + + valid = max_age_from_cache_control("max-age=0", &max_age); + ensure("zero max-age is valid", valid); + + // *TODO: Handle "0000" as zero + //valid = max_age_from_cache_control("max-age=0000", &max_age); + //ensure("multi-zero max-age is valid", valid); + + valid = max_age_from_cache_control("max-age=-123", &max_age); + ensure("less than zero max-age is invalid", !valid); + } +} diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt index fdd510b389..d3a73058c4 100644 --- a/indra/llplugin/CMakeLists.txt +++ b/indra/llplugin/CMakeLists.txt @@ -51,6 +51,14 @@ set(llplugin_HEADER_FILES set_source_files_properties(${llplugin_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) +if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT WORD_SIZE EQUAL 32) + list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES}) add_library (llplugin ${llplugin_SOURCE_FILES}) diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 08d35f9ae7..3fc54573a7 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -79,4 +79,6 @@ if (DARWIN) ) endif (DARWIN) -ll_deploy_sharedlibs_command(SLPlugin) +if (LL_TESTS) + ll_deploy_sharedlibs_command(SLPlugin) +endif (LL_TESTS) diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index edd2cd340b..2dabbc7767 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -52,8 +52,6 @@ #include "lltooltip.h" // Globals -S32 LLCOMBOBOX_HEIGHT = 0; -S32 LLCOMBOBOX_WIDTH = 0; S32 MAX_COMBO_WIDTH = 500; static LLDefaultChildRegistry::Register<LLComboBox> register_combo_box("combo_box"); @@ -486,7 +484,7 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p) LLLineEditor::Params params = p.combo_editor; params.rect(text_entry_rect); params.default_text(LLStringUtil::null); - params.max_length_bytes(mMaxChars); + params.max_length.bytes(mMaxChars); params.commit_callback.function(boost::bind(&LLComboBox::onTextCommit, this, _2)); params.keystroke_callback(boost::bind(&LLComboBox::onTextEntry, this, _1)); params.commit_on_focus_lost(false); @@ -705,10 +703,10 @@ void LLComboBox::onItemSelected(const LLSD& data) setLabel(getSelectedItemLabel()); if (mAllowTextEntry) - { - gFocusMgr.setKeyboardFocus(mTextEntry); - mTextEntry->selectAll(); - } + { + gFocusMgr.setKeyboardFocus(mTextEntry); + mTextEntry->selectAll(); + } } // hiding the list reasserts the old value stored in the text editor/dropdown button hideList(); diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index f369147ded..5f0e4a6843 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -43,9 +43,6 @@ class LLFontGL; class LLViewBorder; -extern S32 LLCOMBOBOX_HEIGHT; -extern S32 LLCOMBOBOX_WIDTH; - class LLComboBox : public LLUICtrl, public LLCtrlListInterface { @@ -224,8 +221,8 @@ private: commit_callback_t mPrearrangeCallback; commit_callback_t mTextEntryCallback; commit_callback_t mSelectionCallback; - boost::signals2::connection mTopLostSignalConnection; - S32 mLastSelectedIndex; + boost::signals2::connection mTopLostSignalConnection; + S32 mLastSelectedIndex; }; // A combo box with icons for the list of items. diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index a1fc977ce1..5f5fe851bb 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -78,7 +78,7 @@ template class LLLineEditor* LLView::getChild<class LLLineEditor>( // LLLineEditor::Params::Params() -: max_length_bytes("max_length", 254), +: max_length(""), keystroke_callback("keystroke_callback"), prevalidate_callback("prevalidate_callback"), background_image("background_image"), @@ -108,7 +108,8 @@ LLLineEditor::Params::Params() LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) : LLUICtrl(p), - mMaxLengthBytes(p.max_length_bytes), + mMaxLengthBytes(p.max_length.bytes), + mMaxLengthChars(p.max_length.chars), mCursorPos( 0 ), mScrollHPos( 0 ), mTextPadLeft(p.text_pad_left), @@ -313,6 +314,12 @@ void LLLineEditor::setMaxTextLength(S32 max_text_length) mMaxLengthBytes = max_len; } +void LLLineEditor::setMaxTextChars(S32 max_text_chars) +{ + S32 max_chars = llmax(0, max_text_chars); + mMaxLengthChars = max_chars; +} + void LLLineEditor::getTextPadding(S32 *left, S32 *right) { *left = mTextPadLeft; @@ -358,6 +365,16 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) } mText.assign(truncated_utf8); + if (mMaxLengthChars) + { + LLWString truncated_wstring = utf8str_to_wstring(truncated_utf8); + if (truncated_wstring.size() > (U32)mMaxLengthChars) + { + truncated_wstring = truncated_wstring.substr(0, mMaxLengthChars); + } + mText.assign(wstring_to_utf8str(truncated_wstring)); + } + if (all_selected) { // ...keep whole thing selected @@ -798,6 +815,7 @@ void LLLineEditor::addChar(const llwchar uni_char) } S32 cur_bytes = mText.getString().size(); + S32 new_bytes = wchar_utf8_length(new_c); BOOL allow_char = TRUE; @@ -807,6 +825,14 @@ void LLLineEditor::addChar(const llwchar uni_char) { allow_char = FALSE; } + else if (mMaxLengthChars) + { + S32 wide_chars = mText.getWString().size(); + if ((wide_chars + 1) > mMaxLengthChars) + { + allow_char = FALSE; + } + } if (allow_char) { @@ -1107,7 +1133,19 @@ void LLLineEditor::pasteHelper(bool is_primary) clean_string = clean_string.substr(0, wchars_that_fit); LLUI::reportBadKeystroke(); } - + + if (mMaxLengthChars) + { + U32 available_chars = mMaxLengthChars - mText.getWString().size(); + + if (available_chars < clean_string.size()) + { + clean_string = clean_string.substr(0, available_chars); + } + + LLUI::reportBadKeystroke(); + } + mText.insert(getCursor(), clean_string); setCursor( getCursor() + (S32)clean_string.length() ); deselect(); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 76d0187712..a1aa6b71c6 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -59,11 +59,19 @@ public: typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t; + struct MaxLength : public LLInitParam::Choice<MaxLength> + { + Alternative<S32> bytes, chars; + + MaxLength() : bytes("max_length_bytes", 254), + chars("max_length_chars", 0) + {} + }; + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { Optional<std::string> default_text; - Optional<S32> max_length_bytes; - + Optional<MaxLength> max_length; Optional<keystroke_callback_t> keystroke_callback; Optional<LLTextValidate::validate_func_t, LLTextValidate::ValidateTextNamedFuncs> prevalidate_callback; @@ -214,6 +222,7 @@ public: void setKeystrokeCallback(callback_t callback, void* user_data); void setMaxTextLength(S32 max_text_length); + void setMaxTextChars(S32 max_text_chars); // Manipulate left and right padding for text void getTextPadding(S32 *left, S32 *right); void setTextPadding(S32 left, S32 right); @@ -277,6 +286,7 @@ protected: LLViewBorder* mBorder; const LLFontGL* mGLFont; S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes + S32 mMaxLengthChars; // Maximum number of characters in the string S32 mCursorPos; // I-beam is just after the mCursorPos-th character. S32 mScrollHPos; // Horizontal offset from the start of mText. Used for scrolling. LLFrameTimer mScrollTimer; diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp index 3df05f4d3f..c1b5efaa72 100644 --- a/indra/llui/llmenubutton.cpp +++ b/indra/llui/llmenubutton.cpp @@ -45,7 +45,8 @@ LLMenuButton::Params::Params() LLMenuButton::LLMenuButton(const LLMenuButton::Params& p) : LLButton(p), mMenu(NULL), - mMenuVisibleLastFrame(false) + mMenuVisibleLastFrame(false), + mMenuPosition(MP_BOTTOM_LEFT) { std::string menu_filename = p.menu_filename; @@ -57,38 +58,51 @@ LLMenuButton::LLMenuButton(const LLMenuButton::Params& p) llwarns << "Error loading menu_button menu" << llendl; } } + + updateMenuOrigin(); } -void LLMenuButton::toggleMenu() +boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_signal_t::slot_type& cb ) { - if(!mMenu) - return; + return LLUICtrl::setMouseDownCallback(cb); +} - if (mMenu->getVisible() || mMenuVisibleLastFrame) - { - mMenu->setVisible(FALSE); - } - else +void LLMenuButton::hideMenu() +{ + if(!mMenu) return; + mMenu->setVisible(FALSE); +} + +void LLMenuButton::setMenu(LLMenuGL* menu, EMenuPosition position /*MP_TOP_LEFT*/) +{ + mMenu = menu; + mMenuPosition = position; +} + +void LLMenuButton::draw() +{ + //we save this off so next frame when we try to close it by + //button click, and it hides menus before we get to it, we know + mMenuVisibleLastFrame = mMenu && mMenu->getVisible(); + + if (mMenuVisibleLastFrame) { - LLRect rect = getRect(); - //mMenu->needsArrange(); //so it recalculates the visible elements - LLMenuGL::showPopup(getParent(), mMenu, rect.mLeft, rect.mBottom); + setForcePressedState(true); } -} + LLButton::draw(); -void LLMenuButton::hideMenu() -{ - if(!mMenu) - return; - mMenu->setVisible(FALSE); + setForcePressedState(false); } - BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask ) { if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key)) { + // *HACK: We emit the mouse down signal to fire the callback bound to the + // menu emerging event before actually displaying the menu. See STORM-263. + LLUICtrl::handleMouseDown(-1, -1, MASK_NONE); + toggleMenu(); return TRUE; } @@ -104,34 +118,52 @@ BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask ) BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask) { - if (hasTabStop() && !getIsChrome()) - { - setFocus(TRUE); - } - + LLButton::handleMouseDown(x, y, mask); toggleMenu(); - if (getSoundFlags() & MOUSE_DOWN) - { - make_ui_sound("UISndClick"); - } - return TRUE; } -void LLMenuButton::draw() +void LLMenuButton::toggleMenu() { - //we save this off so next frame when we try to close it by - //button click, and it hides menus before we get to it, we know - mMenuVisibleLastFrame = mMenu && mMenu->getVisible(); - - if (mMenuVisibleLastFrame) + if(!mMenu) return; + + if (mMenu->getVisible() || mMenuVisibleLastFrame) { - setForcePressedState(true); + mMenu->setVisible(FALSE); } + else + { + mMenu->buildDrawLabels(); + mMenu->arrangeAndClear(); + mMenu->updateParent(LLMenuGL::sMenuContainer); - LLButton::draw(); + updateMenuOrigin(); - setForcePressedState(false); + //mMenu->needsArrange(); //so it recalculates the visible elements + LLMenuGL::showPopup(getParent(), mMenu, mX, mY); + } } +void LLMenuButton::updateMenuOrigin() +{ + if (!mMenu) return; + + LLRect rect = getRect(); + + switch (mMenuPosition) + { + case MP_TOP_LEFT: + { + mX = rect.mLeft; + mY = rect.mTop + mMenu->getRect().getHeight(); + break; + } + case MP_BOTTOM_LEFT: + { + mX = rect.mLeft; + mY = rect.mBottom; + break; + } + } +} diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h index 81ca0e047c..81c3592b16 100644 --- a/indra/llui/llmenubutton.h +++ b/indra/llui/llmenubutton.h @@ -42,22 +42,40 @@ public: Optional<std::string> menu_filename; Params(); - }; + }; + + typedef enum e_menu_position + { + MP_TOP_LEFT, + MP_BOTTOM_LEFT + } EMenuPosition; - void toggleMenu(); + boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ); + /*virtual*/ void draw(); /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask ); + void hideMenu(); + LLMenuGL* getMenu() { return mMenu; } + void setMenu(LLMenuGL* menu, EMenuPosition position = MP_TOP_LEFT); + + void setMenuPosition(EMenuPosition position) { mMenuPosition = position; } protected: friend class LLUICtrlFactory; LLMenuButton(const Params&); + void toggleMenu(); + void updateMenuOrigin(); + private: - LLMenuGL* mMenu; - bool mMenuVisibleLastFrame; + LLMenuGL* mMenu; + bool mMenuVisibleLastFrame; + EMenuPosition mMenuPosition; + S32 mX; + S32 mY; }; diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 6d590cf54e..a6cf86d9b8 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1848,89 +1848,104 @@ BOOL LLMenuGL::isOpen() } } -void LLMenuGL::scrollItemsUp() + + +bool LLMenuGL::scrollItems(EScrollingDirection direction) { - // Slowing down the items scrolling when arrow button is held + // Slowing down items scrolling when arrow button is held if (mScrollItemsTimer.hasExpired() && NULL != mFirstVisibleItem) { mScrollItemsTimer.setTimerExpirySec(.033f); } else { - return; + return false; } - item_list_t::iterator cur_item_iter; - item_list_t::iterator prev_item_iter; - for (cur_item_iter = mItems.begin(), prev_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++) + switch (direction) { - if( (*cur_item_iter) == mFirstVisibleItem) + case SD_UP: + { + item_list_t::iterator cur_item_iter; + item_list_t::iterator prev_item_iter; + for (cur_item_iter = mItems.begin(), prev_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++) { - break; + if( (*cur_item_iter) == mFirstVisibleItem) + { + break; + } + if ((*cur_item_iter)->getVisible()) + { + prev_item_iter = cur_item_iter; + } } - if ((*cur_item_iter)->getVisible()) + + if ((*prev_item_iter)->getVisible()) { - prev_item_iter = cur_item_iter; + mFirstVisibleItem = *prev_item_iter; } + break; } - - if ((*prev_item_iter)->getVisible()) - { - mFirstVisibleItem = *prev_item_iter; - } - - mNeedsArrange = TRUE; - arrangeAndClear(); -} - -void LLMenuGL::scrollItemsDown() -{ - // Slowing down the items scrolling when arrow button is held - if (mScrollItemsTimer.hasExpired()) - { - mScrollItemsTimer.setTimerExpirySec(.033f); - } - else - { - return; - } - - if (NULL == mFirstVisibleItem) - { - mFirstVisibleItem = *mItems.begin(); - } - - item_list_t::iterator cur_item_iter; - - for (cur_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++) + case SD_DOWN: { - if( (*cur_item_iter) == mFirstVisibleItem) + if (NULL == mFirstVisibleItem) { - break; + mFirstVisibleItem = *mItems.begin(); } - } - item_list_t::iterator next_item_iter; + item_list_t::iterator cur_item_iter; - if (cur_item_iter != mItems.end()) - { - for (next_item_iter = ++cur_item_iter; next_item_iter != mItems.end(); next_item_iter++) + for (cur_item_iter = mItems.begin(); cur_item_iter != mItems.end(); cur_item_iter++) { - if( (*next_item_iter)->getVisible()) + if( (*cur_item_iter) == mFirstVisibleItem) { break; } } - - if (next_item_iter != mItems.end() && - (*next_item_iter)->getVisible()) + + item_list_t::iterator next_item_iter; + + if (cur_item_iter != mItems.end()) { - mFirstVisibleItem = *next_item_iter; + for (next_item_iter = ++cur_item_iter; next_item_iter != mItems.end(); next_item_iter++) + { + if( (*next_item_iter)->getVisible()) + { + break; + } + } + + if (next_item_iter != mItems.end() && + (*next_item_iter)->getVisible()) + { + mFirstVisibleItem = *next_item_iter; + } } + break; } - + case SD_BEGIN: + { + mFirstVisibleItem = *mItems.begin(); + break; + } + case SD_END: + { + item_list_t::reverse_iterator first_visible_item_iter = mItems.rend(); + + // Advance by mMaxScrollableItems back from the end of the list + // to make the last item visible. + std::advance(first_visible_item_iter, mMaxScrollableItems); + mFirstVisibleItem = *first_visible_item_iter; + break; + } + default: + llwarns << "Unknown scrolling direction: " << direction << llendl; + } + mNeedsArrange = TRUE; arrangeAndClear(); + + return true; } // rearrange the child rects so they fit the shape of the menu. @@ -2162,7 +2177,7 @@ void LLMenuGL::arrange( void ) LLMenuScrollItem::Params item_params; item_params.name(ARROW_UP); item_params.arrow_type(LLMenuScrollItem::ARROW_UP); - item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItemsUp, this)); + item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItems, this, SD_UP)); mArrowUpItem = LLUICtrlFactory::create<LLMenuScrollItem>(item_params); LLUICtrl::addChild(mArrowUpItem); @@ -2173,7 +2188,7 @@ void LLMenuGL::arrange( void ) LLMenuScrollItem::Params item_params; item_params.name(ARROW_DOWN); item_params.arrow_type(LLMenuScrollItem::ARROW_DOWN); - item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItemsDown, this)); + item_params.scroll_callback.function(boost::bind(&LLMenuGL::scrollItems, this, SD_DOWN)); mArrowDownItem = LLUICtrlFactory::create<LLMenuScrollItem>(item_params); LLUICtrl::addChild(mArrowDownItem); @@ -2603,14 +2618,8 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa ((LLFloater*)getParent())->setFocus(TRUE); } - item_list_t::iterator cur_item_iter; - for (cur_item_iter = mItems.begin(); cur_item_iter != mItems.end(); ++cur_item_iter) - { - if( (*cur_item_iter) == cur_item) - { - break; - } - } + // Current item position in the items list + item_list_t::iterator cur_item_iter = std::find(mItems.begin(), mItems.end(), cur_item); item_list_t::iterator next_item_iter; if (cur_item_iter == mItems.end()) @@ -2621,9 +2630,37 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa { next_item_iter = cur_item_iter; next_item_iter++; + + // First visible item position in the items list + item_list_t::iterator first_visible_item_iter = std::find(mItems.begin(), mItems.end(), mFirstVisibleItem); + if (next_item_iter == mItems.end()) { next_item_iter = mItems.begin(); + + // If current item is the last in the list, the menu is scrolled to the beginning + // and the first item is highlighted. + if (mScrollable && !scrollItems(SD_BEGIN)) + { + return NULL; + } + } + // If current item is the last visible, the menu is scrolled one item down + // and the next item is highlighted. + else if (mScrollable && + (U32)std::abs(std::distance(first_visible_item_iter, next_item_iter)) >= mMaxScrollableItems) + { + // Call highlightNextItem() recursively only if the menu was successfully scrolled down. + // If scroll timer hasn't expired yet the menu won't be scrolled and calling + // highlightNextItem() will result in an endless recursion. + if (scrollItems(SD_DOWN)) + { + return highlightNextItem(cur_item, skip_disabled); + } + else + { + return NULL; + } } } @@ -2681,14 +2718,8 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa ((LLFloater*)getParent())->setFocus(TRUE); } - item_list_t::reverse_iterator cur_item_iter; - for (cur_item_iter = mItems.rbegin(); cur_item_iter != mItems.rend(); ++cur_item_iter) - { - if( (*cur_item_iter) == cur_item) - { - break; - } - } + // Current item reverse position from the end of the list + item_list_t::reverse_iterator cur_item_iter = std::find(mItems.rbegin(), mItems.rend(), cur_item); item_list_t::reverse_iterator prev_item_iter; if (cur_item_iter == mItems.rend()) @@ -2699,9 +2730,37 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa { prev_item_iter = cur_item_iter; prev_item_iter++; + + // First visible item reverse position in the items list + item_list_t::reverse_iterator first_visible_item_iter = std::find(mItems.rbegin(), mItems.rend(), mFirstVisibleItem); + if (prev_item_iter == mItems.rend()) { prev_item_iter = mItems.rbegin(); + + // If current item is the first in the list, the menu is scrolled to the end + // and the last item is highlighted. + if (mScrollable && !scrollItems(SD_END)) + { + return NULL; + } + } + // If current item is the first visible, the menu is scrolled one item up + // and the previous item is highlighted. + else if (mScrollable && + std::distance(first_visible_item_iter, cur_item_iter) <= 0) + { + // Call highlightNextItem() only if the menu was successfully scrolled up. + // If scroll timer hasn't expired yet the menu won't be scrolled and calling + // highlightNextItem() will result in an endless recursion. + if (scrollItems(SD_UP)) + { + return highlightPrevItem(cur_item, skip_disabled); + } + else + { + return NULL; + } } } @@ -2872,12 +2931,12 @@ BOOL LLMenuGL::handleScrollWheel( S32 x, S32 y, S32 clicks ) if( clicks > 0 ) { while( clicks-- ) - scrollItemsDown(); + scrollItems(SD_DOWN); } else { while( clicks++ ) - scrollItemsUp(); + scrollItems(SD_UP); } return TRUE; diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 19b738312e..35544402f4 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -397,6 +397,15 @@ public: static const std::string ARROW_UP; static const std::string ARROW_DOWN; + // for scrollable menus + typedef enum e_scrolling_direction + { + SD_UP = 0, + SD_DOWN = 1, + SD_BEGIN = 2, + SD_END = 3 + } EScrollingDirection; + protected: LLMenuGL(const LLMenuGL::Params& p); friend class LLUICtrlFactory; @@ -503,8 +512,7 @@ public: S32 getShortcutPad() { return mShortcutPad; } - void scrollItemsUp(); - void scrollItemsDown(); + bool scrollItems(EScrollingDirection direction); BOOL isScrollable() const { return mScrollable; } static class LLMenuHolderGL* sMenuContainer; diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index bd65625f53..91e5b6b9de 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -130,7 +130,7 @@ LLMultiSliderCtrl::LLMultiSliderCtrl(const LLMultiSliderCtrl::Params& p) params.name("MultiSliderCtrl Editor"); params.rect(text_rect); params.font(p.font); - params.max_length_bytes(MAX_STRING_LENGTH); + params.max_length.bytes(MAX_STRING_LENGTH); params.commit_callback.function(LLMultiSliderCtrl::onEditorCommit); params.prevalidate_callback(&LLTextValidate::validateFloat); params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM); diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 30cd85619e..dd6c632d10 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -29,7 +29,9 @@ #include "llnotifications.h" #include "llnotificationtemplate.h" +#include "llavatarnamecache.h" #include "llinstantmessage.h" +#include "llcachename.h" #include "llxmlnode.h" #include "lluictrl.h" #include "lluictrlfactory.h" @@ -79,7 +81,9 @@ LLNotificationForm::FormButton::FormButton() LLNotificationForm::FormInput::FormInput() : type("type"), - width("width", 0) + max_length_chars("max_length_chars"), + width("width", 0), + value("value") {} LLNotificationForm::FormElement::FormElement() @@ -1552,17 +1556,50 @@ std::ostream& operator<<(std::ostream& s, const LLNotification& notification) return s; } -void LLPostponedNotification::onCachedNameReceived(const LLUUID& id, const std::string& first, - const std::string& last, bool is_group) +//static +void LLPostponedNotification::lookupName(LLPostponedNotification* thiz, + const LLUUID& id, + bool is_group) +{ + if (is_group) + { + gCacheName->getGroup(id, + boost::bind(&LLPostponedNotification::onGroupNameCache, + thiz, _1, _2, _3)); + } + else + { + LLAvatarNameCache::get(id, + boost::bind(&LLPostponedNotification::onAvatarNameCache, + thiz, _1, _2)); + } +} + +void LLPostponedNotification::onGroupNameCache(const LLUUID& id, + const std::string& full_name, + bool is_group) +{ + finalizeName(full_name); +} + +void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name) { - mName = first + " " + last; + std::string name = av_name.getCompleteName(); - LLStringUtil::trim(mName); - if (mName.empty()) + // from PE merge - we should figure out if this is the right thing to do + if (name.empty()) { - llwarns << "Empty name received for Id: " << id << llendl; - mName = SYSTEM_FROM; + llwarns << "Empty name received for Id: " << agent_id << llendl; + name = SYSTEM_FROM; } + + finalizeName(name); +} + +void LLPostponedNotification::finalizeName(const std::string& name) +{ + mName = name; modifyNotificationParams(); LLNotifications::instance().add(mParams); cleanup(); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index f075c44520..524cff70e8 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -98,8 +98,8 @@ #include "llinitparam.h" #include "llnotificationslistener.h" #include "llnotificationptr.h" -#include "llcachename.h" +class LLAvatarName; typedef enum e_notification_priority { NOTIFICATION_PRIORITY_UNSPECIFIED, @@ -194,7 +194,9 @@ public: { Mandatory<std::string> type; Optional<S32> width; + Optional<S32> max_length_chars; + Optional<std::string> value; FormInput(); }; @@ -973,17 +975,20 @@ public: { // upcast T to the base type to restrict T derivation from LLPostponedNotification LLPostponedNotification* thiz = new T(); - thiz->mParams = params; - gCacheName->get(id, is_group, boost::bind( - &LLPostponedNotification::onCachedNameReceived, thiz, _1, _2, - _3, _4)); + // Avoid header file dependency on llcachename.h + lookupName(thiz, id, is_group); } private: - void onCachedNameReceived(const LLUUID& id, const std::string& first, - const std::string& last, bool is_group); + static void lookupName(LLPostponedNotification* thiz, const LLUUID& id, bool is_group); + // only used for groups + void onGroupNameCache(const LLUUID& id, const std::string& full_name, bool is_group); + // only used for avatars + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + // used for both group and avatar names + void finalizeName(const std::string& name); void cleanup() { diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 9decfa0b25..6b4e9cf923 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -119,7 +119,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) { params.font(p.font); } - params.max_length_bytes(MAX_STRING_LENGTH); + params.max_length.bytes(MAX_STRING_LENGTH); params.commit_callback.function((boost::bind(&LLSpinCtrl::onEditorCommit, this, _2))); if( mPrecision>0 )//should accept float numbers diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index 5e09cee78b..28a064e6b6 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -40,7 +40,8 @@ LLStyle::Params::Params() selected_color("selected_color", LLColor4::black), font("font", LLFontGL::getFontMonospace()), image("image"), - link_href("href") + link_href("href"), + is_link("is_link") {} @@ -51,6 +52,7 @@ LLStyle::LLStyle(const LLStyle::Params& p) mSelectedColor(p.selected_color), mFont(p.font()), mLink(p.link_href), + mIsLink(p.is_link.isProvided() ? p.is_link : !p.link_href().empty()), mDropShadow(p.drop_shadow), mImagep(p.image()) {} @@ -73,7 +75,7 @@ void LLStyle::setLinkHREF(const std::string& href) BOOL LLStyle::isLink() const { - return mLink.size(); + return mIsLink; } BOOL LLStyle::isVisible() const diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 66cd639936..322edc343c 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -46,6 +46,7 @@ public: Optional<const LLFontGL*> font; Optional<LLUIImage*> image; Optional<std::string> link_href; + Optional<bool> is_link; Params(); }; LLStyle(const Params& p = Params()); @@ -106,6 +107,7 @@ private: std::string mFontName; const LLFontGL* mFont; std::string mLink; + bool mIsLink; LLUIImagePtr mImagep; }; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 574b24cf13..758df418e8 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2009-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 @@ -475,8 +475,8 @@ void LLTextBase::drawCursor() { LLColor4 text_color; const LLFontGL* fontp; - text_color = segmentp->getColor(); - fontp = segmentp->getStyle()->getFont(); + text_color = segmentp->getColor(); + fontp = segmentp->getStyle()->getFont(); fontp->render(text, mCursorPos, cursor_rect, LLColor4(1.f - text_color.mV[VRED], 1.f - text_color.mV[VGREEN], 1.f - text_color.mV[VBLUE], alpha), LLFontGL::LEFT, mVAlign, @@ -1602,28 +1602,39 @@ std::string LLTextBase::getText() const return getViewModel()->getValue().asString(); } +// IDEVO - icons can be UI image names or UUID sent from +// server with avatar display name +static LLUIImagePtr image_from_icon_name(const std::string& icon_name) +{ + if (LLUUID::validate(icon_name)) + { + return LLUI::getUIImageByID( LLUUID(icon_name) ); + } + else + { + return LLUI::getUIImage(icon_name); + } +} + void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params) { LLStyle::Params style_params(input_params); style_params.fillFrom(getDefaultStyleParams()); S32 part = (S32)LLTextParser::WHOLE; - if(mParseHTML) + if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358). { S32 start=0,end=0; LLUrlMatch match; std::string text = new_text; while ( LLUrlRegistry::instance().findUrl(text, match, - boost::bind(&LLTextBase::replaceUrlLabel, this, _1, _2)) ) + boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) { start = match.getStart(); end = match.getEnd()+1; - LLStyle::Params link_params = style_params; - link_params.color = match.getColor(); - link_params.readonly_color = match.getColor(); - link_params.font.style("UNDERLINE"); - link_params.link_href = match.getUrl(); + LLStyle::Params link_params(style_params); + link_params.overwriteFrom(match.getStyle()); // output the text before the Url if (start > 0) @@ -1644,26 +1655,20 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para // inserts an avatar icon preceding the Url if appropriate LLTextUtil::processUrlMatch(&match,this); - // output the styled Url (unless we've been asked to suppress hyperlinking) - if (match.isLinkDisabled()) + // output the styled Url + appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.underlineOnHoverOnly()); + + // set the tooltip for the Url label + if (! match.getTooltip().empty()) { - appendAndHighlightText(match.getLabel(), part, style_params); + segment_set_t::iterator it = getSegIterContaining(getLength()-1); + if (it != mSegments.end()) + { + LLTextSegmentPtr segment = *it; + segment->setToolTip(match.getTooltip()); + } } - else - { - appendAndHighlightText(match.getLabel(), part, link_params, match.underlineOnHoverOnly()); - // set the tooltip for the Url label - if (! match.getTooltip().empty()) - { - segment_set_t::iterator it = getSegIterContaining(getLength()-1); - if (it != mSegments.end()) - { - LLTextSegmentPtr segment = *it; - segment->setToolTip(match.getTooltip()); - } - } - } // move on to the rest of the text after the Url if (end < (S32)text.length()) { @@ -1848,8 +1853,9 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig } -void LLTextBase::replaceUrlLabel(const std::string &url, - const std::string &label) +void LLTextBase::replaceUrl(const std::string &url, + const std::string &label, + const std::string &icon) { // get the full (wide) text for the editor so we can change it LLWString text = getWText(); @@ -1870,7 +1876,7 @@ void LLTextBase::replaceUrlLabel(const std::string &url, seg->setEnd(seg_start + seg_length); // if we find a link with our Url, then replace the label - if (style->isLink() && style->getLinkHREF() == url) + if (style->getLinkHREF() == url) { S32 start = seg->getStart(); S32 end = seg->getEnd(); @@ -1879,6 +1885,21 @@ void LLTextBase::replaceUrlLabel(const std::string &url, modified = true; } + // Icon might be updated when more avatar or group info + // becomes available + if (style->isImage() && style->getLinkHREF() == url) + { + LLUIImagePtr image = image_from_icon_name( icon ); + if (image) + { + LLStyle::Params icon_params; + icon_params.image = image; + LLStyleConstSP new_style(new LLStyle(icon_params)); + seg->setStyle(new_style); + modified = true; + } + } + // work out the character offset for the next segment seg_start = seg->getEnd(); } @@ -1976,8 +1997,8 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, else if (hit_past_end_of_line && segmentp->getEnd() > line_iter->mDocIndexEnd - 1) { // segment wraps to next line, so just set doc pos to the end of the line - // segment wraps to next line, so just set doc pos to start of next line (represented by mDocIndexEnd) - pos = llmin(getLength(), line_iter->mDocIndexEnd); + // segment wraps to next line, so just set doc pos to start of next line (represented by mDocIndexEnd) + pos = llmin(getLength(), line_iter->mDocIndexEnd); break; } start_x += text_width; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 1fa449a182..aafcf8ceb0 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -493,7 +493,11 @@ protected: // misc void updateRects(); void needsScroll() { mScrollNeeded = TRUE; } - void replaceUrlLabel(const std::string &url, const std::string &label); + + struct URLLabelCallback; + // Replace a URL with a new icon and label, for example, when + // avatar names are looked up. + void replaceUrl(const std::string &url, const std::string &label, const std::string& icon); void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params()); void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 5680ab8bd4..f49dfec82b 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -31,18 +31,19 @@ #include "llurlmatch.h" #include "llurlregistry.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "lltrans.h" #include "lluicolortable.h" #define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" +// Utility functions +std::string localize_slapp_label(const std::string& url, const std::string& full_name); -LLUrlEntryBase::LLUrlEntryBase() : - mColor(LLUIColorTable::instance().getColor("HTMLLinkColor")), - mDisabledLink(false) -{ -} + +LLUrlEntryBase::LLUrlEntryBase() +{} LLUrlEntryBase::~LLUrlEntryBase() { @@ -53,6 +54,22 @@ std::string LLUrlEntryBase::getUrl(const std::string &string) const return escapeUrl(string); } +//virtual +std::string LLUrlEntryBase::getIcon(const std::string &url) +{ + return mIcon; +} + +LLStyle::Params LLUrlEntryBase::getStyle() const +{ + LLStyle::Params style_params; + style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + style_params.font.style = "UNDERLINE"; + return style_params; +} + + std::string LLUrlEntryBase::getIDStringFromUrl(const std::string &url) const { // return the id from a SLURL in the format /app/{cmd}/{id}/about @@ -130,16 +147,20 @@ void LLUrlEntryBase::addObserver(const std::string &id, mObservers.insert(std::pair<std::string, LLUrlEntryObserver>(id, observer)); } } - -void LLUrlEntryBase::callObservers(const std::string &id, const std::string &label) + +// *NOTE: See also LLUrlEntryAgent::callObservers() +void LLUrlEntryBase::callObservers(const std::string &id, + const std::string &label, + const std::string &icon) { // notify all callbacks waiting on the given uuid - std::multimap<std::string, LLUrlEntryObserver>::iterator it; - for (it = mObservers.find(id); it != mObservers.end();) + typedef std::multimap<std::string, LLUrlEntryObserver>::iterator observer_it; + std::pair<observer_it, observer_it> matching_range = mObservers.equal_range(id); + for (observer_it it = matching_range.first; it != matching_range.second;) { // call the callback - give it the new label LLUrlEntryObserver &observer = it->second; - (*observer.signal)(it->second.url, label); + (*observer.signal)(it->second.url, label, icon); // then remove the signal - we only need to call it once delete observer.signal; mObservers.erase(it++); @@ -308,16 +329,35 @@ LLUrlEntryAgent::LLUrlEntryAgent() boost::regex::perl|boost::regex::icase); mMenuName = "menu_url_agent.xml"; mIcon = "Generic_Person"; - mColor = LLUIColorTable::instance().getColor("AgentLinkColor"); } -void LLUrlEntryAgent::onAgentNameReceived(const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) +// virtual +void LLUrlEntryAgent::callObservers(const std::string &id, + const std::string &label, + const std::string &icon) { + // notify all callbacks waiting on the given uuid + typedef std::multimap<std::string, LLUrlEntryObserver>::iterator observer_it; + std::pair<observer_it, observer_it> matching_range = mObservers.equal_range(id); + for (observer_it it = matching_range.first; it != matching_range.second;) + { + // call the callback - give it the new label + LLUrlEntryObserver &observer = it->second; + std::string final_label = localize_slapp_label(observer.url, label); + (*observer.signal)(observer.url, final_label, icon); + // then remove the signal - we only need to call it once + delete observer.signal; + mObservers.erase(it++); + } +} + +void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id, + const LLAvatarName& av_name) +{ + std::string label = av_name.getCompleteName(); + // received the agent name from the server - tell our observers - callObservers(id.asString(), first + " " + last); + callObservers(id.asString(), label, mIcon); } LLUUID LLUrlEntryAgent::getID(const std::string &string) const @@ -330,6 +370,10 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const // return a tooltip corresponding to the URL type instead of the generic one std::string url = getUrl(string); + if (LLStringUtil::endsWith(url, "/inspect")) + { + return LLTrans::getString("TooltipAgentInspect"); + } if (LLStringUtil::endsWith(url, "/mute")) { return LLTrans::getString("TooltipAgentMute"); @@ -379,50 +423,182 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa } LLUUID agent_id(agent_id_string); - std::string full_name; if (agent_id.isNull()) { return LLTrans::getString("AvatarNameNobody"); } - else if (gCacheName->getFullName(agent_id, full_name)) - { - // customize label string based on agent SLapp suffix - if (LLStringUtil::endsWith(url, "/mute")) - { - return LLTrans::getString("SLappAgentMute") + " " + full_name; - } - if (LLStringUtil::endsWith(url, "/unmute")) - { - return LLTrans::getString("SLappAgentUnmute") + " " + full_name; - } - if (LLStringUtil::endsWith(url, "/im")) - { - return LLTrans::getString("SLappAgentIM") + " " + full_name; - } - if (LLStringUtil::endsWith(url, "/pay")) - { - return LLTrans::getString("SLappAgentPay") + " " + full_name; - } - if (LLStringUtil::endsWith(url, "/offerteleport")) - { - return LLTrans::getString("SLappAgentOfferTeleport") + " " + full_name; - } - if (LLStringUtil::endsWith(url, "/requestfriend")) - { - return LLTrans::getString("SLappAgentRequestFriend") + " " + full_name; - } - return full_name; + + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_id, &av_name)) + { + std::string label = av_name.getCompleteName(); + + // handle suffixes like /mute or /offerteleport + label = localize_slapp_label(url, label); + return label; } else { - gCacheName->get(agent_id, FALSE, - boost::bind(&LLUrlEntryAgent::onAgentNameReceived, - this, _1, _2, _3, _4)); + LLAvatarNameCache::get(agent_id, + boost::bind(&LLUrlEntryAgent::onAvatarNameCache, + this, _1, _2)); addObserver(agent_id_string, url, cb); return LLTrans::getString("LoadingData"); } } +LLStyle::Params LLUrlEntryAgent::getStyle() const +{ + LLStyle::Params style_params = LLUrlEntryBase::getStyle(); + style_params.color = LLUIColorTable::instance().getColor("AgentLinkColor"); + style_params.readonly_color = LLUIColorTable::instance().getColor("AgentLinkColor"); + return style_params; +} + +std::string localize_slapp_label(const std::string& url, const std::string& full_name) +{ + // customize label string based on agent SLapp suffix + if (LLStringUtil::endsWith(url, "/mute")) + { + return LLTrans::getString("SLappAgentMute") + " " + full_name; + } + if (LLStringUtil::endsWith(url, "/unmute")) + { + return LLTrans::getString("SLappAgentUnmute") + " " + full_name; + } + if (LLStringUtil::endsWith(url, "/im")) + { + return LLTrans::getString("SLappAgentIM") + " " + full_name; + } + if (LLStringUtil::endsWith(url, "/pay")) + { + return LLTrans::getString("SLappAgentPay") + " " + full_name; + } + if (LLStringUtil::endsWith(url, "/offerteleport")) + { + return LLTrans::getString("SLappAgentOfferTeleport") + " " + full_name; + } + if (LLStringUtil::endsWith(url, "/requestfriend")) + { + return LLTrans::getString("SLappAgentRequestFriend") + " " + full_name; + } + return full_name; +} + + +std::string LLUrlEntryAgent::getIcon(const std::string &url) +{ + // *NOTE: Could look up a badge here by calling getIDStringFromUrl() + // and looking up the badge for the agent. + return mIcon; +} + +// +// LLUrlEntryAgentName describes a Second Life agent name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) +// +LLUrlEntryAgentName::LLUrlEntryAgentName() +{} + +void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id, + const LLAvatarName& av_name) +{ + std::string label = getName(av_name); + // received the agent name from the server - tell our observers + callObservers(id.asString(), label, mIcon); +} + +std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLabelCallback &cb) +{ + if (!gCacheName) + { + // probably at the login screen, use short string for layout + return LLTrans::getString("LoadingData"); + } + + std::string agent_id_string = getIDStringFromUrl(url); + if (agent_id_string.empty()) + { + // something went wrong, just give raw url + return unescapeUrl(url); + } + + LLUUID agent_id(agent_id_string); + if (agent_id.isNull()) + { + return LLTrans::getString("AvatarNameNobody"); + } + + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_id, &av_name)) + { + return getName(av_name); + } + else + { + LLAvatarNameCache::get(agent_id, + boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache, + this, _1, _2)); + addObserver(agent_id_string, url, cb); + return LLTrans::getString("LoadingData"); + } +} + +LLStyle::Params LLUrlEntryAgentName::getStyle() const +{ + // don't override default colors + return LLStyle::Params().is_link(false); +} + +// +// LLUrlEntryAgentCompleteName describes a Second Life agent complete name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename +// +LLUrlEntryAgentCompleteName::LLUrlEntryAgentCompleteName() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/completename", + boost::regex::perl|boost::regex::icase); +} + +std::string LLUrlEntryAgentCompleteName::getName(const LLAvatarName& avatar_name) +{ + return avatar_name.getCompleteName(); +} + +// +// LLUrlEntryAgentDisplayName describes a Second Life agent display name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname +// +LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/displayname", + boost::regex::perl|boost::regex::icase); +} + +std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name) +{ + return avatar_name.mDisplayName; +} + +// +// LLUrlEntryAgentUserName describes a Second Life agent user name Url, e.g., +// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username +// x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username +// +LLUrlEntryAgentUserName::LLUrlEntryAgentUserName() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/username", + boost::regex::perl|boost::regex::icase); +} + +std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name) +{ + return avatar_name.mUsername.empty() ? avatar_name.getLegacyName() : avatar_name.mUsername; +} + // // LLUrlEntryGroup Describes a Second Life group Url, e.g., // secondlife:///app/group/00005ff3-4044-c79f-9de8-fb28ae0df991/about @@ -436,18 +612,16 @@ LLUrlEntryGroup::LLUrlEntryGroup() mMenuName = "menu_url_group.xml"; mIcon = "Generic_Group"; mTooltip = LLTrans::getString("TooltipGroupUrl"); - mColor = LLUIColorTable::instance().getColor("GroupLinkColor"); } void LLUrlEntryGroup::onGroupNameReceived(const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) + const std::string& name, + bool is_group) { // received the group name from the server - tell our observers - callObservers(id.asString(), first); + callObservers(id.asString(), name, mIcon); } LLUUID LLUrlEntryGroup::getID(const std::string &string) const @@ -483,14 +657,23 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa } else { - gCacheName->get(group_id, TRUE, + gCacheName->getGroup(group_id, boost::bind(&LLUrlEntryGroup::onGroupNameReceived, - this, _1, _2, _3, _4)); + this, _1, _2, _3)); addObserver(group_id_string, url, cb); return LLTrans::getString("LoadingData"); } } +LLStyle::Params LLUrlEntryGroup::getStyle() const +{ + LLStyle::Params style_params = LLUrlEntryBase::getStyle(); + style_params.color = LLUIColorTable::instance().getColor("GroupLinkColor"); + style_params.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor"); + return style_params; +} + + // // LLUrlEntryInventory Describes a Second Life inventory Url, e.g., // secondlife:///app/inventory/0e346d8b-4433-4d66-a6b0-fd37083abc4c/select @@ -789,9 +972,8 @@ std::string LLUrlEntryWorldMap::getLocation(const std::string &url) const // LLUrlEntryNoLink::LLUrlEntryNoLink() { - mPattern = boost::regex("<nolink>[^<]*</nolink>", + mPattern = boost::regex("<nolink>.*</nolink>", boost::regex::perl|boost::regex::icase); - mDisabledLink = true; } std::string LLUrlEntryNoLink::getUrl(const std::string &url) const @@ -805,6 +987,12 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC return getUrl(url); } +LLStyle::Params LLUrlEntryNoLink::getStyle() const +{ + return LLStyle::Params(); +} + + // // LLUrlEntryIcon describes an icon with <icon>...</icon> tags // @@ -812,7 +1000,6 @@ LLUrlEntryIcon::LLUrlEntryIcon() { mPattern = boost::regex("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>", boost::regex::perl|boost::regex::icase); - mDisabledLink = true; } std::string LLUrlEntryIcon::getUrl(const std::string &url) const diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index e25eaa7555..f6424c28b8 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -30,13 +30,17 @@ #include "lluuid.h" #include "lluicolor.h" +#include "llstyle.h" #include <boost/signals2.hpp> #include <boost/regex.hpp> #include <string> #include <map> +class LLAvatarName; + typedef boost::signals2::signal<void (const std::string& url, - const std::string& label)> LLUrlLabelSignal; + const std::string& label, + const std::string& icon)> LLUrlLabelSignal; typedef LLUrlLabelSignal::slot_type LLUrlLabelCallback; /// @@ -71,10 +75,10 @@ public: virtual std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb) { return url; } /// Return an icon that can be displayed next to Urls of this type - virtual std::string getIcon(const std::string &url) { return mIcon; } + virtual std::string getIcon(const std::string &url); - /// Return the color to render the displayed text - LLUIColor getColor() const { return mColor; } + /// Return the style to render the displayed text + virtual LLStyle::Params getStyle() const; /// Given a matched Url, return a tooltip string for the hyperlink virtual std::string getTooltip(const std::string &string) const { return mTooltip; } @@ -85,9 +89,6 @@ public: /// Return the name of a SL location described by this Url, if any virtual std::string getLocation(const std::string &url) const { return ""; } - /// is this a match for a URL that should not be hyperlinked? - bool isLinkDisabled() const { return mDisabledLink; } - /// Should this link text be underlined only when mouse is hovered over it? virtual bool underlineOnHoverOnly(const std::string &string) const { return false; } @@ -100,7 +101,7 @@ protected: std::string getLabelFromWikiLink(const std::string &url) const; std::string getUrlFromWikiLink(const std::string &string) const; void addObserver(const std::string &id, const std::string &url, const LLUrlLabelCallback &cb); - void callObservers(const std::string &id, const std::string &label); + virtual void callObservers(const std::string &id, const std::string &label, const std::string& icon); typedef struct { std::string url; @@ -111,9 +112,7 @@ protected: std::string mIcon; std::string mMenuName; std::string mTooltip; - LLUIColor mColor; std::multimap<std::string, LLUrlEntryObserver> mObservers; - bool mDisabledLink; }; /// @@ -162,18 +161,78 @@ public: /// /// LLUrlEntryAgent Describes a Second Life agent Url, e.g., /// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about -/// class LLUrlEntryAgent : public LLUrlEntryBase { public: LLUrlEntryAgent(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ std::string getIcon(const std::string &url); /*virtual*/ std::string getTooltip(const std::string &string) const; + /*virtual*/ LLStyle::Params getStyle() const; /*virtual*/ LLUUID getID(const std::string &string) const; /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const; +protected: + /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon); +private: + void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); +}; + +/// +/// LLUrlEntryAgentName Describes a Second Life agent name Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) +/// that displays various forms of user name +/// This is a base class for the various implementations of name display +class LLUrlEntryAgentName : public LLUrlEntryBase +{ +public: + LLUrlEntryAgentName(); + /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ LLStyle::Params getStyle() const; +protected: + // override this to pull out relevant name fields + virtual std::string getName(const LLAvatarName& avatar_name) = 0; +private: + void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); +}; + + +/// +/// LLUrlEntryAgentCompleteName Describes a Second Life agent name Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/completename +/// that displays the full display name + user name for an avatar +/// such as "James Linden (james.linden)" +class LLUrlEntryAgentCompleteName : public LLUrlEntryAgentName +{ +public: + LLUrlEntryAgentCompleteName(); +private: + /*virtual*/ std::string getName(const LLAvatarName& avatar_name); +}; + +/// +/// LLUrlEntryAgentDisplayName Describes a Second Life agent display name Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/displayname +/// that displays the just the display name for an avatar +/// such as "James Linden" +class LLUrlEntryAgentDisplayName : public LLUrlEntryAgentName +{ +public: + LLUrlEntryAgentDisplayName(); +private: + /*virtual*/ std::string getName(const LLAvatarName& avatar_name); +}; + +/// +/// LLUrlEntryAgentUserName Describes a Second Life agent username Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/username +/// that displays the just the display name for an avatar +/// such as "james.linden" +class LLUrlEntryAgentUserName : public LLUrlEntryAgentName +{ +public: + LLUrlEntryAgentUserName(); private: - void onAgentNameReceived(const LLUUID& id, const std::string& first, - const std::string& last, BOOL is_group); + /*virtual*/ std::string getName(const LLAvatarName& avatar_name); }; /// @@ -185,10 +244,10 @@ class LLUrlEntryGroup : public LLUrlEntryBase public: LLUrlEntryGroup(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); + /*virtual*/ LLStyle::Params getStyle() const; /*virtual*/ LLUUID getID(const std::string &string) const; private: - void onGroupNameReceived(const LLUUID& id, const std::string& first, - const std::string& last, BOOL is_group); + void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group); }; /// @@ -297,6 +356,7 @@ public: LLUrlEntryNoLink(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getUrl(const std::string &string) const; + /*virtual*/ LLStyle::Params getStyle() const; }; /// diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index e53b0c4370..c1f1382a9f 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -37,16 +37,15 @@ LLUrlMatch::LLUrlMatch() : mIcon(""), mMenuName(""), mLocation(""), - mDisabledLink(false), mUnderlineOnHoverOnly(false) { } void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, - const std::string &icon, const LLUIColor& color, + const std::string &icon, const LLStyle::Params& style, const std::string &menu, const std::string &location, - bool disabled_link, const LLUUID& id, bool underline_on_hover_only) + const LLUUID& id, bool underline_on_hover_only) { mStart = start; mEnd = end; @@ -54,10 +53,10 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, mLabel = label; mTooltip = tooltip; mIcon = icon; - mColor = color; + mStyle = style; + mStyle.link_href = url; mMenuName = menu; mLocation = location; - mDisabledLink = disabled_link; mID = id; mUnderlineOnHoverOnly = underline_on_hover_only; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index d1b2112ee7..2818f45207 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -28,11 +28,11 @@ #ifndef LL_LLURLMATCH_H #define LL_LLURLMATCH_H -#include "linden_common.h" +//#include "linden_common.h" #include <string> #include <vector> -#include "lluicolor.h" +#include "llstyle.h" /// /// LLUrlMatch describes a single Url that was matched within a string by @@ -69,7 +69,7 @@ public: std::string getIcon() const { return mIcon; } /// Return the color to render the displayed text - LLUIColor getColor() const { return mColor; } + LLStyle::Params getStyle() const { return mStyle; } /// Return the name of a XUI file containing the context menu items std::string getMenuName() const { return mMenuName; } @@ -77,21 +77,17 @@ public: /// return the SL location that this Url describes, or "" if none. std::string getLocation() const { return mLocation; } - /// is this a match for a URL that should not be hyperlinked? - bool isLinkDisabled() const { return mDisabledLink; } - /// Should this link text be underlined only when mouse is hovered over it? bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; } /// Change the contents of this match object (used by LLUrlRegistry) void setValues(U32 start, U32 end, const std::string &url, const std::string &label, const std::string &tooltip, const std::string &icon, - const LLUIColor& color, const std::string &menu, - const std::string &location, bool disabled_link - , const LLUUID& id, bool underline_on_hover_only = false ); - - const LLUUID& getID() const { return mID;} + const LLStyle::Params& style, const std::string &menu, + const std::string &location, const LLUUID& id, + bool underline_on_hover_only = false ); + const LLUUID& getID() const { return mID; } private: U32 mStart; U32 mEnd; @@ -101,10 +97,8 @@ private: std::string mIcon; std::string mMenuName; std::string mLocation; - LLUUID mID; - LLUIColor mColor; - bool mDisabledLink; + LLStyle::Params mStyle; bool mUnderlineOnHoverOnly; }; diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index 9d215cf7ef..478b412d5e 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -31,18 +31,25 @@ #include <boost/regex.hpp> // default dummy callback that ignores any label updates from the server -void LLUrlRegistryNullCallback(const std::string &url, const std::string &label) +void LLUrlRegistryNullCallback(const std::string &url, const std::string &label, const std::string& icon) { } LLUrlRegistry::LLUrlRegistry() { + mUrlEntry.reserve(20); + // Urls are matched in the order that they were registered registerUrl(new LLUrlEntryNoLink()); registerUrl(new LLUrlEntryIcon()); registerUrl(new LLUrlEntrySLURL()); registerUrl(new LLUrlEntryHTTP()); registerUrl(new LLUrlEntryHTTPLabel()); + registerUrl(new LLUrlEntryAgentCompleteName()); + registerUrl(new LLUrlEntryAgentDisplayName()); + registerUrl(new LLUrlEntryAgentUserName()); + // LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since + // LLUrlEntryAgent is a less specific (catchall for agent urls) registerUrl(new LLUrlEntryAgent()); registerUrl(new LLUrlEntryGroup()); registerUrl(new LLUrlEntryParcel()); @@ -71,10 +78,13 @@ LLUrlRegistry::~LLUrlRegistry() } } -void LLUrlRegistry::registerUrl(LLUrlEntryBase *url) +void LLUrlRegistry::registerUrl(LLUrlEntryBase *url, bool force_front) { if (url) { + if (force_front) // IDEVO + mUrlEntry.insert(mUrlEntry.begin(), url); + else mUrlEntry.push_back(url); } } @@ -174,10 +184,9 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getLabel(url, cb), match_entry->getTooltip(url), match_entry->getIcon(url), - match_entry->getColor(), + match_entry->getStyle(), match_entry->getMenuName(), match_entry->getLocation(url), - match_entry->isLinkDisabled(), match_entry->getID(url), match_entry->underlineOnHoverOnly(url)); return true; @@ -210,10 +219,9 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr match.getLabel(), match.getTooltip(), match.getIcon(), - match.getColor(), + match.getStyle(), match.getMenuName(), match.getLocation(), - match.isLinkDisabled(), match.getID(), match.underlineOnHoverOnly()); return true; diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 24ce516c43..da16171a97 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -37,7 +37,9 @@ #include <vector> /// This default callback for findUrl() simply ignores any label updates -void LLUrlRegistryNullCallback(const std::string &url, const std::string &label); +void LLUrlRegistryNullCallback(const std::string &url, + const std::string &label, + const std::string &icon); /// /// LLUrlRegistry is a singleton that contains a set of Url types that @@ -64,7 +66,9 @@ public: ~LLUrlRegistry(); /// add a new Url handler to the registry (will be freed on destruction) - void registerUrl(LLUrlEntryBase *url); + /// optionally force it to the front of the list, making it take + /// priority over other regular expression matches for URLs + void registerUrl(LLUrlEntryBase *url, bool force_front = false); /// get the next Url in an input string, starting at a given character offset /// your callback is invoked if the matched Url's label changes in the future diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index ff53ae5624..f30704cb22 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -27,11 +27,28 @@ #include "llstring.h" #include "llfile.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "lluuid.h" #include <string> +// Stub for LLAvatarNameCache +bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) +{ + return false; +} + +void LLAvatarNameCache::get(const LLUUID& agent_id, callback_slot_t slot) +{ + return; +} + +bool LLAvatarNameCache::useDisplayNames() +{ + return false; +} + // // Stub implementation for LLCacheName // @@ -47,7 +64,12 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, std::string& group) return TRUE; } -boost::signals2::connection LLCacheName::get(const LLUUID& id, BOOL is_group, const LLCacheNameCallback& callback) +boost::signals2::connection LLCacheName::get(const LLUUID& id, bool is_group, const LLCacheNameCallback& callback) +{ + return boost::signals2::connection(); +} + +boost::signals2::connection LLCacheName::getGroup(const LLUUID& id, const LLCacheNameCallback& callback) { return boost::signals2::connection(); } @@ -67,3 +89,105 @@ std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil:: { return std::string(); } + +// +// Stub implementation for LLStyle::Params::Params +// + +LLStyle::Params::Params() +{ +} + +// +// Stub implementations for various LLInitParam classes +// + +namespace LLInitParam +{ + BaseBlock::BaseBlock() {} + BaseBlock::~BaseBlock() {} + Param::Param(BaseBlock* enclosing_block) + : mIsProvided(false) + { + const U8* my_addr = reinterpret_cast<const U8*>(this); + const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block); + mEnclosingBlockOffset = (U16)(my_addr - block_addr); + } + void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} + + void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} + param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;} + + void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size) + { + descriptor.mCurrentBlockPtr = this; + } + bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } + bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } + bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } + bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; } + bool BaseBlock::validateBlock(bool emit_errors) const { return true; } + + TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count) + {} + + void TypedParam<LLUIColor>::setValueFromBlock() const + {} + + void TypedParam<LLUIColor>::setBlockFromValue() + {} + + void TypeValues<LLUIColor>::declareValues() + {} + + bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) + { + return false; + } + + TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, _name, value, func, min_count, max_count) + {} + + void TypedParam<const LLFontGL*>::setValueFromBlock() const + {} + + void TypedParam<const LLFontGL*>::setBlockFromValue() + {} + + void TypeValues<LLFontGL::HAlign>::declareValues() + {} + + void TypeValues<LLFontGL::VAlign>::declareValues() + {} + + void TypeValues<LLFontGL::ShadowType>::declareValues() + {} + + void TypedParam<LLUIImage*>::setValueFromBlock() const + {} + + void TypedParam<LLUIImage*>::setBlockFromValue() + {} + + + bool ParamCompare<LLUIImage*, false>::equals( + LLUIImage* const &a, + LLUIImage* const &b) + { + return false; + } + + bool ParamCompare<LLUIColor, false>::equals(const LLUIColor &a, const LLUIColor &b) + { + return false; + } + +} + +//static +LLFontGL* LLFontGL::getFontDefault() +{ + return NULL; +} diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 95affe4460..5c6623da61 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -30,6 +30,7 @@ #include "llurlentry_stub.cpp" #include "lltut.h" #include "../lluicolortable.h" +#include "../lluiimage.h" #include <boost/regex.hpp> @@ -40,6 +41,26 @@ LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& defa LLUIColor::LLUIColor() : mColorPtr(NULL) {} +LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image) +{ +} + +LLUIImage::~LLUIImage() +{ +} + +//virtual +S32 LLUIImage::getWidth() const +{ + return 0; +} + +//virtual +S32 LLUIImage::getHeight() const +{ + return 0; +} + namespace tut { struct LLUrlEntryData diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index 4e38bea1bd..fdaab00f18 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -25,14 +25,135 @@ * $/LicenseInfo$ */ +#include "linden_common.h" + #include "../llurlmatch.h" +#include "../lluiimage.h" #include "lltut.h" -// link seam +// link seams + LLUIColor::LLUIColor() : mColorPtr(NULL) {} +LLStyle::Params::Params() +{ +} + +LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image) +{ +} + +LLUIImage::~LLUIImage() +{ +} + +//virtual +S32 LLUIImage::getWidth() const +{ + return 0; +} + +//virtual +S32 LLUIImage::getHeight() const +{ + return 0; +} + +namespace LLInitParam +{ + BaseBlock::BaseBlock() {} + BaseBlock::~BaseBlock() {} + + void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} + + void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} + param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;} + + void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size) + { + descriptor.mCurrentBlockPtr = this; + } + + Param::Param(BaseBlock* enclosing_block) + : mIsProvided(false) + { + const U8* my_addr = reinterpret_cast<const U8*>(this); + const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block); + mEnclosingBlockOffset = (U16)(my_addr - block_addr); + } + + bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } + bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } + bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } + bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; } + bool BaseBlock::validateBlock(bool emit_errors) const { return true; } + + TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, name, value, func, min_count, max_count) + {} + + void TypedParam<LLUIColor>::setValueFromBlock() const + {} + + void TypedParam<LLUIColor>::setBlockFromValue() + {} + + void TypeValues<LLUIColor>::declareValues() + {} + + bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) + { + return false; + } + + TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) + : super_t(descriptor, _name, value, func, min_count, max_count) + {} + + void TypedParam<const LLFontGL*>::setValueFromBlock() const + {} + + void TypedParam<const LLFontGL*>::setBlockFromValue() + {} + + void TypeValues<LLFontGL::HAlign>::declareValues() + {} + + void TypeValues<LLFontGL::VAlign>::declareValues() + {} + + void TypeValues<LLFontGL::ShadowType>::declareValues() + {} + + void TypedParam<LLUIImage*>::setValueFromBlock() const + {} + + void TypedParam<LLUIImage*>::setBlockFromValue() + {} + + bool ParamCompare<LLUIImage*, false>::equals( + LLUIImage* const &a, + LLUIImage* const &b) + { + return false; + } + + bool ParamCompare<LLUIColor, false>::equals(const LLUIColor &a, const LLUIColor &b) + { + return false; + } + +} + +//static +LLFontGL* LLFontGL::getFontDefault() +{ + return NULL; +} + + namespace tut { struct LLUrlMatchData @@ -59,7 +180,7 @@ namespace tut LLUrlMatch match; ensure("empty()", match.empty()); - match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(0, 1, "http://secondlife.com", "Second Life", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure("! empty()", ! match.empty()); } @@ -72,7 +193,7 @@ namespace tut LLUrlMatch match; ensure_equals("getStart() == 0", match.getStart(), 0); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getStart() == 10", match.getStart(), 10); } @@ -85,7 +206,7 @@ namespace tut LLUrlMatch match; ensure_equals("getEnd() == 0", match.getEnd(), 0); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getEnd() == 20", match.getEnd(), 20); } @@ -98,10 +219,10 @@ namespace tut LLUrlMatch match; ensure_equals("getUrl() == ''", match.getUrl(), ""); - match.setValues(10, 20, "http://slurl.com/", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "http://slurl.com/", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getUrl() == 'http://slurl.com/'", match.getUrl(), "http://slurl.com/"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getUrl() == '' (2)", match.getUrl(), ""); } @@ -114,10 +235,10 @@ namespace tut LLUrlMatch match; ensure_equals("getLabel() == ''", match.getLabel(), ""); - match.setValues(10, 20, "", "Label", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "Label", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getLabel() == 'Label'", match.getLabel(), "Label"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getLabel() == '' (2)", match.getLabel(), ""); } @@ -130,10 +251,10 @@ namespace tut LLUrlMatch match; ensure_equals("getTooltip() == ''", match.getTooltip(), ""); - match.setValues(10, 20, "", "", "Info", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "Info", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getTooltip() == 'Info'", match.getTooltip(), "Info"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getTooltip() == '' (2)", match.getTooltip(), ""); } @@ -146,10 +267,10 @@ namespace tut LLUrlMatch match; ensure_equals("getIcon() == ''", match.getIcon(), ""); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getIcon() == 'Icon'", match.getIcon(), "Icon"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure_equals("getIcon() == '' (2)", match.getIcon(), ""); } @@ -162,10 +283,10 @@ namespace tut LLUrlMatch match; ensure("getMenuName() empty", match.getMenuName().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "", LLUUID::null); ensure_equals("getMenuName() == \"xui_file.xml\"", match.getMenuName(), "xui_file.xml"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure("getMenuName() empty (2)", match.getMenuName().empty()); } @@ -178,10 +299,10 @@ namespace tut LLUrlMatch match; ensure("getLocation() empty", match.getLocation().empty()); - match.setValues(10, 20, "", "", "", "Icon", LLUIColor(), "xui_file.xml", "Paris", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "Icon", LLStyle::Params(), "xui_file.xml", "Paris", LLUUID::null); ensure_equals("getLocation() == \"Paris\"", match.getLocation(), "Paris"); - match.setValues(10, 20, "", "", "", "", LLUIColor(), "", "", false,LLUUID::null); + match.setValues(10, 20, "", "", "", "", LLStyle::Params(), "", "", LLUUID::null); ensure("getLocation() empty (2)", match.getLocation().empty()); } } diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index e1ad9a5c71..9942af6b37 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -29,7 +29,13 @@ #include "llxuiparser.h" #include "llxmlnode.h" + +#ifdef LL_STANDALONE +#include <expat.h> +#else #include "expat/expat.h" +#endif + #include <fstream> #include <boost/tokenizer.hpp> //#include <boost/spirit/include/qi.hpp> diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp index e4d100d1ec..23980ffac2 100644 --- a/indra/mac_updater/mac_updater.cpp +++ b/indra/mac_updater/mac_updater.cpp @@ -61,6 +61,7 @@ Boolean gCancelled = false; const char *gUpdateURL; const char *gProductName; +const char *gBundleID; void *updatethreadproc(void*); @@ -329,6 +330,10 @@ int parse_args(int argc, char **argv) { gProductName = argv[j]; } + else if ((!strcmp(argv[j], "-bundleid")) && (++j < argc)) + { + gBundleID = argv[j]; + } } return 0; @@ -355,6 +360,7 @@ int main(int argc, char **argv) // gUpdateURL = NULL; gProductName = NULL; + gBundleID = NULL; parse_args(argc, argv); if (!gUpdateURL) { @@ -372,6 +378,14 @@ int main(int argc, char **argv) { gProductName = "Second Life"; } + if (gBundleID) + { + llinfos << "Bundle ID is: " << gBundleID << llendl; + } + else + { + gBundleID = "com.secondlife.indra.viewer"; + } } llinfos << "Starting " << gProductName << " Updater" << llendl; @@ -592,7 +606,8 @@ static bool isFSRefViewerBundle(FSRef *targetRef) CFURLRef targetURL = NULL; CFBundleRef targetBundle = NULL; CFStringRef targetBundleID = NULL; - + CFStringRef sourceBundleID = NULL; + targetURL = CFURLCreateFromFSRef(NULL, targetRef); if(targetURL == NULL) @@ -619,7 +634,8 @@ static bool isFSRefViewerBundle(FSRef *targetRef) } else { - if(CFStringCompare(targetBundleID, CFSTR("com.secondlife.indra.viewer"), 0) == kCFCompareEqualTo) + sourceBundleID = CFStringCreateWithCString(NULL, gBundleID, kCFStringEncodingUTF8); + if(CFStringCompare(sourceBundleID, targetBundleID, 0) == kCFCompareEqualTo) { // This is the bundle we're looking for. result = true; diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt index f8d2dabc6c..3ad94b0c64 100644 --- a/indra/media_plugins/base/CMakeLists.txt +++ b/indra/media_plugins/base/CMakeLists.txt @@ -25,6 +25,14 @@ include_directories( ### media_plugin_base +if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT WORD_SIZE EQUAL 32) + set(media_plugin_base_SOURCE_FILES media_plugin_base.cpp ) diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt index 4d82f2747c..56cefde4bd 100644 --- a/indra/media_plugins/example/CMakeLists.txt +++ b/indra/media_plugins/example/CMakeLists.txt @@ -29,6 +29,14 @@ include_directories( ### media_plugin_example +if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT WORD_SIZE EQUAL 32) + set(media_plugin_example_SOURCE_FILES media_plugin_example.cpp ) diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index a5127ae5f4..5786bd1e25 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -30,6 +30,14 @@ include_directories( ### media_plugin_gstreamer010 +if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT WORD_SIZE EQUAL 32) + set(media_plugin_gstreamer010_SOURCE_FILES media_plugin_gstreamer010.cpp llmediaimplgstreamer_syms.cpp diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt index 57478ddf27..05f1236606 100644 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ b/indra/media_plugins/webkit/CMakeLists.txt @@ -32,6 +32,14 @@ include_directories( ### media_plugin_webkit +if(NOT WORD_SIZE EQUAL 32) + if(WINDOWS) + add_definitions(/FIXED:NO) + else(WINDOWS) # not windows therefore gcc LINUX and DARWIN + add_definitions(-fPIC) + endif(WINDOWS) +endif(NOT WORD_SIZE EQUAL 32) + set(media_plugin_webkit_SOURCE_FILES media_plugin_webkit.cpp ) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index e9fb23d19e..09622d3af5 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -140,7 +140,6 @@ set(viewer_SOURCE_FILES lldriverparam.cpp lldynamictexture.cpp llemote.cpp - lleventinfo.cpp lleventnotifier.cpp lleventpoll.cpp llexpandabletextbox.cpp @@ -169,6 +168,7 @@ set(viewer_SOURCE_FILES llfloatercamera.cpp llfloatercolorpicker.cpp llfloaterdaycycle.cpp + llfloaterdisplayname.cpp llfloaterenvsettings.cpp llfloaterevent.cpp llfloaterfonttest.cpp @@ -243,6 +243,7 @@ set(viewer_SOURCE_FILES llhudeffecttrail.cpp llhudicon.cpp llhudmanager.cpp + llhudnametag.cpp llhudobject.cpp llhudrender.cpp llhudtext.cpp @@ -484,6 +485,7 @@ set(viewer_SOURCE_FILES llviewercontrol.cpp llviewercontrollistener.cpp llviewerdisplay.cpp + llviewerdisplayname.cpp llviewerfloaterreg.cpp llviewerfoldertype.cpp llviewergenericmessage.cpp @@ -669,7 +671,6 @@ set(viewer_HEADER_FILES lldriverparam.h lldynamictexture.h llemote.h - lleventinfo.h lleventnotifier.h lleventpoll.h llexpandabletextbox.h @@ -698,6 +699,7 @@ set(viewer_HEADER_FILES llfloatercamera.h llfloatercolorpicker.h llfloaterdaycycle.h + llfloaterdisplayname.h llfloaterenvsettings.h llfloaterevent.h llfloaterfonttest.h @@ -772,6 +774,7 @@ set(viewer_HEADER_FILES llhudeffecttrail.h llhudicon.h llhudmanager.h + llhudnametag.h llhudobject.h llhudrender.h llhudtext.h @@ -1011,6 +1014,7 @@ set(viewer_HEADER_FILES llviewercontrol.h llviewercontrollistener.h llviewerdisplay.h + llviewerdisplayname.h llviewerfloaterreg.h llviewerfoldertype.h llviewergenericmessage.h @@ -1469,6 +1473,9 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/Release/openjpeg.dll ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjpeg.dll ${SHARED_LIB_STAGING_DIR}/Debug/openjpegd.dll + ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll + ${SHARED_LIB_STAGING_DIR}/Debug/fmod.dll ${SHARED_LIB_STAGING_DIR}/Release/msvcr80.dll ${SHARED_LIB_STAGING_DIR}/Release/msvcp80.dll ${SHARED_LIB_STAGING_DIR}/Release/Microsoft.VC80.CRT.manifest @@ -1490,7 +1497,6 @@ if (WINDOWS) ${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt ${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt ${CMAKE_CURRENT_SOURCE_DIR}/dbghelp.dll - ${CMAKE_CURRENT_SOURCE_DIR}/fmod.dll ${ARCH_PREBUILT_DIRS_RELEASE}/libeay32.dll ${ARCH_PREBUILT_DIRS_RELEASE}/qtcore4.dll ${ARCH_PREBUILT_DIRS_RELEASE}/qtgui4.dll diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml index 587b2f2a89..4da2b0fd00 100644 --- a/indra/newview/app_settings/high_graphics.xml +++ b/indra/newview/app_settings/high_graphics.xml @@ -24,6 +24,8 @@ <RenderTerrainLODFactor value="2"/> <!--Default for now--> <RenderTreeLODFactor value="0.5"/> + <!--Default for now--> + <RenderUseFBO value="1"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> diff --git a/indra/newview/app_settings/ignorable_dialogs.xml b/indra/newview/app_settings/ignorable_dialogs.xml index 0720ccee49..9ddf007ce7 100644 --- a/indra/newview/app_settings/ignorable_dialogs.xml +++ b/indra/newview/app_settings/ignorable_dialogs.xml @@ -45,6 +45,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>FirstDisplayName</key> + <map> + <key>Comment</key> + <string>Shows hint when edits profile for the first time</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>FirstReceiveLindens</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml index a5bbdfc1d0..136087f69b 100644 --- a/indra/newview/app_settings/low_graphics.xml +++ b/indra/newview/app_settings/low_graphics.xml @@ -26,6 +26,8 @@ <RenderTerrainLODFactor value="1.0"/> <!--Default for now--> <RenderTreeLODFactor value="0.5"/> + <!--Default for now--> + <RenderUseFBO value="0"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml index a1430a58f9..c150a87cdf 100644 --- a/indra/newview/app_settings/mid_graphics.xml +++ b/indra/newview/app_settings/mid_graphics.xml @@ -24,6 +24,8 @@ <RenderTerrainLODFactor value="1.0"/> <!--Default for now--> <RenderTreeLODFactor value="0.5"/> + <!--Default for now--> + <RenderUseFBO value="0"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 742a20a849..7172f0359a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2897,6 +2897,17 @@ <key>Value</key> <integer>175</integer> </map> + <key>EventURL</key> + <map> + <key>Comment</key> + <string>URL for Event website, displayed in the event floater</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>http://events.secondlife.com/viewer/embed/event/</string> + </map> <key>EveryoneCopy</key> <map> <key>Comment</key> @@ -3852,7 +3863,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>http://search.secondlife.com/viewer/[CATEGORY]?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> + <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&p=[AUTH_TOKEN]&r=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> <key>HighResSnapshot</key> <map> @@ -5772,13 +5783,13 @@ <key>ToastGap</key> <map> <key>Comment</key> - <string>Gap between toasts on a screen</string> + <string>Gap between toasts on a screen (min. value is 5)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>S32</string> <key>Value</key> - <integer>5</integer> + <integer>7</integer> </map> <key>ToastButtonWidth</key> <map> @@ -7965,7 +7976,7 @@ <key>Value</key> <integer>0</integer> </map> - <key>RenderShowGroupTitleAll</key> + <key>NameTagShowGroupTitles</key> <map> <key>Comment</key> <string>Show group titles in name labels</string> @@ -7974,6 +7985,39 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> + <integer>0</integer> + </map> + <key>NameTagShowDisplayNames</key> + <map> + <key>Comment</key> + <string>Show display names in name labels</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>NameTagShowFriends</key> + <map> + <key>Comment</key> + <string>Highlight the name tags of your friends</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>NameTagShowUsernames</key> + <map> + <key>Comment</key> + <string>Show usernames in avatar name tags</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> <integer>1</integer> </map> <key>RenderInitError</key> @@ -8272,7 +8316,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>RenderUseTriStrips</key> <map> @@ -11035,6 +11079,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>UseDisplayNames</key> + <map> + <key>Comment</key> + <string>Use new, changeable, unicode names</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>UseEnergy</key> <map> <key>Comment</key> @@ -12090,5 +12145,16 @@ <key>Value</key> <real>300.0</real> </map> + <key>GroupMembersSortOrder</key> + <map> + <key>Comment</key> + <string>The order by which group members will be sorted (name|donated|online)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>name</string> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml index f741089ca2..e7dce3b989 100644 --- a/indra/newview/app_settings/ultra_graphics.xml +++ b/indra/newview/app_settings/ultra_graphics.xml @@ -24,6 +24,8 @@ <RenderTerrainLODFactor value="2.0"/> <!--Default for now--> <RenderTreeLODFactor value="1.0"/> + <!--Default for now--> + <RenderUseFBO value="1"/> <!--Try Impostors--> <RenderUseImpostors value="TRUE"/> <!--Default for now--> diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp index f52f136118..b9ec304b7e 100644 --- a/indra/newview/llagentui.cpp +++ b/indra/newview/llagentui.cpp @@ -40,29 +40,6 @@ #include "llslurl.h" //static -void LLAgentUI::buildName(std::string& name) -{ - name.clear(); - if (isAgentAvatarValid()) - { - LLNameValue *first_nv = gAgentAvatarp->getNVPair("FirstName"); - LLNameValue *last_nv = gAgentAvatarp->getNVPair("LastName"); - if (first_nv && last_nv) - { - name = first_nv->printData() + " " + last_nv->printData(); - } - else - { - llwarns << "Agent is missing FirstName and/or LastName nv pair." << llendl; - } - } - else - { - name = gSavedSettings.getString("FirstName") + " " + gSavedSettings.getString("LastName"); - } -} - -//static void LLAgentUI::buildFullname(std::string& name) { if (isAgentAvatarValid()) diff --git a/indra/newview/llagentui.h b/indra/newview/llagentui.h index afc0ba5d9a..dda5dc1fd1 100644 --- a/indra/newview/llagentui.h +++ b/indra/newview/llagentui.h @@ -41,7 +41,6 @@ public: LOCATION_FORMAT_FULL, // Parcel, Region (x, y, z) - Maturity }; - static void buildName(std::string& name); static void buildFullname(std::string &name); static void buildSLURL(LLSLURL& slurl, const bool escaped = true); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8c8cb245cb..974ea6b4ae 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -30,6 +30,7 @@ // Viewer includes #include "llversioninfo.h" +#include "llversionviewer.h" #include "llfeaturemanager.h" #include "lluictrlfactory.h" #include "lltexteditor.h" @@ -84,6 +85,7 @@ #include "llsecondlifeurls.h" // Linden library includes +#include "llavatarnamecache.h" #include "llimagej2c.h" #include "llmemory.h" #include "llprimitive.h" @@ -156,7 +158,6 @@ // Included so that constants/settings might be initialized // in save_settings_to_globals() #include "llbutton.h" -#include "llcombobox.h" #include "llstatusbar.h" #include "llsurface.h" #include "llvosky.h" @@ -433,9 +434,6 @@ static void settings_to_globals() MENU_BAR_HEIGHT = gSavedSettings.getS32("MenuBarHeight"); MENU_BAR_WIDTH = gSavedSettings.getS32("MenuBarWidth"); - LLCOMBOBOX_HEIGHT = BTN_HEIGHT - 2; - LLCOMBOBOX_WIDTH = 128; - LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); @@ -1357,8 +1355,7 @@ bool LLAppViewer::cleanup() LLPolyMesh::freeAllMeshes(); - delete gCacheName; - gCacheName = NULL; + LLStartUp::cleanupNameCache(); // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted. @@ -3436,6 +3433,15 @@ void LLAppViewer::saveFinalSnapshot() void LLAppViewer::loadNameCache() { + // display names cache + std::string filename = + gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + llifstream name_cache_stream(filename); + if(name_cache_stream.is_open()) + { + LLAvatarNameCache::importFile(name_cache_stream); + } + if (!gCacheName) return; std::string name_cache; @@ -3445,19 +3451,19 @@ void LLAppViewer::loadNameCache() { if(gCacheName->importFile(cache_file)) return; } +} - // Try to load from the legacy format. This should go away after a - // while. Phoenix 2008-01-30 - LLFILE* name_cache_fp = LLFile::fopen(name_cache, "r"); // Flawfinder: ignore - if (name_cache_fp) +void LLAppViewer::saveNameCache() { - gCacheName->importFile(name_cache_fp); - fclose(name_cache_fp); - } + // display names cache + std::string filename = + gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "avatar_name_cache.xml"); + llofstream name_cache_stream(filename); + if(name_cache_stream.is_open()) + { + LLAvatarNameCache::exportFile(name_cache_stream); } -void LLAppViewer::saveNameCache() -{ if (!gCacheName) return; std::string name_cache; @@ -3657,6 +3663,7 @@ void LLAppViewer::idle() // NOTE: Starting at this point, we may still have pointers to "dead" objects // floating throughout the various object lists. // + idleNameCache(); idleNetwork(); @@ -3994,6 +4001,60 @@ void LLAppViewer::sendLogoutRequest() } } +void LLAppViewer::idleNameCache() +{ + // Neither old nor new name cache can function before agent has a region + LLViewerRegion* region = gAgent.getRegion(); + if (!region) return; + + // deal with any queued name requests and replies. + gCacheName->processPending(); + + // Can't run the new cache until we have the list of capabilities + // for the agent region, and can therefore decide whether to use + // display names or fall back to the old name system. + if (!region->capabilitiesReceived()) return; + + // Agent may have moved to a different region, so need to update cap URL + // for name lookups. Can't do this in the cap grant code, as caps are + // granted to neighbor regions before the main agent gets there. Can't + // do it in the move-into-region code because cap not guaranteed to be + // granted yet, for example on teleport. + bool had_capability = LLAvatarNameCache::hasNameLookupURL(); + std::string name_lookup_url; + name_lookup_url.reserve(128); // avoid a memory allocation below + name_lookup_url = region->getCapability("GetDisplayNames"); + bool have_capability = !name_lookup_url.empty(); + if (have_capability) + { + // we have support for display names, use it + U32 url_size = name_lookup_url.size(); + // capabilities require URLs with slashes before query params: + // https://<host>:<port>/cap/<uuid>/?ids=<blah> + // but the caps are granted like: + // https://<host>:<port>/cap/<uuid> + if (url_size > 0 && name_lookup_url[url_size-1] != '/') + { + name_lookup_url += '/'; + } + LLAvatarNameCache::setNameLookupURL(name_lookup_url); + } + else + { + // Display names not available on this region + LLAvatarNameCache::setNameLookupURL( std::string() ); + } + + // Error recovery - did we change state? + if (had_capability != have_capability) + { + // name tags are persistant on screen, so make sure they refresh + LLVOAvatar::invalidateNameTags(); + } + + LLAvatarNameCache::idle(); +} + // // Handle messages, and all message related stuff // @@ -4019,8 +4080,6 @@ void LLAppViewer::idleNetwork() { LLFastTimer t(FTM_IDLE_NETWORK); // decode - // deal with any queued name requests and replies. - gCacheName->processPending(); LLTimer check_message_timer; // Read all available packets from network const S64 frame_count = gFrameCount; // U32->S64 @@ -4456,6 +4515,8 @@ void LLAppViewer::launchUpdater() LLAppViewer::sUpdaterInfo->mUpdateExePath += update_url.asString(); LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -name \""; LLAppViewer::sUpdaterInfo->mUpdateExePath += LLAppViewer::instance()->getSecondLifeTitle(); + LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" -bundleid \""; + LLAppViewer::sUpdaterInfo->mUpdateExePath += LL_VERSION_BUNDLE_ID; LLAppViewer::sUpdaterInfo->mUpdateExePath += "\" &"; LL_DEBUGS("AppInit") << "Calling updater: " << LLAppViewer::sUpdaterInfo->mUpdateExePath << LL_ENDL; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 56d88f07c8..fdc3b9ef9e 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -204,6 +204,8 @@ private: void idle(); void idleShutdown(); + // update avatar SLID and display name caches + void idleNameCache(); void idleNetwork(); void sendLogoutRequest(); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 79b0c63b38..066b4d8bc3 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -31,11 +31,11 @@ #include "boost/lambda/lambda.hpp" // for lambda::constant +#include "llavatarnamecache.h" // IDEVO #include "llsd.h" #include "lldarray.h" #include "llnotifications.h" #include "llnotificationsutil.h" - #include "roles_constants.h" // for GP_MEMBER_INVITE #include "llagent.h" @@ -65,6 +65,7 @@ #include "llimfloater.h" #include "lltrans.h" #include "llcallingcard.h" +#include "llslurl.h" // IDEVO // static void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) @@ -76,26 +77,22 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin } LLSD args; - args["NAME"] = name; + args["NAME"] = LLSLURL("agent", id, "completename").getSLURLString(); LLSD payload; payload["id"] = id; payload["name"] = name; - // Look for server versions like: Second Life Server 1.24.4.95600 - if (gLastVersionChannel.find(" 1.24.") != std::string::npos) - { - // Old and busted server version, doesn't support friend - // requests with messages. - LLNotificationsUtil::add("AddFriend", args, payload, &callbackAddFriend); - } - else - { + LLNotificationsUtil::add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage); - } // add friend to recent people list LLRecentPeople::instance().add(id); } +void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name) +{ + LLAvatarActions::requestFriendshipDialog(id, av_name.getCompleteName()); +} + // static void LLAvatarActions::requestFriendshipDialog(const LLUUID& id) { @@ -104,9 +101,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id) return; } - std::string full_name; - gCacheName->getFullName(id, full_name); - requestFriendshipDialog(id, full_name); + LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_friendship, _1, _2)); } // static @@ -131,11 +126,10 @@ void LLAvatarActions::removeFriendsDialog(const uuid_vec_t& ids) if(ids.size() == 1) { LLUUID agent_id = ids[0]; - std::string first, last; - if(gCacheName->getName(agent_id, first, last)) + LLAvatarName av_name; + if(LLAvatarNameCache::get(agent_id, &av_name)) { - args["FIRST_NAME"] = first; - args["LAST_NAME"] = last; + args["NAME"] = av_name.mDisplayName; } msgType = "RemoveFromFriends"; @@ -163,14 +157,6 @@ void LLAvatarActions::offerTeleport(const LLUUID& invitee) if (invitee.isNull()) return; - //waiting until Name Cache gets updated with corresponding avatar name - std::string just_to_request_name; - if (!gCacheName->getFullName(invitee, just_to_request_name)) - { - gCacheName->get(invitee, FALSE, boost::bind((void (*)(const LLUUID&)) &LLAvatarActions::offerTeleport, invitee)); - return; - } - LLDynamicArray<LLUUID> ids; ids.push_back(invitee); offerTeleport(ids); @@ -185,20 +171,11 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids) handle_lure(ids); } -// static -void LLAvatarActions::startIM(const LLUUID& id) +static void on_avatar_name_cache_start_im(const LLUUID& agent_id, + const LLAvatarName& av_name) { - if (id.isNull()) - return; - - std::string name; - if (!gCacheName->getFullName(id, name)) - { - gCacheName->get(id, FALSE, boost::bind(&LLAvatarActions::startIM, id)); - return; - } - - LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id); + std::string name = av_name.getCompleteName(); + LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id); if (session_id != LLUUID::null) { LLIMFloater::show(session_id); @@ -207,6 +184,16 @@ void LLAvatarActions::startIM(const LLUUID& id) } // static +void LLAvatarActions::startIM(const LLUUID& id) +{ + if (id.isNull()) + return; + + LLAvatarNameCache::get(id, + boost::bind(&on_avatar_name_cache_start_im, _1, _2)); +} + +// static void LLAvatarActions::endIM(const LLUUID& id) { if (id.isNull()) @@ -219,6 +206,18 @@ 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(); + LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true); + if (session_id != LLUUID::null) + { + gIMMgr->startCall(session_id); + } + make_ui_sound("UISndStartIM"); +} + // static void LLAvatarActions::startCall(const LLUUID& id) { @@ -226,15 +225,8 @@ void LLAvatarActions::startCall(const LLUUID& id) { return; } - - std::string name; - gCacheName->getFullName(id, name); - LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id, true); - if (session_id != LLUUID::null) - { - gIMMgr->startCall(session_id); - } - make_ui_sound("UISndStartIM"); + LLAvatarNameCache::get(id, + boost::bind(&on_avatar_name_cache_start_call, _1, _2)); } // static @@ -330,14 +322,14 @@ void LLAvatarActions::showProfile(const LLUUID& id) // static void LLAvatarActions::showOnMap(const LLUUID& id) { - std::string name; - if (!gCacheName->getFullName(id, name)) + LLAvatarName av_name; + if (!LLAvatarNameCache::get(id, &av_name)) { - gCacheName->get(id, FALSE, boost::bind(&LLAvatarActions::showOnMap, id)); + LLAvatarNameCache::get(id, boost::bind(&LLAvatarActions::showOnMap, id)); return; } - gFloaterWorldMap->trackAvatar(id, name); + gFloaterWorldMap->trackAvatar(id, av_name.mDisplayName); LLFloaterReg::showInstance("world_map"); } @@ -497,14 +489,15 @@ namespace action_give_inventory return acceptable; } - static void build_residents_string(const std::vector<std::string>& avatar_names, std::string& residents_string) + 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<std::string>::const_iterator it = avatar_names.begin(); ; ) + for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; ) { - residents_string.append(*it); + LLAvatarName av_name = *it; + residents_string.append(av_name.mDisplayName); if (++it == avatar_names.end()) { break; @@ -541,7 +534,7 @@ namespace action_give_inventory struct LLShareInfo : public LLSingleton<LLShareInfo> { - std::vector<std::string> mAvatarNames; + std::vector<LLAvatarName> mAvatarNames; uuid_vec_t mAvatarUuids; }; @@ -602,7 +595,7 @@ namespace action_give_inventory } else { - LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); + LLGiveInventory::doGiveInventoryItem(avatar_uuid, inv_item, session_id); shared = true; } } @@ -634,11 +627,10 @@ namespace action_give_inventory * @param avatar_names - avatar names request to be sent. * @param avatar_uuids - avatar names request to be sent. */ - static void give_inventory(const std::vector<std::string>& avatar_names, const uuid_vec_t& avatar_uuids) + static void give_inventory(const uuid_vec_t& avatar_uuids, const std::vector<LLAvatarName> avatar_names) { llassert(avatar_names.size() == avatar_uuids.size()); - LLInventoryPanel* active_panel = get_active_inventory_panel(); if (!active_panel) return; @@ -727,7 +719,7 @@ void LLAvatarActions::toggleBlock(const LLUUID& id) { std::string name; - gCacheName->getFullName(id, name); + gCacheName->getFullName(id, name); // needed for mute LLMute mute(id, name, LLMute::AGENT); if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName)) @@ -915,23 +907,6 @@ bool LLAvatarActions::handleUnfreeze(const LLSD& notification, const LLSD& respo } return false; } -// static -bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (option == 0) - { - // Servers older than 1.25 require the text of the message to be the - // calling card folder ID for the offering user. JC - LLUUID calling_card_folder_id = - gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); - std::string message = calling_card_folder_id.asString(); - requestFriendship(notification["payload"]["id"].asUUID(), - notification["payload"]["name"].asString(), - message); - } - return false; -} // static void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message) @@ -949,7 +924,6 @@ void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::stri LLSD payload; payload["from_id"] = target_id; - payload["SESSION_NAME"] = target_name; payload["SUPPRESS_TOAST"] = true; LLNotificationsUtil::add("FriendshipOffered", args, payload); } @@ -964,16 +938,16 @@ bool LLAvatarActions::isFriend(const LLUUID& id) bool LLAvatarActions::isBlocked(const LLUUID& id) { std::string name; - gCacheName->getFullName(id, name); + gCacheName->getFullName(id, name); // needed for mute return LLMuteList::getInstance()->isMuted(id, name); } // static bool LLAvatarActions::canBlock(const LLUUID& id) { - std::string firstname, lastname; - gCacheName->getName(id, firstname, lastname); - bool is_linden = !LLStringUtil::compareStrings(lastname, "Linden"); + std::string full_name; + gCacheName->getFullName(id, full_name); // needed for mute + bool is_linden = (full_name.find("Linden") != std::string::npos); bool is_self = id == gAgentID; return !is_self && !is_linden; } diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 44bd3778da..2db2918eed 100644 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -195,7 +195,6 @@ public: static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL); private: - static bool callbackAddFriend(const LLSD& notification, const LLSD& response); static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response); static bool handleRemove(const LLSD& notification, const LLSD& response); static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id); diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 09fbed9e06..d0f4d19f56 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -28,17 +28,19 @@ #include "llavatariconctrl.h" +// viewer includes #include "llagent.h" #include "llavatarconstants.h" #include "llcallingcard.h" // for LLAvatarTracker #include "llavataractions.h" #include "llmenugl.h" #include "lluictrlfactory.h" - -#include "llcachename.h" #include "llagentdata.h" #include "llimfloater.h" +// library includes +#include "llavatarnamecache.h" + #define MENU_ITEM_VIEW_PROFILE 0 #define MENU_ITEM_SEND_IM 1 @@ -227,6 +229,9 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) // Check if cache already contains image_id for that avatar if (!updateFromCache()) { + // *TODO: Consider getting avatar icon/badge directly from + // People API, rather than sending AvatarPropertyRequest + // messages. People API already hits the user table. LLIconCtrl::setValue(mDefaultIconName); app->addObserver(mAvatarId, this); app->sendAvatarPropertiesRequest(mAvatarId); @@ -238,10 +243,9 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) LLIconCtrl::setValue(value); } - if (gCacheName) - { - gCacheName->get(mAvatarId, FALSE, boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3, _4)); - } + LLAvatarNameCache::get(mAvatarId, + boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, + this, _1, _2)); } bool LLAvatarIconCtrl::updateFromCache() @@ -284,24 +288,21 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type) } } -void LLAvatarIconCtrl::nameUpdatedCallback( - const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) +void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { - if (id == mAvatarId) + if (agent_id == mAvatarId) { - mFirstName = first; - mLastName = last; + // Most avatar icon controls are next to a UI element that shows + // a display name, so only show username. + mFullName = av_name.mUsername; if (mDrawTooltip) { - setToolTip(mFirstName + " " + mLastName); + setToolTip(mFullName); } else { - setToolTip(std::string("")); + setToolTip(std::string()); } } } diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index b24d7356a8..7f568fc5b8 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -31,6 +31,8 @@ #include "llavatarpropertiesprocessor.h" #include "llviewermenu.h" +class LLAvatarName; + class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache> { public: @@ -84,22 +86,16 @@ public: // LLAvatarPropertiesProcessor observer trigger virtual void processProperties(void* data, EAvatarProcessorType type); - void nameUpdatedCallback( - const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); const LLUUID& getAvatarId() const { return mAvatarId; } - const std::string& getFirstName() const { return mFirstName; } - const std::string& getLastName() const { return mLastName; } + const std::string& getFullName() const { return mFullName; } void setDrawTooltip(bool value) { mDrawTooltip = value;} protected: LLUUID mAvatarId; - std::string mFirstName; - std::string mLastName; + std::string mFullName; bool mDrawTooltip; std::string mDefaultIconName; diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 09083dcb98..ff7dfccc0a 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -38,6 +38,7 @@ // newview #include "llagentdata.h" // for comparator #include "llavatariconctrl.h" +#include "llavatarnamecache.h" #include "llcallingcard.h" // for LLAvatarTracker #include "llcachename.h" #include "lllistcontextmenu.h" @@ -131,6 +132,7 @@ LLAvatarList::LLAvatarList(const Params& p) , mShowLastInteractionTime(p.show_last_interaction_time) , mContextMenu(NULL) , mDirty(true) // to force initial update +, mNeedUpdateNames(false) , mLITUpdateTimer(NULL) , mShowIcons(true) , mShowInfoBtn(p.show_info_btn) @@ -149,8 +151,17 @@ LLAvatarList::LLAvatarList(const Params& p) mLITUpdateTimer->setTimerExpirySec(0); // zero to force initial update mLITUpdateTimer->start(); } + + LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLAvatarList::handleDisplayNamesOptionChanged, this)); +} + + +void LLAvatarList::handleDisplayNamesOptionChanged() +{ + mNeedUpdateNames = true; } + LLAvatarList::~LLAvatarList() { delete mLITUpdateTimer; @@ -170,6 +181,11 @@ void LLAvatarList::draw() LLFlatListViewEx::draw(); + if (mNeedUpdateNames) + { + updateAvatarNames(); + } + if (mDirty) refresh(); @@ -233,7 +249,6 @@ void LLAvatarList::addAvalineItem(const LLUUID& item_id, const LLUUID& session_i ////////////////////////////////////////////////////////////////////////// // PROTECTED SECTION ////////////////////////////////////////////////////////////////////////// - void LLAvatarList::refresh() { bool have_names = TRUE; @@ -252,12 +267,15 @@ void LLAvatarList::refresh() // Handle added items. unsigned nadded = 0; + const std::string waiting_str = LLTrans::getString("AvatarNameWaiting"); + for (uuid_vec_t::const_iterator it=added.begin(); it != added.end(); it++) { - std::string name; const LLUUID& buddy_id = *it; - have_names &= (bool)gCacheName->getFullName(buddy_id, name); - if (!have_filter || findInsensitive(name, mNameFilter)) + LLAvatarName av_name; + have_names &= LLAvatarNameCache::get(buddy_id, &av_name); + + if (!have_filter || findInsensitive(av_name.mDisplayName, mNameFilter)) { if (nadded >= ADD_LIMIT) { @@ -266,7 +284,11 @@ void LLAvatarList::refresh() } else { - addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id)); + // *NOTE: If you change the UI to show a different string, + // be sure to change the filter code below. + addNewItem(buddy_id, + av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, + LLAvatarTracker::instance().isBuddyOnline(buddy_id)); modified = true; nadded++; } @@ -288,10 +310,10 @@ void LLAvatarList::refresh() for (std::vector<LLSD>::const_iterator it=cur_values.begin(); it != cur_values.end(); it++) { - std::string name; const LLUUID& buddy_id = it->asUUID(); - have_names &= (bool)gCacheName->getFullName(buddy_id, name); - if (!findInsensitive(name, mNameFilter)) + LLAvatarName av_name; + have_names &= LLAvatarNameCache::get(buddy_id, &av_name); + if (!findInsensitive(av_name.mDisplayName, mNameFilter)) { removeItemByUUID(buddy_id); modified = true; @@ -337,20 +359,34 @@ void LLAvatarList::refresh() onCommit(); } +void LLAvatarList::updateAvatarNames() +{ + std::vector<LLPanel*> items; + getItems(items); + + for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++) + { + LLAvatarListItem* item = static_cast<LLAvatarListItem*>(*it); + item->updateAvatarName(); + } + mNeedUpdateNames = false; +} + + bool LLAvatarList::filterHasMatches() { uuid_vec_t values = getIDs(); for (uuid_vec_t::const_iterator it=values.begin(); it != values.end(); it++) { - std::string name; const LLUUID& buddy_id = *it; - BOOL have_name = gCacheName->getFullName(buddy_id, name); + LLAvatarName av_name; + bool have_name = LLAvatarNameCache::get(buddy_id, &av_name); // 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(name, mNameFilter)) + if (have_name && !findInsensitive(av_name.mDisplayName, mNameFilter)) { continue; } @@ -384,7 +420,7 @@ S32 LLAvatarList::notifyParent(const LLSD& info) void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_online, EAddPosition pos) { LLAvatarListItem* item = new LLAvatarListItem(); - item->setName(name); + // This sets the name as a side effect item->setAvatarId(id, mSessionID, mIgnoreOnlineStatus); item->setOnline(mIgnoreOnlineStatus ? true : is_online); item->showLastInteractionTime(mShowLastInteractionTime); @@ -551,11 +587,13 @@ void LLAvalineListItem::setName(const std::string& name) std::string hidden_name = LLTrans::getString("AvalineCaller", args); LL_DEBUGS("Avaline") << "Avaline caller: " << uuid << ", name: " << hidden_name << LL_ENDL; - LLAvatarListItem::setName(hidden_name); + LLAvatarListItem::setAvatarName(hidden_name); + LLAvatarListItem::setAvatarToolTip(hidden_name); } else { const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name); - LLAvatarListItem::setName(formatted_phone); + LLAvatarListItem::setAvatarName(formatted_phone); + LLAvatarListItem::setAvatarToolTip(formatted_phone); } } diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index 9d3dcb75f3..cacbcf7244 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -28,7 +28,6 @@ #define LL_LLAVATARLIST_H #include "llflatlistview.h" - #include "llavatarlistitem.h" class LLTimer; @@ -96,6 +95,7 @@ public: virtual S32 notifyParent(const LLSD& info); void addAvalineItem(const LLUUID& item_id, const LLUUID& session_id, const std::string& item_name); + void handleDisplayNamesOptionChanged(); protected: void refresh(); @@ -105,14 +105,17 @@ protected: const uuid_vec_t& vnew, uuid_vec_t& vadded, uuid_vec_t& vremoved); - void updateLastInteractionTimes(); + void updateLastInteractionTimes(); + void rebuildNames(); void onItemDoubleClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask); + void updateAvatarNames(); private: bool mIgnoreOnlineStatus; bool mShowLastInteractionTime; bool mDirty; + bool mNeedUpdateNames; bool mShowIcons; bool mShowInfoBtn; bool mShowProfileBtn; diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index c54913a3e1..a56dc129d4 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -35,6 +35,7 @@ #include "lltextutil.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llavatariconctrl.h" #include "lloutputmonitorctrl.h" @@ -186,11 +187,16 @@ void LLAvatarListItem::setOnline(bool online) setState(online ? IS_ONLINE : IS_OFFLINE); } -void LLAvatarListItem::setName(const std::string& name) +void LLAvatarListItem::setAvatarName(const std::string& name) { setNameInternal(name, mHighlihtSubstring); } +void LLAvatarListItem::setAvatarToolTip(const std::string& tooltip) +{ + mAvatarName->setToolTip(tooltip); +} + void LLAvatarListItem::setHighlight(const std::string& highlight) { setNameInternal(mAvatarName->getText(), mHighlihtSubstring = highlight); @@ -249,7 +255,8 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b mAvatarIcon->setValue(id); // Set avatar name. - gCacheName->get(id, FALSE, boost::bind(&LLAvatarListItem::onNameCache, this, _2, _3)); + LLAvatarNameCache::get(id, + boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2)); } } @@ -335,23 +342,33 @@ const LLUUID& LLAvatarListItem::getAvatarId() const return mAvatarId; } -const std::string LLAvatarListItem::getAvatarName() const +std::string LLAvatarListItem::getAvatarName() const { return mAvatarName->getValue(); } -//== PRIVATE SECTION ========================================================== +std::string LLAvatarListItem::getAvatarToolTip() const +{ + return mAvatarName->getToolTip(); +} + +void LLAvatarListItem::updateAvatarName() +{ + LLAvatarNameCache::get(getAvatarId(), + boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2)); +} + +//== PRIVATE SECITON ========================================================== void LLAvatarListItem::setNameInternal(const std::string& name, const std::string& highlight) { LLTextUtil::textboxSetHighlightedVal(mAvatarName, mAvatarNameStyle, name, highlight); - mAvatarName->setToolTip(name); } -void LLAvatarListItem::onNameCache(const std::string& first_name, const std::string& last_name) +void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name) { - std::string name = first_name + " " + last_name; - setName(name); + setAvatarName(av_name.mDisplayName); + setAvatarToolTip(av_name.mUsername); //requesting the list to resort notifyParent(LLSD().with("sort", LLSD())); diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 52187284eb..a069838ac3 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -36,6 +36,7 @@ #include "llcallingcard.h" // for LLFriendObserver class LLAvatarIconCtrl; +class LLAvatarName; class LLIconCtrl; class LLAvatarListItem : public LLPanel, public LLFriendObserver @@ -86,7 +87,9 @@ public: virtual void changed(U32 mask); // from LLFriendObserver void setOnline(bool online); - void setName(const std::string& name); + void updateAvatarName(); // re-query the name cache + void setAvatarName(const std::string& name); + void setAvatarToolTip(const std::string& tooltip); void setHighlight(const std::string& highlight); void setState(EItemState item_style); void setAvatarId(const LLUUID& id, const LLUUID& session_id, bool ignore_status_changes = false, bool is_resident = true); @@ -100,7 +103,8 @@ public: void setAvatarIconVisible(bool visible); const LLUUID& getAvatarId() const; - const std::string getAvatarName() const; + std::string getAvatarName() const; + std::string getAvatarToolTip() const; void onInfoBtnClick(); void onProfileBtnClick(); @@ -154,7 +158,7 @@ private: } EAvatarListItemChildIndex; void setNameInternal(const std::string& name, const std::string& highlight); - void onNameCache(const std::string& first_name, const std::string& last_name); + void onAvatarNameCache(const LLAvatarName& av_name); std::string formatSeconds(U32 secs); diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index b11bba58e4..078bd73379 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -27,13 +27,14 @@ #include "llviewerprecompiledheaders.h" +#include "llcallfloater.h" + #include "llnotificationsutil.h" #include "lltrans.h" -#include "llcallfloater.h" - #include "llagent.h" #include "llagentdata.h" // for gAgentID +#include "llavatarnamecache.h" #include "llavatariconctrl.h" #include "llavatarlist.h" #include "llbottomtray.h" @@ -44,6 +45,7 @@ #include "llspeakers.h" #include "lltextutil.h" #include "lltransientfloatermgr.h" +#include "llviewerdisplayname.h" #include "llviewerwindow.h" #include "llvoicechannel.h" #include "llviewerparcelmgr.h" @@ -77,7 +79,8 @@ public: void setName(const std::string& name) { const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name); - LLAvatarListItem::setName(formatted_phone); + LLAvatarListItem::setAvatarName(formatted_phone); + LLAvatarListItem::setAvatarToolTip(formatted_phone); } void setSpeakerId(const LLUUID& id) { mSpeakingIndicator->setSpeakerId(id); } @@ -112,6 +115,11 @@ LLCallFloater::LLCallFloater(const LLSD& key) // force docked state since this floater doesn't save it between recreations setDocked(true); + + // 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() @@ -368,9 +376,31 @@ void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) 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) { @@ -415,9 +445,10 @@ void LLCallFloater::initAgentData() { mAgentPanel->getChild<LLUICtrl>("user_icon")->setValue(gAgentID); - std::string name; - gCacheName->getFullName(gAgentID, name); - mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(name); + // 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); @@ -435,12 +466,12 @@ void LLCallFloater::setModeratorMutedVoice(bool moderator_muted) mSpeakingIndicator->setIsMuted(moderator_muted); } -void LLCallFloater::updateAgentModeratorState() +void LLCallFloater::onModeratorNameCache(const LLAvatarName& av_name) { std::string name; - gCacheName->getFullName(gAgentID, name); + name = av_name.mDisplayName; - if(gAgent.isInGroup(mSpeakerManager->getSessionID())) + 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. @@ -458,6 +489,11 @@ void LLCallFloater::updateAgentModeratorState() 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 diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 881f777b48..3bc7043353 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -34,6 +34,7 @@ class LLAvatarList; class LLAvatarListItem; +class LLAvatarName; class LLNonAvatarCaller; class LLOutputMonitorCtrl; class LLParticipantList; @@ -116,11 +117,16 @@ private: */ 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). diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index a664dbe53a..0d55c4429a 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -37,6 +37,7 @@ //#include <iterator> #include "indra_constants.h" +#include "llavatarnamecache.h" #include "llcachename.h" #include "llstl.h" #include "lltimer.h" @@ -44,6 +45,7 @@ #include "message.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llbutton.h" #include "llinventoryobserver.h" #include "llinventorymodel.h" @@ -90,8 +92,10 @@ const F32 OFFLINE_SECONDS = FIND_FREQUENCY + 8.0f; // static LLAvatarTracker LLAvatarTracker::sInstance; - - +static void on_avatar_name_cache_notify(const LLUUID& agent_id, + const LLAvatarName& av_name, + bool online, + LLSD payload); ///---------------------------------------------------------------------------- /// Class LLAvatarTracker @@ -244,7 +248,7 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) using namespace std; U32 new_buddy_count = 0; - std::string first,last; + std::string full_name; LLUUID agent_id; for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr) { @@ -254,7 +258,8 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds) { ++new_buddy_count; mBuddyInfo[agent_id] = (*itr).second; - gCacheName->getName(agent_id, first, last); + // IDEVO: is this necessary? name is unused? + gCacheName->getFullName(agent_id, full_name); addChangedMask(LLFriendObserver::ADD, agent_id); lldebugs << "Added buddy " << agent_id << ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline") @@ -627,12 +632,9 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) { - std::string name; LLSD args; - if(gCacheName->getFullName(agent_id, name)) - { - args["NAME"] = name; - } + args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString(); + LLSD payload; payload["from_id"] = agent_id; if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights) @@ -674,8 +676,6 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { tracking_id = mTrackingData->mAvatarID; } - BOOL notify = FALSE; - LLSD args; LLSD payload; for(S32 i = 0; i < count; ++i) { @@ -685,17 +685,6 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) if(info) { setBuddyOnline(agent_id,online); - if(chat_notify) - { - std::string first, last; - if(gCacheName->getName(agent_id, first, last)) - { - notify = TRUE; - args["FIRST"] = first; - args["LAST"] = last; - } - - } } else { @@ -711,29 +700,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) // *TODO: get actual inventory id gInventory.addChangedMask(LLInventoryObserver::CALLING_CARD, LLUUID::null); } - if(notify) + if(chat_notify) { - // Popup a notify box with online status of this agent - LLNotificationPtr notification; - - if (online) - { - notification = - LLNotificationsUtil::add("FriendOnline", - args, - payload.with("respond_on_mousedown", TRUE), - boost::bind(&LLAvatarActions::startIM, agent_id)); - } - else - { - notification = - LLNotificationsUtil::add("FriendOffline", args, payload); - } - - // If there's an open IM session with this agent, send a notification there too. - LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id); - std::string notify_msg = notification->getMessage(); - LLIMModel::instance().proccessOnlineOfflineNotification(session_id, notify_msg); + // 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)); } mModifyMask |= LLFriendObserver::ONLINE; @@ -742,6 +714,37 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) } } +static void on_avatar_name_cache_notify(const LLUUID& agent_id, + const LLAvatarName& av_name, + bool online, + LLSD payload) +{ + // 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; + + LLNotificationPtr notification; + if (online) + { + notification = + LLNotificationsUtil::add("FriendOnline", + args, + payload.with("respond_on_mousedown", TRUE), + boost::bind(&LLAvatarActions::startIM, agent_id)); + } + else + { + notification = + LLNotificationsUtil::add("FriendOffline", args, payload); + } + + // If there's an open IM session with this agent, send a notification there too. + LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id); + std::string notify_msg = notification->getMessage(); + LLIMModel::instance().proccessOnlineOfflineNotification(session_id, notify_msg); +} + void LLAvatarTracker::formFriendship(const LLUUID& id) { if(id.notNull()) @@ -862,10 +865,9 @@ bool LLCollectProxyBuddies::operator()(const LLUUID& buddy_id, LLRelationship* b bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy) { - gCacheName->getName(buddy_id, mFirst, mLast); - std::ostringstream fullname; - fullname << mFirst << " " << mLast; - buddy_map_t::value_type value(fullname.str(), buddy_id); + LLAvatarName av_name; + LLAvatarNameCache::get( buddy_id, &av_name); + buddy_map_t::value_type value(av_name.mDisplayName, buddy_id); if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) { mMappable.insert(value); @@ -875,10 +877,8 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy) { - gCacheName->getName(buddy_id, mFirst, mLast); - std::ostringstream fullname; - fullname << mFirst << " " << mLast; - buddy_map_t::value_type value(fullname.str(), buddy_id); + gCacheName->getFullName(buddy_id, mFullName); + buddy_map_t::value_type value(mFullName, buddy_id); if(buddy->isOnline()) { mOnline.insert(value); @@ -888,10 +888,10 @@ bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy) { - gCacheName->getName(buddy_id, mFirst, mLast); - std::ostringstream fullname; - fullname << mFirst << " " << mLast; - buddy_map_t::value_type value(fullname.str(), buddy_id); + LLAvatarName av_name; + LLAvatarNameCache::get(buddy_id, &av_name); + mFullName = av_name.mDisplayName; + buddy_map_t::value_type value(mFullName, buddy_id); if(buddy->isOnline()) { mOnline.insert(value); @@ -902,5 +902,3 @@ bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bud } return true; } - - diff --git a/indra/newview/llcallingcard.h b/indra/newview/llcallingcard.h index 15ca51743a..8803cce59d 100644 --- a/indra/newview/llcallingcard.h +++ b/indra/newview/llcallingcard.h @@ -235,8 +235,7 @@ public: virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy); typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t; buddy_map_t mMappable; - std::string mFirst; - std::string mLast; + std::string mFullName; }; // collect dictionary sorted map of name -> agent_id for every online buddy @@ -248,8 +247,7 @@ public: virtual bool operator()(const LLUUID& buddy_id, LLRelationship* buddy); typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t; buddy_map_t mOnline; - std::string mFirst; - std::string mLast; + std::string mFullName; }; // collect dictionary sorted map of name -> agent_id for every buddy, @@ -263,8 +261,7 @@ public: typedef std::map<std::string, LLUUID, LLDictionaryLess> buddy_map_t; buddy_map_t mOnline; buddy_map_t mOffline; - std::string mFirst; - std::string mLast; + std::string mFullName; }; #endif // LL_LLCALLINGCARD_H diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index eb10add254..378c4358b3 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -26,10 +26,12 @@ #include "llviewerprecompiledheaders.h" +#include "llchathistory.h" + +#include "llavatarnamecache.h" #include "llinstantmessage.h" #include "llimview.h" -#include "llchathistory.h" #include "llcommandhandler.h" #include "llpanel.h" #include "lluictrlfactory.h" @@ -53,6 +55,7 @@ #include "llworld.h" #include "lluiconstants.h" +#include "llviewercontrol.h" #include "llsidetray.h"//for blocked objects panel @@ -98,6 +101,18 @@ LLObjectIMHandler gObjectIMHandler; class LLChatHistoryHeader: public LLPanel { public: + LLChatHistoryHeader() + : LLPanel(), + mPopupMenuHandleAvatar(), + mPopupMenuHandleObject(), + mAvatarID(), + mSourceType(CHAT_SOURCE_UNKNOWN), + mFrom(), + mSessionID(), + mMinUserNameWidth(0), + mUserNameFont(NULL) + {} + static LLChatHistoryHeader* createInstance(const std::string& file_name) { LLChatHistoryHeader* pInstance = new LLChatHistoryHeader; @@ -240,7 +255,6 @@ public: mAvatarID = chat.mFromID; mSessionID = chat.mSessionID; mSourceType = chat.mSourceType; - gCacheName->get(mAvatarID, FALSE, boost::bind(&LLChatHistoryHeader::nameUpdatedCallback, this, _1, _2, _3, _4)); //*TODO overly defensive thing, source type should be maintained out there if((chat.mFromID.isNull() && chat.mFromName.empty()) || chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull()) @@ -248,22 +262,40 @@ public: mSourceType = CHAT_SOURCE_SYSTEM; } - LLTextBox* userName = getChild<LLTextBox>("user_name"); + mUserNameFont = style_params.font(); + LLTextBox* user_name = getChild<LLTextBox>("user_name"); + user_name->setReadOnlyColor(style_params.readonly_color()); + user_name->setColor(style_params.color()); - userName->setReadOnlyColor(style_params.readonly_color()); - userName->setColor(style_params.color()); - - userName->setValue(chat.mFromName); - mFrom = chat.mFromName; - if (chat.mFromName.empty() || CHAT_SOURCE_SYSTEM == mSourceType) + if (chat.mFromName.empty() + || mSourceType == CHAT_SOURCE_SYSTEM + || mAvatarID.isNull()) { mFrom = LLTrans::getString("SECOND_LIFE"); - userName->setValue(mFrom); + user_name->setValue(mFrom); + updateMinUserNameWidth(); + } + else if (mSourceType == CHAT_SOURCE_AGENT + && chat.mChatStyle != CHAT_STYLE_HISTORY) + { + // ...from a normal user, lookup the name and fill in later. + // *NOTE: Do not do this for chat history logs, otherwise the viewer + // will flood the People API with lookup requests on startup + + // 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)); + } + else { + // ...from an object, just use name as given + mFrom = chat.mFromName; + user_name->setValue(mFrom); + updateMinUserNameWidth(); } - mMinUserNameWidth = style_params.font()->getWidth(userName->getWText().c_str()) + PADDING; - setTimeField(chat); LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon"); @@ -317,12 +349,39 @@ public: LLPanel::draw(); } - void nameUpdatedCallback(const LLUUID& id,const std::string& first,const std::string& last,BOOL is_group) + void updateMinUserNameWidth() { - if (id != mAvatarID) - return; - mFrom = first + " " + last; + if (mUserNameFont) + { + LLTextBox* user_name = getChild<LLTextBox>("user_name"); + const LLWString& text = user_name->getWText(); + mMinUserNameWidth = mUserNameFont->getWidth(text.c_str()) + PADDING; + } } + + 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()) + { + 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; @@ -449,6 +508,7 @@ protected: LLUUID mSessionID; S32 mMinUserNameWidth; + const LLFontGL* mUserNameFont; }; LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL; diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index e78bdbe25c..d353c809ca 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -31,6 +31,7 @@ #include "llchatmsgbox.h" #include "llavatariconctrl.h" +#include "llcommandhandler.h" #include "llfloaterreg.h" #include "lllocalcliprect.h" #include "lltrans.h" @@ -45,6 +46,40 @@ static const S32 msg_right_offset = 10; static const S32 msg_height_pad = 5; //******************************************************************************************************************* +// LLObjectHandler +//******************************************************************************************************************* + +// handle secondlife:///app/object/<ID>/inspect SLURLs +class LLObjectHandler : public LLCommandHandler +{ +public: + LLObjectHandler() : LLCommandHandler("object", UNTRUSTED_BLOCK) { } + + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) + { + if (params.size() < 2) return false; + + LLUUID object_id; + if (!object_id.set(params[0], FALSE)) + { + return false; + } + + const std::string verb = params[1].asString(); + + if (verb == "inspect") + { + LLFloaterReg::showInstance("inspect_object", LLSD().with("object_id", object_id)); + return true; + } + + return false; + } +}; + +LLObjectHandler gObjectHandler; + +//******************************************************************************************************************* //LLNearbyChatToastPanel //******************************************************************************************************************* @@ -173,11 +208,22 @@ void LLNearbyChatToastPanel::init(LLSD& notification) str_sender+=" "; - //append user name + //append sender name + if (mSourceType == CHAT_SOURCE_AGENT || mSourceType == CHAT_SOURCE_OBJECT) { LLStyle::Params style_params_name; LLColor4 userNameColor = LLUIColorTable::instance().getColor("ChatToastAgentNameColor"); + std::string href; + + if (mSourceType == CHAT_SOURCE_AGENT) + { + href = LLSLURL("agent", mFromID, "about").getSLURLString(); + } + else + { + href = LLSLURL("object", mFromID, "inspect").getSLURLString(); + } style_params_name.color(userNameColor); @@ -186,11 +232,16 @@ void LLNearbyChatToastPanel::init(LLSD& notification) style_params_name.font.name(font_name); style_params_name.font.size(font_style_size); - style_params_name.link_href = LLSLURL("agent",mFromID,"about").getSLURLString(); + style_params_name.link_href = href; + style_params_name.is_link = true; msg_text->appendText(str_sender, FALSE, style_params_name); } + else + { + msg_text->appendText(str_sender, false); + } } //append text diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index ee8646aad0..f31ff14df6 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -267,7 +267,11 @@ bool LLCommandLineParser::parseAndStoreResults(po::command_line_parser& clp) { clp.options(gOptionsDesc); clp.positional(gPositionalOptions); - clp.style(po::command_line_style::default_style + // SNOW-626: Boost 1.42 erroneously added allow_guessing to the default style + // (see http://groups.google.com/group/boost-list/browse_thread/thread/545d7bf98ff9bb16?fwc=2&pli=1) + // Remove allow_guessing from the default style, because that is not allowed + // when we have options that are a prefix of other options (aka, --help and --helperuri). + clp.style((po::command_line_style::default_style & ~po::command_line_style::allow_guessing) | po::command_line_style::allow_long_disguise); if(mExtraParser) { diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp index e575e06c5a..fcc73a07bc 100644 --- a/indra/newview/lldateutil.cpp +++ b/indra/newview/lldateutil.cpp @@ -166,3 +166,23 @@ std::string LLDateUtil::ageFromDate(const std::string& date_string) { return ageFromDate(date_string, LLDate::now()); } + +//std::string LLDateUtil::ageFromDateISO(const std::string& date_string, +// const LLDate& now) +//{ +// S32 born_month, born_day, born_year; +// S32 matched = sscanf(date_string.c_str(), "%d-%d-%d", +// &born_year, &born_month, &born_day); +// if (matched != 3) return "???"; +// date.fromYMDHMS(year, month, day); +// F64 secs_since_epoch = date.secondsSinceEpoch(); +// // Correct for the fact that specified date is in Pacific time, == UTC - 8 +// secs_since_epoch += 8.0 * 60.0 * 60.0; +// date.secondsSinceEpoch(secs_since_epoch); +// return ageFromDate(born_year, born_month, born_day, now); +//} +// +//std::string LLDateUtil::ageFromDateISO(const std::string& date_string) +//{ +// return ageFromDateISO(date_string, LLDate::now()); +//} diff --git a/indra/newview/lldateutil.h b/indra/newview/lldateutil.h index 5b465367dc..2843a357c9 100644 --- a/indra/newview/lldateutil.h +++ b/indra/newview/lldateutil.h @@ -61,6 +61,14 @@ namespace LLDateUtil // Calls the above with LLDate::now() std::string ageFromDate(const std::string& date_string); + + // As above, for YYYY-MM-DD dates + //std::string ageFromDateISO(const std::string& date_string, const LLDate& now); + + // Calls the above with LLDate::now() + //std::string ageFromDateISO(const std::string& date_string); + + //std::string ageFromDate(S32 born_year, S32 born_month, S32 born_day, const LLDate& now); } #endif diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 9cf9b69d3e..2cea41df0a 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -47,6 +47,7 @@ class LLCamera; class LLDrawPool; class LLDrawable; class LLFace; +class LLFacePool; class LLSpatialGroup; class LLSpatialBridge; class LLSpatialPartition; diff --git a/indra/newview/lleventinfo.cpp b/indra/newview/lleventinfo.cpp deleted file mode 100644 index b7b4e10b17..0000000000 --- a/indra/newview/lleventinfo.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file lleventinfo.cpp - * @brief LLEventInfo class 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$ - */ - -#include "llviewerprecompiledheaders.h" -#include "lleventinfo.h" - -#include "lluuid.h" -#include "message.h" - -LLEventInfo::cat_map LLEventInfo::sCategories; - -void LLEventInfo::unpack(LLMessageSystem *msg) -{ - U32 event_id; - msg->getU32("EventData", "EventID", event_id); - mID = event_id; - - msg->getString("EventData", "Name", mName); - - msg->getString("EventData", "Category", mCategoryStr); - - msg->getString("EventData", "Date", mTimeStr); - - U32 duration; - msg->getU32("EventData","Duration",duration); - mDuration = duration; - - U32 date; - msg->getU32("EventData", "DateUTC", date); - mUnixTime = date; - - msg->getString("EventData", "Desc", mDesc); - - std::string buffer; - msg->getString("EventData", "Creator", buffer); - mRunByID = LLUUID(buffer); - - U32 foo; - msg->getU32("EventData", "Cover", foo); - - mHasCover = foo ? TRUE : FALSE; - if (mHasCover) - { - U32 cover; - msg->getU32("EventData", "Amount", cover); - mCover = cover; - } - - msg->getString("EventData", "SimName", mSimName); - - msg->getVector3d("EventData", "GlobalPos", mPosGlobal); - - // Mature content - U32 event_flags; - msg->getU32("EventData", "EventFlags", event_flags); - mEventFlags = event_flags; -} - -// static -void LLEventInfo::loadCategories(const LLSD& options) -{ - for(LLSD::array_const_iterator resp_it = options.beginArray(), - end = options.endArray(); resp_it != end; ++resp_it) - { - LLSD name = (*resp_it)["category_name"]; - if(name.isDefined()) - { - LLSD id = (*resp_it)["category_id"]; - if(id.isDefined()) - { - LLEventInfo::sCategories[id.asInteger()] = name.asString(); - } - } - } -} diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp index 68559a4236..bedab75f98 100644 --- a/indra/newview/lleventnotifier.cpp +++ b/indra/newview/lleventnotifier.cpp @@ -31,10 +31,63 @@ #include "llnotificationsutil.h" #include "message.h" -#include "lleventinfo.h" #include "llfloaterreg.h" #include "llfloaterworldmap.h" +#include "llfloaterevent.h" #include "llagent.h" +#include "llcommandhandler.h" // secondlife:///app/... support + +class LLEventHandler : public LLCommandHandler +{ +public: + // requires trusted browser to trigger + LLEventHandler() : LLCommandHandler("event", UNTRUSTED_THROTTLE) { } + bool handle(const LLSD& params, const LLSD& query_map, + LLMediaCtrl* web) + { + if (params.size() < 2) + { + return false; + } + std::string event_command = params[1].asString(); + S32 event_id = params[0].asInteger(); + if(event_command == "details") + { + LLFloaterEvent* floater = LLFloaterReg::getTypedInstance<LLFloaterEvent>("event"); + if (floater) + { + floater->setEventID(event_id); + LLFloaterReg::showTypedInstance<LLFloaterEvent>("event"); + return true; + } + } + else if(event_command == "notify") + { + // we're adding or removing a notification, so grab the date, name and notification bool + if (params.size() < 3) + { + return false; + } + if(params[2].asString() == "enable") + { + gEventNotifier.add(event_id); + // tell the server to modify the database as this was a slurl event notification command + gEventNotifier.serverPushRequest(event_id, true); + + } + else + { + gEventNotifier.remove(event_id); + } + return true; + } + + + return false; + } +}; +LLEventHandler gEventHandler; + LLEventNotifier gEventNotifier; @@ -63,31 +116,102 @@ void LLEventNotifier::update() // Check our notifications again and send out updates // if they happen. - time_t alert_time = time_corrected() + 5 * 60; + F64 alert_time = LLDate::now().secondsSinceEpoch() + 5 * 60; en_map::iterator iter; for (iter = mEventNotifications.begin(); iter != mEventNotifications.end();) { LLEventNotification *np = iter->second; - if (np->getEventDate() < (alert_time)) + iter++; + if (np->getEventDateEpoch() < alert_time) { LLSD args; args["NAME"] = np->getEventName(); + args["DATE"] = np->getEventDateStr(); LLNotificationsUtil::add("EventNotification", args, LLSD(), - boost::bind(&LLEventNotification::handleResponse, np, _1, _2)); - mEventNotifications.erase(iter++); + boost::bind(&LLEventNotifier::handleResponse, this, np->getEventID(), _1, _2)); + remove(np->getEventID()); + } - else + } + mNotificationTimer.reset(); + } +} + + + +bool LLEventNotifier::handleResponse(U32 eventId, const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch (option) + { + case 0: + { + LLFloaterEvent* floater = LLFloaterReg::getTypedInstance<LLFloaterEvent>("event"); + if (floater) { - iter++; + floater->setEventID(eventId); + LLFloaterReg::showTypedInstance<LLFloaterEvent>("event"); } + break; } - mNotificationTimer.reset(); + case 1: + break; } + return true; } +bool LLEventNotifier::add(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName) +{ + LLEventNotification *new_enp = new LLEventNotification(eventId, eventEpoch, eventDateStr, eventName); + + llinfos << "Add event " << eventName << " id " << eventId << " date " << eventDateStr << llendl; + if(!new_enp->isValid()) + { + delete new_enp; + return false; + } + + mEventNotifications[new_enp->getEventID()] = new_enp; + return true; + +} + +void LLEventNotifier::add(U32 eventId) +{ + + gMessageSystem->newMessageFast(_PREHASH_EventInfoRequest); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + gMessageSystem->nextBlockFast(_PREHASH_EventData); + gMessageSystem->addU32Fast(_PREHASH_EventID, eventId); + gAgent.sendReliableMessage(); + +} + +//static +void LLEventNotifier::processEventInfoReply(LLMessageSystem *msg, void **) +{ + // extract the agent id + LLUUID agent_id; + U32 event_id; + std::string event_name; + std::string eventd_date; + U32 event_time_utc; + + msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); + msg->getU32("EventData", "EventID", event_id); + msg->getString("EventData", "Name", event_name); + msg->getString("EventData", "Date", eventd_date); + msg->getU32("EventData", "DateUTC", event_time_utc); + + gEventNotifier.add(event_id, (F64)event_time_utc, eventd_date, event_name); +} + + void LLEventNotifier::load(const LLSD& event_options) { for(LLSD::array_const_iterator resp_it = event_options.beginArray(), @@ -95,15 +219,7 @@ void LLEventNotifier::load(const LLSD& event_options) { LLSD response = *resp_it; - LLEventNotification *new_enp = new LLEventNotification(); - - if(!new_enp->load(response)) - { - delete new_enp; - continue; - } - - mEventNotifications[new_enp->getEventID()] = new_enp; + add(response["event_id"].asInteger(), response["event_date_ut"], response["event_date"].asString(), response["event_name"].asString()); } } @@ -117,32 +233,6 @@ BOOL LLEventNotifier::hasNotification(const U32 event_id) return FALSE; } - -void LLEventNotifier::add(LLEventInfo &event_info) -{ - // We need to tell the simulator that we want to pay attention to - // this event, as well as add it to our list. - - if (mEventNotifications.find(event_info.mID) != mEventNotifications.end()) - { - // We already have a notification for this event, don't bother. - return; - } - - // Push up a message to tell the server we have this notification. - gMessageSystem->newMessage("EventNotificationAddRequest"); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - gMessageSystem->nextBlock("EventData"); - gMessageSystem->addU32("EventID", event_info.mID); - gAgent.sendReliableMessage(); - - LLEventNotification *enp = new LLEventNotification; - enp->load(event_info); - mEventNotifications[event_info.mID] = enp; -} - void LLEventNotifier::remove(const U32 event_id) { en_map::iterator iter; @@ -153,164 +243,36 @@ void LLEventNotifier::remove(const U32 event_id) return; } - // Push up a message to tell the server to remove this notification. - gMessageSystem->newMessage("EventNotificationRemoveRequest"); + serverPushRequest(event_id, false); + delete iter->second; + mEventNotifications.erase(iter); +} + + +void LLEventNotifier::serverPushRequest(U32 event_id, bool add) +{ + // Push up a message to tell the server we have this notification. + gMessageSystem->newMessage(add?"EventNotificationAddRequest":"EventNotificationRemoveRequest"); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); gMessageSystem->nextBlock("EventData"); gMessageSystem->addU32("EventID", event_id); gAgent.sendReliableMessage(); - - delete iter->second; - mEventNotifications.erase(iter); -} - -LLEventNotification::LLEventNotification() : - mEventID(0), - mEventDate(0), - mEventName("") -{ } -LLEventNotification::~LLEventNotification() +LLEventNotification::LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName) : + mEventID(eventId), + mEventName(eventName), + mEventDateEpoch(eventEpoch), + mEventDateStr(eventDateStr) { + } -bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - switch (option) - { - case 0: - { - gAgent.teleportViaLocation(getEventPosGlobal()); - LLFloaterWorldMap* floater_world_map = LLFloaterWorldMap::getInstance(); - if(floater_world_map) floater_world_map->trackLocation(getEventPosGlobal()); - break; - } - case 1: - LLFloaterReg::showInstance("search", LLSD().with("category", "events").with("id", S32(getEventID()))); - break; - case 2: - break; - } - // We could clean up the notification on the server now if we really wanted to. - return false; -} -BOOL LLEventNotification::load(const LLSD& response) -{ - BOOL event_ok = TRUE; - LLSD option = response.get("event_id"); - if (option.isDefined()) - { - mEventID = option.asInteger(); - } - else - { - event_ok = FALSE; - } - option = response.get("event_name"); - if (option.isDefined()) - { - llinfos << "Event: " << option.asString() << llendl; - mEventName = option.asString(); - } - else - { - event_ok = FALSE; - } - option = response.get("event_date"); - if (option.isDefined()) - { - llinfos << "EventDate: " << option.asString() << llendl; - mEventDateStr = option.asString(); - } - else - { - event_ok = FALSE; - } - - option = response.get("event_date_ut"); - if (option.isDefined()) - { - llinfos << "EventDate: " << option.asString() << llendl; - mEventDate = strtoul(option.asString().c_str(), NULL, 10); - } - else - { - event_ok = FALSE; - } - - S32 grid_x = 0; - S32 grid_y = 0; - S32 x_region = 0; - S32 y_region = 0; - - option = response.get("grid_x"); - if (option.isDefined()) - { - llinfos << "GridX: " << option.asInteger() << llendl; - grid_x= option.asInteger(); - } - else - { - event_ok = FALSE; - } - - option = response.get("grid_y"); - if (option.isDefined()) - { - llinfos << "GridY: " << option.asInteger() << llendl; - grid_y = option.asInteger(); - } - else - { - event_ok = FALSE; - } - - option = response.get("x_region"); - if (option.isDefined()) - { - llinfos << "RegionX: " << option.asInteger() << llendl; - x_region = option.asInteger(); - } - else - { - event_ok = FALSE; - } - - option = response.get("y_region"); - if (option.isDefined()) - { - llinfos << "RegionY: " << option.asInteger() << llendl; - y_region = option.asInteger(); - } - else - { - event_ok = FALSE; - } - - mEventPosGlobal.mdV[VX] = grid_x * 256 + x_region; - mEventPosGlobal.mdV[VY] = grid_y * 256 + y_region; - mEventPosGlobal.mdV[VZ] = 0.f; - - return event_ok; -} - -BOOL LLEventNotification::load(const LLEventInfo &event_info) -{ - - mEventID = event_info.mID; - mEventName = event_info.mName; - mEventDateStr = event_info.mTimeStr; - mEventDate = event_info.mUnixTime; - mEventPosGlobal = event_info.mPosGlobal; - return TRUE; -} diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h index 0367fc47b0..697a708762 100644 --- a/indra/newview/lleventnotifier.h +++ b/indra/newview/lleventnotifier.h @@ -30,7 +30,6 @@ #include "llframetimer.h" #include "v3dmath.h" -class LLEventInfo; class LLEventNotification; @@ -41,15 +40,21 @@ public: virtual ~LLEventNotifier(); void update(); // Notify the user of the event if it's coming up + bool add(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName); + void add(U32 eventId); + void load(const LLSD& event_options); // In the format that it comes in from login - void add(LLEventInfo &event_info); // Add a new notification for an event void remove(U32 event_id); BOOL hasNotification(const U32 event_id); + void serverPushRequest(U32 event_id, bool add); typedef std::map<U32, LLEventNotification *> en_map; + bool handleResponse(U32 eventId, const LLSD& notification, const LLSD& response); + static void processEventInfoReply(LLMessageSystem *msg, void **); + protected: en_map mEventNotifications; LLFrameTimer mNotificationTimer; @@ -59,25 +64,21 @@ protected: class LLEventNotification { public: - LLEventNotification(); - virtual ~LLEventNotification(); + LLEventNotification(U32 eventId, F64 eventEpoch, const std::string& eventDateStr, const std::string &eventName); + - BOOL load(const LLSD& en); // In the format it comes in from login - BOOL load(const LLEventInfo &event_info); // From existing event_info on the viewer. - //void setEventID(const U32 event_id); - //void setEventName(std::string &event_name); U32 getEventID() const { return mEventID; } const std::string &getEventName() const { return mEventName; } - time_t getEventDate() const { return mEventDate; } - const std::string &getEventDateStr() const { return mEventDateStr; } - LLVector3d getEventPosGlobal() const { return mEventPosGlobal; } - bool handleResponse(const LLSD& notification, const LLSD& payload); + bool isValid() const { return mEventID > 0 && mEventDateEpoch != 0 && mEventName.size() > 0; } + const F64 &getEventDateEpoch() const { return mEventDateEpoch; } + const std::string &getEventDateStr() const { return mEventDateStr; } + + protected: U32 mEventID; // EventID for this event std::string mEventName; + F64 mEventDateEpoch; std::string mEventDateStr; - time_t mEventDate; - LLVector3d mEventPosGlobal; }; extern LLEventNotifier gEventNotifier; diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index dd08706f4f..b08c113923 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -117,6 +117,12 @@ void LLFirstUse::notMoving(bool enable) } // static +void LLFirstUse::setDisplayName(bool enable) +{ + firstUseNotification("FirstDisplayName", enable, "HintDisplayName", LLSD(), LLSD().with("target", "set_display_name").with("direction", "left")); +} + +// static void LLFirstUse::receiveLindens(bool enable) { firstUseNotification("FirstReceiveLindens", enable, "HintLindenDollar", LLSD(), LLSD().with("target", "linden_balance").with("direction", "bottom")); diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h index 275f134400..3b7ff6383b 100644 --- a/indra/newview/llfirstuse.h +++ b/indra/newview/llfirstuse.h @@ -91,6 +91,7 @@ public: static void notMoving(bool enable = true); static void newInventory(bool enable = true); static void receiveLindens(bool enable = true); + static void setDisplayName(bool enable = true); static void useSandbox(); protected: diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 9f96a22f56..aa66fcf9b8 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -35,10 +35,14 @@ #include "llimview.h" // for gIMMgr #include "lltooldraganddrop.h" // for LLToolDragAndDrop #include "llviewercontrol.h" +#include "llviewerregion.h" // getCapability() #include "llworld.h" // Linden libraries +#include "llavatarnamecache.h" // IDEVO #include "llbutton.h" +#include "llcachename.h" +#include "llhttpclient.h" // IDEVO #include "lllineeditor.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" @@ -47,6 +51,11 @@ #include "lluictrlfactory.h" #include "message.h" +//#include "llsdserialize.h" + +//put it back as a member once the legacy path is out? +static std::map<LLUUID, LLAvatarName> sAvatarNameMap; + LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback, BOOL allow_multiple, BOOL closeOnSelect) @@ -152,7 +161,7 @@ void LLFloaterAvatarPicker::onBtnFind() find(); } -static void getSelectedAvatarData(const LLScrollListCtrl* from, std::vector<std::string>& avatar_names, uuid_vec_t& avatar_ids) +static void getSelectedAvatarData(const LLScrollListCtrl* from, uuid_vec_t& avatar_ids, std::vector<LLAvatarName>& avatar_names) { std::vector<LLScrollListItem*> items = from->getAllSelected(); for (std::vector<LLScrollListItem*>::iterator iter = items.begin(); iter != items.end(); ++iter) @@ -160,8 +169,21 @@ static void getSelectedAvatarData(const LLScrollListCtrl* from, std::vector<std: LLScrollListItem* item = *iter; if (item->getUUID().notNull()) { - avatar_names.push_back(item->getColumn(0)->getValue().asString()); avatar_ids.push_back(item->getUUID()); + + std::map<LLUUID, LLAvatarName>::iterator iter = sAvatarNameMap.find(item->getUUID()); + if (iter != sAvatarNameMap.end()) + { + avatar_names.push_back(iter->second); + } + else + { + // the only case where it isn't in the name map is friends + // but it should be in the name cache + LLAvatarName av_name; + LLAvatarNameCache::get(item->getUUID(), &av_name); + avatar_names.push_back(av_name); + } } } } @@ -197,10 +219,10 @@ void LLFloaterAvatarPicker::onBtnSelect() if(list) { - std::vector<std::string> avatar_names; uuid_vec_t avatar_ids; - getSelectedAvatarData(list, avatar_names, avatar_ids); - mSelectionCallback(avatar_names, avatar_ids); + std::vector<LLAvatarName> avatar_names; + getSelectedAvatarData(list, avatar_ids, avatar_names); + mSelectionCallback(avatar_ids, avatar_names); } } getChild<LLScrollListCtrl>("SearchResults")->deselectAllItems(TRUE); @@ -250,15 +272,22 @@ void LLFloaterAvatarPicker::populateNearMe() if(av == gAgent.getID()) continue; LLSD element; element["id"] = av; // value - std::string fullname; - if(!gCacheName->getFullName(av, fullname)) + LLAvatarName av_name; + + if (!LLAvatarNameCache::get(av, &av_name)) { + element["columns"][0]["column"] = "name"; element["columns"][0]["value"] = LLCacheName::getDefaultName(); all_loaded = FALSE; } else { - element["columns"][0]["value"] = fullname; + element["columns"][0]["column"] = "name"; + element["columns"][0]["value"] = av_name.mDisplayName; + element["columns"][1]["column"] = "username"; + element["columns"][1]["value"] = av_name.mUsername; + + sAvatarNameMap[av] = av_name; } near_me_scroller->addElement(element); empty = FALSE; @@ -293,7 +322,6 @@ void LLFloaterAvatarPicker::populateFriend() LLAvatarTracker::instance().applyFunctor(collector); LLCollectAllBuddies::buddy_map_t::iterator it; - for(it = collector.mOnline.begin(); it!=collector.mOnline.end(); it++) { friends_scroller->addStringUUIDItem(it->first, it->second); @@ -345,23 +373,81 @@ BOOL LLFloaterAvatarPicker::visibleItemsSelected() const return FALSE; } +class LLAvatarPickerResponder : public LLHTTPClient::Responder +{ +public: + LLUUID mQueryID; + + LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { } + + /*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content) + { + //std::ostringstream ss; + //LLSDSerialize::toPrettyXML(content, ss); + //llinfos << ss.str() << llendl; + + // in case of invalid characters, the avatar picker returns a 400 + // just set it to process so it displays 'not found' + if (isGoodStatus(status) || status == 400) + { + LLFloaterAvatarPicker* floater = + LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker"); + if (floater) + { + floater->processResponse(mQueryID, content); + } + } + else + { + llinfos << "avatar picker failed " << status + << " reason " << reason << llendl; + + } + } +}; + void LLFloaterAvatarPicker::find() { + //clear our stored LLAvatarNames + sAvatarNameMap.clear(); + std::string text = getChild<LLUICtrl>("Edit")->getValue().asString(); mQueryID.generate(); - LLMessageSystem* msg = gMessageSystem; - - msg->newMessage("AvatarPickerRequest"); - msg->nextBlock("AgentData"); - msg->addUUID("AgentID", gAgent.getID()); - msg->addUUID("SessionID", gAgent.getSessionID()); - msg->addUUID("QueryID", mQueryID); // not used right now - msg->nextBlock("Data"); - msg->addString("Name", text); + std::string url; + url.reserve(128); // avoid a memory allocation or two - gAgent.sendReliableMessage(); + 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()) + { + // capability urls don't end in '/', but we need one to parse + // query parameters correctly + if (url.size() > 0 && url[url.size()-1] != '/') + { + url += "/"; + } + url += "?page_size=100&names="; + url += LLURI::escape(text); + llinfos << "avatar picker " << url << llendl; + LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID)); + } + else + { + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("AvatarPickerRequest"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->addUUID("QueryID", mQueryID); // not used right now + msg->nextBlock("Data"); + msg->addString("Name", text); + gAgent.sendReliableMessage(); + } getChild<LLScrollListCtrl>("SearchResults")->deleteAllItems(); getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching")); @@ -502,12 +588,21 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* } else { - avatar_name = first_name + " " + last_name; + 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; + } LLSD element; element["id"] = avatar_id; // value + element["columns"][0]["column"] = "name"; element["columns"][0]["value"] = avatar_name; search_results->addElement(element); } @@ -521,10 +616,61 @@ 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; + + LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults"); + + 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; + } + + // 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); +} + //static void LLFloaterAvatarPicker::editKeystroke(LLLineEditor* caller, void* user_data) { - getChildView("Find")->setEnabled(caller->getText().size() >= 3); + getChildView("Find")->setEnabled(caller->getText().size() > 0); } // virtual @@ -582,8 +728,8 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled() if(list) { uuid_vec_t avatar_ids; - std::vector<std::string> avatar_names; - getSelectedAvatarData(list, avatar_names, avatar_ids); + std::vector<LLAvatarName> avatar_names; + getSelectedAvatarData(list, avatar_ids, avatar_names); return mOkButtonValidateSignal(avatar_ids); } } diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index b476e898e9..96c039443a 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -31,6 +31,7 @@ #include <vector> +class LLAvatarName; class LLScrollListCtrl; class LLFloaterAvatarPicker : public LLFloater @@ -40,7 +41,7 @@ public: typedef validate_signal_t::slot_type validate_callback_t; // The callback function will be called with an avatar name and UUID. - typedef boost::function<void (const std::vector<std::string>&, const uuid_vec_t&)> select_callback_t; + typedef boost::function<void (const uuid_vec_t&, const std::vector<LLAvatarName>&)> select_callback_t; // Call this to select an avatar. static LLFloaterAvatarPicker* show(select_callback_t callback, BOOL allow_multiple = FALSE, @@ -54,6 +55,7 @@ public: void setOkBtnEnableCb(validate_callback_t cb); static void processAvatarPickerReply(class LLMessageSystem* msg, void**); + void processResponse(const LLUUID& query_id, const LLSD& content); BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp index 10cf26521f..4e10b4fc2c 100644 --- a/indra/newview/llfloateravatartextures.cpp +++ b/indra/newview/llfloateravatartextures.cpp @@ -27,6 +27,9 @@ #include "llviewerprecompiledheaders.h" #include "llfloateravatartextures.h" +// library headers +#include "llavatarnamecache.h" + #include "llagent.h" #include "llagentwearables.h" #include "lltexturectrl.h" @@ -131,10 +134,10 @@ void LLFloaterAvatarTextures::refresh() LLVOAvatar *avatarp = find_avatar(mID); if (avatarp) { - std::string fullname; - if (gCacheName->getFullName(avatarp->getID(), fullname)) + LLAvatarName av_name; + if (LLAvatarNameCache::get(avatarp->getID(), &av_name)) { - setTitle(mTitle + ": " + fullname); + setTitle(mTitle + ": " + av_name.getCompleteName()); } for (U32 i=0; i < TEX_NUM_INDICES; i++) { diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index a02b67f08e..61cf4dad93 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -82,7 +82,7 @@ void LLFloaterBump::onOpen(const LLSD& key) void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd) { - if (mcd->mFirstName.empty() || list->getItemCount() >= 20) + if (mcd->mFullName.empty() || list->getItemCount() >= 20) { return; } @@ -120,8 +120,7 @@ void LLFloaterBump::add(LLScrollListCtrl* list, LLMeanCollisionData* mcd) // All above action strings are in XML file LLUIString text = getString(action); text.setArg("[TIME]", timeStr); - text.setArg("[FIRST]", mcd->mFirstName); - text.setArg("[LAST]", mcd->mLastName); + text.setArg("[NAME]", mcd->mFullName); LLSD row; row["id"] = mcd->mPerp; diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index f46a2be0fa..ee8487b160 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -177,7 +177,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info) object_list->addElement(row); floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice())); - floater->getChild<LLUICtrl>("buy_text")->setTextArg("[NAME]", owner_name); + floater->getChild<LLUICtrl>("buy_name_text")->setTextArg("[NAME]", owner_name); // Must do this after the floater is created, because // sometimes the inventory is already there and diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index e48e1ab64f..83105ef27c 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -180,9 +180,8 @@ public: void updateNames(); // Name cache callback void updateGroupName(const LLUUID& id, - const std::string& first_name, - const std::string& last_name, - BOOL is_group); + const std::string& name, + bool is_group); void refreshUI(); @@ -819,28 +818,26 @@ void LLFloaterBuyLandUI::updateNames() } else if (parcelp->getIsGroupOwned()) { - gCacheName->get(parcelp->getGroupID(), TRUE, + gCacheName->getGroup(parcelp->getGroupID(), boost::bind(&LLFloaterBuyLandUI::updateGroupName, this, - _1, _2, _3, _4)); + _1, _2, _3)); } else { - mParcelSellerName = - LLSLURL("agent", parcelp->getOwnerID(), "inspect").getSLURLString(); + mParcelSellerName = LLSLURL("agent", parcelp->getOwnerID(), "completename").getSLURLString(); } } void LLFloaterBuyLandUI::updateGroupName(const LLUUID& id, - const std::string& first_name, - const std::string& last_name, - BOOL is_group) + const std::string& name, + bool is_group) { LLParcel* parcelp = mParcel->getParcel(); if (parcelp && parcelp->getGroupID() == id) { // request is current - mParcelSellerName = first_name; + mParcelSellerName = name; } } diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp new file mode 100644 index 0000000000..ac8f107928 --- /dev/null +++ b/indra/newview/llfloaterdisplayname.cpp @@ -0,0 +1,223 @@ +/** + * @file llfloaterdisplayname.cpp + * @author Leyla Farazha + * @brief Implementation of the LLFloaterDisplayName 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 "llfloaterreg.h" +#include "llfloater.h" + +#include "llnotificationsutil.h" +#include "llviewerdisplayname.h" + +#include "llnotifications.h" +#include "llfloaterdisplayname.h" +#include "llavatarnamecache.h" + +#include "llagent.h" + + +class LLFloaterDisplayName : public LLFloater +{ +public: + LLFloaterDisplayName(const LLSD& key); + virtual ~LLFloaterDisplayName() {}; + /*virtual*/ BOOL postBuild(); + void onSave(); + void onReset(); + void onCancel(); + /*virtual*/ void onOpen(const LLSD& key); + +private: + + void onCacheSetName(bool success, + const std::string& reason, + const LLSD& content); +}; + +LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) + : LLFloater(key) +{ +} + +void LLFloaterDisplayName::onOpen(const LLSD& key) +{ + getChild<LLUICtrl>("display_name_editor")->clear(); + getChild<LLUICtrl>("display_name_confirm")->clear(); + + LLAvatarName av_name; + LLAvatarNameCache::get(gAgent.getID(), &av_name); + + F64 now_secs = LLDate::now().secondsSinceEpoch(); + + if (now_secs < av_name.mNextUpdate) + { + // ...can't update until some time in the future + F64 next_update_local_secs = + av_name.mNextUpdate - LLStringOps::getLocalTimeOffset(); + LLDate next_update_local(next_update_local_secs); + // display as "July 18 12:17 PM" + std::string next_update_string = + next_update_local.toHTTPDateString("%B %d %I:%M %p"); + getChild<LLUICtrl>("lockout_text")->setTextArg("[TIME]", next_update_string); + getChild<LLUICtrl>("lockout_text")->setVisible(true); + getChild<LLUICtrl>("save_btn")->setEnabled(false); + getChild<LLUICtrl>("display_name_editor")->setEnabled(false); + getChild<LLUICtrl>("display_name_confirm")->setEnabled(false); + getChild<LLUICtrl>("cancel_btn")->setFocus(TRUE); + + } + else + { + getChild<LLUICtrl>("lockout_text")->setVisible(false); + getChild<LLUICtrl>("save_btn")->setEnabled(true); + getChild<LLUICtrl>("display_name_editor")->setEnabled(true); + getChild<LLUICtrl>("display_name_confirm")->setEnabled(true); + + } +} + +BOOL LLFloaterDisplayName::postBuild() +{ + getChild<LLUICtrl>("reset_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onReset, this)); + getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this)); + getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this)); + + center(); + + return TRUE; +} + +void LLFloaterDisplayName::onCacheSetName(bool success, + const std::string& reason, + const LLSD& content) +{ + if (success) + { + // Inform the user that the change took place, but will take a while + // to percolate. + 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; + } + + // Request failed, notify the user + std::string error_tag = content["error_tag"].asString(); + llinfos << "set name failure error_tag " << error_tag << llendl; + + // We might have a localized string for this message + // error_args will usually be empty from the server. + if (!error_tag.empty() + && LLNotifications::getInstance()->templateExists(error_tag)) + { + LLNotificationsUtil::add(error_tag); + return; + } + + // The server error might have a localized message for us + std::string lang_code = LLUI::getLanguage(); + LLSD error_desc = content["error_description"]; + if (error_desc.has( lang_code )) + { + LLSD args; + args["MESSAGE"] = error_desc[lang_code].asString(); + LLNotificationsUtil::add("GenericAlert", args); + return; + } + + // No specific error, throw a generic one + LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); +} + +void LLFloaterDisplayName::onCancel() +{ + setVisible(false); +} + +void LLFloaterDisplayName::onReset() +{ + if (LLAvatarNameCache::useDisplayNames()) + { + LLViewerDisplayName::set("", + boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3)); + } + else + { + LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); + } + + setVisible(false); +} + + +void LLFloaterDisplayName::onSave() +{ + std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString(); + std::string display_name_confirm = getChild<LLUICtrl>("display_name_confirm")->getValue().asString(); + + if (display_name_utf8.compare(display_name_confirm)) + { + LLNotificationsUtil::add("SetDisplayNameMismatch"); + return; + } + + const U32 DISPLAY_NAME_MAX_LENGTH = 31; // characters, not bytes + LLWString display_name_wstr = utf8string_to_wstring(display_name_utf8); + if (display_name_wstr.size() > DISPLAY_NAME_MAX_LENGTH) + { + LLSD args; + args["LENGTH"] = llformat("%d", DISPLAY_NAME_MAX_LENGTH); + LLNotificationsUtil::add("SetDisplayNameFailedLength", args); + return; + } + + if (LLAvatarNameCache::useDisplayNames()) + { + LLViewerDisplayName::set(display_name_utf8, + boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3)); + } + else + { + LLNotificationsUtil::add("SetDisplayNameFailedGeneric"); + } + + setVisible(false); +} + + +////////////////////////////////////////////////////////////////////////////// +// LLInspectObjectUtil +////////////////////////////////////////////////////////////////////////////// +void LLFloaterDisplayNameUtil::registerFloater() +{ + LLFloaterReg::add("display_name", "floater_display_name.xml", + &LLFloaterReg::build<LLFloaterDisplayName>); +} diff --git a/indra/newview/lleventinfo.h b/indra/newview/llfloaterdisplayname.h index 958a276fbf..a00bf56712 100644 --- a/indra/newview/lleventinfo.h +++ b/indra/newview/llfloaterdisplayname.h @@ -1,8 +1,7 @@ /** - * @file lleventinfo.h - * @brief LLEventInfo class definition + * @file llfloaterdisplayname.h * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * @@ -24,51 +23,16 @@ * $/LicenseInfo$ */ -#ifndef LL_LLEVENTINFO_H -#define LL_LLEVENTINFO_H +#ifndef LLFLOATERDISPLAYNAME_H +#define LLFLOATERDISPLAYNAME_H -#include <map> -#include "v3dmath.h" -#include "lluuid.h" - -class LLMessageSystem; - -class LLEventInfo +namespace LLFloaterDisplayNameUtil { -public: - LLEventInfo() : - mID(0), - mDuration(0), - mUnixTime(0), - mHasCover(FALSE), - mCover(0), - mEventFlags(0), - mSelected(FALSE) - {} - - void unpack(LLMessageSystem *msg); - - static void loadCategories(const LLSD& options); + // Register with LLFloaterReg + void registerFloater(); +} -public: - std::string mName; - U32 mID; - std::string mDesc; - std::string mCategoryStr; - U32 mDuration; - std::string mTimeStr; - LLUUID mRunByID; - std::string mSimName; - LLVector3d mPosGlobal; - time_t mUnixTime; // seconds from 1970 - BOOL mHasCover; - U32 mCover; - U32 mEventFlags; - BOOL mSelected; - typedef std::map<U32, std::string> cat_map; - static cat_map sCategories; -}; -#endif // LL_LLEVENTINFO_H +#endif diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp index ee2ba2ba54..0b5ac8e798 100644 --- a/indra/newview/llfloaterevent.cpp +++ b/indra/newview/llfloaterevent.cpp @@ -38,10 +38,11 @@ #include "llcachename.h" #include "llcommandhandler.h" // secondlife:///app/chat/ support #include "lleventflags.h" -#include "lleventnotifier.h" +#include "llmediactrl.h" #include "llexpandabletextbox.h" #include "llfloater.h" #include "llfloaterreg.h" +#include "llmediactrl.h" #include "llfloaterworldmap.h" #include "llinventorymodel.h" #include "llsecondlifeurls.h" @@ -57,35 +58,10 @@ #include "lltrans.h" -class LLEventHandler : public LLCommandHandler -{ -public: - // requires trusted browser to trigger - LLEventHandler() : LLCommandHandler("event", UNTRUSTED_THROTTLE) { } - bool handle(const LLSD& params, const LLSD& query_map, - LLMediaCtrl* web) - { - if (params.size() < 1) - { - return false; - } - - LLFloaterEvent* floater = LLFloaterReg::getTypedInstance<LLFloaterEvent>("event"); - if (floater) - { - floater->setEventID(params[0].asInteger()); - LLFloaterReg::showTypedInstance<LLFloaterEvent>("event"); - return true; - } - - return false; - } -}; -LLEventHandler gEventHandler; - LLFloaterEvent::LLFloaterEvent(const LLSD& key) : LLFloater(key), - + LLViewerMediaObserver(), + mBrowser(NULL), mEventID(0) { } @@ -98,253 +74,51 @@ LLFloaterEvent::~LLFloaterEvent() BOOL LLFloaterEvent::postBuild() { - mTBName = getChild<LLTextBox>("event_name"); - - mTBCategory = getChild<LLTextBox>("event_category"); - - mTBDate = getChild<LLTextBox>("event_date"); - - mTBDuration = getChild<LLTextBox>("event_duration"); - - mTBDesc = getChild<LLExpandableTextBox>("event_desc"); - - mTBRunBy = getChild<LLTextBox>("event_runby"); - mTBLocation = getChild<LLTextBox>("event_location"); - mTBCover = getChild<LLTextBox>("event_cover"); - - mTeleportBtn = getChild<LLButton>( "teleport_btn"); - mTeleportBtn->setClickedCallback(onClickTeleport, this); - - mMapBtn = getChild<LLButton>( "map_btn"); - mMapBtn->setClickedCallback(onClickMap, this); - - mNotifyBtn = getChild<LLButton>( "notify_btn"); - mNotifyBtn->setClickedCallback(onClickNotify, this); - - mCreateEventBtn = getChild<LLButton>( "create_event_btn"); - mCreateEventBtn->setClickedCallback(onClickCreateEvent, this); - - mGodDeleteEventBtn = getChild<LLButton>( "god_delete_event_btn"); - mGodDeleteEventBtn->setClickedCallback(boost::bind(&LLFloaterEvent::onClickDeleteEvent, this)); - - return TRUE; -} - -void LLFloaterEvent::setEventID(const U32 event_id) -{ - mEventID = event_id; - // Should reset all of the panel state here - resetInfo(); - - if (event_id != 0) + mBrowser = getChild<LLMediaCtrl>("browser"); + if (mBrowser) { - sendEventInfoRequest(); + mBrowser->addObserver(this); } -} - -void LLFloaterEvent::onClickDeleteEvent() -{ - LLMessageSystem* msg = gMessageSystem; - - msg->newMessageFast(_PREHASH_EventGodDelete); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - - msg->nextBlockFast(_PREHASH_EventData); - msg->addU32Fast(_PREHASH_EventID, mEventID); - gAgent.sendReliableMessage(); -} - -void LLFloaterEvent::sendEventInfoRequest() -{ - LLMessageSystem *msg = gMessageSystem; - - msg->newMessageFast(_PREHASH_EventInfoRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - msg->nextBlockFast(_PREHASH_EventData); - msg->addU32Fast(_PREHASH_EventID, mEventID); - gAgent.sendReliableMessage(); + return TRUE; } -//static -void LLFloaterEvent::processEventInfoReply(LLMessageSystem *msg, void **) +void LLFloaterEvent::handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event) { - // extract the agent id - LLUUID agent_id; - msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); - - LLFloaterEvent* floater = LLFloaterReg::getTypedInstance<LLFloaterEvent>("event"); - - if(floater) + switch (event) { - floater->mEventInfo.unpack(msg); - floater->mTBName->setText(floater->mEventInfo.mName); - floater->mTBCategory->setText(floater->mEventInfo.mCategoryStr); - floater->mTBDate->setText(floater->mEventInfo.mTimeStr); - floater->mTBDesc->setText(floater->mEventInfo.mDesc); - floater->mTBRunBy->setText(LLSLURL("agent", floater->mEventInfo.mRunByID, "inspect").getSLURLString()); - - floater->mTBDuration->setText(llformat("%d:%.2d", floater->mEventInfo.mDuration / 60, floater->mEventInfo.mDuration % 60)); - - if (!floater->mEventInfo.mHasCover) - { - floater->mTBCover->setText(floater->getString("none")); - } - else - { - floater->mTBCover->setText(llformat("%d", floater->mEventInfo.mCover)); - } - - F32 global_x = (F32)floater->mEventInfo.mPosGlobal.mdV[VX]; - F32 global_y = (F32)floater->mEventInfo.mPosGlobal.mdV[VY]; - - S32 region_x = llround(global_x) % REGION_WIDTH_UNITS; - S32 region_y = llround(global_y) % REGION_WIDTH_UNITS; - S32 region_z = llround((F32)floater->mEventInfo.mPosGlobal.mdV[VZ]); - - std::string desc = floater->mEventInfo.mSimName + llformat(" (%d, %d, %d)", region_x, region_y, region_z); - floater->mTBLocation->setText(desc); - - floater->getChildView("rating_icon_m")->setVisible( FALSE); - floater->getChildView("rating_icon_r")->setVisible( FALSE); - floater->getChildView("rating_icon_pg")->setVisible( FALSE); - floater->getChild<LLUICtrl>("rating_value")->setValue(floater->getString("unknown")); - - //for some reason there's not adult flags for now, so see if region is adult and then - //set flags - LLWorldMapMessage::url_callback_t cb = boost::bind( ®ionInfoCallback, floater->mEventInfo.mID, _1); - LLWorldMapMessage::getInstance()->sendNamedRegionRequest(floater->mEventInfo.mSimName, cb, std::string("unused"), false); - - if (floater->mEventInfo.mUnixTime < time_corrected()) - { - floater->mNotifyBtn->setEnabled(FALSE); - } - else - { - floater->mNotifyBtn->setEnabled(TRUE); - } - - if (gEventNotifier.hasNotification(floater->mEventInfo.mID)) - { - floater->mNotifyBtn->setLabel(floater->getString("dont_notify")); - } - else - { - floater->mNotifyBtn->setLabel(floater->getString("notify")); - } - - floater->mMapBtn->setEnabled(TRUE); - floater->mTeleportBtn->setEnabled(TRUE); + case MEDIA_EVENT_NAVIGATE_BEGIN: + getChild<LLUICtrl>("status_text")->setValue(getString("loading_text")); + break; + + case MEDIA_EVENT_NAVIGATE_COMPLETE: + getChild<LLUICtrl>("status_text")->setValue(getString("done_text")); + break; + + default: + break; } } -//static -void LLFloaterEvent::regionInfoCallback(U32 event_id, U64 region_handle) +void LLFloaterEvent::setEventID(const U32 event_id) { - LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromHandle(region_handle); - LLFloaterEvent* floater = LLFloaterReg::getTypedInstance<LLFloaterEvent>("event"); + mEventID = event_id; - if (sim_info && floater && (event_id == floater->getEventID())) + if (event_id != 0) { - // update the event with the maturity info - if (sim_info->isAdult()) - { - floater->getChildView("rating_icon_m")->setVisible( FALSE); - floater->getChildView("rating_icon_r")->setVisible( TRUE); - floater->getChildView("rating_icon_pg")->setVisible( FALSE); - floater->getChild<LLUICtrl>("rating_value")->setValue(floater->getString("adult")); - - } - else if (floater->mEventInfo.mEventFlags & EVENT_FLAG_MATURE) - { - floater->getChildView("rating_icon_m")->setVisible( TRUE); - floater->getChildView("rating_icon_r")->setVisible( FALSE); - floater->getChildView("rating_icon_pg")->setVisible( FALSE); - floater->getChild<LLUICtrl>("rating_value")->setValue(floater->getString("moderate")); - } - else - { - floater->getChildView("rating_icon_m")->setVisible( FALSE); - floater->getChildView("rating_icon_r")->setVisible( FALSE); - floater->getChildView("rating_icon_pg")->setVisible( TRUE); - floater->getChild<LLUICtrl>("rating_value")->setValue(floater->getString("general")); - } + LLSD subs; + subs["EVENT_ID"] = (S32)event_id; + // get the search URL and expand all of the substitutions + // (also adds things like [LANGUAGE], [VERSION], [OS], etc.) + std::ostringstream url; + url << gSavedSettings.getString("EventURL") << event_id << "/" << std::endl; + // and load the URL in the web view + mBrowser->navigateTo(url.str()); + } } void LLFloaterEvent::draw() { - mGodDeleteEventBtn->setVisible(gAgent.isGodlike()); - LLPanel::draw(); } - -void LLFloaterEvent::resetInfo() -{ - mTBName->setText(LLStringUtil::null); - mTBCategory->setText(LLStringUtil::null); - mTBDate->setText(LLStringUtil::null); - mTBDesc->setText(LLStringUtil::null); - mTBDuration->setText(LLStringUtil::null); - mTBCover->setText(LLStringUtil::null); - mTBLocation->setText(LLStringUtil::null); - mTBRunBy->setText(LLStringUtil::null); - mNotifyBtn->setEnabled(FALSE); - mMapBtn->setEnabled(FALSE); - mTeleportBtn->setEnabled(FALSE); -} - -// static -void LLFloaterEvent::onClickTeleport(void* data) -{ - LLFloaterEvent* self = (LLFloaterEvent*)data; - LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); - if (!self->mEventInfo.mPosGlobal.isExactlyZero()&&worldmap_instance) - { - gAgent.teleportViaLocation(self->mEventInfo.mPosGlobal); - worldmap_instance->trackLocation(self->mEventInfo.mPosGlobal); - } -} - - -// static -void LLFloaterEvent::onClickMap(void* data) -{ - LLFloaterEvent* self = (LLFloaterEvent*)data; - LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); - - if (!self->mEventInfo.mPosGlobal.isExactlyZero()&&worldmap_instance) - { - worldmap_instance->trackLocation(self->mEventInfo.mPosGlobal); - LLFloaterReg::showInstance("world_map", "center"); - } -} - - -// static -void LLFloaterEvent::onClickCreateEvent(void* data) -{ - LLNotificationsUtil::add("PromptGoToEventsPage");//, LLSD(), LLSD(), callbackCreateEventWebPage); -} - - -// static -void LLFloaterEvent::onClickNotify(void *data) -{ - LLFloaterEvent* self = (LLFloaterEvent*)data; - - if (!gEventNotifier.hasNotification(self->mEventID)) - { - gEventNotifier.add(self->mEventInfo); - self->mNotifyBtn->setLabel(self->getString("dont_notify")); - } - else - { - gEventNotifier.remove(self->mEventInfo.mID); - self->mNotifyBtn->setLabel(self->getString("notify")); - } -} diff --git a/indra/newview/llfloaterevent.h b/indra/newview/llfloaterevent.h index bfed2f259b..b1963309da 100644 --- a/indra/newview/llfloaterevent.h +++ b/indra/newview/llfloaterevent.h @@ -28,17 +28,15 @@ #define LL_LLFLOATEREVENT_H #include "llfloater.h" -#include "lleventinfo.h" -#include "lluuid.h" -#include "v3dmath.h" +#include "llviewermediaobserver.h" -class LLTextBox; -class LLTextEditor; + +class LLMediaCtrl; class LLButton; -class LLExpandableTextBox; -class LLMessageSystem; -class LLFloaterEvent : public LLFloater +class LLFloaterEvent : public LLFloater, + public LLViewerMediaObserver + { public: LLFloaterEvent(const LLSD& key); @@ -48,44 +46,18 @@ public: /*virtual*/ void draw(); void setEventID(const U32 event_id); - void sendEventInfoRequest(); - - static void processEventInfoReply(LLMessageSystem *msg, void **); U32 getEventID() { return mEventID; } -protected: - void resetInfo(); - - static void onClickTeleport(void*); - static void onClickMap(void*); - //static void onClickLandmark(void*); - static void onClickCreateEvent(void*); - static void onClickNotify(void*); - void onClickDeleteEvent(); - - static void regionInfoCallback(U32 event_id, U64 region_handle); protected: + /*virtual*/ void handleMediaEvent(LLPluginClassMedia *self, EMediaEvent event); + U32 mEventID; - LLEventInfo mEventInfo; - - LLTextBox* mTBName; - LLTextBox* mTBCategory; - LLTextBox* mTBDate; - LLTextBox* mTBDuration; - LLExpandableTextBox* mTBDesc; - LLTextBox* mTBRunBy; - LLTextBox* mTBLocation; - LLTextBox* mTBCover; + LLMediaCtrl* mBrowser; - LLButton* mTeleportBtn; - LLButton* mMapBtn; - LLButton* mCreateEventBtn; - LLButton* mGodDeleteEventBtn; - LLButton* mNotifyBtn; }; #endif // LL_LLFLOATEREVENT_H diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp index 2dbe324586..662e1c4f42 100644 --- a/indra/newview/llfloatergodtools.cpp +++ b/indra/newview/llfloatergodtools.cpp @@ -28,6 +28,7 @@ #include "llfloatergodtools.h" +#include "llavatarnamecache.h" #include "llcoord.h" #include "llfontgl.h" #include "llframetimer.h" @@ -1143,11 +1144,11 @@ void LLPanelObjectTools::onClickSetBySelection(void* data) panelp->getChild<LLUICtrl>("target_avatar_name")->setValue(name); } -void LLPanelObjectTools::callbackAvatarID(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLPanelObjectTools::callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { if (ids.empty() || names.empty()) return; mTargetAvatar = ids[0]; - getChild<LLUICtrl>("target_avatar_name")->setValue(names[0]); + getChild<LLUICtrl>("target_avatar_name")->setValue(names[0].getCompleteName()); refresh(); } diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h index 60fc95580f..1aa8b838fb 100644 --- a/indra/newview/llfloatergodtools.h +++ b/indra/newview/llfloatergodtools.h @@ -35,6 +35,7 @@ #include "llpanel.h" #include <vector> +class LLAvatarName; class LLButton; class LLCheckBoxCtrl; class LLComboBox; @@ -225,7 +226,7 @@ public: void onChangeAnything(); void onApplyChanges(); void onClickSet(); - void callbackAvatarID(const std::vector<std::string>& names, const uuid_vec_t& ids); + void callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); void onClickDeletePublicOwnedBy(); void onClickDeleteAllScriptedOwnedBy(); void onClickDeleteAllOwnedBy(); diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 7bf158488f..3cd3c74ee4 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -50,6 +50,7 @@ LLFloaterHardwareSettings::LLFloaterHardwareSettings(const LLSD& key) // but init them anyway mUseVBO(0), mUseAniso(0), + mUseFBO(0), mFSAASamples(0), mGamma(0.0), mVideoCardMem(0), @@ -74,6 +75,7 @@ void LLFloaterHardwareSettings::refresh() mUseVBO = gSavedSettings.getBOOL("RenderVBOEnable"); mUseAniso = gSavedSettings.getBOOL("RenderAnisotropic"); + mUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); mFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); mGamma = gSavedSettings.getF32("RenderGamma"); mVideoCardMem = gSavedSettings.getS32("TextureMemory"); @@ -159,6 +161,7 @@ void LLFloaterHardwareSettings::cancel() { gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO); gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso); + gSavedSettings.setBOOL("RenderUseFBO", mUseFBO); gSavedSettings.setU32("RenderFSAASamples", mFSAASamples); gSavedSettings.setF32("RenderGamma", mGamma); gSavedSettings.setS32("TextureMemory", mVideoCardMem); diff --git a/indra/newview/llfloaterhardwaresettings.h b/indra/newview/llfloaterhardwaresettings.h index f59b77b17f..626771b1d2 100644 --- a/indra/newview/llfloaterhardwaresettings.h +++ b/indra/newview/llfloaterhardwaresettings.h @@ -70,6 +70,7 @@ public: protected: BOOL mUseVBO; BOOL mUseAniso; + BOOL mUseFBO; U32 mFSAASamples; F32 mGamma; S32 mVideoCardMem; diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp index 691f1b206c..a09b9ea235 100644 --- a/indra/newview/llfloaterinspect.cpp +++ b/indra/newview/llfloaterinspect.cpp @@ -31,7 +31,7 @@ #include "llfloaterreg.h" #include "llfloatertools.h" #include "llavataractions.h" -#include "llcachename.h" +#include "llavatarnamecache.h" #include "llscrolllistctrl.h" #include "llscrolllistitem.h" #include "llselectmgr.h" @@ -205,8 +205,12 @@ void LLFloaterInspect::refresh() substitution["datetime"] = (S32) timestamp; LLStringUtil::format (timeStr, substitution); - gCacheName->getFullName(obj->mPermissions->getOwner(), owner_name); - gCacheName->getFullName(obj->mPermissions->getCreator(), creator_name); + 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(); + row["id"] = obj->getObject()->getID(); row["columns"][0]["column"] = "object_name"; row["columns"][0]["type"] = "text"; diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index e124263db5..a6025661b7 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -31,7 +31,7 @@ #include "llfloaterland.h" -#include "llcachename.h" +#include "llavatarnamecache.h" #include "llfocusmgr.h" #include "llnotificationsutil.h" #include "llparcel.h" @@ -1378,10 +1378,7 @@ bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, co } else { - std::string first, last; - gCacheName->getName(owner_id, first, last); - args["FIRST"] = first; - args["LAST"] = last; + args["NAME"] = LLSLURL("agent", owner_id, "completename").getSLURLString(); LLNotificationsUtil::add("OtherObjectsReturned", args); } send_return_objects_message(parcel->getLocalID(), RT_OWNER); @@ -1599,9 +1596,9 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo } // Placeholder for name. - std::string name; - gCacheName->getFullName(owner_id, name); - item_params.columns.add().value(name).font(FONT).column("name"); + LLAvatarName av_name; + LLAvatarNameCache::get(owner_id, &av_name); + item_params.columns.add().value(av_name.getCompleteName()).font(FONT).column("name"); object_count_str = llformat("%d", object_count); item_params.columns.add().value(object_count_str).font(FONT).column("count"); @@ -1710,9 +1707,7 @@ void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata) } else { - std::string name; - gCacheName->getFullName(owner_id, name); - args["NAME"] = name; + args["NAME"] = LLSLURL("agent", owner_id, "completename").getSLURLString(); LLNotificationsUtil::add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2)); } } @@ -1771,10 +1766,7 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata) } else { - std::string name; - gCacheName->getFullName(owner_id, name); - args["NAME"] = name; - + args["NAME"] = LLSLURL("agent", owner_id, "completename").getSLURLString(); LLNotificationsUtil::add("ReturnObjectsNotOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2)); } } @@ -2765,12 +2757,12 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata) void LLPanelLandAccess::onClickAddAccess() { - gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1,_2)) ); + gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1)) ); } -void LLPanelLandAccess::callbackAvatarCBAccess(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLPanelLandAccess::callbackAvatarCBAccess(const uuid_vec_t& ids) { - if (!names.empty() && !ids.empty()) + if (!ids.empty()) { LLUUID id = ids[0]; LLParcel* parcel = mParcel->getParcel(); @@ -2809,13 +2801,13 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data) // static void LLPanelLandAccess::onClickAddBanned() { - gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1,_2))); + gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1))); } // static -void LLPanelLandAccess::callbackAvatarCBBanned(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLPanelLandAccess::callbackAvatarCBBanned(const uuid_vec_t& ids) { - if (!names.empty() && !ids.empty()) + if (!ids.empty()) { LLUUID id = ids[0]; LLParcel* parcel = mParcel->getParcel(); diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 309e0ee4e1..a096fb64cd 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -372,8 +372,8 @@ public: void onClickAddAccess(); void onClickAddBanned(); - void callbackAvatarCBBanned(const std::vector<std::string>& names, const uuid_vec_t& ids); - void callbackAvatarCBAccess(const std::vector<std::string>& names, const uuid_vec_t& ids); + void callbackAvatarCBBanned(const uuid_vec_t& ids); + void callbackAvatarCBAccess(const uuid_vec_t& ids); protected: LLNameListCtrl* mListAccess; diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp index 151a76285b..b0009fd94f 100644 --- a/indra/newview/llfloaterpay.cpp +++ b/indra/newview/llfloaterpay.cpp @@ -41,6 +41,7 @@ #include "lllineeditor.h" #include "llmutelist.h" #include "llfloaterreporter.h" +#include "llslurl.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" #include "llviewerregion.h" @@ -96,10 +97,6 @@ private: static void onGive(void* data); void give(S32 amount); static void processPayPriceReply(LLMessageSystem* msg, void **userdata); - void onCacheOwnerName(const LLUUID& owner_id, - const std::string& firstname, - const std::string& lastname, - BOOL is_group); void finishPayUI(const LLUUID& target_id, BOOL is_group); protected: @@ -152,7 +149,7 @@ BOOL LLFloaterPay::postBuild() mCallbackData.push_back(info); childSetAction("fastpay 1",&LLFloaterPay::onGive,info); - getChildView("fastpay 1")->setVisible( FALSE); + getChildView("fastpay 1")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 1"); mQuickPayInfo[i] = info; @@ -162,7 +159,7 @@ BOOL LLFloaterPay::postBuild() mCallbackData.push_back(info); childSetAction("fastpay 5",&LLFloaterPay::onGive,info); - getChildView("fastpay 5")->setVisible( FALSE); + getChildView("fastpay 5")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 5"); mQuickPayInfo[i] = info; @@ -172,7 +169,7 @@ BOOL LLFloaterPay::postBuild() mCallbackData.push_back(info); childSetAction("fastpay 10",&LLFloaterPay::onGive,info); - getChildView("fastpay 10")->setVisible( FALSE); + getChildView("fastpay 10")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 10"); mQuickPayInfo[i] = info; @@ -182,14 +179,14 @@ BOOL LLFloaterPay::postBuild() mCallbackData.push_back(info); childSetAction("fastpay 20",&LLFloaterPay::onGive,info); - getChildView("fastpay 20")->setVisible( FALSE); + getChildView("fastpay 20")->setVisible(FALSE); mQuickPayButton[i] = getChild<LLButton>("fastpay 20"); mQuickPayInfo[i] = info; ++i; - getChildView("amount text")->setVisible( FALSE); + getChildView("amount text")->setVisible(FALSE); std::string last_amount; if(sLastAmount > 0) @@ -197,7 +194,7 @@ BOOL LLFloaterPay::postBuild() last_amount = llformat("%d", sLastAmount); } - getChildView("amount")->setVisible( FALSE); + getChildView("amount")->setVisible(FALSE); getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this); getChild<LLUICtrl>("amount")->setValue(last_amount); @@ -208,7 +205,7 @@ BOOL LLFloaterPay::postBuild() childSetAction("pay btn",&LLFloaterPay::onGive,info); setDefaultBtn("pay btn"); - getChildView("pay btn")->setVisible( FALSE); + getChildView("pay btn")->setVisible(FALSE); getChildView("pay btn")->setEnabled((sLastAmount > 0)); childSetAction("cancel btn",&LLFloaterPay::onCancel,this); @@ -243,25 +240,25 @@ void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata) if (PAY_PRICE_HIDE == price) { - self->getChildView("amount")->setVisible( FALSE); - self->getChildView("pay btn")->setVisible( FALSE); - self->getChildView("amount text")->setVisible( FALSE); + self->getChildView("amount")->setVisible(FALSE); + self->getChildView("pay btn")->setVisible(FALSE); + self->getChildView("amount text")->setVisible(FALSE); } else if (PAY_PRICE_DEFAULT == price) { - self->getChildView("amount")->setVisible( TRUE); - self->getChildView("pay btn")->setVisible( TRUE); - self->getChildView("amount text")->setVisible( TRUE); + self->getChildView("amount")->setVisible(TRUE); + self->getChildView("pay btn")->setVisible(TRUE); + self->getChildView("amount text")->setVisible(TRUE); } else { // PAY_PRICE_HIDE and PAY_PRICE_DEFAULT are negative values // So we take the absolute value here after we have checked for those cases - self->getChildView("amount")->setVisible( TRUE); - self->getChildView("pay btn")->setVisible( TRUE); + self->getChildView("amount")->setVisible(TRUE); + self->getChildView("pay btn")->setVisible(TRUE); self->getChildView("pay btn")->setEnabled(TRUE); - self->getChildView("amount text")->setVisible( TRUE); + self->getChildView("amount text")->setVisible(TRUE); self->getChild<LLUICtrl>("amount")->setValue(llformat("%d", llabs(price))); } @@ -409,9 +406,9 @@ void LLFloaterPay::payDirectly(money_callback callback, floater->setCallback(callback); floater->mObjectSelection = NULL; - floater->getChildView("amount")->setVisible( TRUE); - floater->getChildView("pay btn")->setVisible( TRUE); - floater->getChildView("amount text")->setVisible( TRUE); + floater->getChildView("amount")->setVisible(TRUE); + floater->getChildView("pay btn")->setVisible(TRUE); + floater->getChildView("amount text")->setVisible(TRUE); floater->getChildView("fastpay text")->setVisible(TRUE); for(S32 i=0;i<MAX_PAY_BUTTONS;++i) @@ -424,33 +421,26 @@ void LLFloaterPay::payDirectly(money_callback callback, void LLFloaterPay::finishPayUI(const LLUUID& target_id, BOOL is_group) { - gCacheName->get(target_id, is_group, boost::bind(&LLFloaterPay::onCacheOwnerName, this, _1, _2, _3, _4)); - - // Make sure the amount field has focus - - getChild<LLUICtrl>("amount")->setFocus( TRUE); - - LLLineEditor* amount = getChild<LLLineEditor>("amount"); - amount->selectAll(); - mTargetIsGroup = is_group; -} - -void LLFloaterPay::onCacheOwnerName(const LLUUID& owner_id, - const std::string& firstname, - const std::string& lastname, - BOOL is_group) -{ + std::string slurl; if (is_group) { setTitle(getString("payee_group")); + slurl = LLSLURL("group", target_id, "inspect").getSLURLString(); } else { setTitle(getString("payee_resident")); + slurl = LLSLURL("agent", target_id, "inspect").getSLURLString(); } + getChild<LLTextBox>("payee_name")->setText(slurl); - getChild<LLUICtrl>("payee_name")->setTextArg("[FIRST]", firstname); - getChild<LLUICtrl>("payee_name")->setTextArg("[LAST]", lastname); + // Make sure the amount field has focus + + LLLineEditor* amount = getChild<LLLineEditor>("amount"); + amount->setFocus(TRUE); + amount->selectAll(); + + mTargetIsGroup = is_group; } // static diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 41f85ae29d..2bea3d37ff 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -77,6 +77,7 @@ #include "llvosky.h" // linden library includes +#include "llavatarnamecache.h" #include "llerror.h" #include "llfontgl.h" #include "llrect.h" @@ -179,6 +180,8 @@ void LLVoiceSetKeyDialog::onCancel(void* user_data) // if creating/destroying these is too slow, we'll need to create // a static member and update all our static callbacks +void handleNameTagOptionChanged(const LLSD& newvalue); +void handleDisplayNamesOptionChanged(const LLSD& newvalue); bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response); //bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater); @@ -214,6 +217,18 @@ bool callback_clear_browser_cache(const LLSD& notification, const LLSD& response return false; } +void handleNameTagOptionChanged(const LLSD& newvalue) +{ + LLVOAvatar::invalidateNameTags(); +} + +void handleDisplayNamesOptionChanged(const LLSD& newvalue) +{ + LLAvatarNameCache::setUseDisplayNames(newvalue.asBoolean()); + LLVOAvatar::invalidateNameTags(); +} + + /*bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -307,6 +322,10 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.BlockList", boost::bind(&LLFloaterPreference::onClickBlockList, this)); sSkin = gSavedSettings.getString("SkinCurrent"); + + 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)); } BOOL LLFloaterPreference::postBuild() diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index ed81fdec16..7792b3fb40 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -43,6 +43,7 @@ #include "llagent.h" #include "llappviewer.h" +#include "llavatarname.h" #include "llfloateravatarpicker.h" #include "llbutton.h" #include "llcheckboxctrl.h" @@ -599,13 +600,13 @@ void LLPanelRegionGeneralInfo::onClickKick() // this depends on the grandparent view being a floater // in order to set up floater dependency LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1,_2), FALSE, TRUE); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE); parent_floater->addDependentFloater(child_floater); } -void LLPanelRegionGeneralInfo::onKickCommit(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLPanelRegionGeneralInfo::onKickCommit(const uuid_vec_t& ids) { - if (names.empty() || ids.empty()) return; + if (ids.empty()) return; if(ids[0].notNull()) { strings_t strings; @@ -841,11 +842,11 @@ void LLPanelRegionDebugInfo::onClickChooseAvatar() } -void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLPanelRegionDebugInfo::callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { if (ids.empty() || names.empty()) return; mTargetAvatar = ids[0]; - getChild<LLUICtrl>("target_avatar_name")->setValue(LLSD(names[0])); + getChild<LLUICtrl>("target_avatar_name")->setValue(LLSD(names[0].getCompleteName())); refreshFromRegion( gAgent.getRegion() ); } @@ -1512,24 +1513,17 @@ void LLPanelEstateInfo::onClickKickUser() // this depends on the grandparent view being a floater // in order to set up floater dependency LLFloater* parent_floater = gFloaterView->getParentFloater(this); - LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1, _2), FALSE, TRUE); + LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE); parent_floater->addDependentFloater(child_floater); } -void LLPanelEstateInfo::onKickUserCommit(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLPanelEstateInfo::onKickUserCommit(const uuid_vec_t& ids) { - if (names.empty() || ids.empty()) return; + if (ids.empty()) return; - //check to make sure there is one valid user and id - if( (ids[0].isNull()) || - (names[0].length() == 0) ) - { - return; - } - //Bring up a confirmation dialog LLSD args; - args["EVIL_USER"] = names[0]; + args["EVIL_USER"] = LLSLURL("agent", ids[0], "completename").getSLURLString(); LLSD payload; payload["agent_id"] = ids[0]; LLNotificationsUtil::add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, this, _1, _2)); @@ -1695,12 +1689,12 @@ bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& res LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]); // avatar picker yes multi-select, yes close-on-select - LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, _2, (void*)change_info), TRUE, TRUE); + LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), TRUE, TRUE); return false; } // static -void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, const uuid_vec_t& ids, void* data) +void LLPanelEstateInfo::accessAddCore3(const uuid_vec_t& ids, void* data) { LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data; if (!change_info) return; @@ -1956,8 +1950,15 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) getChildView("remove_allowed_avatar_btn")->setEnabled(god || owner || manager); getChildView("add_allowed_group_btn")->setEnabled(god || owner || manager); getChildView("remove_allowed_group_btn")->setEnabled(god || owner || manager); - getChildView("add_banned_avatar_btn")->setEnabled(god || owner || manager); - getChildView("remove_banned_avatar_btn")->setEnabled(god || owner || manager); + + // Can't ban people from mainland, orientation islands, etc. because this + // creates much network traffic and server load. + // Disable their accounts in CSR tool instead. + bool linden_estate = (getEstateID() <= ESTATE_LAST_LINDEN); + 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("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index 2393c74c45..c0758fa92d 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -34,6 +34,7 @@ #include "llhost.h" #include "llpanel.h" +class LLAvatarName; class LLDispatcher; class LLLineEditor; class LLMessageSystem; @@ -162,7 +163,7 @@ public: protected: virtual BOOL sendUpdate(); void onClickKick(); - void onKickCommit(const std::vector<std::string>& names, const uuid_vec_t& ids); + void onKickCommit(const uuid_vec_t& ids); static void onClickKickAll(void* userdata); bool onKickAllCommit(const LLSD& notification, const LLSD& response); static void onClickMessage(void* userdata); @@ -187,7 +188,7 @@ protected: virtual BOOL sendUpdate(); void onClickChooseAvatar(); - void callbackAvatarID(const std::vector<std::string>& names, const uuid_vec_t& ids); + void callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); static void onClickReturn(void *); bool callbackReturn(const LLSD& notification, const LLSD& response); static void onClickTopColliders(void*); @@ -278,7 +279,7 @@ public: // Core methods for all above add/remove button clicks static void accessAddCore(U32 operation_flag, const std::string& dialog_name); static bool accessAddCore2(const LLSD& notification, const LLSD& response); - static void accessAddCore3(const std::vector<std::string>& names, const uuid_vec_t& ids, void* data); + static void accessAddCore3(const uuid_vec_t& ids, void* data); static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name); static bool accessRemoveCore2(const LLSD& notification, const LLSD& response); @@ -290,7 +291,7 @@ public: // Send the actual EstateOwnerRequest "estateaccessdelta" message static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id); - void onKickUserCommit(const std::vector<std::string>& names, const uuid_vec_t& ids); + void onKickUserCommit(const uuid_vec_t& ids); static void onClickMessageEstate(void* data); bool onMessageCommit(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 66d7e804ea..c08848b1ea 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -33,6 +33,8 @@ // linden library includes #include "llassetstorage.h" +#include "llavatarnamecache.h" +#include "llcachename.h" #include "llfontgl.h" #include "llimagej2c.h" #include "llinventory.h" @@ -175,9 +177,8 @@ BOOL LLFloaterReporter::postBuild() childSetAction("cancel_btn", onClickCancel, this); // grab the user's name - std::string fullname; - LLAgentUI::buildFullname(fullname); - getChild<LLUICtrl>("reporter_field")->setValue(fullname); + std::string reporter = LLSLURL("agent", gAgent.getID(), "inspect").getSLURLString(); + getChild<LLUICtrl>("reporter_field")->setValue(reporter); center(); @@ -260,22 +261,7 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id) if (objectp->isAvatar()) { - // we have the information we need - std::string object_owner; - - LLNameValue* firstname = objectp->getNVPair("FirstName"); - LLNameValue* lastname = objectp->getNVPair("LastName"); - if (firstname && lastname) - { - object_owner.append(firstname->getString()); - object_owner.append(1, ' '); - object_owner.append(lastname->getString()); - } - else - { - object_owner.append("Unknown"); - } - setFromAvatar(mObjectID, object_owner); + setFromAvatarID(mObjectID); } else { @@ -302,11 +288,11 @@ void LLFloaterReporter::onClickSelectAbuser() gFloaterView->getParentFloater(this)->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE )); } -void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLFloaterReporter::callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { if (ids.empty() || names.empty()) return; - getChild<LLUICtrl>("abuser_name_edit")->setValue(names[0] ); + getChild<LLUICtrl>("abuser_name_edit")->setValue(names[0].getCompleteName()); mAbuserID = ids[0]; @@ -314,18 +300,27 @@ void LLFloaterReporter::callbackAvatarID(const std::vector<std::string>& names, } -void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name) +void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id) { mAbuserID = mObjectID = avatar_id; - mOwnerName = avatar_name; - - std::string avatar_link = - LLSLURL("agent", mObjectID, "inspect").getSLURLString(); + std::string avatar_link = LLSLURL("agent", mObjectID, "inspect").getSLURLString(); getChild<LLUICtrl>("owner_name")->setValue(avatar_link); - getChild<LLUICtrl>("object_name")->setValue(avatar_name); - getChild<LLUICtrl>("abuser_name_edit")->setValue(avatar_name); + + LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2)); } +void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name) +{ + if (mObjectID == avatar_id) + { + mOwnerName = av_name.getCompleteName(); + getChild<LLUICtrl>("object_name")->setValue(av_name.getCompleteName()); + getChild<LLUICtrl>("object_name")->setToolTip(av_name.getCompleteName()); + getChild<LLUICtrl>("abuser_name_edit")->setValue(av_name.getCompleteName()); + } +} + + // static void LLFloaterReporter::onClickSend(void *userdata) { @@ -465,16 +460,15 @@ void LLFloaterReporter::show(const LLUUID& object_id, const std::string& avatar_ { LLFloaterReporter* f = LLFloaterReg::showTypedInstance<LLFloaterReporter>("reporter"); - // grab the user's name - std::string fullname; - LLAgentUI::buildFullname(fullname); - f->getChild<LLUICtrl>("reporter_field")->setValue(fullname); - if (avatar_name.empty()) + { // Request info for this object f->getObjectInfo(object_id); + } else - f->setFromAvatar(object_id, avatar_name); + { + f->setFromAvatarID(object_id); + } // Need to deselect on close f->mDeselectOnClose = TRUE; diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h index 92e842d318..cd98f7be57 100644 --- a/indra/newview/llfloaterreporter.h +++ b/indra/newview/llfloaterreporter.h @@ -32,6 +32,7 @@ #include "lluuid.h" #include "v3math.h" +class LLAvatarName; class LLMessageSystem; class LLViewerTexture; class LLInventoryItem; @@ -117,8 +118,9 @@ private: void setPosBox(const LLVector3d &pos); void enableControls(BOOL own_avatar); void getObjectInfo(const LLUUID& object_id); - void callbackAvatarID(const std::vector<std::string>& names, const uuid_vec_t& ids); - void setFromAvatar(const LLUUID& avatar_id, const std::string& avatar_name = LLStringUtil::null); + void callbackAvatarID(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); + void setFromAvatarID(const LLUUID& avatar_id); + void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name); private: EReportType mReportType; diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index cd792c263c..a50907601c 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -28,6 +28,8 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterscriptlimits.h" +// library includes +#include "llavatarnamecache.h" #include "llsdutil.h" #include "llsdutil_math.h" #include "message.h" @@ -289,7 +291,7 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) LLTabContainer* tab = instance->getChild<LLTabContainer>("scriptlimits_panels"); if(tab) { - LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); + LLPanelScriptLimitsRegionMemory* panel_memory = (LLPanelScriptLimitsRegionMemory*)tab->getChild<LLPanel>("script_limits_region_memory_panel"); if(panel_memory) { panel_memory->getChild<LLUICtrl>("loading_text")->setValue(LLSD(std::string(""))); @@ -300,9 +302,9 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref) btn->setEnabled(true); } - panel_memory->setRegionSummary(content); - } - } + panel_memory->setRegionSummary(content); + } +} } } @@ -592,17 +594,24 @@ void LLPanelScriptLimitsRegionMemory::setErrorStatus(U32 status, const std::stri // callback from the name cache with an owner name to add to the list void LLPanelScriptLimitsRegionMemory::onNameCache( const LLUUID& id, - const std::string& first_name, - const std::string& last_name) + const std::string& full_name) { - std::string name = first_name + " " + last_name; - LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list"); if(!list) { return; } + std::string name; + if (LLAvatarNameCache::useDisplayNames()) + { + name = LLCacheName::buildUsername(full_name); + } + else + { + name = full_name; + } + std::vector<LLSD>::iterator id_itor; for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor) { @@ -668,6 +677,9 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) std::string name_buf = content["parcels"][i]["objects"][j]["name"].asString(); LLUUID task_id = content["parcels"][i]["objects"][j]["id"].asUUID(); LLUUID owner_id = content["parcels"][i]["objects"][j]["owner_id"].asUUID(); + // This field may not be sent by all server versions, but it's OK if + // it uses the LLSD default of false + bool is_group_owned = content["parcels"][i]["objects"][j]["is_group_owned"].asBoolean(); F32 location_x = 0.0f; F32 location_y = 0.0f; @@ -693,15 +705,27 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) // ...and if not use the slightly more painful method of disovery: else { - BOOL name_is_cached = gCacheName->getFullName(owner_id, owner_buf); + BOOL name_is_cached; + if (is_group_owned) + { + name_is_cached = gCacheName->getGroupName(owner_id, owner_buf); + } + else + { + name_is_cached = gCacheName->getFullName(owner_id, owner_buf); // username + if (LLAvatarNameCache::useDisplayNames()) + { + owner_buf = LLCacheName::buildUsername(owner_buf); + } + } if(!name_is_cached) { if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end()) { names_requested.push_back(owner_id); - gCacheName->get(owner_id, TRUE, - boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, - this, _1, _2, _3)); + gCacheName->get(owner_id, is_group_owned, // username + boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache, + this, _1, _2)); } } } @@ -1309,7 +1333,7 @@ void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content) // static void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata) -{ +{ LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance<LLFloaterScriptLimits>("script_limits"); if(instance) { diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index 46e2e6f0e2..9bcfa5fe14 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -164,10 +164,8 @@ public: void returnObjects(); private: - void onNameCache(const LLUUID& id, - const std::string& first_name, - const std::string& last_name); + const std::string& name); LLSD mContent; LLUUID mParcelId; diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 3d87904dbe..8558a1277c 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -27,6 +27,7 @@ #include "llfloatersellland.h" +#include "llavatarnamecache.h" #include "llfloateravatarpicker.h" #include "llfloaterreg.h" #include "llfloaterland.h" @@ -41,6 +42,8 @@ #include "lluictrlfactory.h" #include "llviewerwindow.h" +class LLAvatarName; + // defined in llfloaterland.cpp void send_parcel_select_objects(S32 parcel_local_id, U32 return_type, uuid_list_t* return_ids = NULL); @@ -89,7 +92,9 @@ private: bool onConfirmSale(const LLSD& notification, const LLSD& response); static void doShowObjects(void *userdata); - void callbackAvatarPick(const std::vector<std::string>& names, const uuid_vec_t& ids); + void callbackAvatarPick(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); + + void onBuyerNameCache(const LLAvatarName& av_name); public: virtual BOOL postBuild(); @@ -224,12 +229,17 @@ void LLFloaterSellLandUI::updateParcelInfo() if(mSellToBuyer) { - std::string name; - gCacheName->getFullName(mAuthorizedBuyer, name); - getChild<LLUICtrl>("sell_to_agent")->setValue(name); + LLAvatarNameCache::get(mAuthorizedBuyer, + boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2)); } } +void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name) +{ + getChild<LLUICtrl>("sell_to_agent")->setValue(av_name.getCompleteName()); + getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.mUsername); +} + void LLFloaterSellLandUI::setBadge(const char* id, Badge badge) { static std::string badgeOK("badge_ok.j2c"); @@ -385,7 +395,7 @@ void LLFloaterSellLandUI::doSelectAgent() addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE)); } -void LLFloaterSellLandUI::callbackAvatarPick(const std::vector<std::string>& names, const uuid_vec_t& ids) +void LLFloaterSellLandUI::callbackAvatarPick(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { LLParcel* parcel = mParcelSelection->getParcel(); @@ -396,7 +406,7 @@ void LLFloaterSellLandUI::callbackAvatarPick(const std::vector<std::string>& nam mAuthorizedBuyer = ids[0]; - getChild<LLUICtrl>("sell_to_agent")->setValue(names[0]); + getChild<LLUICtrl>("sell_to_agent")->setValue(names[0].getCompleteName()); refreshUI(); } diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index 099b657c7c..2aaf403d5f 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -28,7 +28,9 @@ #include "llfloatertopobjects.h" +// library includes #include "message.h" +#include "llavatarnamecache.h" #include "llfontgl.h" #include "llagent.h" @@ -189,37 +191,53 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) LLSD element; element["id"] = task_id; - element["object_name"] = name_buf; - element["owner_name"] = owner_buf; - element["columns"][0]["column"] = "score"; - element["columns"][0]["value"] = llformat("%0.3f", score); - element["columns"][0]["font"] = "SANSSERIF"; + + LLSD columns; + columns[0]["column"] = "score"; + columns[0]["value"] = llformat("%0.3f", score); + columns[0]["font"] = "SANSSERIF"; + + columns[1]["column"] = "name"; + columns[1]["value"] = name_buf; + columns[1]["font"] = "SANSSERIF"; + + // Owner names can have trailing spaces sent from server + LLStringUtil::trim(owner_buf); - element["columns"][1]["column"] = "name"; - element["columns"][1]["value"] = name_buf; - element["columns"][1]["font"] = "SANSSERIF"; - element["columns"][2]["column"] = "owner"; - element["columns"][2]["value"] = owner_buf; - element["columns"][2]["font"] = "SANSSERIF"; - element["columns"][3]["column"] = "location"; - element["columns"][3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z); - element["columns"][3]["font"] = "SANSSERIF"; - element["columns"][4]["column"] = "time"; - element["columns"][4]["value"] = formatted_time((time_t)time_stamp); - element["columns"][4]["font"] = "SANSSERIF"; + 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]["value"] = formatted_time((time_t)time_stamp); + columns[4]["font"] = "SANSSERIF"; if (mCurrentMode == STAT_REPORT_TOP_SCRIPTS && have_extended_data) { - element["columns"][5]["column"] = "mono_time"; - element["columns"][5]["value"] = llformat("%0.3f", mono_score); - element["columns"][5]["font"] = "SANSSERIF"; + columns[5]["column"] = "mono_time"; + columns[5]["value"] = llformat("%0.3f", mono_score); + columns[5]["font"] = "SANSSERIF"; - element["columns"][6]["column"] = "URLs"; - element["columns"][6]["value"] = llformat("%d", public_urls); - element["columns"][6]["font"] = "SANSSERIF"; + columns[6]["column"] = "URLs"; + columns[6]["value"] = llformat("%d", public_urls); + columns[6]["font"] = "SANSSERIF"; } - + element["columns"] = columns; list->addElement(element); mObjectListData.append(element); diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 6327039b7f..1628a421ec 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -39,7 +39,6 @@ #include "lltracker.h" #include "llslurl.h" -class LLEventInfo; class LLFriendObserver; class LLInventoryModel; class LLInventoryObserver; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index 387e300b74..c38cd4d090 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -224,7 +224,7 @@ LLFolderView::LLFolderView(const Params& p) params.name("ren"); params.rect(rect); params.font(getLabelFontForStyle(LLFontGL::NORMAL)); - params.max_length_bytes(DB_INV_ITEM_NAME_STR_LEN); + 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); diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h index 66ab4ce5eb..afaac86b04 100644 --- a/indra/newview/llfolderview.h +++ b/indra/newview/llfolderview.h @@ -114,7 +114,7 @@ public: const std::string getFilterSubString(BOOL trim = FALSE); U32 getFilterObjectTypes() const; PermissionMask getFilterPermissions() const; - // JAMESDEBUG use getFilter()->getShowFolderState(); + // *NOTE: use getFilter()->getShowFolderState(); //LLInventoryFilter::EFolderShow getShowFolderState(); U32 getSortOrder() const; BOOL isFilterModified(); diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h index ade30d9266..3bfbf36110 100644 --- a/indra/newview/llfoldervieweventlistener.h +++ b/indra/newview/llfoldervieweventlistener.h @@ -25,7 +25,7 @@ #ifndef LLFOLDERVIEWEVENTLISTENER_H #define LLFOLDERVIEWEVENTLISTENER_H -#include "lldarray.h" // JAMESDEBUG convert to std::vector +#include "lldarray.h" // *TODO: convert to std::vector #include "llfoldertype.h" #include "llfontgl.h" // just for StyleFlags enum #include "llinventorytype.h" diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index ab9317afd9..2006e094a8 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -51,7 +51,7 @@ enum EInventorySortGroup SG_ITEM }; -// JAMESDEBUG *TODO: do we really need one sort object per folder? +// *TODO: do we really need one sort object per folder? // can we just have one of these per LLFolderView ? class LLInventorySort { diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp index 2f856abe8f..e9f1e3bc22 100644 --- a/indra/newview/llfriendcard.cpp +++ b/indra/newview/llfriendcard.cpp @@ -26,13 +26,14 @@ #include "llviewerprecompiledheaders.h" +#include "llfriendcard.h" + +#include "llavatarnamecache.h" #include "llinventory.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" #include "lltrans.h" -#include "llfriendcard.h" - #include "llcallingcard.h" // for LLAvatarTracker #include "llviewerinventory.h" #include "llinventorymodel.h" @@ -541,8 +542,9 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID) { bool shouldBeAdded = true; - std::string name; - gCacheName->getFullName(avatarID, name); + LLAvatarName av_name; + LLAvatarNameCache::get(avatarID, &av_name); + const std::string& name = av_name.mUsername; lldebugs << "Processing buddy name: " << name << ", id: " << avatarID diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 83846f5b61..d43b3a5d6e 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -48,6 +48,7 @@ #include "lltoolmgr.h" #include "llselectmgr.h" #include "llhudmanager.h" +#include "llhudtext.h" #include "llrendersphere.h" #include "llviewerobjectlist.h" #include "lltoolselectrect.h" @@ -888,7 +889,7 @@ void LLViewerObjectList::renderObjectBeacons() color = debug_beacon.mTextColor; color.mV[3] *= 1.f; - hud_textp->setString(utf8str_to_wstring(debug_beacon.mString)); + hud_textp->setString(debug_beacon.mString); hud_textp->setColor(color); hud_textp->setPositionAgent(debug_beacon.mPositionAgent); debug_beacon.mHUDObject = hud_textp; diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp index d837ed8205..7f6df627e0 100644 --- a/indra/newview/llhints.cpp +++ b/indra/newview/llhints.cpp @@ -211,9 +211,16 @@ void LLHintPopup::draw() else if (!targetp->isInVisibleChain()) { // if target is invisible, don't draw, but keep alive in case widget comes back + // but do make it so that it allows mouse events to pass through + setEnabled(false); + setMouseOpaque(false); } else { + // revert back enabled and mouse opaque state in case we disabled it before + setEnabled(true); + setMouseOpaque(true); + LLRect target_rect; targetp->localRectToOtherView(targetp->getLocalRect(), &target_rect, getParent()); diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h index 7712ebac1a..8d7b8d4288 100644 --- a/indra/newview/llhudicon.h +++ b/indra/newview/llhudicon.h @@ -44,6 +44,7 @@ // Renders a 2D icon billboard floating at the location specified. class LLDrawable; class LLViewerObject; +class LLViewerTexture; class LLHUDIcon : public LLHUDObject { diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp new file mode 100644 index 0000000000..fc758569e4 --- /dev/null +++ b/indra/newview/llhudnametag.cpp @@ -0,0 +1,1066 @@ +/** + * @file llhudnametag.cpp + * @brief Name tags for avatars + * @author James Cook + * + * $LicenseInfo:firstyear=2010&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 "llhudnametag.h" + +#include "llrender.h" + +#include "llagent.h" +#include "llviewercontrol.h" +#include "llcriticaldamp.h" +#include "lldrawable.h" +#include "llfontgl.h" +#include "llglheaders.h" +#include "llhudrender.h" +#include "llui.h" +#include "llviewercamera.h" +#include "llviewertexturelist.h" +#include "llviewerobject.h" +#include "llvovolume.h" +#include "llviewerwindow.h" +#include "llstatusbar.h" +#include "llmenugl.h" +#include "pipeline.h" +#include <boost/tokenizer.hpp> + + +const F32 SPRING_STRENGTH = 0.7f; +const F32 RESTORATION_SPRING_TIME_CONSTANT = 0.1f; +const F32 HORIZONTAL_PADDING = 16.f; +const F32 VERTICAL_PADDING = 12.f; +const F32 LINE_PADDING = 3.f; // aka "leading" +const F32 BUFFER_SIZE = 2.f; +const F32 MIN_EDGE_OVERLAP = 3.f; +const F32 HUD_TEXT_MAX_WIDTH = 190.f; +const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f; +const F32 RESIZE_TIME = 0.f; +const S32 NUM_OVERLAP_ITERATIONS = 10; +const F32 NEIGHBOR_FORCE_FRACTION = 1.f; +const F32 POSITION_DAMPING_TC = 0.2f; +const F32 MAX_STABLE_CAMERA_VELOCITY = 0.1f; +const F32 LOD_0_SCREEN_COVERAGE = 0.15f; +const F32 LOD_1_SCREEN_COVERAGE = 0.30f; +const F32 LOD_2_SCREEN_COVERAGE = 0.40f; + +std::set<LLPointer<LLHUDNameTag> > LLHUDNameTag::sTextObjects; +std::vector<LLPointer<LLHUDNameTag> > LLHUDNameTag::sVisibleTextObjects; +BOOL LLHUDNameTag::sDisplayText = TRUE ; + +bool llhudnametag_further_away::operator()(const LLPointer<LLHUDNameTag>& lhs, const LLPointer<LLHUDNameTag>& rhs) const +{ + return lhs->getDistance() > rhs->getDistance(); +} + + +LLHUDNameTag::LLHUDNameTag(const U8 type) +: LLHUDObject(type), + mDoFade(TRUE), + mFadeDistance(8.f), + mFadeRange(4.f), + mLastDistance(0.f), + mZCompare(TRUE), + mVisibleOffScreen(FALSE), + mOffscreen(FALSE), + mColor(1.f, 1.f, 1.f, 1.f), +// mScale(), + mWidth(0.f), + mHeight(0.f), + mFontp(LLFontGL::getFontSansSerifSmall()), + mBoldFontp(LLFontGL::getFontSansSerifBold()), + mSoftScreenRect(), + mPositionAgent(), + mPositionOffset(), + mMass(10.f), + mMaxLines(10), + mOffsetY(0), + mRadius(0.1f), + mTextSegments(), + mLabelSegments(), + mTextAlignment(ALIGN_TEXT_CENTER), + mVertAlignment(ALIGN_VERT_CENTER), + mLOD(0), + mHidden(FALSE) +{ + LLPointer<LLHUDNameTag> ptr(this); + sTextObjects.insert(ptr); +} + +LLHUDNameTag::~LLHUDNameTag() +{ +} + + +BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) +{ + if (!mVisible || mHidden) + { + return FALSE; + } + + // don't pick text that isn't bound to a viewerobject + if (!mSourceObject || mSourceObject->mDrawable.isNull()) + { + return FALSE; + } + + F32 alpha_factor = 1.f; + LLColor4 text_color = mColor; + if (mDoFade) + { + if (mLastDistance > mFadeDistance) + { + alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange); + text_color.mV[3] = text_color.mV[3]*alpha_factor; + } + } + if (text_color.mV[3] < 0.01f) + { + return FALSE; + } + + mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); + + // scale screen size of borders down + //RN: for now, text on hud objects is never occluded + + LLVector3 x_pixel_vec; + LLVector3 y_pixel_vec; + + LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + + LLVector3 width_vec = mWidth * x_pixel_vec; + LLVector3 height_vec = mHeight * y_pixel_vec; + + LLCoordGL screen_pos; + LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); + + LLVector2 screen_offset; + screen_offset = updateScreenPos(mPositionOffset); + + LLVector3 render_position = mPositionAgent + + (x_pixel_vec * screen_offset.mV[VX]) + + (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); + //LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); + + LLVector3 v[] = + { + bg_pos, + bg_pos + width_vec, + bg_pos + width_vec + height_vec, + bg_pos + height_vec, + }; + + if (debug_render) + { + 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 t = 0.f; + + if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) || + LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) ) + { + if (t <= 1.f) + { + intersection = start + dir*t; + return TRUE; + } + } + } + + return FALSE; +} + +void LLHUDNameTag::render() +{ + if (sDisplayText) + { + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + renderText(FALSE); + } +} + +void LLHUDNameTag::renderForSelect() +{ + LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); + renderText(TRUE); +} + +void LLHUDNameTag::renderText(BOOL for_select) +{ + if (!mVisible || mHidden) + { + return; + } + + // don't pick text that isn't bound to a viewerobject + if (for_select && + (!mSourceObject || mSourceObject->mDrawable.isNull())) + { + return; + } + + if (for_select) + { + gGL.getTexUnit(0)->disable(); + } + else + { + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + } + + LLGLState gls_blend(GL_BLEND, for_select ? FALSE : TRUE); + LLGLState gls_alpha(GL_ALPHA_TEST, for_select ? FALSE : TRUE); + + LLColor4 shadow_color(0.f, 0.f, 0.f, 1.f); + F32 alpha_factor = 1.f; + LLColor4 text_color = mColor; + if (mDoFade) + { + if (mLastDistance > mFadeDistance) + { + alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange); + text_color.mV[3] = text_color.mV[3]*alpha_factor; + } + } + if (text_color.mV[3] < 0.01f) + { + return; + } + shadow_color.mV[3] = text_color.mV[3]; + + mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); + + // *TODO: cache this image + LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Rect"); + + // *TODO: make this a per-text setting + 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 + + LLVector3 x_pixel_vec; + LLVector3 y_pixel_vec; + + 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); +// } + + 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); + 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); + + // 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(); + } + + F32 y_offset = (F32)mOffsetY; + + // Render label + { + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + + for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin(); + segment_iter != mLabelSegments.end(); ++segment_iter ) + { + // Label segments use default font + const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp; + y_offset -= fontp->getLineHeight(); + + F32 x_offset; + if (mTextAlignment == ALIGN_TEXT_CENTER) + { + x_offset = -0.5f*segment_iter->getWidth(fontp); + } + else // ALIGN_LEFT + { + x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f); + } + + LLColor4 label_color(0.f, 0.f, 0.f, 1.f); + label_color.mV[VALPHA] = alpha_factor; + hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, FALSE); + } + } + + // Render text + { + // -1 mMaxLines means unlimited lines. + S32 start_segment; + S32 max_lines = getMaxLines(); + + if (max_lines < 0) + { + start_segment = 0; + } + else + { + start_segment = llmax((S32)0, (S32)mTextSegments.size() - max_lines); + } + + for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment; + segment_iter != mTextSegments.end(); ++segment_iter ) + { + const LLFontGL* fontp = segment_iter->mFont; + y_offset -= fontp->getLineHeight(); + y_offset -= LINE_PADDING; + + U8 style = segment_iter->mStyle; + LLFontGL::ShadowType shadow = LLFontGL::DROP_SHADOW; + + F32 x_offset; + if (mTextAlignment== ALIGN_TEXT_CENTER) + { + x_offset = -0.5f*segment_iter->getWidth(fontp); + } + else // ALIGN_LEFT + { + x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f); + + // *HACK + x_offset += 1; + } + + text_color = segment_iter->mColor; + text_color.mV[VALPHA] *= alpha_factor; + + hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, FALSE); + } + } + /// Reset the default color to white. The renderer expects this to be the default. + gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f); + if (for_select) + { + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + } +} + +void LLHUDNameTag::setString(const std::string &text_utf8) +{ + mTextSegments.clear(); + addLine(text_utf8, mColor); +} + +void LLHUDNameTag::clearString() +{ + mTextSegments.clear(); +} + + +void LLHUDNameTag::addLine(const std::string &text_utf8, + const LLColor4& color, + const LLFontGL::StyleFlags style, + const LLFontGL* font) +{ + LLWString wline = utf8str_to_wstring(text_utf8); + if (!wline.empty()) + { + // use default font for segment if custom font not specified + if (!font) + { + font = mFontp; + } + typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; + LLWString seps(utf8str_to_wstring("\r\n")); + boost::char_separator<llwchar> sep(seps.c_str()); + + tokenizer tokens(wline, sep); + tokenizer::iterator iter = tokens.begin(); + + while (iter != tokens.end()) + { + U32 line_length = 0; + do + { + F32 max_pixels = HUD_TEXT_MAX_WIDTH; + S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); + LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); + mTextSegments.push_back(segment); + line_length += segment_length; + } + while (line_length != iter->size()); + ++iter; + } + } +} + +void LLHUDNameTag::setLabel(const std::string &label_utf8) +{ + mLabelSegments.clear(); + addLabel(label_utf8); +} + +void LLHUDNameTag::addLabel(const std::string& label_utf8) +{ + LLWString wstr = utf8string_to_wstring(label_utf8); + if (!wstr.empty()) + { + LLWString seps(utf8str_to_wstring("\r\n")); + LLWString empty; + + typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; + boost::char_separator<llwchar> sep(seps.c_str(), empty.c_str(), boost::keep_empty_tokens); + + tokenizer tokens(wstr, sep); + tokenizer::iterator iter = tokens.begin(); + + while (iter != tokens.end()) + { + U32 line_length = 0; + do + { + S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(), + HUD_TEXT_MAX_WIDTH, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); + LLHUDTextSegment segment(iter->substr(line_length, segment_length), LLFontGL::NORMAL, mColor, mFontp); + mLabelSegments.push_back(segment); + line_length += segment_length; + } + while (line_length != iter->size()); + ++iter; + } + } +} + +void LLHUDNameTag::setZCompare(const BOOL zcompare) +{ + mZCompare = zcompare; +} + +void LLHUDNameTag::setFont(const LLFontGL* font) +{ + mFontp = font; +} + + +void LLHUDNameTag::setColor(const LLColor4 &color) +{ + mColor = color; + for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin(); + segment_iter != mTextSegments.end(); ++segment_iter ) + { + segment_iter->mColor = color; + } +} + +void LLHUDNameTag::setAlpha(F32 alpha) +{ + mColor.mV[VALPHA] = alpha; + for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin(); + segment_iter != mTextSegments.end(); ++segment_iter ) + { + segment_iter->mColor.mV[VALPHA] = alpha; + } +} + + +void LLHUDNameTag::setDoFade(const BOOL do_fade) +{ + mDoFade = do_fade; +} + +void LLHUDNameTag::updateVisibility() +{ + if (mSourceObject) + { + mSourceObject->updateText(); + } + + mPositionAgent = gAgent.getPosAgentFromGlobal(mPositionGlobal); + + if (!mSourceObject) + { + //llwarns << "LLHUDNameTag::updateScreenPos -- mSourceObject is NULL!" << llendl; + mVisible = TRUE; + sVisibleTextObjects.push_back(LLPointer<LLHUDNameTag> (this)); + return; + } + + // Not visible if parent object is dead + if (mSourceObject->isDead()) + { + mVisible = FALSE; + return; + } + + // push text towards camera by radius of object, but not past camera + LLVector3 vec_from_camera = mPositionAgent - LLViewerCamera::getInstance()->getOrigin(); + LLVector3 dir_from_camera = vec_from_camera; + dir_from_camera.normVec(); + + if (dir_from_camera * LLViewerCamera::getInstance()->getAtAxis() <= 0.f) + { //text is behind camera, don't render + mVisible = FALSE; + return; + } + + if (vec_from_camera * LLViewerCamera::getInstance()->getAtAxis() <= LLViewerCamera::getInstance()->getNear() + 0.1f + mSourceObject->getVObjRadius()) + { + mPositionAgent = LLViewerCamera::getInstance()->getOrigin() + vec_from_camera * ((LLViewerCamera::getInstance()->getNear() + 0.1f) / (vec_from_camera * LLViewerCamera::getInstance()->getAtAxis())); + } + else + { + mPositionAgent -= dir_from_camera * mSourceObject->getVObjRadius(); + } + + mLastDistance = (mPositionAgent - LLViewerCamera::getInstance()->getOrigin()).magVec(); + + if (mLOD >= 3 || !mTextSegments.size() || (mDoFade && (mLastDistance > mFadeDistance + mFadeRange))) + { + mVisible = FALSE; + return; + } + + LLVector3 x_pixel_vec; + LLVector3 y_pixel_vec; + + LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + + LLVector3 render_position = mPositionAgent + + (x_pixel_vec * mPositionOffset.mV[VX]) + + (y_pixel_vec * mPositionOffset.mV[VY]); + + mOffscreen = FALSE; + if (!LLViewerCamera::getInstance()->sphereInFrustum(render_position, mRadius)) + { + if (!mVisibleOffScreen) + { + mVisible = FALSE; + return; + } + else + { + mOffscreen = TRUE; + } + } + + mVisible = TRUE; + sVisibleTextObjects.push_back(LLPointer<LLHUDNameTag> (this)); +} + +LLVector2 LLHUDNameTag::updateScreenPos(LLVector2 &offset) +{ + LLCoordGL screen_pos; + LLVector2 screen_pos_vec; + LLVector3 x_pixel_vec; + LLVector3 y_pixel_vec; + LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); + LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); + if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) + { + // bubble off-screen, so find a spot for it along screen edge + LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(world_pos, screen_pos); + } + + screen_pos_vec.setVec((F32)screen_pos.mX, (F32)screen_pos.mY); + + LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); + S32 bottom = world_rect.mBottom + STATUS_BAR_HEIGHT; + + LLVector2 screen_center; + screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], (F32)world_rect.mLeft + mWidth * 0.5f, (F32)world_rect.mRight - mWidth * 0.5f); + + if(mVertAlignment == ALIGN_VERT_TOP) + { + screen_center.mV[VY] = llclamp((F32)screen_pos_vec.mV[VY], + (F32)bottom, + (F32)world_rect.mTop - mHeight - (F32)MENU_BAR_HEIGHT); + mSoftScreenRect.setLeftTopAndSize(screen_center.mV[VX] - (mWidth + BUFFER_SIZE) * 0.5f, + screen_center.mV[VY] + (mHeight + BUFFER_SIZE), mWidth + BUFFER_SIZE, mHeight + BUFFER_SIZE); + } + else + { + screen_center.mV[VY] = llclamp((F32)screen_pos_vec.mV[VY], + (F32)bottom + mHeight * 0.5f, + (F32)world_rect.mTop - mHeight * 0.5f - (F32)MENU_BAR_HEIGHT); + mSoftScreenRect.setCenterAndSize(screen_center.mV[VX], screen_center.mV[VY], mWidth + BUFFER_SIZE, mHeight + BUFFER_SIZE); + } + + return offset + (screen_center - LLVector2((F32)screen_pos.mX, (F32)screen_pos.mY)); +} + +void LLHUDNameTag::updateSize() +{ + F32 height = 0.f; + 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; + else start_segment = llmax((S32)0, (S32)mTextSegments.size() - max_lines); + + std::vector<LLHUDTextSegment>::iterator iter = mTextSegments.begin() + start_segment; + while (iter != mTextSegments.end()) + { + const LLFontGL* fontp = iter->mFont; + height += fontp->getLineHeight(); + height += LINE_PADDING; + width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH)); + ++iter; + } + + // Don't want line spacing under the last line + if (height > 0.f) + { + height -= LINE_PADDING; + } + + iter = mLabelSegments.begin(); + while (iter != mLabelSegments.end()) + { + height += mFontp->getLineHeight(); + width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); + ++iter; + } + + if (width == 0.f) + { + return; + } + + width += HORIZONTAL_PADDING; + height += VERTICAL_PADDING; + + // *TODO: Could do a timer-based resize here + //mWidth = llmax(width, lerp(mWidth, (F32)width, u)); + //mHeight = llmax(height, lerp(mHeight, (F32)height, u)); + mWidth = width; + mHeight = height; +} + +void LLHUDNameTag::updateAll() +{ + // iterate over all text objects, calculate their restoration forces, + // and add them to the visible set if they are on screen and close enough + sVisibleTextObjects.clear(); + + TextObjectIterator text_it; + for (text_it = sTextObjects.begin(); text_it != sTextObjects.end(); ++text_it) + { + LLHUDNameTag* textp = (*text_it); + textp->mTargetPositionOffset.clearVec(); + textp->updateSize(); + textp->updateVisibility(); + } + + // sort back to front for rendering purposes + std::sort(sVisibleTextObjects.begin(), sVisibleTextObjects.end(), llhudnametag_further_away()); + + // iterate from front to back, and set LOD based on current screen coverage + F32 screen_area = (F32)(gViewerWindow->getWindowWidthScaled() * gViewerWindow->getWindowHeightScaled()); + F32 current_screen_area = 0.f; + std::vector<LLPointer<LLHUDNameTag> >::reverse_iterator r_it; + 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()); +// } + } + + LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); + F32 camera_vel = camera_vel_stat->getCurrent(); + if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) + { + return; + } + + VisibleTextObjectIterator src_it; + + for (S32 i = 0; i < NUM_OVERLAP_ITERATIONS; i++) + { + for (src_it = sVisibleTextObjects.begin(); src_it != sVisibleTextObjects.end(); ++src_it) + { + 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; + intersect_rect.intersectWith(dst_textp->mSoftScreenRect); + intersect_rect.stretch(-BUFFER_SIZE * 0.5f); + + F32 src_center_x = src_textp->mSoftScreenRect.getCenterX(); + F32 src_center_y = src_textp->mSoftScreenRect.getCenterY(); + F32 dst_center_x = dst_textp->mSoftScreenRect.getCenterX(); + F32 dst_center_y = dst_textp->mSoftScreenRect.getCenterY(); + F32 intersect_center_x = intersect_rect.getCenterX(); + F32 intersect_center_y = intersect_rect.getCenterY(); + LLVector2 force = lerp(LLVector2(dst_center_x - intersect_center_x, dst_center_y - intersect_center_y), + LLVector2(intersect_center_x - src_center_x, intersect_center_y - src_center_y), + 0.5f); + force.setVec(dst_center_x - src_center_x, dst_center_y - src_center_y); + force.normVec(); + + LLVector2 src_force = -1.f * force; + LLVector2 dst_force = force; + + LLVector2 force_strength; + F32 src_mult = dst_textp->mMass / (dst_textp->mMass + src_textp->mMass); + F32 dst_mult = 1.f - src_mult; + F32 src_aspect_ratio = src_textp->mSoftScreenRect.getWidth() / src_textp->mSoftScreenRect.getHeight(); + F32 dst_aspect_ratio = dst_textp->mSoftScreenRect.getWidth() / dst_textp->mSoftScreenRect.getHeight(); + src_force.mV[VY] *= src_aspect_ratio; + src_force.normVec(); + dst_force.mV[VY] *= dst_aspect_ratio; + dst_force.normVec(); + + src_force.mV[VX] *= llmin(intersect_rect.getWidth() * src_mult, intersect_rect.getHeight() * SPRING_STRENGTH); + src_force.mV[VY] *= llmin(intersect_rect.getHeight() * src_mult, intersect_rect.getWidth() * SPRING_STRENGTH); + dst_force.mV[VX] *= llmin(intersect_rect.getWidth() * dst_mult, intersect_rect.getHeight() * SPRING_STRENGTH); + dst_force.mV[VY] *= llmin(intersect_rect.getHeight() * dst_mult, intersect_rect.getWidth() * SPRING_STRENGTH); + + src_textp->mTargetPositionOffset += src_force; + dst_textp->mTargetPositionOffset += dst_force; + src_textp->mTargetPositionOffset = src_textp->updateScreenPos(src_textp->mTargetPositionOffset); + dst_textp->mTargetPositionOffset = dst_textp->updateScreenPos(dst_textp->mTargetPositionOffset); + } + } + } + } + + 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)); + } +} + +void LLHUDNameTag::setLOD(S32 lod) +{ + mLOD = lod; + //RN: uncomment this to visualize LOD levels + //std::string label = llformat("%d", lod); + //setLabel(label); +} + +S32 LLHUDNameTag::getMaxLines() +{ + switch(mLOD) + { + case 0: + return mMaxLines; + case 1: + return mMaxLines > 0 ? mMaxLines / 2 : 5; + case 2: + return mMaxLines > 0 ? mMaxLines / 3 : 2; + default: + // label only + return 0; + } +} + +void LLHUDNameTag::markDead() +{ + sTextObjects.erase(LLPointer<LLHUDNameTag>(this)); + LLHUDObject::markDead(); +} + +void LLHUDNameTag::shiftAll(const LLVector3& offset) +{ + TextObjectIterator text_it; + for (text_it = sTextObjects.begin(); text_it != sTextObjects.end(); ++text_it) + { + LLHUDNameTag *textp = text_it->get(); + textp->shift(offset); + } +} + +void LLHUDNameTag::shift(const LLVector3& offset) +{ + mPositionAgent += offset; +} + +//static +void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list) +{ + //this might put an object on the pick list a second time, overriding it's mGLName, which is ok + // *FIX: we should probably cull against pick frustum + 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); + } +} + +//static +// called when UI scale changes, to flush font width caches +void LLHUDNameTag::reshape() +{ + TextObjectIterator text_it; + for (text_it = sTextObjects.begin(); text_it != sTextObjects.end(); ++text_it) + { + LLHUDNameTag* textp = (*text_it); + std::vector<LLHUDTextSegment>::iterator segment_iter; + for (segment_iter = textp->mTextSegments.begin(); + segment_iter != textp->mTextSegments.end(); ++segment_iter ) + { + segment_iter->clearFontWidthMap(); + } + for(segment_iter = textp->mLabelSegments.begin(); + segment_iter != textp->mLabelSegments.end(); ++segment_iter ) + { + segment_iter->clearFontWidthMap(); + } + } +} + +//============================================================================ + +F32 LLHUDNameTag::LLHUDTextSegment::getWidth(const LLFontGL* font) +{ + std::map<const LLFontGL*, F32>::iterator iter = mFontWidthMap.find(font); + if (iter != mFontWidthMap.end()) + { + return iter->second; + } + else + { + F32 width = font->getWidthF32(mText.c_str()); + mFontWidthMap[font] = width; + return width; + } +} diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h new file mode 100644 index 0000000000..3325c22def --- /dev/null +++ b/indra/newview/llhudnametag.h @@ -0,0 +1,185 @@ +/** + * @file llhudnametag.h + * @brief Name tags for avatars + * @author James Cook + * + * $LicenseInfo:firstyear=2010&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 LLHUDNAMETAG_H +#define LLHUDNAMETAG_H + +#include "llpointer.h" + +#include "llhudobject.h" +#include "v4color.h" +//#include "v4coloru.h" +#include "v2math.h" +#include "llrect.h" +//#include "llframetimer.h" +#include "llfontgl.h" +#include <set> +#include <vector> + +class LLDrawable; +class LLHUDNameTag; + +struct llhudnametag_further_away +{ + bool operator()(const LLPointer<LLHUDNameTag>& lhs, const LLPointer<LLHUDNameTag>& rhs) const; +}; + +class LLHUDNameTag : public LLHUDObject +{ +protected: + class LLHUDTextSegment + { + public: + LLHUDTextSegment(const LLWString& text, const LLFontGL::StyleFlags style, const LLColor4& color, const LLFontGL* font) + : mColor(color), + mStyle(style), + mText(text), + mFont(font) + {} + F32 getWidth(const LLFontGL* font); + const LLWString& getText() const { return mText; } + void clearFontWidthMap() { mFontWidthMap.clear(); } + + LLColor4 mColor; + LLFontGL::StyleFlags mStyle; + const LLFontGL* mFont; + private: + LLWString mText; + std::map<const LLFontGL*, F32> mFontWidthMap; + }; + +public: + typedef enum e_text_alignment + { + ALIGN_TEXT_LEFT, + ALIGN_TEXT_CENTER + } ETextAlignment; + + typedef enum e_vert_alignment + { + ALIGN_VERT_TOP, + ALIGN_VERT_CENTER + } EVertAlignment; + +public: + // Set entire string, eliminating existing lines + void setString(const std::string& text_utf8); + + void clearString(); + + // Add text a line at a time, allowing custom formatting + void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL); + + // For bubble chat, set the part above the chat text + void setLabel(const std::string& label_utf8); + void addLabel(const std::string& label_utf8); + + // Sets the default font for lines with no font specified + void setFont(const LLFontGL* font); + void setColor(const LLColor4 &color); + void setAlpha(F32 alpha); + void setZCompare(const BOOL zcompare); + void setDoFade(const BOOL do_fade); + void setVisibleOffScreen(BOOL visible) { mVisibleOffScreen = visible; } + + // mMaxLines of -1 means unlimited lines. + void setMaxLines(S32 max_lines) { mMaxLines = max_lines; } + void setFadeDistance(F32 fade_distance, F32 fade_range) { mFadeDistance = fade_distance; mFadeRange = fade_range; } + void updateVisibility(); + LLVector2 updateScreenPos(LLVector2 &offset_target); + void updateSize(); +// void setMass(F32 mass) { mMass = llmax(0.1f, mass); } + void setTextAlignment(ETextAlignment alignment) { mTextAlignment = alignment; } + void setVertAlignment(EVertAlignment alignment) { mVertAlignment = alignment; } + /*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; } + void setHidden( BOOL hide ) { mHidden = hide; } + void shift(const LLVector3& offset); + + BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); + + static void shiftAll(const LLVector3& offset); + static void addPickable(std::set<LLViewerObject*> &pick_list); + static void reshape(); + static void setDisplayText(BOOL flag) { sDisplayText = flag ; } + +protected: + LLHUDNameTag(const U8 type); + + /*virtual*/ void render(); + /*virtual*/ void renderForSelect(); + void renderText(BOOL for_select); + static void updateAll(); + void setLOD(S32 lod); + S32 getMaxLines(); + +private: + ~LLHUDNameTag(); + BOOL mDoFade; + F32 mFadeRange; + F32 mFadeDistance; + F32 mLastDistance; + BOOL mZCompare; + BOOL mVisibleOffScreen; + BOOL mOffscreen; + LLColor4 mColor; +// LLVector3 mScale; + F32 mWidth; + F32 mHeight; +// LLColor4U mPickColor; + const LLFontGL* mFontp; + const LLFontGL* mBoldFontp; + LLRectf mSoftScreenRect; + LLVector3 mPositionAgent; + LLVector2 mPositionOffset; + LLVector2 mTargetPositionOffset; + F32 mMass; + S32 mMaxLines; + S32 mOffsetY; + F32 mRadius; + std::vector<LLHUDTextSegment> mTextSegments; + std::vector<LLHUDTextSegment> mLabelSegments; +// LLFrameTimer mResizeTimer; + ETextAlignment mTextAlignment; + EVertAlignment mVertAlignment; + S32 mLOD; + BOOL mHidden; + + static BOOL sDisplayText ; + static std::set<LLPointer<LLHUDNameTag> > sTextObjects; + static std::vector<LLPointer<LLHUDNameTag> > sVisibleTextObjects; +// static std::vector<LLPointer<LLHUDNameTag> > sVisibleHUDTextObjects; + typedef std::set<LLPointer<LLHUDNameTag> >::iterator TextObjectIterator; + typedef std::vector<LLPointer<LLHUDNameTag> >::iterator VisibleTextObjectIterator; +}; + +#endif diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp index 3e814a0773..09200ee5be 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2002-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 @@ -24,9 +24,6 @@ * $/LicenseInfo$ */ -// llhudobject.cpp -// Copyright 2002, Linden Research, Inc. - #include "llviewerprecompiledheaders.h" #include "llhudobject.h" @@ -38,7 +35,7 @@ #include "llhudeffecttrail.h" #include "llhudeffectlookat.h" #include "llhudeffectpointat.h" - +#include "llhudnametag.h" #include "llvoicevisualizer.h" #include "llagent.h" @@ -66,7 +63,6 @@ LLHUDObject::LLHUDObject(const U8 type) : mVisible = TRUE; mType = type; mDead = FALSE; - mOnHUDAttachment = FALSE; } LLHUDObject::~LLHUDObject() @@ -145,6 +141,9 @@ LLHUDObject *LLHUDObject::addHUDObject(const U8 type) case LL_HUD_ICON: hud_objectp = new LLHUDIcon(type); break; + case LL_HUD_NAME_TAG: + hud_objectp = new LLHUDNameTag(type); + break; default: llwarns << "Unknown type of hud object:" << (U32) type << llendl; } @@ -257,6 +256,7 @@ void LLHUDObject::updateAll() LLFastTimer ftm(FTM_HUD_UPDATE); LLHUDText::updateAll(); LLHUDIcon::updateAll(); + LLHUDNameTag::updateAll(); sortObjects(); } @@ -326,6 +326,14 @@ void LLHUDObject::renderAllForTimer() } // static +void LLHUDObject::reshapeAll() +{ + // only hud objects that use fonts care about window size/scale changes + LLHUDText::reshape(); + LLHUDNameTag::reshape(); +} + +// static void LLHUDObject::sortObjects() { sHUDObjects.sort(hud_object_further_away()); diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h index 97145b9a84..4282ade34d 100644 --- a/indra/newview/llhudobject.h +++ b/indra/newview/llhudobject.h @@ -36,7 +36,7 @@ #include "v4color.h" #include "v3math.h" #include "v3dmath.h" -#include "lldrawpool.h" +#include "lldrawpool.h" // TODO: eliminate, unused below #include <list> class LLViewerCamera; @@ -71,6 +71,9 @@ public: static void renderAllForSelect(); static void renderAllForTimer(); + // Some objects may need to update when window shape changes + static void reshapeAll(); + static void cleanupHUDObjects(); enum @@ -91,7 +94,8 @@ public: LL_HUD_EFFECT_EDIT, LL_HUD_EFFECT_LOOKAT, LL_HUD_EFFECT_POINTAT, - LL_HUD_EFFECT_VOICE_VISUALIZER // Ventrella + LL_HUD_EFFECT_VOICE_VISUALIZER, // Ventrella + LL_HUD_NAME_TAG }; protected: static void sortObjects(); @@ -108,7 +112,6 @@ protected: BOOL mDead; BOOL mVisible; LLVector3d mPositionGlobal; - BOOL mOnHUDAttachment; LLPointer<LLViewerObject> mSourceObject; LLPointer<LLViewerObject> mTargetObject; diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 96638018c4..6a423e529a 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -1,7 +1,6 @@ - /** * @file llhudtext.cpp - * @brief LLHUDText class implementation + * @brief Floating text above objects, set via script with llSetText() * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code @@ -56,16 +55,16 @@ const F32 HORIZONTAL_PADDING = 15.f; const F32 VERTICAL_PADDING = 12.f; const F32 BUFFER_SIZE = 2.f; const F32 MIN_EDGE_OVERLAP = 3.f; -F32 HUD_TEXT_MAX_WIDTH = 190.f; +const F32 HUD_TEXT_MAX_WIDTH = 190.f; const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f; const F32 RESIZE_TIME = 0.f; const S32 NUM_OVERLAP_ITERATIONS = 10; const F32 NEIGHBOR_FORCE_FRACTION = 1.f; const F32 POSITION_DAMPING_TC = 0.2f; const F32 MAX_STABLE_CAMERA_VELOCITY = 0.1f; -const F32 LOD_0_SCREEN_COVERAGE = 0.15f; -const F32 LOD_1_SCREEN_COVERAGE = 0.30f; -const F32 LOD_2_SCREEN_COVERAGE = 0.40f; +//const F32 LOD_0_SCREEN_COVERAGE = 0.15f; +//const F32 LOD_1_SCREEN_COVERAGE = 0.30f; +//const F32 LOD_2_SCREEN_COVERAGE = 0.40f; std::set<LLPointer<LLHUDText> > LLHUDText::sTextObjects; std::vector<LLPointer<LLHUDText> > LLHUDText::sVisibleTextObjects; @@ -74,15 +73,14 @@ BOOL LLHUDText::sDisplayText = TRUE ; bool lltextobject_further_away::operator()(const LLPointer<LLHUDText>& lhs, const LLPointer<LLHUDText>& rhs) const { - return (lhs->getDistance() > rhs->getDistance()) ? true : false; + return lhs->getDistance() > rhs->getDistance(); } LLHUDText::LLHUDText(const U8 type) : LLHUDObject(type), - mUseBubble(FALSE), - mUsePixelSize(TRUE), - mVisibleOffScreen(FALSE), + mOnHUDAttachment(FALSE), +// mVisibleOffScreen(FALSE), mWidth(0.f), mHeight(0.f), mFontp(LLFontGL::getFontSansSerifSmall()), @@ -92,7 +90,7 @@ LLHUDText::LLHUDText(const U8 type) : mOffsetY(0), mTextAlignment(ALIGN_TEXT_CENTER), mVertAlignment(ALIGN_VERT_CENTER), - mLOD(0), +// mLOD(0), mHidden(FALSE) { mColor = LLColor4(1.f, 1.f, 1.f, 1.f); @@ -100,7 +98,6 @@ LLHUDText::LLHUDText(const U8 type) : mFadeDistance = 8.f; mFadeRange = 4.f; mZCompare = TRUE; - mDropShadow = TRUE; mOffscreen = FALSE; mRadius = 0.1f; LLPointer<LLHUDText> ptr(this); @@ -111,112 +108,6 @@ LLHUDText::~LLHUDText() { } - -BOOL LLHUDText::lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render) -{ - if (!mVisible || mHidden) - { - return FALSE; - } - - // don't pick text that isn't bound to a viewerobject or isn't in a bubble - if (!mSourceObject || mSourceObject->mDrawable.isNull() || !mUseBubble) - { - return FALSE; - } - - F32 alpha_factor = 1.f; - LLColor4 text_color = mColor; - if (mDoFade) - { - if (mLastDistance > mFadeDistance) - { - alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange); - text_color.mV[3] = text_color.mV[3]*alpha_factor; - } - } - if (text_color.mV[3] < 0.01f) - { - return FALSE; - } - - mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f)); - - // scale screen size of borders down - //RN: for now, text on hud objects is never occluded - - LLVector3 x_pixel_vec; - LLVector3 y_pixel_vec; - - if (mOnHUDAttachment) - { - x_pixel_vec = LLVector3::y_axis / (F32)gViewerWindow->getWindowWidthScaled(); - y_pixel_vec = LLVector3::z_axis / (F32)gViewerWindow->getWindowHeightScaled(); - } - else - { - LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); - } - - LLVector3 width_vec = mWidth * x_pixel_vec; - LLVector3 height_vec = mHeight * y_pixel_vec; - - LLCoordGL screen_pos; - LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); - - LLVector2 screen_offset; - screen_offset = updateScreenPos(mPositionOffset); - - LLVector3 render_position = mPositionAgent - + (x_pixel_vec * screen_offset.mV[VX]) - + (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); - //LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]); - - LLVector3 v[] = - { - bg_pos, - bg_pos + width_vec, - bg_pos + width_vec + height_vec, - bg_pos + height_vec, - }; - - if (debug_render) - { - 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 t = 0.f; - - if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, NULL, NULL, &t, FALSE) || - LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, NULL, NULL, &t, FALSE) ) - { - if (t <= 1.f) - { - intersection = start + dir*t; - return TRUE; - } - } - } - - return FALSE; -} - void LLHUDText::render() { if (!mOnHUDAttachment && sDisplayText) @@ -242,21 +133,13 @@ void LLHUDText::renderText(BOOL for_select) return; } - // don't pick text that isn't bound to a viewerobject or isn't in a bubble - if (for_select && - (!mSourceObject || mSourceObject->mDrawable.isNull() || !mUseBubble)) + // don't pick text + if (for_select) { return; } - if (for_select) - { - gGL.getTexUnit(0)->disable(); - } - else - { - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - } + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); LLGLState gls_blend(GL_BLEND, for_select ? FALSE : TRUE); LLGLState gls_alpha(GL_ALPHA_TEST, for_select ? FALSE : TRUE); @@ -284,7 +167,7 @@ void LLHUDText::renderText(BOOL for_select) LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square"); // *TODO: make this a per-text setting - LLColor4 bg_color = LLUIColorTable::instance().getColor("BackgroundChatColor"); + LLColor4 bg_color = LLUIColorTable::instance().getColor("ObjectBubbleColor"); bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor); const S32 border_height = 16; @@ -330,178 +213,17 @@ void LLHUDText::renderText(BOOL for_select) LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE); LLVector2 screen_offset; - if (!mUseBubble) - { - screen_offset = mPositionOffset; - } - else - { - screen_offset = updateScreenPos(mPositionOffset); - } + screen_offset = mPositionOffset; LLVector3 render_position = mPositionAgent + (x_pixel_vec * screen_offset.mV[VX]) + (y_pixel_vec * screen_offset.mV[VY]); - //if (mOnHUD) - //{ - // render_position.mV[VY] -= fmodf(render_position.mV[VY], 1.f / (F32)gViewerWindow->getWindowWidthScaled()); - // render_position.mV[VZ] -= fmodf(render_position.mV[VZ], 1.f / (F32)gViewerWindow->getWindowHeightScaled()); - //} - //else - //{ - // render_position = LLViewerCamera::getInstance()->roundToPixel(render_position); - //} - - if (mUseBubble) - { - 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); - - // 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(); - } - F32 y_offset = (F32)mOffsetY; // Render label { gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - - for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin(); - segment_iter != mLabelSegments.end(); ++segment_iter ) - { - const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp; - y_offset -= fontp->getLineHeight(); - - F32 x_offset; - if (mTextAlignment == ALIGN_TEXT_CENTER) - { - x_offset = -0.5f*segment_iter->getWidth(fontp); - } - else // ALIGN_LEFT - { - x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f); - } - - LLColor4 label_color(0.f, 0.f, 0.f, 1.f); - label_color.mV[VALPHA] = alpha_factor; - hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, mOnHUDAttachment); - } } // Render text @@ -522,15 +244,11 @@ void LLHUDText::renderText(BOOL for_select) for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment; segment_iter != mTextSegments.end(); ++segment_iter ) { - const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp; + const LLFontGL* fontp = segment_iter->mFont; y_offset -= fontp->getLineHeight(); U8 style = segment_iter->mStyle; - LLFontGL::ShadowType shadow = LLFontGL::NO_SHADOW; - if (mDropShadow) - { - shadow = LLFontGL::DROP_SHADOW; - } + LLFontGL::ShadowType shadow = LLFontGL::DROP_SHADOW; F32 x_offset; if (mTextAlignment== ALIGN_TEXT_CENTER) @@ -550,21 +268,12 @@ void LLHUDText::renderText(BOOL for_select) } /// Reset the default color to white. The renderer expects this to be the default. gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f); - if (for_select) - { - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - } -} - -void LLHUDText::setStringUTF8(const std::string &wtext) -{ - setString(utf8str_to_wstring(wtext)); } -void LLHUDText::setString(const LLWString &wtext) +void LLHUDText::setString(const std::string &text_utf8) { mTextSegments.clear(); - addLine(wtext, mColor); + addLine(text_utf8, mColor); } void LLHUDText::clearString() @@ -573,21 +282,19 @@ void LLHUDText::clearString() } -void LLHUDText::addLine(const std::string &str, const LLColor4& color, const LLFontGL::StyleFlags style) +void LLHUDText::addLine(const std::string &text_utf8, + const LLColor4& color, + const LLFontGL::StyleFlags style, + const LLFontGL* font) { - addLine(utf8str_to_wstring(str), color, style); -} - - -void LLHUDText::addLine(const LLWString &wstr, const LLColor4& color, const LLFontGL::StyleFlags style) -{ - if (gNoRender) - { - return; - } - if (!wstr.empty()) + LLWString wline = utf8str_to_wstring(text_utf8); + if (!wline.empty()) { - LLWString wline(wstr); + // use default font for segment if custom font not specified + if (!font) + { + font = mFontp; + } typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; LLWString seps(utf8str_to_wstring("\r\n")); boost::char_separator<llwchar> sep(seps.c_str()); @@ -600,8 +307,10 @@ void LLHUDText::addLine(const LLWString &wstr, const LLColor4& color, const LLFo U32 line_length = 0; do { - S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(), mUseBubble ? HUD_TEXT_MAX_WIDTH : HUD_TEXT_MAX_WIDTH_NO_BUBBLE, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); - mTextSegments.push_back(LLHUDTextSegment(iter->substr(line_length, segment_length), style, color)); + F32 max_pixels = HUD_TEXT_MAX_WIDTH_NO_BUBBLE; + S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); + LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); + mTextSegments.push_back(segment); line_length += segment_length; } while (line_length != iter->size()); @@ -610,47 +319,6 @@ void LLHUDText::addLine(const LLWString &wstr, const LLColor4& color, const LLFo } } -void LLHUDText::setLabel(const std::string &label) -{ - setLabel(utf8str_to_wstring(label)); -} - -void LLHUDText::setLabel(const LLWString &wlabel) -{ - mLabelSegments.clear(); - - if (!wlabel.empty()) - { - LLWString wstr(wlabel); - LLWString seps(utf8str_to_wstring("\r\n")); - LLWString empty; - - typedef boost::tokenizer<boost::char_separator<llwchar>, LLWString::const_iterator, LLWString > tokenizer; - boost::char_separator<llwchar> sep(seps.c_str(), empty.c_str(), boost::keep_empty_tokens); - - tokenizer tokens(wstr, sep); - tokenizer::iterator iter = tokens.begin(); - - while (iter != tokens.end()) - { - U32 line_length = 0; - do - { - S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(), mUseBubble ? HUD_TEXT_MAX_WIDTH : HUD_TEXT_MAX_WIDTH_NO_BUBBLE, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); - mLabelSegments.push_back(LLHUDTextSegment(iter->substr(line_length, segment_length), LLFontGL::NORMAL, mColor)); - line_length += segment_length; - } - while (line_length != iter->size()); - ++iter; - } - } -} - -void LLHUDText::setDropShadow(const BOOL do_shadow) -{ - mDropShadow = do_shadow; -} - void LLHUDText::setZCompare(const BOOL zcompare) { mZCompare = zcompare; @@ -672,12 +340,17 @@ void LLHUDText::setColor(const LLColor4 &color) } } - -void LLHUDText::setUsePixelSize(const BOOL use_pixel_size) +void LLHUDText::setAlpha(F32 alpha) { - mUsePixelSize = use_pixel_size; + mColor.mV[VALPHA] = alpha; + for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin(); + segment_iter != mTextSegments.end(); ++segment_iter ) + { + segment_iter->mColor.mV[VALPHA] = alpha; + } } + void LLHUDText::setDoFade(const BOOL do_fade) { mDoFade = do_fade; @@ -745,7 +418,7 @@ void LLHUDText::updateVisibility() mLastDistance = (mPositionAgent - LLViewerCamera::getInstance()->getOrigin()).magVec(); - if (mLOD >= 3 || !mTextSegments.size() || (mDoFade && (mLastDistance > mFadeDistance + mFadeRange))) + if (!mTextSegments.size() || (mDoFade && (mLastDistance > mFadeDistance + mFadeRange))) { mVisible = FALSE; return; @@ -763,15 +436,15 @@ void LLHUDText::updateVisibility() mOffscreen = FALSE; if (!LLViewerCamera::getInstance()->sphereInFrustum(render_position, mRadius)) { - if (!mVisibleOffScreen) - { +// if (!mVisibleOffScreen) +// { mVisible = FALSE; return; - } - else - { - mOffscreen = TRUE; - } +// } +// else +// { +// mOffscreen = TRUE; +// } } mVisible = TRUE; @@ -786,11 +459,11 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset) LLVector3 y_pixel_vec; LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec); LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec); - if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) - { - // bubble off-screen, so find a spot for it along screen edge - LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(world_pos, screen_pos); - } +// if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen) +// { +// // bubble off-screen, so find a spot for it along screen edge +// LLViewerCamera::getInstance()->projectPosAgentToScreenEdge(world_pos, screen_pos); +// } screen_pos_vec.setVec((F32)screen_pos.mX, (F32)screen_pos.mY); @@ -821,12 +494,12 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset) void LLHUDText::updateSize() { + F32 height = 0.f; 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 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; @@ -835,17 +508,12 @@ void LLHUDText::updateSize() std::vector<LLHUDTextSegment>::iterator iter = mTextSegments.begin() + start_segment; while (iter != mTextSegments.end()) { - width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); + const LLFontGL* fontp = iter->mFont; + height += fontp->getLineHeight(); + width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH)); ++iter; } - iter = mLabelSegments.begin(); - while (iter != mLabelSegments.end()) - { - width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH)); - ++iter; - } - if (width == 0.f) { return; @@ -854,18 +522,8 @@ void LLHUDText::updateSize() width += HORIZONTAL_PADDING; height += VERTICAL_PADDING; - if (!mResizeTimer.getStarted() && (width != mWidth || height != mHeight)) - { - mResizeTimer.start(); - } - - // *NOTE: removed logic which did a divide by zero. - F32 u = 1.f;//llclamp(mResizeTimer.getElapsedTimeF32() / RESIZE_TIME, 0.f, 1.f); - if (u == 1.f) - { - mResizeTimer.stop(); - } - + // *TODO: Could do some sort of timer-based resize logic here + F32 u = 1.f; mWidth = llmax(width, lerp(mWidth, (F32)width, u)); mHeight = llmax(height, lerp(mHeight, (F32)height, u)); } @@ -889,146 +547,31 @@ void LLHUDText::updateAll() // sort back to front for rendering purposes std::sort(sVisibleTextObjects.begin(), sVisibleTextObjects.end(), lltextobject_further_away()); std::sort(sVisibleHUDTextObjects.begin(), sVisibleHUDTextObjects.end(), lltextobject_further_away()); - - // iterate from front to back, and set LOD based on current screen coverage - F32 screen_area = (F32)(gViewerWindow->getWindowWidthScaled() * gViewerWindow->getWindowHeightScaled()); - F32 current_screen_area = 0.f; - std::vector<LLPointer<LLHUDText> >::reverse_iterator r_it; - for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it) - { - LLHUDText* 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()); - } - } - - LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat(); - F32 camera_vel = camera_vel_stat->getCurrent(); - if (camera_vel > MAX_STABLE_CAMERA_VELOCITY) - { - return; - } - - VisibleTextObjectIterator src_it; - - for (S32 i = 0; i < NUM_OVERLAP_ITERATIONS; i++) - { - for (src_it = sVisibleTextObjects.begin(); src_it != sVisibleTextObjects.end(); ++src_it) - { - LLHUDText* src_textp = (*src_it); - - if (!src_textp->mUseBubble) - { - continue; - } - VisibleTextObjectIterator dst_it = src_it; - ++dst_it; - for (; dst_it != sVisibleTextObjects.end(); ++dst_it) - { - LLHUDText* dst_textp = (*dst_it); - - if (!dst_textp->mUseBubble) - { - continue; - } - if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect)) - { - LLRectf intersect_rect = src_textp->mSoftScreenRect; - intersect_rect.intersectWith(dst_textp->mSoftScreenRect); - intersect_rect.stretch(-BUFFER_SIZE * 0.5f); - - F32 src_center_x = src_textp->mSoftScreenRect.getCenterX(); - F32 src_center_y = src_textp->mSoftScreenRect.getCenterY(); - F32 dst_center_x = dst_textp->mSoftScreenRect.getCenterX(); - F32 dst_center_y = dst_textp->mSoftScreenRect.getCenterY(); - F32 intersect_center_x = intersect_rect.getCenterX(); - F32 intersect_center_y = intersect_rect.getCenterY(); - LLVector2 force = lerp(LLVector2(dst_center_x - intersect_center_x, dst_center_y - intersect_center_y), - LLVector2(intersect_center_x - src_center_x, intersect_center_y - src_center_y), - 0.5f); - force.setVec(dst_center_x - src_center_x, dst_center_y - src_center_y); - force.normVec(); - - LLVector2 src_force = -1.f * force; - LLVector2 dst_force = force; - - LLVector2 force_strength; - F32 src_mult = dst_textp->mMass / (dst_textp->mMass + src_textp->mMass); - F32 dst_mult = 1.f - src_mult; - F32 src_aspect_ratio = src_textp->mSoftScreenRect.getWidth() / src_textp->mSoftScreenRect.getHeight(); - F32 dst_aspect_ratio = dst_textp->mSoftScreenRect.getWidth() / dst_textp->mSoftScreenRect.getHeight(); - src_force.mV[VY] *= src_aspect_ratio; - src_force.normVec(); - dst_force.mV[VY] *= dst_aspect_ratio; - dst_force.normVec(); - - src_force.mV[VX] *= llmin(intersect_rect.getWidth() * src_mult, intersect_rect.getHeight() * SPRING_STRENGTH); - src_force.mV[VY] *= llmin(intersect_rect.getHeight() * src_mult, intersect_rect.getWidth() * SPRING_STRENGTH); - dst_force.mV[VX] *= llmin(intersect_rect.getWidth() * dst_mult, intersect_rect.getHeight() * SPRING_STRENGTH); - dst_force.mV[VY] *= llmin(intersect_rect.getHeight() * dst_mult, intersect_rect.getWidth() * SPRING_STRENGTH); - - src_textp->mTargetPositionOffset += src_force; - dst_textp->mTargetPositionOffset += dst_force; - src_textp->mTargetPositionOffset = src_textp->updateScreenPos(src_textp->mTargetPositionOffset); - dst_textp->mTargetPositionOffset = dst_textp->updateScreenPos(dst_textp->mTargetPositionOffset); - } - } - } - } - - 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)); - } } -void LLHUDText::setLOD(S32 lod) -{ - mLOD = lod; - //RN: uncomment this to visualize LOD levels - //std::string label = llformat("%d", lod); - //setLabel(label); -} +//void LLHUDText::setLOD(S32 lod) +//{ +// mLOD = lod; +// //RN: uncomment this to visualize LOD levels +// //std::string label = llformat("%d", lod); +// //setLabel(label); +//} S32 LLHUDText::getMaxLines() { - switch(mLOD) - { - case 0: - return mMaxLines; - case 1: - return mMaxLines > 0 ? mMaxLines / 2 : 5; - case 2: - return mMaxLines > 0 ? mMaxLines / 3 : 2; - default: - // label only - return 0; - } + return mMaxLines; + //switch(mLOD) + //{ + //case 0: + // return mMaxLines; + //case 1: + // return mMaxLines > 0 ? mMaxLines / 2 : 5; + //case 2: + // return mMaxLines > 0 ? mMaxLines / 3 : 2; + //default: + // // label only + // return 0; + //} } void LLHUDText::markDead() @@ -1079,22 +622,6 @@ void LLHUDText::shift(const LLVector3& offset) mPositionAgent += offset; } -//static -void LLHUDText::addPickable(std::set<LLViewerObject*> &pick_list) -{ - //this might put an object on the pick list a second time, overriding it's mGLName, which is ok - // *FIX: we should probably cull against pick frustum - 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); - } -} - //static // called when UI scale changes, to flush font width caches void LLHUDText::reshape() @@ -1109,11 +636,6 @@ void LLHUDText::reshape() { segment_iter->clearFontWidthMap(); } - for(segment_iter = textp->mLabelSegments.begin(); - segment_iter != textp->mLabelSegments.end(); ++segment_iter ) - { - segment_iter->clearFontWidthMap(); - } } } diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index 4f4ee55a61..f05ee4d594 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -28,18 +28,15 @@ #define LL_LLHUDTEXT_H #include "llpointer.h" -#include "lldarrayptr.h" #include "llhudobject.h" #include "v4color.h" #include "v4coloru.h" #include "v2math.h" #include "llrect.h" -#include "llframetimer.h" #include "llfontgl.h" #include <set> #include <vector> -#include "lldarray.h" // Renders a 2D text billboard floating at the location specified. class LLDrawable; @@ -56,14 +53,19 @@ protected: class LLHUDTextSegment { public: - LLHUDTextSegment(const LLWString& text, const LLFontGL::StyleFlags style, const LLColor4& color) - : mColor(color), mStyle(style), mText(text) {} + LLHUDTextSegment(const LLWString& text, const LLFontGL::StyleFlags style, const LLColor4& color, const LLFontGL* font) + : mColor(color), + mStyle(style), + mText(text), + mFont(font) + {} F32 getWidth(const LLFontGL* font); - const LLWString& getText() const { return mText; }; + const LLWString& getText() const { return mText; } void clearFontWidthMap() { mFontWidthMap.clear(); } LLColor4 mColor; LLFontGL::StyleFlags mStyle; + const LLFontGL* mFont; private: LLWString mText; std::map<const LLFontGL*, F32> mFontWidthMap; @@ -83,20 +85,21 @@ public: } EVertAlignment; public: - void setStringUTF8(const std::string &utf8string); - void setString(const LLWString &wstring); + // Set entire string, eliminating existing lines + void setString(const std::string& text_utf8); + void clearString(); - void addLine(const std::string &text, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL); - void addLine(const LLWString &wtext, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL); - void setLabel(const std::string &label); - void setLabel(const LLWString &label); - void setDropShadow(const BOOL do_shadow); + + // Add text a line at a time, allowing custom formatting + void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL); + + // Sets the default font for lines with no font specified void setFont(const LLFontGL* font); void setColor(const LLColor4 &color); - void setUsePixelSize(const BOOL use_pixel_size); + void setAlpha(F32 alpha); void setZCompare(const BOOL zcompare); void setDoFade(const BOOL do_fade); - void setVisibleOffScreen(BOOL visible) { mVisibleOffScreen = visible; } +// void setVisibleOffScreen(BOOL visible) { mVisibleOffScreen = visible; } // mMaxLines of -1 means unlimited lines. void setMaxLines(S32 max_lines) { mMaxLines = max_lines; } @@ -110,21 +113,17 @@ 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; } void setHidden( BOOL hide ) { mHidden = hide; } void setOnHUDAttachment(BOOL on_hud) { mOnHUDAttachment = on_hud; } void shift(const LLVector3& offset); - BOOL lineSegmentIntersect(const LLVector3& start, const LLVector3& end, LLVector3& intersection, BOOL debug_render = FALSE); - static void shiftAll(const LLVector3& offset); static void renderAllHUD(); - static void addPickable(std::set<LLViewerObject*> &pick_list); static void reshape(); static void setDisplayText(BOOL flag) { sDisplayText = flag ; } + protected: LLHUDText(const U8 type); @@ -132,21 +131,17 @@ protected: /*virtual*/ void renderForSelect(); void renderText(BOOL for_select); static void updateAll(); - void setLOD(S32 lod); S32 getMaxLines(); private: ~LLHUDText(); - BOOL mOnHUD; - BOOL mUseBubble; - BOOL mDropShadow; + BOOL mOnHUDAttachment; BOOL mDoFade; F32 mFadeRange; F32 mFadeDistance; F32 mLastDistance; - BOOL mUsePixelSize; BOOL mZCompare; - BOOL mVisibleOffScreen; +// BOOL mVisibleOffScreen; BOOL mOffscreen; LLColor4 mColor; LLVector3 mScale; @@ -164,11 +159,8 @@ private: S32 mOffsetY; F32 mRadius; std::vector<LLHUDTextSegment> mTextSegments; - std::vector<LLHUDTextSegment> mLabelSegments; - LLFrameTimer mResizeTimer; ETextAlignment mTextAlignment; EVertAlignment mVertAlignment; - S32 mLOD; BOOL mHidden; static BOOL sDisplayText ; diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 56d3ed1c4d..e000abda2a 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -32,6 +32,7 @@ #include "llagent.h" #include "llappviewer.h" +#include "llavatarnamecache.h" #include "llbutton.h" #include "llbottomtray.h" #include "llchannelmanager.h" @@ -275,12 +276,6 @@ BOOL LLIMFloater::postBuild() mInputEditor->setReplaceNewlinesWithSpaces( FALSE ); mInputEditor->setPassDelete( TRUE ); - std::string session_name(LLIMModel::instance().getName(mSessionID)); - - mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + session_name); - - setTitle(session_name); - childSetCommitCallback("chat_editor", onSendMsg, this); mChatHistory = getChild<LLChatHistory>("chat_history"); @@ -298,6 +293,19 @@ BOOL LLIMFloater::postBuild() 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) @@ -311,6 +319,23 @@ BOOL LLIMFloater::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() { @@ -1071,13 +1096,9 @@ void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info) { mOtherTyping = true; - // Create typing is started title string - LLUIString typing_start(mTypingStart); - typing_start.setArg("[NAME]", im_info->mName); - // Save and set new title mSavedTitle = getTitle(); - setTitle (typing_start); + setTitle (mTypingStart); // Update speaker LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index e604623b1b..e80e45e64a 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -32,6 +32,7 @@ #include "lltooldraganddrop.h" #include "lltransientdockablefloater.h" +class LLAvatarName; class LLLineEditor; class LLPanelChatControlPanel; class LLChatHistory; @@ -124,6 +125,12 @@ private: /* 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); diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 01e1c3caa0..fe8a46e908 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -28,6 +28,7 @@ #include "llimview.h" +#include "llavatarnamecache.h" // IDEVO #include "llfloaterreg.h" #include "llfontgl.h" #include "llgl.h" @@ -64,11 +65,6 @@ #include "llviewerparcelmgr.h" -const static std::string IM_TIME("time"); -const static std::string IM_TEXT("message"); -const static std::string IM_FROM("from"); -const static std::string IM_FROM_ID("from_id"); - const static std::string ADHOC_NAME_SUFFIX(" Conference"); const static std::string NEARBY_P2P_BY_OTHER("nearby_P2P_by_other"); @@ -101,6 +97,20 @@ BOOL LLSessionTimeoutTimer::tick() return TRUE; } +static void on_avatar_name_cache_toast(const LLUUID& agent_id, + const LLAvatarName& av_name, + LLSD msg) +{ + LLSD args; + args["MESSAGE"] = msg["message"]; + args["TIME"] = msg["time"]; + // *TODO: Can this ever be an object name or group name? + 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"]) @@ -128,14 +138,9 @@ void toast_callback(const LLSD& msg){ return; } - LLSD args; - args["MESSAGE"] = msg["message"]; - args["TIME"] = msg["time"]; - args["FROM"] = msg["from"]; - 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())); + LLAvatarNameCache::get(msg["from_id"].asUUID(), + boost::bind(&on_avatar_name_cache_toast, + _1, _2, msg)); } void LLIMModel::setActiveSessionID(const LLUUID& session_id) @@ -283,7 +288,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES // no text notifications break; case P2P_SESSION: - gCacheName->getFullName(mOtherParticipantID, other_avatar_name); + gCacheName->getFullName(mOtherParticipantID, other_avatar_name); // voice if(direction == LLVoiceChannel::INCOMING_CALL) { @@ -418,13 +423,17 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo const LLSD& msg = *it; std::string from = msg[IM_FROM]; - LLUUID from_id = LLUUID::null; - if (msg[IM_FROM_ID].isUndefined()) + LLUUID from_id; + if (msg[IM_FROM_ID].isDefined()) + { + from_id = msg[IM_FROM_ID].asUUID(); + } + else { + // Legacy chat logs only wrote the legacy name, not the agent_id gCacheName->getUUID(from, from_id); } - std::string timestamp = msg[IM_TIME]; std::string text = msg[IM_TEXT]; @@ -515,6 +524,12 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline() return !mOtherParticipantIsAvatar; } +void LLIMModel::LLIMSession::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name) +{ + // if username is empty, display names isn't enabled, use the display name + mHistoryFileName = av_name.mUsername.empty() ? av_name.mDisplayName : av_name.mUsername; +} + void LLIMModel::LLIMSession::buildHistoryFileName() { mHistoryFileName = mName; @@ -533,6 +548,12 @@ void LLIMModel::LLIMSession::buildHistoryFileName() //in case of incoming ad-hoc sessions mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4); } + + // look up username to use as the log name + if (isP2P()) + { + LLAvatarNameCache::get(mOtherParticipantID, boost::bind(&LLIMModel::LLIMSession::onAvatarNameCache, this, _1, _2)); + } } //static @@ -1028,17 +1049,27 @@ void LLIMModel::sendMessage(const std::string& utf8_text, if( session == 0)//??? shouldn't really happen { LLRecentPeople::instance().add(other_participant_id); + return; } - else + // IM_SESSION_INVITE means that this is an Ad-hoc incoming chat + // (it can be also Group chat but it is checked above) + // In this case mInitialTargetIDs contains Ad-hoc session ID and it should not be added + // to Recent People to prevent showing of an item with (???)(???). See EXT-8246. + // Concrete participants will be added into this list once they sent message in chat. + if (IM_SESSION_INVITE == dialog) return; + + if (IM_SESSION_CONFERENCE_START == dialog) // outgoing ad-hoc session { - // IM_SESSION_INVITE means that this is an Ad-hoc incoming chat - // (it can be also Group chat but it is checked above) - // In this case mInitialTargetIDs contains Ad-hoc session ID and it should not be added - // to Recent People to prevent showing of an item with (???)(???). See EXT-8246. - // Concrete participants will be added into this list once they sent message in chat. - if (IM_SESSION_INVITE == dialog) return; - // Add only online members to recent (EXT-8658) - addSpeakersToRecent(im_session_id); + // Add only online members of conference to recent list (EXT-8658) + addSpeakersToRecent(im_session_id); + } + else // outgoing P2P session + { + // Add the recepient of the session. + if (!session->mInitialTargetIDs.empty()) + { + LLRecentPeople::instance().add(*(session->mInitialTargetIDs.begin())); + } } } } @@ -1764,11 +1795,23 @@ void LLOutgoingCallDialog::show(const LLSD& key) callee_name = LLTextUtil::formatPhoneNumber(callee_name); } - setTitle(callee_name); - LLSD callee_id = mPayload["other_user_id"]; - getChild<LLUICtrl>("calling")->setTextArg("[CALLEE_NAME]", callee_name); - getChild<LLUICtrl>("connecting")->setTextArg("[CALLEE_NAME]", callee_name); + // Beautification: Since you know who you called, just show display name + std::string title = callee_name; + std::string final_callee_name = callee_name; + if (mPayload["session_type"].asInteger() == LLIMModel::LLIMSession::P2P_SESSION) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(callee_id, &av_name)) + { + final_callee_name = av_name.mDisplayName; + title = av_name.getCompleteName(); + } + } + getChild<LLUICtrl>("calling")->setTextArg("[CALLEE_NAME]", final_callee_name); + getChild<LLUICtrl>("connecting")->setTextArg("[CALLEE_NAME]", final_callee_name); + + setTitle(title); // for outgoing group calls callee_id == group id == session id setIcon(callee_id, callee_id); @@ -1923,16 +1966,21 @@ BOOL LLIncomingCallDialog::postBuild() if (caller_name == "anonymous") { caller_name = getString("anonymous"); + setCallerName(caller_name, caller_name, call_type); } else if (!is_avatar) { caller_name = LLTextUtil::formatPhoneNumber(caller_name); + setCallerName(caller_name, caller_name, call_type); + } + else + { + // Get the full name information + LLAvatarNameCache::get(caller_id, + boost::bind(&LLIncomingCallDialog::onAvatarNameCache, + this, _1, _2, call_type)); } - setTitle(caller_name + " " + call_type); - - LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name"); - caller_name_widget->setValue(caller_name + " " + call_type); setIcon(session_id, caller_id); childSetAction("Accept", onAccept, this); @@ -1960,6 +2008,24 @@ BOOL LLIncomingCallDialog::postBuild() return TRUE; } +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"); + caller_name_widget->setValue(ui_label + " " + call_type); +} + +void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + const std::string& call_type) +{ + std::string title = av_name.getCompleteName(); + setCallerName(title, av_name.mDisplayName, call_type); +} void LLIncomingCallDialog::onOpen(const LLSD& key) { @@ -2067,8 +2133,11 @@ void LLIncomingCallDialog::processCallResponse(S32 response) } else { - if (gCacheName->getFullName(caller_id, correct_session_name)) + // *NOTE: really should be using callbacks here + LLAvatarName av_name; + if (LLAvatarNameCache::get(caller_id, &av_name)) { + correct_session_name = av_name.mDisplayName + " (" + av_name.mUsername + ")"; correct_session_name.append(ADHOC_NAME_SUFFIX); } } @@ -2589,7 +2658,8 @@ void LLIMMgr::inviteToSession( { if (caller_name.empty()) { - gCacheName->get(caller_id, FALSE, boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3, _4)); + gCacheName->get(caller_id, false, // voice + boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3)); } else { @@ -2599,9 +2669,9 @@ void LLIMMgr::inviteToSession( } } -void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group) { - payload["caller_name"] = first + " " + last; + payload["caller_name"] = name; payload["session_name"] = payload["caller_name"].asString(); std::string notify_box_type = payload["notify_box_type"].asString(); @@ -2822,13 +2892,14 @@ void LLIMMgr::noteOfflineUsers( for(S32 i = 0; i < count; ++i) { info = at.getBuddyInfo(ids.get(i)); - std::string first, last; - if(info && !info->isOnline() - && gCacheName->getName(ids.get(i), first, last)) + LLAvatarName av_name; + if (info + && !info->isOnline() + && LLAvatarNameCache::get(ids.get(i), &av_name)) { LLUIString offline = LLTrans::getString("offline_message"); - offline.setArg("[FIRST]", first); - offline.setArg("[LAST]", last); + // Use display name only because this user is your friend + offline.setArg("[NAME]", av_name.mDisplayName); im_model.proccessOnlineOfflineNotification(session_id, offline); } } diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index f7a4406f00..3da4465862 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -35,7 +35,7 @@ #include "llvoicechannel.h" - +class LLAvatarName; class LLFriendObserver; class LLCallDialogManager; class LLIMSpeakerMgr; @@ -98,6 +98,8 @@ public: /** ad-hoc sessions involve sophisticated chat history file naming schemes */ void buildHistoryFileName(); + void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name); + //*TODO make private static std::string generateHash(const std::set<LLUUID>& sorted_uuids); @@ -457,7 +459,7 @@ private: void processIMTypingCore(const LLIMInfo* im_info, BOOL typing); - static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); + 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 notifyObserverSessionRemoved(const LLUUID& session_id); @@ -539,6 +541,13 @@ public: static void onStartIM(void* user_data); private: + void setCallerName(const std::string& ui_title, + const std::string& ui_label, + const std::string& call_type); + void onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + const std::string& call_type); + /*virtual*/ void onLifetimeExpired(); void processCallResponse(S32 response); }; diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index b367d68b02..29dcb2c4d3 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -31,6 +31,7 @@ #include "llagent.h" #include "llagentdata.h" #include "llavataractions.h" +#include "llavatarnamecache.h" #include "llavatarpropertiesprocessor.h" #include "llcallingcard.h" #include "lldateutil.h" @@ -51,6 +52,7 @@ #include "llfloater.h" #include "llfloaterreg.h" #include "llmenubutton.h" +#include "lltextbox.h" #include "lltooltip.h" // positionViewNearMouse() #include "lltrans.h" #include "lluictrl.h" @@ -137,17 +139,13 @@ private: // Is used to determine if "Add friend" option should be enabled in gear menu bool isNotFriend(); - // Callback for gCacheName to look up avatar name - void nameUpdatedCallback( - const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group); + void onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name); private: LLUUID mAvatarID; // Need avatar name information to spawn friend add request - std::string mAvatarName; + LLAvatarName mAvatarName; // an in-flight request for avatar properties from LLAvatarPropertiesProcessor // is represented by this object LLFetchAvatarData* mPropertiesRequest; @@ -330,6 +328,8 @@ void LLInspectAvatar::requestUpdate() // Clear out old data so it doesn't flash between old and new getChild<LLUICtrl>("user_name")->setValue(""); + getChild<LLUICtrl>("user_name_small")->setValue(""); + getChild<LLUICtrl>("user_slid")->setValue(""); getChild<LLUICtrl>("user_subtitle")->setValue(""); getChild<LLUICtrl>("user_details")->setValue(""); @@ -367,9 +367,9 @@ void LLInspectAvatar::requestUpdate() getChild<LLUICtrl>("avatar_icon")->setValue(LLSD(mAvatarID) ); - gCacheName->get(mAvatarID, FALSE, - boost::bind(&LLInspectAvatar::nameUpdatedCallback, - this, _1, _2, _3, _4)); + LLAvatarNameCache::get(mAvatarID, + boost::bind(&LLInspectAvatar::onAvatarNameCache, + this, _1, _2)); } void LLInspectAvatar::processAvatarData(LLAvatarData* data) @@ -556,7 +556,7 @@ void LLInspectAvatar::updateVolumeSlider() LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn"); - bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden"); + bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); mute_btn->setEnabled( !is_linden); mute_btn->setValue( is_muted ); @@ -587,7 +587,7 @@ void LLInspectAvatar::onClickMuteVolume() LLMuteList* mute_list = LLMuteList::getInstance(); bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat); - LLMute mute(mAvatarID, mAvatarName, LLMute::AGENT); + LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT); if (!is_muted) { mute_list->add(mute, LLMute::flagVoiceChat); @@ -606,22 +606,36 @@ void LLInspectAvatar::onVolumeChange(const LLSD& data) LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume); } -void LLInspectAvatar::nameUpdatedCallback( - const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) +void LLInspectAvatar::onAvatarNameCache( + const LLUUID& agent_id, + const LLAvatarName& av_name) { - if (id == mAvatarID) + if (agent_id == mAvatarID) { - mAvatarName = first + " " + last; - getChild<LLUICtrl>("user_name")->setValue(LLSD(mAvatarName) ); + 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); + mAvatarName = av_name; + + // 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 ); + + } + } } void LLInspectAvatar::onClickAddFriend() { - LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName); + LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName.getLegacyName()); closeFloater(); } @@ -689,7 +703,7 @@ void LLInspectAvatar::onClickShare() void LLInspectAvatar::onToggleMute() { - LLMute mute(mAvatarID, mAvatarName, LLMute::AGENT); + LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT); if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName)) { @@ -706,7 +720,7 @@ void LLInspectAvatar::onToggleMute() void LLInspectAvatar::onClickReport() { - LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName); + LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName()); closeFloater(); } @@ -730,17 +744,17 @@ void LLInspectAvatar::onClickZoomIn() void LLInspectAvatar::onClickFindOnMap() { - gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName); + gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName.mDisplayName); LLFloaterReg::showInstance("world_map"); } bool LLInspectAvatar::enableMute() { - bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden"); + bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); bool is_self = mAvatarID == gAgent.getID(); - if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName)) + if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName())) { return true; } @@ -752,10 +766,10 @@ bool LLInspectAvatar::enableMute() bool LLInspectAvatar::enableUnmute() { - bool is_linden = LLStringUtil::endsWith(mAvatarName, " Linden"); + bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden"); bool is_self = mAvatarID == gAgent.getID(); - if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName)) + if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName())) { return true; } diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp index 214b135bc1..76617b55bf 100644 --- a/indra/newview/llinspectgroup.cpp +++ b/indra/newview/llinspectgroup.cpp @@ -78,9 +78,8 @@ public: // Callback for gCacheName to look up group name // Faster than waiting for group properties to return void nameUpdatedCallback(const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group); + const std::string& name, + bool is_group); // Button/menu callbacks void onClickViewProfile(); @@ -219,21 +218,19 @@ void LLInspectGroup::requestUpdate() mPropertiesRequest = new LLFetchGroupData(mGroupID, this); // Name lookup will be faster out of cache, use that - gCacheName->get(mGroupID, TRUE, + gCacheName->getGroup(mGroupID, boost::bind(&LLInspectGroup::nameUpdatedCallback, - this, _1, _2, _3, _4)); + this, _1, _2, _3)); } void LLInspectGroup::nameUpdatedCallback( const LLUUID& id, - const std::string& first, - const std::string& last, - BOOL is_group) + const std::string& name, + bool is_group) { if (id == mGroupID) { - // group names are returned as a first name - getChild<LLUICtrl>("group_name")->setValue(LLSD(first) ); + getChild<LLUICtrl>("group_name")->setValue( LLSD(name) ); } // Otherwise possibly a request for an older inspector, ignore it diff --git a/indra/newview/llinspectremoteobject.cpp b/indra/newview/llinspectremoteobject.cpp index e956b3b8de..bf6cf52298 100644 --- a/indra/newview/llinspectremoteobject.cpp +++ b/indra/newview/llinspectremoteobject.cpp @@ -60,12 +60,12 @@ public: private: void update(); - static void nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data); + void onNameCache(const LLUUID& id, const std::string& name, bool is_group); private: LLUUID mObjectID; LLUUID mOwnerID; - std::string mOwner; + std::string mOwnerLegacyName; std::string mSLurl; std::string mName; bool mGroupOwned; @@ -75,7 +75,7 @@ LLInspectRemoteObject::LLInspectRemoteObject(const LLSD& sd) : LLInspect(LLSD()), mObjectID(NULL), mOwnerID(NULL), - mOwner(""), + mOwnerLegacyName(), mSLurl(""), mName(""), mGroupOwned(false) @@ -112,10 +112,11 @@ void LLInspectRemoteObject::onOpen(const LLSD& data) mSLurl = data["slurl"].asString(); // work out the owner's name - mOwner = ""; + mOwnerLegacyName = ""; if (gCacheName) { - gCacheName->get(mOwnerID, mGroupOwned, nameCallback, this); + gCacheName->get(mOwnerID, mGroupOwned, // muting + boost::bind(&LLInspectRemoteObject::onNameCache, this, _1, _2, _3)); } // update the inspector with the current object state @@ -144,7 +145,7 @@ void LLInspectRemoteObject::onClickMap() void LLInspectRemoteObject::onClickBlock() { LLMute::EType mute_type = mGroupOwned ? LLMute::GROUP : LLMute::AGENT; - LLMute mute(mOwnerID, mOwner, mute_type); + LLMute mute(mOwnerID, mOwnerLegacyName, mute_type); LLMuteList::getInstance()->add(mute); LLPanelBlockedList::showPanelAndSelect(mute.mID); closeFloater(); @@ -155,16 +156,10 @@ void LLInspectRemoteObject::onClickClose() closeFloater(); } -//static -void LLInspectRemoteObject::nameCallback(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data) +void LLInspectRemoteObject::onNameCache(const LLUUID& id, const std::string& name, bool is_group) { - LLInspectRemoteObject *self = (LLInspectRemoteObject*)data; - self->mOwner = first; - if (!last.empty()) - { - self->mOwner += " " + last; - } - self->update(); + mOwnerLegacyName = name; + update(); } void LLInspectRemoteObject::update() @@ -174,7 +169,7 @@ void LLInspectRemoteObject::update() getChild<LLUICtrl>("object_name")->setValue("<nolink>" + mName + "</nolink>"); // show the object's owner - click it to show profile - std::string owner = mOwner; + std::string owner; if (! mOwnerID.isNull()) { if (mGroupOwned) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 569dfc08e2..b15dcd993a 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -29,6 +29,7 @@ // external projects #include "lltransfersourceasset.h" +#include "llavatarnamecache.h" // IDEVO #include "llagent.h" #include "llagentcamera.h" @@ -3503,6 +3504,13 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act { std::string callingcard_name; gCacheName->getFullName(item->getCreatorUUID(), callingcard_name); + // IDEVO + LLAvatarName av_name; + if (LLAvatarNameCache::useDisplayNames() + && LLAvatarNameCache::get(item->getCreatorUUID(), &av_name)) + { + callingcard_name = av_name.mDisplayName + " (" + av_name.mUsername + ")"; + } LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID()); if (session_id != LLUUID::null) { diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index d714cae872..1527f8f4c9 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -224,7 +224,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) LLLineEditor::Params params = p.combo_editor; params.rect(text_entry_rect); params.default_text(LLStringUtil::null); - params.max_length_bytes(p.max_chars); + params.max_length.bytes(p.max_chars); params.keystroke_callback(boost::bind(&LLLocationInputCtrl::onTextEntry, this, _1)); params.commit_on_focus_lost(false); params.follows.flags(FOLLOWS_ALL); diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index f5f4feeab3..c8fd1e1d9a 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -26,13 +26,18 @@ #include "llviewerprecompiledheaders.h" +#include "lllogchat.h" + +// viewer includes #include "llagent.h" #include "llagentui.h" -#include "lllogchat.h" #include "lltrans.h" #include "llviewercontrol.h" +// library includes +#include "llchat.h" #include "llinstantmessage.h" +#include "llsdserialize.h" #include "llsingleton.h" // for LLSingleton #include <boost/algorithm/string/trim.hpp> @@ -56,12 +61,13 @@ const S32 LOG_RECALL_SIZE = 2048; -const static std::string IM_TIME("time"); -const static std::string IM_TEXT("message"); -const static std::string IM_FROM("from"); -const static std::string IM_FROM_ID("from_id"); -const static std::string IM_SEPARATOR(": "); +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 IM_SOURCE_TYPE("source_type"); +const static std::string IM_SEPARATOR(": "); const static std::string NEW_LINE("\n"); const static std::string NEW_LINE_SPACE_PREFIX("\n "); const static std::string TWO_SPACES(" "); @@ -184,7 +190,8 @@ std::string LLLogChat::makeLogFileName(std::string filename) { filename = cleanFileName(filename); filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename); - filename += ".txt"; + // new files are llsd notation format + filename += ".llsd"; return filename; } @@ -234,6 +241,18 @@ void LLLogChat::saveHistory(const std::string& filename, const LLUUID& from_id, const std::string& line) { + LLChat chat; + chat.mText = line; + chat.mFromName = from; + chat.mFromID = from_id; + // default to being from an agent + chat.mSourceType = CHAT_SOURCE_AGENT; + saveHistory(filename, chat); +} + +//static +void LLLogChat::saveHistory(const std::string& filename, const LLChat& chat) +{ std::string tmp_filename = filename; LLStringUtil::trim(tmp_filename); if (tmp_filename.empty()) @@ -254,89 +273,27 @@ void LLLogChat::saveHistory(const std::string& filename, LLSD item; if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) - item["time"] = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")); + item[IM_TIME] = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")); - item["from_id"] = from_id; - item["message"] = line; + item[IM_FROM_ID] = chat.mFromID; + item[IM_TEXT] = chat.mText; + item[IM_SOURCE_TYPE] = chat.mSourceType; //adding "Second Life:" for all system messages to make chat log history parsing more reliable - if (from.empty() && from_id.isNull()) + if (chat.mFromName.empty() && chat.mFromID.isNull()) { - item["from"] = SYSTEM_FROM; + item[IM_FROM] = SYSTEM_FROM; } else { - item["from"] = from; + item[IM_FROM] = chat.mFromName; } - file << LLChatLogFormatter(item) << std::endl; + file << LLSDOStreamer<LLSDNotationFormatter>(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 - { - 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); - } -} - void append_to_last_message(std::list<LLSD>& messages, const std::string& line) { if (!messages.size()) return; @@ -346,6 +303,7 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line) messages.back()[IM_TEXT] = im_text; } +// static void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages) { if (file_name.empty()) @@ -409,53 +367,25 @@ void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& me fclose(fptr); } -//*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>" -void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const -{ - if (!im.isMap()) - { - llwarning("invalid LLSD type of an instant message", 0); - return; - } - - if (im[IM_TIME].isDefined()) - { - std::string timestamp = im[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()) - { - std::string from = im[IM_FROM].asString(); - boost::trim(from); - if (from.size()) - { - ostr << from << IM_SEPARATOR; - } - } - - if (im[IM_TEXT].isDefined()) - { - std::string im_text = im[IM_TEXT].asString(); - - //multilined text will be saved with prepended spaces - boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX); - ostr << im_text; - } -} - -bool LLChatLogParser::parse(std::string& raw, LLSD& im) +// static +bool LLChatLogParser::parse(const std::string& raw, LLSD& im) { if (!raw.length()) return false; im = LLSD::emptyMap(); + // In Viewer 2.1 we added UUID to chat/IM logging so we can look up + // display names + if (raw[0] == '{') + { + // ...this is a viewer 2.1, new-style LLSD notation format log + std::istringstream raw_stream(raw); + LLPointer<LLSDParser> parser = new LLSDNotationParser(); + S32 count = parser->parse(raw_stream, im, raw.length()); + // expect several map items per parsed line + return (count != LLSDParser::PARSE_FAILURE); + } + //matching a timestamp boost::match_results<std::string::const_iterator> matches; if (!boost::regex_match(raw, matches, TIMESTAMP_AND_STUFF)) return false; diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index e544bb2d45..8b1cc3484f 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -24,10 +24,11 @@ * $/LicenseInfo$ */ - #ifndef LL_LLLOGCHAT_H #define LL_LLLOGCHAT_H +class LLChat; + class LLLogChat { public: @@ -40,49 +41,22 @@ public: }; static std::string timestamp(bool withdate = false); static std::string makeLogFileName(std::string(filename)); + + // Log a single line item to the appropriate chat file + static void saveHistory(const std::string& filename, const LLChat& chat); + + // Prefer the above version - it saves more metadata about the item static void saveHistory(const std::string& filename, const std::string& from, const LLUUID& from_id, const std::string& line); - /** @deprecated @see loadAllHistory() */ - static void loadHistory(const std::string& filename, - void (*callback)(ELogLineType, const LLSD&, void*), - void* userdata); - static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages); private: static std::string cleanFileName(std::string filename); }; /** - * Formatter for the plain text chat log files - */ -class LLChatLogFormatter -{ -public: - LLChatLogFormatter(const LLSD& im) : mIM(im) {} - virtual ~LLChatLogFormatter() {}; - - friend std::ostream& operator<<(std::ostream& str, const LLChatLogFormatter& formatter) - { - formatter.format(formatter.mIM, str); - return str; - } - -protected: - - /** - * Format an instant message to a stream - * Timestamps and sender names are required - * New lines of multilined messages are prepended with a space - */ - void format(const LLSD& im, std::ostream& ostr) const; - - LLSD mIM; -}; - -/** * Parser for the plain text chat log files */ class LLChatLogParser @@ -100,11 +74,18 @@ public: * * @return false if failed to parse mandatory data - message text */ - static bool parse(std::string& raw, LLSD& im); + static bool parse(const std::string& raw, LLSD& im); protected: LLChatLogParser(); virtual ~LLChatLogParser() {}; }; +// 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 IM_SOURCE_TYPE; //("source_type"); + #endif diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 3def135fb4..029e700c4c 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -139,6 +139,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia requested_options.append("initial-outfit"); requested_options.append("gestures"); + requested_options.append("display_names"); requested_options.append("event_categories"); requested_options.append("event_notifications"); requested_options.append("classified_categories"); diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index eb00663d3f..af8fdb17cf 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -112,9 +112,8 @@ LLMute::LLMute(const LLUUID& id, const std::string& name, EType type, U32 flags) LLNameValue* lastname = mute_object->getNVPair("LastName"); if (firstname && lastname) { - mName.assign( firstname->getString() ); - mName.append(" "); - mName.append( lastname->getString() ); + mName = LLCacheName::buildFullName( + firstname->getString(), lastname->getString()); } mType = mute_object->isAvatar() ? AGENT : OBJECT; } @@ -410,7 +409,7 @@ void LLMuteList::updateRemove(const LLMute& mute) gAgent.sendReliableMessage(); } -void notify_automute_callback(const LLUUID& agent_id, const std::string& first_name, const std::string& last_name, BOOL is_group, LLMuteList::EAutoReason reason) +void notify_automute_callback(const LLUUID& agent_id, const std::string& full_name, bool is_group, LLMuteList::EAutoReason reason) { std::string notif_name; switch (reason) @@ -428,8 +427,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n } LLSD args; - args["FIRST"] = first_name; - args["LAST"] = last_name; + args["NAME"] = full_name; LLNotificationPtr notif_ptr = LLNotifications::instance().add(notif_name, args, LLSD()); if (notif_ptr) @@ -444,7 +442,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n } -BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, const std::string& first_name, const std::string& last_name) +BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason) { BOOL removed = FALSE; @@ -454,24 +452,17 @@ BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason, co removed = TRUE; remove(automute); - if (first_name.empty() && last_name.empty()) - { - std::string cache_first, cache_last; - if (gCacheName->getName(agent_id, cache_first, cache_last)) + std::string full_name; + if (gCacheName->getFullName(agent_id, full_name)) { // name in cache, call callback directly - notify_automute_callback(agent_id, cache_first, cache_last, FALSE, reason); + notify_automute_callback(agent_id, full_name, false, reason); } else { // not in cache, lookup name from cache - gCacheName->get(agent_id, FALSE, boost::bind(¬ify_automute_callback, _1, _2, _3, _4, reason)); - } - } - else - { - // call callback directly - notify_automute_callback(agent_id, first_name, last_name, FALSE, reason); + gCacheName->get(agent_id, false, + boost::bind(¬ify_automute_callback, _1, _2, _3, reason)); } } diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 62c72dd9c6..04e1570081 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -63,7 +63,7 @@ public: public: LLUUID mID; // agent or object id - std::string mName; // agent or object name + std::string mName; // agent or object name, does not store last name "Resident" EType mType; // needed for UI display of existing mutes U32 mFlags; // flags pertaining to this mute entry }; @@ -96,7 +96,7 @@ public: // Remove both normal and legacy mutes, for any or all properties. BOOL remove(const LLMute& mute, U32 flags = 0); - BOOL autoRemove(const LLUUID& agent_id, const EAutoReason reason, const std::string& first_name = LLStringUtil::null, const std::string& last_name = LLStringUtil::null); + BOOL autoRemove(const LLUUID& agent_id, const EAutoReason reason); // Name is required to test against legacy text-only mutes. BOOL isMuted(const LLUUID& id, const std::string& name = LLStringUtil::null, U32 flags = 0) const; diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp index c31da84f78..1099316a19 100644 --- a/indra/newview/llnamebox.cpp +++ b/indra/newview/llnamebox.cpp @@ -82,26 +82,15 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group) setText(mInitialValue); } -void LLNameBox::refresh(const LLUUID& id, const std::string& firstname, - const std::string& lastname, BOOL is_group) +void LLNameBox::refresh(const LLUUID& id, const std::string& full_name, bool is_group) { if (id == mNameID) { - std::string name; - if (!is_group) - { - name = firstname + " " + lastname; - } - else - { - name = firstname; - } - setName(name, is_group); + setName(full_name, is_group); } } -void LLNameBox::refreshAll(const LLUUID& id, const std::string& firstname, - const std::string& lastname, BOOL is_group) +void LLNameBox::refreshAll(const LLUUID& id, const std::string& full_name, bool is_group) { std::set<LLNameBox*>::iterator it; for (it = LLNameBox::sInstances.begin(); @@ -109,7 +98,7 @@ void LLNameBox::refreshAll(const LLUUID& id, const std::string& firstname, ++it) { LLNameBox* box = *it; - box->refresh(id, firstname, lastname, is_group); + box->refresh(id, full_name, is_group); } } diff --git a/indra/newview/llnamebox.h b/indra/newview/llnamebox.h index dbabcc0e52..76e8551268 100644 --- a/indra/newview/llnamebox.h +++ b/indra/newview/llnamebox.h @@ -53,10 +53,9 @@ public: void setNameID(const LLUUID& name_id, BOOL is_group); - void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); + void refresh(const LLUUID& id, const std::string& full_name, bool is_group); - static void refreshAll(const LLUUID& id, const std::string& firstname, - const std::string& lastname, BOOL is_group); + static void refreshAll(const LLUUID& id, const std::string& full_name, bool is_group); protected: LLNameBox (const Params&); diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp index f53252b614..b3b1ff7c06 100644 --- a/indra/newview/llnameeditor.cpp +++ b/indra/newview/llnameeditor.cpp @@ -75,26 +75,15 @@ void LLNameEditor::setNameID(const LLUUID& name_id, BOOL is_group) setText(name); } -void LLNameEditor::refresh(const LLUUID& id, const std::string& firstname, - const std::string& lastname, BOOL is_group) +void LLNameEditor::refresh(const LLUUID& id, const std::string& full_name, bool is_group) { if (id == mNameID) { - std::string name; - if (!is_group) - { - name = firstname + " " + lastname; - } - else - { - name = firstname; - } - setText(name); + setText(full_name); } } -void LLNameEditor::refreshAll(const LLUUID& id, const std::string& firstname, - const std::string& lastname, BOOL is_group) +void LLNameEditor::refreshAll(const LLUUID& id, const std::string& full_name, bool is_group) { std::set<LLNameEditor*>::iterator it; for (it = LLNameEditor::sInstances.begin(); @@ -102,7 +91,7 @@ void LLNameEditor::refreshAll(const LLUUID& id, const std::string& firstname, ++it) { LLNameEditor* box = *it; - box->refresh(id, firstname, lastname, is_group); + box->refresh(id, full_name, is_group); } } diff --git a/indra/newview/llnameeditor.h b/indra/newview/llnameeditor.h index d8360f9f4b..b8c4a6042e 100644 --- a/indra/newview/llnameeditor.h +++ b/indra/newview/llnameeditor.h @@ -59,10 +59,9 @@ public: void setNameID(const LLUUID& name_id, BOOL is_group); - void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); + void refresh(const LLUUID& id, const std::string& full_name, bool is_group); - static void refreshAll(const LLUUID& id, const std::string& firstname, - const std::string& lastname, BOOL is_group); + static void refreshAll(const LLUUID& id, const std::string& full_name, bool is_group); // Take/return agent UUIDs diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 6521ae3b1e..38100aa6c5 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -30,6 +30,7 @@ #include <boost/tokenizer.hpp> +#include "llavatarnamecache.h" #include "llcachename.h" #include "llfloaterreg.h" #include "llinventory.h" @@ -38,6 +39,7 @@ #include "llscrolllistcolumn.h" #include "llsdparam.h" #include "lltooltip.h" +#include "lltrans.h" static LLDefaultChildRegistry::Register<LLNameListCtrl> r("name_list"); @@ -52,7 +54,8 @@ void LLNameListCtrl::NameTypeNames::declareValues() LLNameListCtrl::Params::Params() : name_column(""), - allow_calling_card_drop("allow_calling_card_drop", false) + allow_calling_card_drop("allow_calling_card_drop", false), + short_names("short_names", false) { name = "name_list"; } @@ -61,7 +64,8 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p) : LLScrollListCtrl(p), mNameColumnIndex(p.name_column.column_index), mNameColumn(p.name_column.column_name), - mAllowCallingCardDrop(p.allow_calling_card_drop) + mAllowCallingCardDrop(p.allow_calling_card_drop), + mShortNames(p.short_names) {} // public @@ -292,10 +296,24 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( break; case INDIVIDUAL: { - std::string name; - if (gCacheName->getFullName(id, name)) + LLAvatarName av_name; + if (id.isNull()) { - fullname = name; + fullname = LLTrans::getString("AvatarNameNobody"); + } + else if (LLAvatarNameCache::get(id, &av_name)) + { + if (mShortNames) + fullname = av_name.mDisplayName; + else + fullname = av_name.getCompleteName(); + } + else + { + // ...schedule a callback + LLAvatarNameCache::get(id, + boost::bind(&LLNameListCtrl::onAvatarNameCache, + this, _1, _2)); } break; } @@ -350,34 +368,25 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) } } -// public -void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first, - const std::string& last, BOOL is_group) +void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name) { - //llinfos << "LLNameListCtrl::refresh " << id << " '" << first << " " - // << last << "'" << llendl; - - std::string fullname; - if (!is_group) - { - fullname = first + " " + last; - } + std::string name; + if (mShortNames) + name = av_name.mDisplayName; else - { - fullname = first; - } + name = av_name.getCompleteName(); - // TODO: scan items for that ID, fix if necessary item_list::iterator iter; for (iter = getItemList().begin(); iter != getItemList().end(); iter++) { LLScrollListItem* item = *iter; - if (item->getUUID() == id) + if (item->getUUID() == agent_id) { LLScrollListCell* cell = item->getColumn(mNameColumnIndex); if (cell) { - cell->setValue(fullname); + cell->setValue(name); } } } @@ -386,19 +395,6 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first, } -// static -void LLNameListCtrl::refreshAll(const LLUUID& id, const std::string& first, - const std::string& last, BOOL is_group) -{ - LLInstanceTrackerScopedGuard guard; - LLInstanceTracker<LLNameListCtrl>::instance_iter it; - for (it = guard.beginInstances(); it != guard.endInstances(); ++it) - { - LLNameListCtrl& ctrl = *it; - ctrl.refresh(id, first, last, is_group); - } -} - void LLNameListCtrl::updateColumns() { LLScrollListCtrl::updateColumns(); diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 981e3df16b..6805630ef1 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -31,6 +31,7 @@ #include "llscrolllistctrl.h" +class LLAvatarName; class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl> @@ -74,6 +75,7 @@ public: { Optional<NameColumn> name_column; Optional<bool> allow_calling_card_drop; + Optional<bool> short_names; Params(); }; @@ -99,11 +101,6 @@ public: void removeNameItem(const LLUUID& agent_id); - void refresh(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); - - static void refreshAll(const LLUUID& id, const std::string& firstname, - const std::string& lastname, BOOL is_group); - // LLView interface /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, @@ -118,11 +115,13 @@ public: /*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); private: S32 mNameColumnIndex; std::string mNameColumn; BOOL mAllowCallingCardDrop; + bool mShortNames; // display name only, no SLID }; /** diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 28aea7ae3d..f16cc4cef4 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -55,12 +55,6 @@ static const S32 RESIZE_BAR_THICKNESS = 3; -const static std::string IM_TIME("time"); -const static std::string IM_TEXT("message"); -const static std::string IM_FROM("from"); -const static std::string IM_FROM_ID("from_id"); - - LLNearbyChat::LLNearbyChat(const LLSD& key) : LLDockableFloater(NULL, false, false, key) ,mChatHistory(NULL) @@ -185,7 +179,7 @@ void LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args) if (gSavedPerAccountSettings.getBOOL("LogNearbyChat")) { - LLLogChat::saveHistory("chat", chat.mFromName, chat.mFromID, chat.mText); + LLLogChat::saveHistory("chat", chat); } } @@ -275,8 +269,12 @@ void LLNearbyChat::loadHistory() const LLSD& msg = *it; std::string from = msg[IM_FROM]; - LLUUID from_id = LLUUID::null; - if (msg[IM_FROM_ID].isUndefined()) + LLUUID from_id; + if (msg[IM_FROM_ID].isDefined()) + { + from_id = msg[IM_FROM_ID].asUUID(); + } + else { gCacheName->getUUID(from, from_id); } @@ -288,11 +286,14 @@ void LLNearbyChat::loadHistory() chat.mTimeStr = msg[IM_TIME].asString(); chat.mChatStyle = CHAT_STYLE_HISTORY; - chat.mSourceType = CHAT_SOURCE_AGENT; - if (from_id.isNull() && SYSTEM_FROM == from) + if (msg.has(IM_SOURCE_TYPE)) + { + S32 source_type = msg[IM_SOURCE_TYPE].asInteger(); + chat.mSourceType = (EChatSourceType)source_type; + } + else if (from_id.isNull() && SYSTEM_FROM == from) { chat.mSourceType = CHAT_SOURCE_SYSTEM; - } else if (from_id.isNull()) { diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 6db8001d57..f084002385 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2001-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 @@ -31,6 +31,7 @@ // Library includes (should move below) #include "indra_constants.h" +#include "llavatarnamecache.h" #include "llmath.h" #include "llfloaterreg.h" #include "llfocusmgr.h" @@ -568,56 +569,36 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask ) return FALSE; } - std::string avatar_name; - if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, avatar_name)) + // If the cursor is near an avatar on the minimap, a mini-inspector will be + // shown for the avatar, instead of the normal map tooltip. + if (handleToolTipAgent(mClosestAgentToCursor)) { - // only show tooltip if same inspector not already open - LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar"); - if (!existing_inspector - || !existing_inspector->getVisible() - || existing_inspector->getKey()["avatar_id"].asUUID() != mClosestAgentToCursor) - { - LLInspector::Params p; - p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); - p.message(avatar_name); - p.image.name("Inspector_I"); - p.click_callback(boost::bind(showAvatarInspector, mClosestAgentToCursor)); - p.visible_time_near(6.f); - p.visible_time_far(3.f); - p.delay_time(0.35f); - p.wrap(false); - - LLToolTipMgr::instance().show(p); - } return TRUE; } - LLStringUtil::format_map_t args; - LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); - if( region ) - { - args["[REGION]"] = region->getName() + "\n"; - } - else - { - args["[REGION]"] = ""; - } - - std::string msg = mToolTipMsg; - LLStringUtil::format(msg, args); - LLRect sticky_rect; - // set sticky_rect - if (region) + std::string region_name; + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); + if(region) { + // set sticky_rect S32 SLOP = 4; - localPointToScreen( - x - SLOP, y - SLOP, - &(sticky_rect.mLeft), &(sticky_rect.mBottom) ); + localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; + + region_name = region->getName(); + if (!region_name.empty()) + { + region_name += "\n"; + } } + LLStringUtil::format_map_t args; + args["[REGION]"] = region_name; + std::string msg = mToolTipMsg; + LLStringUtil::format(msg, args); + LLToolTipMgr::instance().show(LLToolTip::Params() .message(msg) .sticky_rect(sticky_rect)); @@ -625,6 +606,35 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask ) return TRUE; } +BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id) +{ + LLAvatarName av_name; + if (avatar_id.isNull() || !LLAvatarNameCache::get(avatar_id, &av_name)) + { + return FALSE; + } + + // only show tooltip if same inspector not already open + LLFloater* existing_inspector = LLFloaterReg::findInstance("inspect_avatar"); + if (!existing_inspector + || !existing_inspector->getVisible() + || existing_inspector->getKey()["avatar_id"].asUUID() != avatar_id) + { + LLInspector::Params p; + p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); + p.message(av_name.getCompleteName()); + p.image.name("Inspector_I"); + p.click_callback(boost::bind(showAvatarInspector, avatar_id)); + p.visible_time_near(6.f); + p.visible_time_far(3.f); + p.delay_time(0.35f); + p.wrap(false); + + LLToolTipMgr::instance().show(p); + } + return TRUE; +} + // static void LLNetMap::showAvatarInspector(const LLUUID& avatar_id) { diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index e25ada4c95..650bce0da4 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -86,13 +86,14 @@ private: void drawTracking( const LLVector3d& pos_global, const LLColor4& color, BOOL draw_arrow = TRUE); + BOOL handleToolTipAgent(const LLUUID& avatar_id); static void showAvatarInspector(const LLUUID& avatar_id); void createObjectImage(); -private: static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop); +private: bool mUpdateNow; LLUIColor mBackgroundColor; diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp index 4231a73af1..70d588db52 100644 --- a/indra/newview/llnotificationhandlerutil.cpp +++ b/indra/newview/llnotificationhandlerutil.cpp @@ -107,8 +107,11 @@ void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif) } const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"), - REVOKED_MODIFY_RIGHTS("RevokedModifyRights"), OBJECT_GIVE_ITEM( - "ObjectGiveItem"), PAYMENT_RECIVED("PaymentRecived"), + 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"), @@ -130,7 +133,8 @@ bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification) { return GRANTED_MODIFY_RIGHTS == notification->getName() || REVOKED_MODIFY_RIGHTS == notification->getName() - || PAYMENT_RECIVED == notification->getName() + || PAYMENT_RECEIVED == notification->getName() + || PAYMENT_SENT == notification->getName() || OFFER_FRIENDSHIP == notification->getName() || FRIENDSHIP_OFFERED == notification->getName() || FRIENDSHIP_ACCEPTED == notification->getName() @@ -311,34 +315,35 @@ 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) + +{ + LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, full_name, from_name, message, + from_id, LLUUID()); +} + // static void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only) { - const std::string name = LLHandlerUtil::getSubstitutionName(notification); - - const std::string& session_name = notification->getPayload().has( - "SESSION_NAME") ? notification->getPayload()["SESSION_NAME"].asString() : name; - // 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"]; - //there still appears a log history file with weird name " .txt" - if (" " == session_name || "{waiting}" == session_name || "{nobody}" == session_name) + if (from_id.isNull()) { - llwarning("Weird session name (" + session_name + ") for notification " + notification->getName(), 666) + llwarns << " from_id for notification " << notification->getName() << " is null " << llendl; + return; } if(to_file_only) { - logToIM(IM_NOTHING_SPECIAL, session_name, "", notification->getMessage(), - LLUUID(), LLUUID()); + gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID())); } else { - logToIM(IM_NOTHING_SPECIAL, session_name, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), - from_id, LLUUID()); + gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id)); } } } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index db9d386b6b..33c968bf00 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -38,6 +38,7 @@ #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "lllistcontextmenu.h" +#include "llmenubutton.h" #include "llnotificationsutil.h" #include "lloutfitobserver.h" #include "llsidetray.h" @@ -126,18 +127,6 @@ public: llassert(mMenu); } - void show(LLView* spawning_view) - { - if (!mMenu) return; - - updateItemsVisibility(); - mMenu->buildDrawLabels(); - mMenu->updateParent(LLMenuGL::sMenuContainer); - S32 menu_x = 0; - S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight(); - LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y); - } - void updateItemsVisibility() { if (!mMenu) return; @@ -148,6 +137,8 @@ public: mMenu->arrangeAndClear(); // update menu height } + LLMenuGL* getMenu() { return mMenu; } + private: const LLUUID& getSelectedOutfitID() { @@ -386,6 +377,11 @@ BOOL LLOutfitsList::postBuild() mAccordion = getChild<LLAccordionCtrl>("outfits_accordion"); mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR); + LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); + + menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenu::updateItemsVisibility, mGearMenu)); + menu_gear_btn->setMenu(mGearMenu->getMenu()); + return TRUE; } @@ -727,13 +723,6 @@ bool LLOutfitsList::isActionEnabled(const LLSD& userdata) return false; } -// virtual -void LLOutfitsList::showGearMenu(LLView* spawning_view) -{ - if (!mGearMenu) return; - mGearMenu->show(spawning_view); -} - void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const { // Collect selected items from all selected lists. diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index f73ae5bef2..5fecbb83e7 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -94,8 +94,6 @@ public: /*virtual*/ bool isActionEnabled(const LLSD& userdata); - /*virtual*/ void showGearMenu(LLView* spawning_view); - const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } /*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const; diff --git a/indra/newview/llpanelappearancetab.h b/indra/newview/llpanelappearancetab.h index 81366c5db4..2ed6b00497 100644 --- a/indra/newview/llpanelappearancetab.h +++ b/indra/newview/llpanelappearancetab.h @@ -39,8 +39,6 @@ public: virtual bool isActionEnabled(const LLSD& userdata) = 0; - virtual void showGearMenu(LLView* spawning_view) = 0; - virtual void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const {} static const std::string& getFilterSubString() { return sFilterSubString; } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 68ca65420a..57180f63b5 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -44,7 +44,7 @@ #include "llfloaterreg.h" #include "llnotificationsutil.h" #include "llvoiceclient.h" -#include "llnamebox.h" +#include "lltextbox.h" #include "lltrans.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -218,13 +218,8 @@ void LLPanelAvatarNotes::rightsConfirmationCallback(const LLSD& notification, void LLPanelAvatarNotes::confirmModifyRights(bool grant, S32 rights) { - std::string first, last; LLSD args; - if (gCacheName->getName(getAvatarId(), first, last)) - { - args["FIRST_NAME"] = first; - args["LAST_NAME"] = last; - } + args["NAME"] = LLSLURL("agent", getAvatarId(), "displayname").getSLURLString(); if (grant) { @@ -562,8 +557,7 @@ void LLPanelAvatarProfile::resetData() 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")->setTextArg("[FIRST]", LLStringUtil::null); - getChild<LLUICtrl>("partner_text")->setTextArg("[LAST]", LLStringUtil::null); + getChild<LLUICtrl>("partner_text")->setValue(LLStringUtil::null); } void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType type) @@ -654,15 +648,14 @@ void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data) { - LLNameBox* name_box = getChild<LLNameBox>("partner_text"); + LLTextBox* partner_text = getChild<LLTextBox>("partner_text"); if (avatar_data->partner_id.notNull()) { - name_box->setNameID(avatar_data->partner_id, FALSE); + partner_text->setText(LLSLURL("agent", avatar_data->partner_id, "inspect").getSLURLString()); } else { - name_box->setNameID(LLUUID::null, FALSE); - name_box->setText(getString("no_partner_text")); + partner_text->setText(getString("no_partner_text")); } } diff --git a/indra/newview/llpanelavatartag.cpp b/indra/newview/llpanelavatartag.cpp index 77d67c7b09..4ac818eb26 100644 --- a/indra/newview/llpanelavatartag.cpp +++ b/indra/newview/llpanelavatartag.cpp @@ -80,7 +80,7 @@ void LLPanelAvatarTag::setAvatarId(const LLUUID& avatar_id) { mIcon->setValue(avatar_id); } - setName(std::string(mIcon->getFirstName()+ " "+ mIcon->getLastName())); + setName(std::string(mIcon->getFullName())); } boost::signals2::connection LLPanelAvatarTag::setLeftButtonClickCallback( diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp index fd2e961cb7..81e199d85b 100644 --- a/indra/newview/llpanelblockedlist.cpp +++ b/indra/newview/llpanelblockedlist.cpp @@ -29,6 +29,7 @@ #include "llpanelblockedlist.h" // library include +#include "llavatarname.h" #include "llfloater.h" #include "llfloaterreg.h" #include "llnotificationsutil.h" @@ -180,10 +181,10 @@ void LLPanelBlockedList::onBlockByNameClick() LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName); } -void LLPanelBlockedList::callbackBlockPicked(const std::vector<std::string>& names, const uuid_vec_t& ids) +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], LLMute::AGENT); + LLMute mute(ids[0], names[0].getLegacyName(), LLMute::AGENT); LLMuteList::getInstance()->add(mute); showPanelAndSelect(mute.mID); } diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h index eb9f082d87..74ad82e32d 100644 --- a/indra/newview/llpanelblockedlist.h +++ b/indra/newview/llpanelblockedlist.h @@ -36,7 +36,8 @@ // class LLLineEditor; // class LLMessageSystem; // class LLUUID; - class LLScrollListCtrl; +class LLAvatarName; +class LLScrollListCtrl; class LLPanelBlockedList : public LLPanel, public LLMuteListObserver @@ -72,7 +73,7 @@ private: void onPickBtnClick(); void onBlockByNameClick(); - void callbackBlockPicked(const std::vector<std::string>& names, const uuid_vec_t& ids); + void callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); static void callbackBlockByName(const std::string& text); private: diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 3a31d99598..80df420a4e 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -40,7 +40,6 @@ #include "llavataractions.h" #include "llgroupactions.h" #include "lllineeditor.h" -#include "llnamebox.h" #include "llnamelistctrl.h" #include "llnotificationsutil.h" #include "llscrolllistitem.h" @@ -206,7 +205,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group) { mInsignia->setCommitCallback(onCommitAny, this); } - mFounderName = getChild<LLNameBox>("founder_name"); + mFounderName = getChild<LLTextBox>("founder_name"); mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor"); @@ -638,7 +637,7 @@ void LLPanelGroupGeneral::update(LLGroupChange gc) if (mEditCharter) mEditCharter->setEnabled(mAllowEdit && can_change_ident); if (mGroupNameEditor) mGroupNameEditor->setVisible(FALSE); - if (mFounderName) mFounderName->setNameID(gdatap->mFounderID,FALSE); + if (mFounderName) mFounderName->setText(LLSLURL("agent", gdatap->mFounderID, "inspect").getSLURLString()); if (mInsignia) { if (gdatap->mInsigniaID.notNull()) diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h index cbf173f845..88c092c461 100644 --- a/indra/newview/llpanelgroupgeneral.h +++ b/indra/newview/llpanelgroupgeneral.h @@ -37,7 +37,6 @@ class LLButton; class LLNameListCtrl; class LLCheckBoxCtrl; class LLComboBox; -class LLNameBox; class LLSpinCtrl; class LLPanelGroupGeneral : public LLPanelGroupTab @@ -91,7 +90,7 @@ private: // Group information (include any updates in updateChanged) LLLineEditor *mGroupNameEditor; - LLNameBox *mFounderName; + LLTextBox *mFounderName; LLTextureCtrl *mInsignia; LLTextEditor *mEditCharter; diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index b26bcc854c..ca48e8561b 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -28,6 +28,7 @@ #include "llpanelgroupinvite.h" #include "llagent.h" +#include "llavatarnamecache.h" #include "llfloateravatarpicker.h" #include "llbutton.h" #include "llcallingcard.h" @@ -62,9 +63,13 @@ public: static void callbackClickAdd(void* userdata); static void callbackClickRemove(void* userdata); static void callbackSelect(LLUICtrl* ctrl, void* userdata); - static void callbackAddUsers(const std::vector<std::string>& names, - const uuid_vec_t& agent_ids, + static void callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data); + + static void onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + void* user_data); + bool inviteOwnerCallback(const LLSD& notification, const LLSD& response); public: @@ -287,7 +292,7 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata) LLFloater* parentp; parentp = gFloaterView->getParentFloater(panelp); - parentp->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(impl::callbackAddUsers, _1, _2, + parentp->addDependentFloater(LLFloaterAvatarPicker::show(boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE)); } @@ -353,16 +358,38 @@ void LLPanelGroupInvite::impl::callbackClickOK(void* userdata) if ( selfp ) selfp->submitInvitations(); } + + //static -void LLPanelGroupInvite::impl::callbackAddUsers(const std::vector<std::string>& names, - const uuid_vec_t& ids, - void* user_data) +void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data) +{ + 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)); + } + +} + +void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + void* user_data) { impl* selfp = (impl*) user_data; - if ( selfp) selfp->addUsers(names, ids); + if (selfp) + { + std::vector<std::string> names; + uuid_vec_t agent_ids; + agent_ids.push_back(agent_id); + names.push_back(av_name.getCompleteName()); + + selfp->addUsers(names, agent_ids); + } } + LLPanelGroupInvite::LLPanelGroupInvite(const LLUUID& group_id) : LLPanel(), mImplementation(new impl(group_id)), @@ -398,16 +425,18 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) std::vector<std::string> names; for (S32 i = 0; i < (S32)agent_ids.size(); i++) { + std::string fullname; LLUUID agent_id = agent_ids[i]; LLViewerObject* dest = gObjectList.findObject(agent_id); - std::string fullname; if(dest && dest->isAvatar()) { LLNameValue* nvfirst = dest->getNVPair("FirstName"); LLNameValue* nvlast = dest->getNVPair("LastName"); if(nvfirst && nvlast) { - fullname = std::string(nvfirst->getString()) + " " + std::string(nvlast->getString()); + fullname = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); + } if (!fullname.empty()) { @@ -430,8 +459,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) { // actually it should happen, just in case gCacheName->get(LLUUID(agent_id), false, boost::bind( - &LLPanelGroupInvite::addUserCallback, this, _1, _2, - _3)); + &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 @@ -447,16 +475,16 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids) mImplementation->addUsers(names, agent_ids); } -void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& first_name, const std::string& last_name) +void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const std::string& full_name) { std::vector<std::string> names; uuid_vec_t agent_ids; - std::string full_name = first_name + " " + last_name; agent_ids.push_back(id); - names.push_back(first_name + " " + last_name); + names.push_back(full_name); mImplementation->addUsers(names, agent_ids); } + void LLPanelGroupInvite::draw() { LLPanel::draw(); diff --git a/indra/newview/llpanelgroupinvite.h b/indra/newview/llpanelgroupinvite.h index 01e7315486..a7bfd2226e 100644 --- a/indra/newview/llpanelgroupinvite.h +++ b/indra/newview/llpanelgroupinvite.h @@ -40,7 +40,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& first_name, const std::string& last_name); + void addUserCallback(const LLUUID& id, const std::string& full_name); void clear(); void update(); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index a24dbf6681..cdf6e51bf8 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -30,6 +30,7 @@ #include "llview.h" +#include "llavatarnamecache.h" #include "llinventory.h" #include "llviewerinventory.h" #include "llinventorydefines.h" @@ -540,6 +541,12 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg) msg->getU8("Data","AssetType",asset_type,i); 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); + } + LLSD row; row["id"] = id; diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 639364ff8d..0d1d96eae6 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -49,6 +49,7 @@ #include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llfocusmgr.h" +#include "llviewercontrol.h" #include "roles_constants.h" @@ -742,10 +743,12 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab() mHasMatch(FALSE), mNumOwnerAdditions(0) { + mUdpateSessionID = LLUUID::null; } LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab() { + gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName()); } BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) @@ -772,6 +775,17 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) // Show the member's profile on double click. mMembersList->setDoubleClickCallback(onMemberDoubleClick, this); mMembersList->setContextMenu(LLScrollListCtrl::MENU_AVATAR); + + LLSD row; + row["columns"][0]["column"] = "name"; + row["columns"][1]["column"] = "donated"; + row["columns"][2]["column"] = "online"; + mMembersList->addElement(row); + std::string order_by = gSavedSettings.getString("GroupMembersSortOrder"); + if(!order_by.empty()) + { + mMembersList->sortByColumn(order_by, TRUE); + } LLButton* button = parent->getChild<LLButton>("member_invite", recurse); if ( button ) @@ -1110,11 +1124,7 @@ void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, c for (uuid_vec_t::const_iterator i = selected_members.begin(); i != selected_members.end(); ++i) { LLSD args; - std::string name; - - gCacheName->getFullName(*i, name); - - args["AVATAR_NAME"] = name; + args["AVATAR_NAME"] = LLSLURL("agent", *i, "displayname").getSLURLString(); args["GROUP_NAME"] = group_data->mName; LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args)); @@ -1533,6 +1543,10 @@ 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 { @@ -1560,6 +1574,59 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) } } +void LLPanelGroupMembersSubTab::addMemberToList(LLUUID id, LLGroupMemberData* data) +{ + LLUIString donated = getString("donation_area"); + donated.setArg("[AREA]", llformat("%d", data->getContribution())); + + LLSD row; + row["id"] = id; + + row["columns"][0]["column"] = "name"; + // value is filled in by name list control + + row["columns"][1]["column"] = "donated"; + row["columns"][1]["value"] = donated.getString(); + + row["columns"][2]["column"] = "online"; + row["columns"][2]["value"] = data->getOnlineStatus(); + row["columns"][2]["font"] = "SANSSERIF_SMALL"; + + mMembersList->addElement(row); + + mHasMatch = TRUE; +} + +void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, const LLUUID& id) +{ + // 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; + + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if (!gdatap) + { + llwarns << "LLPanelGroupMembersSubTab::updateMembers() -- No group data!" << llendl; + return; + } + + std::string fullname; + gCacheName->getFullName(id, fullname); + if (matchesSearchFilter(fullname)) + { + addMemberToList(id, gdatap->mMembers[id]); + if(!mMembersList->getEnabled()) + { + mMembersList->setEnabled(TRUE); + } + } + +} + void LLPanelGroupMembersSubTab::updateMembers() { mPendingMemberUpdate = FALSE; @@ -1584,12 +1651,13 @@ void LLPanelGroupMembersSubTab::updateMembers() //cleanup list only for first iretation if(mMemberProgress == gdatap->mMembers.begin()) + { mMembersList->deleteAllItems(); + } LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); - LLUIString donated = getString("donation_area"); - + S32 i = 0; for( ; mMemberProgress != end && i<UPDATE_MEMBERS_PER_FRAME; ++mMemberProgress, ++i) @@ -1597,38 +1665,19 @@ void LLPanelGroupMembersSubTab::updateMembers() if (!mMemberProgress->second) continue; // Do filtering on name if it is already in the cache. - bool add_member = true; - std::string fullname; if (gCacheName->getFullName(mMemberProgress->first, fullname)) { - if ( !matchesSearchFilter(fullname) ) + if (matchesSearchFilter(fullname)) { - add_member = false; + addMemberToList(mMemberProgress->first, mMemberProgress->second); } } - - if (add_member) + else { - donated.setArg("[AREA]", llformat("%d", mMemberProgress->second->getContribution())); - - LLSD row; - row["id"] = (*mMemberProgress).first; - - row["columns"][0]["column"] = "name"; - // value is filled in by name list control - - row["columns"][1]["column"] = "donated"; - row["columns"][1]["value"] = donated.getString(); - - row["columns"][2]["column"] = "online"; - row["columns"][2]["value"] = mMemberProgress->second->getOnlineStatus(); - row["columns"][2]["font"] = "SANSSERIF_SMALL"; - - LLScrollListItem* member = mMembersList->addElement(row); - - LLUUID id = member->getUUID(); - mHasMatch = TRUE; + // 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)); } } diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 6a773f1ebb..270259c16f 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -187,6 +187,9 @@ public: virtual void setGroupID(const LLUUID& id); + void addMemberToList(LLUUID id, LLGroupMemberData* data); + void onNameCache(const LLUUID& update_id, const LLUUID& id); + protected: typedef std::map<LLUUID, LLRoleMemberChangeType> role_change_data_map_t; typedef std::map<LLUUID, role_change_data_map_t*> member_role_changes_map_t; @@ -207,6 +210,9 @@ 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; diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp index 7489c02d8d..0cc5dcda82 100644 --- a/indra/newview/llpanelimcontrolpanel.cpp +++ b/indra/newview/llpanelimcontrolpanel.cpp @@ -180,7 +180,7 @@ void LLPanelIMControlPanel::onViewProfileButtonClicked() void LLPanelIMControlPanel::onAddFriendButtonClicked() { LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon"); - std::string full_name = avatar_icon->getFirstName() + " " + avatar_icon->getLastName(); + std::string full_name = avatar_icon->getFullName(); LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name); } @@ -231,6 +231,15 @@ void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id) 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)); } } @@ -246,6 +255,16 @@ void LLPanelIMControlPanel::changed(U32 mask) } } +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); + } +} + LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id): mParticipantList(NULL) { diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h index 45ada3ae1d..3bbe24ecb9 100644 --- a/indra/newview/llpanelimcontrolpanel.h +++ b/indra/newview/llpanelimcontrolpanel.h @@ -83,6 +83,9 @@ public: // 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(); diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp index b69cee9586..87acd83b23 100644 --- a/indra/newview/llpanellandmarkinfo.cpp +++ b/indra/newview/llpanellandmarkinfo.cpp @@ -39,6 +39,7 @@ #include "llagent.h" #include "llagentui.h" #include "lllandmarkactions.h" +#include "llslurl.h" #include "llviewerinventory.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" @@ -246,13 +247,10 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem) ////////////////// if (pItem->getCreatorUUID().notNull()) { - std::string name; + // IDEVO LLUUID creator_id = pItem->getCreatorUUID(); - if (!gCacheName->getFullName(creator_id, name)) - { - gCacheName->get(creator_id, FALSE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mCreator, _2, _3)); - } + std::string name = + LLSLURL("agent", creator_id, "inspect").getSLURLString(); mCreator->setText(name); } else @@ -269,20 +267,12 @@ void LLPanelLandmarkInfo::displayItemInfo(const LLInventoryItem* pItem) if (perm.isGroupOwned()) { LLUUID group_id = perm.getGroup(); - if (!gCacheName->getGroupName(group_id, name)) - { - gCacheName->get(group_id, TRUE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mOwner, _2, _3)); - } + name = LLSLURL("group", group_id, "inspect").getSLURLString(); } else { LLUUID owner_id = perm.getOwner(); - if (!gCacheName->getFullName(owner_id, name)) - { - gCacheName->get(owner_id, FALSE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mOwner, _2, _3)); - } + name = LLSLURL("agent", owner_id, "inspect").getSLURLString(); } mOwner->setText(name); } diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index c4a484d368..e5695f420a 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -47,6 +47,7 @@ #include "llinventorymodelbackgroundfetch.h" #include "llinventorypanel.h" #include "lllandmarkactions.h" +#include "llmenubutton.h" #include "llplacesinventorybridge.h" #include "llplacesinventorypanel.h" #include "llsidetray.h" @@ -191,6 +192,7 @@ LLLandmarksPanel::LLLandmarksPanel() , mLibraryInventoryPanel(NULL) , mCurrentSelectedList(NULL) , mListCommands(NULL) + , mGearButton(NULL) , mGearFolderMenu(NULL) , mGearLandmarkMenu(NULL) { @@ -685,7 +687,9 @@ void LLLandmarksPanel::initListCommandsHandlers() { mListCommands = getChild<LLPanel>("bottom_panel"); - mListCommands->childSetAction(OPTIONS_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); + mGearButton = getChild<LLMenuButton>(OPTIONS_BUTTON_NAME); + mGearButton->setMouseDownCallback(boost::bind(&LLLandmarksPanel::onActionsButtonClick, this)); + mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this)); LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>(TRASH_BUTTON_NAME); @@ -741,7 +745,7 @@ void LLLandmarksPanel::onActionsButtonClick() } } - showActionMenu(menu,OPTIONS_BUTTON_NAME); + mGearButton->setMenu(menu); } void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_name) @@ -750,7 +754,10 @@ void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_ { menu->buildDrawLabels(); menu->updateParent(LLMenuGL::sMenuContainer); - LLView* spawning_view = getChild<LLView> (spawning_view_name); + menu->arrangeAndClear(); + + LLView* spawning_view = getChild<LLView>(spawning_view_name); + S32 menu_x, menu_y; //show menu in co-ordinates of panel spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index 0d4402d8cb..28c19d3e5f 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -39,6 +39,7 @@ class LLAccordionCtrlTab; class LLFolderViewItem; +class LLMenuButton; class LLMenuGL; class LLInventoryPanel; class LLPlacesInventoryPanel; @@ -155,6 +156,7 @@ private: LLPlacesInventoryPanel* mLandmarksInventoryPanel; LLPlacesInventoryPanel* mMyInventoryPanel; LLPlacesInventoryPanel* mLibraryInventoryPanel; + LLMenuButton* mGearButton; LLMenuGL* mGearLandmarkMenu; LLMenuGL* mGearFolderMenu; LLMenuGL* mMenuAdd; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 7c93d8a1f9..467aefc60f 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -205,7 +205,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, } #if !USE_VIEWER_AUTH - getChild<LLLineEditor>("username_edit")->setPrevalidate(LLTextValidate::validateASCIIPrintableNoPipe); getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this); // change z sort of clickable text to be behind buttons @@ -501,8 +500,16 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential, LLSD identifier = credential->getIdentifier(); if((std::string)identifier["type"] == "agent") { - sInstance->getChild<LLUICtrl>("username_edit")->setValue((std::string)identifier["first_name"] + " " + - (std::string)identifier["last_name"]); + std::string firstname = identifier["first_name"].asString(); + std::string lastname = identifier["last_name"].asString(); + std::string login_id = firstname; + if (!lastname.empty() && lastname != "Resident") + { + // support traditional First Last name SLURLs + login_id += " "; + login_id += lastname; + } + sInstance->getChild<LLUICtrl>("username_edit")->setValue(login_id); } else if((std::string)identifier["type"] == "account") { @@ -566,7 +573,8 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential, LL_INFOS2("Credentials", "Authentication") << "retrieving username:" << username << LL_ENDL; // determine if the username is a first/last form or not. size_t separator_index = username.find_first_of(' '); - if (separator_index == username.npos) + if (separator_index == username.npos + && !LLGridManager::getInstance()->isSystemGrid()) { LL_INFOS2("Credentials", "Authentication") << "account: " << username << LL_ENDL; // single username, so this is a 'clear' identifier @@ -583,9 +591,23 @@ void LLPanelLogin::getFields(LLPointer<LLCredential>& credential, } else { + // Be lenient in terms of what separators we allow for two-word names + // and allow legacy users to login with firstname.lastname + separator_index = username.find_first_of(" ._"); std::string first = username.substr(0, separator_index); - std::string last = username.substr(separator_index, username.npos); + std::string last; + if (separator_index != username.npos) + { + last = username.substr(separator_index+1, username.npos); LLStringUtil::trim(last); + } + else + { + // ...on Linden grids, single username users as considered to have + // last name "Resident" + // *TODO: Make login.cgi support "account_name" like above + last = "Resident"; + } if (last.find_first_of(' ') == last.npos) { @@ -805,7 +827,7 @@ void LLPanelLogin::loadLoginPage() curl_free(curl_version); // Grid - char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLoginID().c_str(), 0); + char* curl_grid = curl_escape(LLGridManager::getInstance()->getGridLabel().c_str(), 0); oStr << "&grid=" << curl_grid; curl_free(curl_grid); gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid()); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 5b07e4863b..cc69dbd9d4 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -39,6 +39,7 @@ #include "llinventorypanel.h" #include "llfiltereditor.h" #include "llfloaterreg.h" +#include "llmenubutton.h" #include "lloutfitobserver.h" #include "llpreviewtexture.h" #include "llresmgr.h" @@ -192,6 +193,8 @@ BOOL LLPanelMainInventory::postBuild() mFilterEditor->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterEdit, this, _2)); } + mGearMenuButton = getChild<LLMenuButton>("options_gear_btn"); + initListCommandsHandlers(); // *TODO:Get the cost info from the server @@ -900,7 +903,6 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data) void LLPanelMainInventory::initListCommandsHandlers() { - childSetAction("options_gear_btn", boost::bind(&LLPanelMainInventory::onGearButtonClick, this)); childSetAction("trash_btn", boost::bind(&LLPanelMainInventory::onTrashButtonClick, this)); childSetAction("add_btn", boost::bind(&LLPanelMainInventory::onAddButtonClick, this)); @@ -914,6 +916,7 @@ void LLPanelMainInventory::initListCommandsHandlers() mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2)); mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2)); mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mGearMenuButton->setMenu(mMenuGearDefault); mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); // Update the trash button when selected item(s) get worn or taken off. @@ -927,11 +930,6 @@ void LLPanelMainInventory::updateListCommands() mTrashButton->setEnabled(trash_enabled); } -void LLPanelMainInventory::onGearButtonClick() -{ - showActionMenu(mMenuGearDefault,"options_gear_btn"); -} - void LLPanelMainInventory::onAddButtonClick() { setUploadCostIfNeeded(); diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index cf2cc14531..f95a99157d 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -40,6 +40,7 @@ class LLSaveFolderState; class LLFilterEditor; class LLTabContainer; class LLFloaterInventoryFinder; +class LLMenuButton; class LLMenuGL; class LLFloater; @@ -129,7 +130,6 @@ private: protected: void initListCommandsHandlers(); void updateListCommands(); - void onGearButtonClick(); void onAddButtonClick(); void showActionMenu(LLMenuGL* menu, std::string spawning_view_name); void onTrashButtonClick(); @@ -145,6 +145,7 @@ private: LLDragAndDropButton* mTrashButton; LLMenuGL* mMenuGearDefault; LLMenuGL* mMenuAdd; + LLMenuButton* mGearMenuButton; bool mNeedUploadCost; // List Commands // diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp index 36a3aae15f..5ea94e0611 100644 --- a/indra/newview/llpanelme.cpp +++ b/indra/newview/llpanelme.cpp @@ -26,17 +26,28 @@ #include "llviewerprecompiledheaders.h" +#include "llpanelme.h" + +// Viewer includes #include "llpanelprofile.h" #include "llavatarconstants.h" -#include "llpanelme.h" #include "llagent.h" #include "llagentcamera.h" #include "llagentwearables.h" -#include "lliconctrl.h" +#include "llfirstuse.h" +#include "llfloaterreg.h" +#include "llhints.h" #include "llsidetray.h" +#include "llviewercontrol.h" +#include "llviewerdisplayname.h" + +// Linden libraries +#include "llavatarnamecache.h" // IDEVO +#include "lliconctrl.h" +#include "llnotifications.h" +#include "llnotificationsutil.h" // IDEVO #include "lltabcontainer.h" #include "lltexturectrl.h" -#include "llviewercontrol.h" #define PICKER_SECOND_LIFE "2nd_life_pic" #define PICKER_FIRST_LIFE "real_world_pic" @@ -165,6 +176,8 @@ LLPanelMyProfileEdit::LLPanelMyProfileEdit() buildFromFile( "panel_edit_profile.xml"); setAvatarId(gAgent.getID()); + + LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLPanelMyProfileEdit::onAvatarNameChanged, this)); } void LLPanelMyProfileEdit::onOpen(const LLSD& key) @@ -174,7 +187,52 @@ void LLPanelMyProfileEdit::onOpen(const LLSD& key) // 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) @@ -207,15 +265,63 @@ void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_d getChild<LLUICtrl>("show_in_search_checkbox")->setValue((BOOL)(avatar_data->flags & AVATAR_ALLOW_PUBLISH)); - std::string first, last; - BOOL found = gCacheName->getName(avatar_data->avatar_id, first, last); - if (found) + 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>("name_text")->setTextArg("[FIRST]", first); - getChild<LLUICtrl>("name_text")->setTextArg("[LAST]", last); + 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(); @@ -223,6 +329,11 @@ BOOL LLPanelMyProfileEdit::postBuild() 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(); } /** @@ -250,8 +361,12 @@ void LLPanelMyProfileEdit::resetData() { LLPanelMyProfile::resetData(); - getChild<LLUICtrl>("name_text")->setTextArg("[FIRST]", LLStringUtil::null); - getChild<LLUICtrl>("name_text")->setTextArg("[LAST]", LLStringUtil::null); + //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) @@ -263,6 +378,43 @@ 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); diff --git a/indra/newview/llpanelme.h b/indra/newview/llpanelme.h index 984ba1e9a2..d5b2fee869 100644 --- a/indra/newview/llpanelme.h +++ b/indra/newview/llpanelme.h @@ -28,8 +28,9 @@ #define LL_LLPANELMEPROFILE_H #include "llpanel.h" -#include "llpanelavatar.h" +#include "llpanelprofile.h" +class LLAvatarName; class LLPanelMyProfileEdit; class LLPanelProfile; class LLIconCtrl; @@ -77,17 +78,23 @@ public: /*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 @@ -95,6 +102,8 @@ private: */ 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; diff --git a/indra/newview/llpanelmediasettingspermissions.cpp b/indra/newview/llpanelmediasettingspermissions.cpp index 5378886b56..cb0b7789ff 100644 --- a/indra/newview/llpanelmediasettingspermissions.cpp +++ b/indra/newview/llpanelmediasettingspermissions.cpp @@ -101,16 +101,16 @@ void LLPanelMediaSettingsPermissions::draw() if(mPermsGroupName) { mPermsGroupName->setNameID(group_id, true); - }; + } } else { if(mPermsGroupName) { mPermsGroupName->setNameID(LLUUID::null, TRUE); - mPermsGroupName->refresh(LLUUID::null, LLStringUtil::null, LLStringUtil::null, true); - }; - }; + mPermsGroupName->refresh(LLUUID::null, std::string(), true); + } + } } //////////////////////////////////////////////////////////////////////////////// @@ -192,7 +192,7 @@ void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& me data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); }; }; - + // *NOTE: If any of a particular flavor is tentative, we have to disable // them all because of an architectural issue: namely that we represent // these as a bit field, and we can't selectively apply only one bit to all selected diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 494db01f77..5638374178 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -56,6 +56,7 @@ #include "llinventorymodel.h" #include "llinventorymodelbackgroundfetch.h" #include "llloadingindicator.h" +#include "llmenubutton.h" #include "llpaneloutfitsinventory.h" #include "lluiconstants.h" #include "llsaveoutfitcombobtn.h" @@ -403,7 +404,9 @@ LLPanelOutfitEdit::LLPanelOutfitEdit() mAddWearablesPanel(NULL), mFolderViewFilterCmbBox(NULL), mListViewFilterCmbBox(NULL), - mPlusBtn(NULL) + mPlusBtn(NULL), + mWearablesGearMenuBtn(NULL), + mGearMenuBtn(NULL) { mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(FALSE); @@ -478,13 +481,14 @@ BOOL LLPanelOutfitEdit::postBuild() childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL); childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL); childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL); - childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); - childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL); childSetCommitCallback("shop_btn_2", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL); setVisibleCallback(boost::bind(&LLPanelOutfitEdit::onVisibilityChange, this, _2)); + mWearablesGearMenuBtn = getChild<LLMenuButton>("wearables_gear_menu_btn"); + mGearMenuBtn = getChild<LLMenuButton>("gear_menu_btn"); + mCOFWearables = findChild<LLCOFWearables>("cof_wearables_list"); mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::filterWearablesBySelectedItem, this)); @@ -557,6 +561,13 @@ BOOL LLPanelOutfitEdit::postBuild() mWearableItemsList->setComparator(mWearableListViewItemsComparator); + // Creating "Add Wearables" panel gear menu after initialization of mWearableItemsList and mInventoryItemsPanel. + mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel); + mWearablesGearMenuBtn->setMenu(mAddWearablesGearMenu); + + mGearMenu = LLPanelOutfitEditGearMenu::create(); + mGearMenuBtn->setMenu(mGearMenu); + mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this)); return TRUE; } @@ -1256,37 +1267,6 @@ void LLPanelOutfitEdit::resetAccordionState() } } -void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button) -{ - LLMenuGL* menu = NULL; - - if (mAddWearablesPanel->getVisible()) - { - if (!mAddWearablesGearMenu) - { - mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel); - } - - menu = mAddWearablesGearMenu; - } - else - { - if (!mGearMenu) - { - mGearMenu = LLPanelOutfitEditGearMenu::create(); - } - - menu = mGearMenu; - } - - if (!menu) return; - - menu->arrangeAndClear(); // update menu height - S32 menu_y = menu->getRect().getHeight() + clicked_button->getRect().getHeight(); - menu->buildDrawLabels(); - LLMenuGL::showPopup(clicked_button, menu, 0, menu_y); -} - void LLPanelOutfitEdit::onAddMoreButtonClicked() { toggleAddWearablesPanel(); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 2dca986e33..963db84503 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -54,6 +54,7 @@ class LLScrollListCtrl; class LLToggleableMenu; class LLFilterEditor; class LLFilteredWearableListManager; +class LLMenuButton; class LLMenuGL; class LLFindNonLinksByMask; class LLFindWearablesOfType; @@ -186,8 +187,6 @@ public: std::string& tooltip_msg); private: - - void onGearButtonClick(LLUICtrl* clicked_button); void onAddMoreButtonClicked(); void showFilteredWearablesListView(LLWearableType::EType type); void onOutfitChanging(bool started); @@ -238,8 +237,8 @@ private: LLMenuGL* mAddWearablesGearMenu; bool mInitialized; std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; - - + LLMenuButton* mWearablesGearMenuBtn; + LLMenuButton* mGearMenuBtn; }; diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index d6d8a38ebe..4f2cfa2bbc 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -232,9 +232,7 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() { mListCommands = getChild<LLPanel>("bottom_panel"); mListCommands->childSetAction("wear_btn", boost::bind(&LLPanelOutfitsInventory::onWearButtonClick, this)); - mMyOutfitsPanel->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::showGearMenu, this)); mMyOutfitsPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); - mCurrentOutfitPanel->childSetAction("options_gear_btn", boost::bind(&LLPanelOutfitsInventory::showGearMenu, this)); } void LLPanelOutfitsInventory::updateListCommands() @@ -258,14 +256,6 @@ void LLPanelOutfitsInventory::updateListCommands() } } -void LLPanelOutfitsInventory::showGearMenu() -{ - if (!mActivePanel) return; - - LLView* spawning_view = getChild<LLView>("options_gear_btn"); - mActivePanel->showGearMenu(spawning_view); -} - void LLPanelOutfitsInventory::onTrashButtonClick() { LLNotificationsUtil::add("DeleteOutfits", LLSD(), LLSD(), boost::bind(&LLPanelOutfitsInventory::onOutfitsRemovalConfirmation, this, _1, _2)); diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index d096b17145..b79a2d3224 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -27,7 +27,9 @@ #include "llviewerprecompiledheaders.h" // libs +#include "llavatarname.h" #include "llfloaterreg.h" +#include "llmenubutton.h" #include "llmenugl.h" #include "llnotificationsutil.h" #include "lleventtimer.h" @@ -463,7 +465,11 @@ LLPanelPeople::LLPanelPeople() mAllFriendList(NULL), mNearbyList(NULL), mRecentList(NULL), - mGroupList(NULL) + mGroupList(NULL), + mNearbyGearButton(NULL), + mFriendsGearButton(NULL), + mGroupsGearButton(NULL), + mRecentGearButton(NULL) { mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList, this)); mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList, this)); @@ -599,11 +605,6 @@ BOOL LLPanelPeople::postBuild() buttonSetAction("teleport_btn", boost::bind(&LLPanelPeople::onTeleportButtonClicked, this)); buttonSetAction("share_btn", boost::bind(&LLPanelPeople::onShareButtonClicked, this)); - getChild<LLPanel>(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked, this)); - getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked, this)); - getChild<LLPanel>(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked, this)); - getChild<LLPanel>(GROUP_TAB_NAME)->childSetAction("groups_viewsort_btn",boost::bind(&LLPanelPeople::onGroupsViewSortButtonClicked, this)); - // Must go after setting commit callback and initializing all pointers to children. mTabContainer->selectTabByName(NEARBY_TAB_NAME); @@ -623,24 +624,41 @@ BOOL LLPanelPeople::postBuild() 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(); LLMenuGL* nearby_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("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); + } LLMenuGL* friend_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("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); + } LLMenuGL* group_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_groups_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if(group_view_sort) + { mGroupsViewSortMenuHandle = group_view_sort->getHandle(); + mGroupsGearButton->setMenu(group_view_sort); + } LLMenuGL* recent_view_sort = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_recent_view_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); if(recent_view_sort) + { mRecentViewSortMenuHandle = recent_view_sort->getHandle(); + mRecentGearButton->setMenu(recent_view_sort); + } LLVoiceClient::getInstance()->addObserver(this); @@ -910,7 +928,7 @@ void LLPanelPeople::showGroupMenu(LLMenuGL* menu) // Calculate its coordinates. // (assumes that groups panel is the current tab) - LLPanel* bottom_panel = mTabContainer->getCurrentPanel()->getChild<LLPanel>("bottom_panel"); + LLPanel* bottom_panel = mTabContainer->getCurrentPanel()->getChild<LLPanel>("bottom_panel"); LLPanel* parent_panel = mTabContainer->getCurrentPanel(); menu->arrangeAndClear(); S32 menu_height = menu->getRect().getHeight(); @@ -1150,12 +1168,10 @@ void LLPanelPeople::onActivateButtonClicked() } // static -void LLPanelPeople::onAvatarPicked( - const std::vector<std::string>& names, - const uuid_vec_t& ids) +void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names) { if (!names.empty() && !ids.empty()) - LLAvatarActions::requestFriendshipDialog(ids[0], names[0]); + LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName()); } void LLPanelPeople::onGroupPlusButtonClicked() @@ -1347,38 +1363,6 @@ void LLPanelPeople::onMoreButtonClicked() // *TODO: not implemented yet } -void LLPanelPeople::onFriendsViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mFriendsViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); -} - -void LLPanelPeople::onGroupsViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mGroupsViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); -} - -void LLPanelPeople::onRecentViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mRecentViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); -} - -void LLPanelPeople::onNearbyViewSortButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mNearbyViewSortMenuHandle.get(); - if (!menu) - return; - showGroupMenu(menu); -} - void LLPanelPeople::onOpen(const LLSD& key) { std::string tab_name = key["people_panel_tab_name"]; diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index d0913ee756..4412aed062 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -32,10 +32,12 @@ #include "llcallingcard.h" // for avatar tracker #include "llvoiceclient.h" -class LLFilterEditor; -class LLTabContainer; class LLAvatarList; +class LLAvatarName; +class LLFilterEditor; class LLGroupList; +class LLMenuButton; +class LLTabContainer; class LLPanelPeople : public LLPanel @@ -100,10 +102,6 @@ private: void onShareButtonClicked(); void onMoreButtonClicked(); void onActivateButtonClicked(); - void onRecentViewSortButtonClicked(); - void onNearbyViewSortButtonClicked(); - void onFriendsViewSortButtonClicked(); - void onGroupsViewSortButtonClicked(); void onAvatarListDoubleClicked(LLUICtrl* ctrl); void onAvatarListCommitted(LLAvatarList* list); void onGroupPlusButtonClicked(); @@ -122,9 +120,7 @@ private: bool onNearbyViewSortMenuItemCheck(const LLSD& userdata); // misc callbacks - static void onAvatarPicked( - const std::vector<std::string>& names, - const uuid_vec_t& ids); + static void onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names); void onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list); @@ -157,6 +153,11 @@ private: Updater* mNearbyListUpdater; Updater* mRecentListUpdater; + LLMenuButton* mNearbyGearButton; + LLMenuButton* mFriendsGearButton; + LLMenuButton* mGroupsGearButton; + LLMenuButton* mRecentGearButton; + std::string mFilterSubString; std::string mFilterSubStringOrig; }; diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index e35574be6c..59130236f2 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -379,7 +379,7 @@ void LLPanelPermissions::refresh() if (mLabelGroupName) { mLabelGroupName->setNameID(LLUUID::null, TRUE); - mLabelGroupName->refresh(LLUUID::null,LLStringUtil::null, LLStringUtil::null, TRUE); + mLabelGroupName->refresh(LLUUID::null, std::string(), true); mLabelGroupName->setEnabled(FALSE); } } diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp index 27787ac211..ccef563544 100644 --- a/indra/newview/llpanelpicks.cpp +++ b/indra/newview/llpanelpicks.cpp @@ -229,9 +229,9 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type) LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data); if(avatar_picks && getAvatarId() == avatar_picks->target_id) { - std::string name, second_name; - gCacheName->getName(getAvatarId(),name,second_name); - getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", name); + std::string full_name; + gCacheName->getFullName(getAvatarId(), full_name); + getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", full_name); // Save selection, to be able to edit same item after saving changes. See EXT-3023. LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID]; diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index bbaffda2f2..9cbb512e70 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -28,6 +28,7 @@ #include "llpanelplaceinfo.h" +#include "llavatarname.h" #include "llsdutil.h" #include "llsdutil_math.h" @@ -304,9 +305,15 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPickEdit* } // static -void LLPanelPlaceInfo::nameUpdatedCallback(LLTextBox* text, - const std::string& first, - const std::string& last) +void LLPanelPlaceInfo::onNameCache(LLTextBox* text, const std::string& full_name) { - text->setText(first + " " + last); + text->setText(full_name); +} + +// static +void LLPanelPlaceInfo::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + LLTextBox* text) +{ + text->setText( av_name.getCompleteName() ); } diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 1e0975a898..64f0b6b550 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -34,6 +34,7 @@ #include "llremoteparcelrequest.h" +class LLAvatarName; class LLExpandableTextBox; class LLIconCtrl; class LLInventoryItem; @@ -96,9 +97,10 @@ public: void createPick(const LLVector3d& pos_global, LLPanelPickEdit* pick_panel); protected: - static void nameUpdatedCallback(LLTextBox* text, - const std::string& first, - const std::string& last); + static void onNameCache(LLTextBox* text, const std::string& full_name); + static void onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name, + LLTextBox* text); /** * mParcelID is valid only for remote places, in other cases it's null. See resetLocation() diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 801db1e741..68ecb0165c 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -28,6 +28,7 @@ #include "llpanelplaceprofile.h" +#include "llavatarnamecache.h" #include "llparcel.h" #include "message.h" @@ -45,6 +46,7 @@ #include "llappviewer.h" #include "llcallbacklist.h" #include "llbuycurrencyhtml.h" +#include "llslurl.h" #include "llstatusbar.h" #include "llviewercontrol.h" #include "llviewerparcelmgr.h" @@ -430,11 +432,11 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, if(!parcel->getGroupID().isNull()) { // FIXME: Using parcel group as region group. - gCacheName->get(parcel->getGroupID(), TRUE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mRegionGroupText, _2, _3)); + gCacheName->getGroup(parcel->getGroupID(), + boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionGroupText, _2)); - gCacheName->get(parcel->getGroupID(), TRUE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mParcelOwner, _2, _3)); + gCacheName->getGroup(parcel->getGroupID(), + boost::bind(&LLPanelPlaceInfo::onNameCache, mParcelOwner, _2)); } else { @@ -446,10 +448,12 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, else { // Figure out the owner's name - gCacheName->get(parcel->getOwnerID(), FALSE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mParcelOwner, _2, _3)); - gCacheName->get(region->getOwner(), FALSE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mRegionOwnerText, _2, _3)); + 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)); } if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus()) @@ -471,9 +475,10 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID(); if(auth_buyer_id.notNull()) { - gCacheName->get(auth_buyer_id, TRUE, - boost::bind(&LLPanelPlaceInfo::nameUpdatedCallback, mSaleToText, _2, _3)); - + 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/llpanelprofile.h b/indra/newview/llpanelprofile.h index 0546c18583..d2bcee8076 100644 --- a/indra/newview/llpanelprofile.h +++ b/indra/newview/llpanelprofile.h @@ -27,7 +27,6 @@ #ifndef LL_LLPANELPROFILE_H #define LL_LLPANELPROFILE_H -#include "llviewerprecompiledheaders.h" #include "llpanel.h" #include "llpanelavatar.h" diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp index dba047660d..7635aedf58 100644 --- a/indra/newview/llpanelprofileview.cpp +++ b/indra/newview/llpanelprofileview.cpp @@ -26,11 +26,13 @@ #include "llviewerprecompiledheaders.h" +#include "llpanelprofileview.h" + #include "llavatarconstants.h" +#include "llavatarnamecache.h" // IDEVO +#include "llclipboard.h" #include "lluserrelations.h" -#include "llpanelprofileview.h" - #include "llavatarpropertiesprocessor.h" #include "llcallingcard.h" #include "llpanelavatar.h" @@ -98,11 +100,15 @@ void LLPanelProfileView::onOpen(const LLSD& key) 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. - gCacheName->get(getAvatarId(), FALSE, - boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4)); + LLAvatarNameCache::get(getAvatarId(), + boost::bind(&LLPanelProfileView::onAvatarNameCache, this, _1, _2)); updateOnlineStatus(); @@ -124,7 +130,8 @@ BOOL LLPanelProfileView::postBuild() mStatusText->setVisible(false); childSetCommitCallback("back",boost::bind(&LLPanelProfileView::onBackBtnClick,this),NULL); - + childSetCommitCallback("copy_to_clipboard",boost::bind(&LLPanelProfileView::onCopyToClipboard,this),NULL); + return TRUE; } @@ -144,6 +151,12 @@ void LLPanelProfileView::onBackBtnClick() } } +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()); @@ -192,10 +205,43 @@ void LLPanelProfileView::processOnlineStatus(bool online) mStatusText->setValue(status); } -void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group) +void LLPanelProfileView::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name) { - llassert(getAvatarId() == id); - getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_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 index 9972b085d8..c6d921fdc4 100644 --- a/indra/newview/llpanelprofileview.h +++ b/indra/newview/llpanelprofileview.h @@ -33,6 +33,7 @@ #include "llagent.h" #include "lltooldraganddrop.h" +class LLAvatarName; class LLPanelProfile; class LLPanelProfileTab; class LLTextBox; @@ -73,6 +74,7 @@ public: protected: void onBackBtnClick(); + void onCopyToClipboard(); bool isGrantedToSeeOnlineStatus(); /** @@ -93,11 +95,11 @@ protected: private: // LLCacheName will call this function when avatar name is loaded from server. // This is required to display names that have not been cached yet. - void onAvatarNameCached( - const LLUUID& id, - const std::string& first_name, - const std::string& last_name, - BOOL is_group); +// 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; diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index 9b8167b15a..766f93e0a5 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -27,6 +27,7 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterreg.h" +#include "llmenubutton.h" #include "llfloaterworldmap.h" #include "llpanelteleporthistory.h" @@ -375,7 +376,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() mHistoryAccordion(NULL), mAccordionTabMenu(NULL), mLastSelectedFlatlList(NULL), - mLastSelectedItemIndex(-1) + mLastSelectedItemIndex(-1), + mMenuGearButton(NULL) { buildFromFile( "panel_teleport_history.xml"); } @@ -439,8 +441,6 @@ BOOL LLTeleportHistoryPanel::postBuild() } } - getChild<LLPanel>("bottom_panel")->childSetAction("gear_btn",boost::bind(&LLTeleportHistoryPanel::onGearButtonClicked, this)); - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; registrar.add("TeleportHistory.ExpandAllFolders", boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders, this)); @@ -448,9 +448,14 @@ BOOL LLTeleportHistoryPanel::postBuild() registrar.add("TeleportHistory.ClearTeleportHistory", boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory, this)); mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2)); - LLMenuGL* gear_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + mMenuGearButton = getChild<LLMenuButton>("gear_btn"); + + LLMenuGL* gear_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());; if(gear_menu) + { mGearMenuHandle = gear_menu->getHandle(); + mMenuGearButton->setMenu(gear_menu); + } return TRUE; } @@ -985,27 +990,6 @@ LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTa return NULL; } -void LLTeleportHistoryPanel::onGearButtonClicked() -{ - LLMenuGL* menu = (LLMenuGL*)mGearMenuHandle.get(); - if (!menu) - return; - - // Shows the menu at the top of the button bar. - - // Calculate its coordinates. - LLPanel* bottom_panel = getChild<LLPanel>("bottom_panel"); - menu->arrangeAndClear(); - S32 menu_height = menu->getRect().getHeight(); - S32 menu_x = -2; // *HACK: compensates HPAD in showPopup() - S32 menu_y = bottom_panel->getRect().mTop + menu_height; - - // Actually show the menu. - menu->buildDrawLabels(); - menu->updateParent(LLMenuGL::sMenuContainer); - LLMenuGL::showPopup(this, menu, menu_x, menu_y); -} - bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const { S32 tabs_cnt = mItemContainers.size(); diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index b5a025b39b..3d29454d15 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -38,6 +38,7 @@ class LLTeleportHistoryStorage; class LLAccordionCtrl; class LLAccordionCtrlTab; class LLFlatListView; +class LLMenuButton; class LLTeleportHistoryPanel : public LLPanelPlacesTab { @@ -94,7 +95,6 @@ private: void showTeleportHistory(); void handleItemSelect(LLFlatListView* ); LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *); - void onGearButtonClicked(); bool isActionEnabled(const LLSD& userdata) const; void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); @@ -118,6 +118,7 @@ private: ContextMenu mContextMenu; LLContextMenu* mAccordionTabMenu; LLHandle<LLView> mGearMenuHandle; + LLMenuButton* mMenuGearButton; }; diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index 860470cd73..3b3d0cdce5 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -32,6 +32,7 @@ #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "llinventoryobserver.h" +#include "llmenubutton.h" #include "llsidetray.h" #include "llviewermenu.h" #include "llwearableitemslist.h" @@ -63,16 +64,7 @@ public: llassert(mMenu); } - void show(LLView* spawning_view) - { - if (!mMenu) return; - - mMenu->buildDrawLabels(); - mMenu->updateParent(LLMenuGL::sMenuContainer); - S32 menu_x = 0; - S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight(); - LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y); - } + LLMenuGL* getMenu() { return mMenu; } private: @@ -189,6 +181,10 @@ BOOL LLPanelWearing::postBuild() mCOFItemsList = getChild<LLWearableItemsList>("cof_items_list"); mCOFItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onWearableItemsListRightClick, this, _1, _2, _3)); + LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); + + menu_gear_btn->setMenu(mGearMenu->getMenu()); + return TRUE; } @@ -253,13 +249,6 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata) return false; } -// virtual -void LLPanelWearing::showGearMenu(LLView* spawning_view) -{ - if (!mGearMenu) return; - mGearMenu->show(spawning_view); -} - boost::signals2::connection LLPanelWearing::setSelectionChangeCallback(commit_callback_t cb) { if (!mCOFItemsList) return boost::signals2::connection(); diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h index 1fa97735b1..157b2c4c5f 100644 --- a/indra/newview/llpanelwearing.h +++ b/indra/newview/llpanelwearing.h @@ -58,8 +58,6 @@ public: /*virtual*/ bool isActionEnabled(const LLSD& userdata); - /*virtual*/ void showGearMenu(LLView* spawning_view); - /*virtual*/ void getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const; boost::signals2::connection setSelectionChangeCallback(commit_callback_t cb); diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index c8aa9ac91e..01b3b5572e 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -331,11 +331,18 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param) 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->setName(name); + item->setAvatarName(name); + } + found = tooltip.find(moderator_indicator); + if (found != tooltip.npos) + { + tooltip.erase(found, moderator_indicator_len); + item->setAvatarToolTip(tooltip); } } } @@ -351,12 +358,20 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param) 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->setName(name); + item->setAvatarName(name); + } + found = tooltip.find(moderator_indicator); + if (found == std::string::npos) + { + tooltip += " "; + tooltip += moderator_indicator; + item->setAvatarToolTip(tooltip); } } } diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp index 5c923a0409..18c9ac28c1 100644 --- a/indra/newview/llscreenchannel.cpp +++ b/indra/newview/llscreenchannel.cpp @@ -253,8 +253,8 @@ void LLScreenChannel::addToast(const LLToast::Params& p) if(mControlHovering) { new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2)); - new_toast_elem.toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopFadingToasts, this)); - new_toast_elem.toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startFadingToasts, this)); + new_toast_elem.toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopFadingToast, this, new_toast_elem.toast)); + new_toast_elem.toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startFadingToast, this, new_toast_elem.toast)); } if(show_toast) @@ -339,7 +339,6 @@ void LLScreenChannel::deleteToast(LLToast* toast) if(mHoveredToast == toast) { mHoveredToast = NULL; - startFadingToasts(); } // close the toast @@ -698,38 +697,23 @@ void LLScreenChannel::closeStartUpToast() } } -void LLNotificationsUI::LLScreenChannel::stopFadingToasts() +void LLNotificationsUI::LLScreenChannel::stopFadingToast(LLToast* toast) { - if (!mToastList.size()) return; + if (!toast || toast != mHoveredToast) return; - if (!mHoveredToast) return; - - std::vector<ToastElem>::iterator it = mToastList.begin(); - while (it != mToastList.end()) - { - ToastElem& elem = *it; - elem.toast->stopFading(); - ++it; - } + // Pause fade timer of the hovered toast. + toast->stopFading(); } -void LLNotificationsUI::LLScreenChannel::startFadingToasts() +void LLNotificationsUI::LLScreenChannel::startFadingToast(LLToast* toast) { - if (!mToastList.size()) return; - - //because onMouseLeave is processed after onMouseEnter - if (isHovering()) return; - - std::vector<ToastElem>::iterator it = mToastList.begin(); - while (it != mToastList.end()) + if (!toast || toast == mHoveredToast) { - ToastElem& elem = *it; - if (elem.toast->getVisible()) - { - elem.toast->startFading(); - } - ++it; + return; } + + // Reset its fade timer. + toast->startFading(); } //-------------------------------------------------------------------------- diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h index 6cf6d97550..a1fdd6e32c 100644 --- a/indra/newview/llscreenchannel.h +++ b/indra/newview/llscreenchannel.h @@ -193,11 +193,11 @@ public: void closeStartUpToast(); - /** Stop fading all toasts */ - virtual void stopFadingToasts(); + /** Stop fading given toast */ + virtual void stopFadingToast(LLToast* toast); - /** Start fading all toasts */ - virtual void startFadingToasts(); + /** Start fading given toast */ + virtual void startFadingToast(LLToast* toast); // get StartUp Toast's state static bool getStartUpToastShown() { return mWasStartUpToastShown; } diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index b053432f9c..f9c0fd398e 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -315,11 +315,12 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) if (item->getCreatorUUID().notNull()) { - std::string name; - gCacheName->getFullName(item->getCreatorUUID(), name); + LLUUID creator_id = item->getCreatorUUID(); + std::string name = + LLSLURL("agent", creator_id, "completename").getSLURLString(); getChildView("BtnCreator")->setEnabled(TRUE); getChildView("LabelCreatorTitle")->setEnabled(TRUE); - getChildView("LabelCreatorName")->setEnabled(TRUE); + getChildView("LabelCreatorName")->setEnabled(FALSE); getChild<LLUICtrl>("LabelCreatorName")->setValue(name); } else @@ -342,11 +343,12 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item) } else { - gCacheName->getFullName(perm.getOwner(), name); + LLUUID owner_id = perm.getOwner(); + name = LLSLURL("agent", owner_id, "completename").getSLURLString(); } getChildView("BtnOwner")->setEnabled(TRUE); getChildView("LabelOwnerTitle")->setEnabled(TRUE); - getChildView("LabelOwnerName")->setEnabled(TRUE); + getChildView("LabelOwnerName")->setEnabled(FALSE); getChild<LLUICtrl>("LabelOwnerName")->setValue(name); } else diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp index 4552088cad..47d904dfcc 100644 --- a/indra/newview/llsidepaneltaskinfo.cpp +++ b/indra/newview/llsidepaneltaskinfo.cpp @@ -345,7 +345,7 @@ void LLSidepanelTaskInfo::refresh() if (mLabelGroupName) { mLabelGroupName->setNameID(LLUUID::null, TRUE); - mLabelGroupName->refresh(LLUUID::null,LLStringUtil::null, LLStringUtil::null, TRUE); + mLabelGroupName->refresh(LLUUID::null, std::string(), true); mLabelGroupName->setEnabled(FALSE); } } diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 196ed5e0bb..40aea05839 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -70,13 +70,13 @@ void LLSpeaker::lookupName() { if (mDisplayName.empty()) { - gCacheName->get(mID, FALSE, boost::bind(&LLSpeaker::onAvatarNameLookup, this, _1, _2, _3, _4)); + gCacheName->get(mID, false, boost::bind(&LLSpeaker::onNameCache, this, _1, _2, _3)); } } -void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void LLSpeaker::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group) { - mDisplayName = first + " " + last; + mDisplayName = full_name; } bool LLSpeaker::isInVoiceChannel() diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h index 08fb405265..35f2ee7056 100644 --- a/indra/newview/llspeakers.h +++ b/indra/newview/llspeakers.h @@ -60,7 +60,7 @@ public: ~LLSpeaker() {}; void lookupName(); - void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); + void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group); bool isInVoiceChannel(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index c56cacd12b..5ee4599200 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -46,6 +46,7 @@ #endif #include "llares.h" +#include "llavatarnamecache.h" #include "lllandmark.h" #include "llcachename.h" #include "lldir.h" @@ -118,7 +119,6 @@ #include "llpanellogin.h" #include "llmutelist.h" #include "llavatarpropertiesprocessor.h" -#include "llfloaterevent.h" #include "llpanelclassified.h" #include "llpanelpick.h" #include "llpanelgrouplandmoney.h" @@ -261,11 +261,10 @@ void apply_udp_blacklist(const std::string& csv); bool process_login_success_response(); void transition_back_to_login_panel(const std::string& emsg); -void callback_cache_name(const LLUUID& id, const std::string& firstname, const std::string& lastname, BOOL is_group) +void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is_group) { - LLNameListCtrl::refreshAll(id, firstname, lastname, is_group); - LLNameBox::refreshAll(id, firstname, lastname, is_group); - LLNameEditor::refreshAll(id, firstname, lastname, is_group); + LLNameBox::refreshAll(id, full_name, is_group); + LLNameEditor::refreshAll(id, full_name, is_group); // TODO: Actually be intelligent about the refresh. // For now, just brute force refresh the dialogs. @@ -1272,16 +1271,7 @@ bool idle_startup() gXferManager->registerCallbacks(gMessageSystem); - if ( gCacheName == NULL ) - { - gCacheName = new LLCacheName(gMessageSystem); - gCacheName->addObserver(&callback_cache_name); - gCacheName->LocalizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting")); - gCacheName->LocalizeCacheName("nobody", LLTrans::getString("AvatarNameNobody")); - gCacheName->LocalizeCacheName("none", LLTrans::getString("GroupNameNone")); - // Load stored cache if possible - LLAppViewer::instance()->loadNameCache(); - } + LLStartUp::initNameCache(); // update the voice settings *after* gCacheName initialization // so that we can construct voice UI that relies on the name cache @@ -1605,12 +1595,6 @@ bool idle_startup() LLFloaterReg::showInstance("hud", LLSD(), FALSE); } - LLSD event_categories = response["event_categories"]; - if(event_categories.isDefined()) - { - LLEventInfo::loadCategories(event_categories); - } - LLSD event_notifications = response["event_notifications"]; if(event_notifications.isDefined()) { @@ -1623,7 +1607,6 @@ bool idle_startup() LLClassifiedInfo::loadCategories(classified_categories); } - // This method MUST be called before gInventory.findCategoryUUIDForType because of // gInventory.mIsAgentInvUsable is set to true in the gInventory.buildParentChildMap. gInventory.buildParentChildMap(); @@ -2322,8 +2305,8 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("MapBlockReply", LLWorldMapMessage::processMapBlockReply); msg->setHandlerFunc("MapItemReply", LLWorldMapMessage::processMapItemReply); - - msg->setHandlerFunc("EventInfoReply", LLFloaterEvent::processEventInfoReply); + msg->setHandlerFunc("EventInfoReply", LLEventNotifier::processEventInfoReply); + msg->setHandlerFunc("PickInfoReply", &LLAvatarPropertiesProcessor::processPickInfoReply); // msg->setHandlerFunc("ClassifiedInfoReply", LLPanelClassified::processClassifiedInfoReply); msg->setHandlerFunc("ClassifiedInfoReply", LLAvatarPropertiesProcessor::processClassifiedInfoReply); @@ -2668,6 +2651,33 @@ void LLStartUp::fontInit() LLFontGL::loadDefaultFonts(); } +void LLStartUp::initNameCache() +{ + // Can be called multiple times + if ( gCacheName ) return; + + gCacheName = new LLCacheName(gMessageSystem); + gCacheName->addObserver(&callback_cache_name); + gCacheName->localizeCacheName("waiting", LLTrans::getString("AvatarNameWaiting")); + gCacheName->localizeCacheName("nobody", LLTrans::getString("AvatarNameNobody")); + gCacheName->localizeCacheName("none", LLTrans::getString("GroupNameNone")); + // Load stored cache if possible + LLAppViewer::instance()->loadNameCache(); + + // Start cache in not-running state until we figure out if we have + // capabilities for display name lookup + LLAvatarNameCache::initClass(false); + LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames")); +} + +void LLStartUp::cleanupNameCache() +{ + LLAvatarNameCache::cleanupClass(); + + delete gCacheName; + gCacheName = NULL; +} + bool LLStartUp::dispatchURL() { // ok, if we've gotten this far and have a startup URL diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index e79aa0dbee..be1043cf91 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -87,8 +87,12 @@ public: // Load default fonts not already loaded at start screen static void fontInit(); + static void initNameCache(); + static void copyLibraryGestures(const std::string& same_gender_gestures); + static void cleanupNameCache(); + // outfit_folder_name can be a folder anywhere in your inventory, // but the name must be a case-sensitive exact match. // gender_name is either "male" or "female" diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index 99342bb564..e7b5c13860 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -26,14 +26,15 @@ #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 "llsyswellwindow.h" - #include "llbottomtray.h" #include "llscriptfloater.h" #include "llviewercontrol.h" @@ -278,14 +279,31 @@ LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& mChiclet->setOtherParticipantId(otherParticipantId); mChiclet->setVisible(true); - LLTextBox* contactName = getChild<LLTextBox>("contact_name"); - contactName->setValue(name); + 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"); diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h index 5854deb840..9f8ab01810 100644 --- a/indra/newview/llsyswellwindow.h +++ b/indra/newview/llsyswellwindow.h @@ -37,6 +37,7 @@ #include "boost/shared_ptr.hpp" +class LLAvatarName; class LLFlatListView; class LLChiclet; class LLIMChiclet; @@ -202,6 +203,7 @@ private: 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: diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index a9ab98da5f..c3090cb1fc 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -102,6 +102,7 @@ LLToast::LLToast(const LLToast::Params& p) if(!p.on_delete_toast().empty()) mOnDeleteToastSignal.connect(p.on_delete_toast()); + // *TODO: This signal doesn't seem to be used at all. if(!p.on_mouse_enter().empty()) mOnMouseEnterSignal.connect(p.on_mouse_enter()); } diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 2d0c360905..8b2f066d41 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -76,6 +76,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal LLNotificationFormPtr form = mNotification->getForm(); std::string edit_text_name; std::string edit_text_contents; + S32 edit_text_max_chars = 0; bool is_password = false; LLToastPanel::setBackgroundVisible(FALSE); @@ -115,6 +116,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal { edit_text_contents = (*it)["value"].asString(); edit_text_name = (*it)["name"].asString(); + edit_text_max_chars = (*it)["max_length_chars"].asInteger(); } else if (type == "password") { @@ -253,6 +255,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal mLineEditor->setName(edit_text_name); mLineEditor->reshape(leditor_rect.getWidth(), leditor_rect.getHeight()); mLineEditor->setRect(leditor_rect); + mLineEditor->setMaxTextChars(edit_text_max_chars); mLineEditor->setText(edit_text_contents); // decrease limit of line editor of teleport offer dialog to avoid truncation of diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 78cc96b353..371aad64bb 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -36,6 +36,7 @@ #include "llnotifications.h" #include "llviewertexteditor.h" +#include "llavatarnamecache.h" #include "lluiconstants.h" #include "llui.h" #include "llviewercontrol.h" @@ -67,7 +68,11 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification pGroupIcon->setValue(groupData.mInsigniaID); //header title - const std::string& from_name = payload["sender_name"].asString(); + std::string from_name = payload["sender_name"].asString(); + if (LLAvatarNameCache::useDisplayNames()) + { + from_name = LLCacheName::buildUsername(from_name); + } std::stringstream from; from << from_name << "/" << groupData.mName; LLTextBox* pTitleText = getChild<LLTextBox>("title"); diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index 1d8b82ec1b..e0cb200ef5 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -141,7 +141,8 @@ void LLToastIMPanel::spawnNameToolTip() { // Spawn at right side of the name textbox. LLRect sticky_rect = mAvatarName->calcScreenRect(); - S32 icon_x = llmin(sticky_rect.mLeft + mAvatarName->getTextPixelWidth() + 3, sticky_rect.mRight - 16); + S32 icon_x = + llmin(sticky_rect.mLeft + mAvatarName->getTextPixelWidth() + 3, sticky_rect.mRight); LLCoordGL pos(icon_x, sticky_rect.mTop); LLToolTip::Params params; diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 6bb95168e2..1c745906aa 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1469,13 +1469,12 @@ static void show_item_sharing_confirmation(const std::string name, } static void get_name_cb(const LLUUID& id, - const std::string& first_name, - const std::string& last_name, + const std::string& full_name, LLViewerInventoryItem* inv_item, const LLSD& dest, const LLUUID& dest_agent) { - show_item_sharing_confirmation(first_name + " " + last_name, + show_item_sharing_confirmation(full_name, inv_item, dest, id, @@ -1528,7 +1527,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ } else { - gCacheName->get(dest_agent, FALSE, boost::bind(&get_name_cb, _1, _2, _3, inv_item, dest, dest_agent)); + gCacheName->get(dest_agent, false, boost::bind(&get_name_cb, _1, _2, inv_item, dest, dest_agent)); } return true; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 864de018e0..d992d808c7 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -34,6 +34,7 @@ #include "llagent.h" #include "llagentcamera.h" +#include "llavatarnamecache.h" #include "llviewercontrol.h" #include "llfocusmgr.h" //#include "llfirstuse.h" @@ -874,23 +875,40 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l || !existing_inspector->getVisible() || existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID()) { - std::string avatar_name; + // IDEVO: 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) { - avatar_name = llformat("%s %s", firstname->getString(), lastname->getString()); + 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)) + { + final_name = av_name.getCompleteName(); } else { - avatar_name = LLTrans::getString("TooltipPerson"); + final_name = full_name; } - + // *HACK: We may select this object, so pretend it was clicked mPick = mHoverPick; LLInspector::Params p; p.fillFrom(LLUICtrlFactory::instance().getDefaultParams<LLInspector>()); - p.message(avatar_name); + p.message(final_name); p.image.name("Inspector_I"); p.click_callback(boost::bind(showAvatarInspector, hover_object->getID())); p.visible_time_near(6.f); diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index 8391c0f832..c3dd17def9 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -564,16 +564,16 @@ void LLTracker::renderBeacon(LLVector3d pos_global, std::string text; text = llformat( "%.0f m", to_vec.magVec()); - LLWString wstr; - wstr += utf8str_to_wstring(label); - wstr += '\n'; - wstr += utf8str_to_wstring(text); + std::string str; + str += label; + str += '\n'; + str += text; hud_textp->setFont(LLFontGL::getFontSansSerif()); hud_textp->setZCompare(FALSE); hud_textp->setColor(LLColor4(1.f, 1.f, 1.f, llmax(0.2f, llmin(1.f,(dist-FADE_DIST)/FADE_DIST)))); - hud_textp->setString(wstr); + hud_textp->setString(str); hud_textp->setVertAlignment(LLHUDText::ALIGN_VERT_CENTER); hud_textp->setPositionAgent(pos_agent); } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 916cbe2267..6640e32cd2 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -318,7 +318,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLImageGL::updateStats(gFrameTimeSeconds); LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode"); - LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("RenderShowGroupTitleAll") && gSavedSettings.getS32("AvatarNameTagMode")); + LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode")); gPipeline.mBackfaceCull = TRUE; gFrameCount++; diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp new file mode 100644 index 0000000000..5741fab29a --- /dev/null +++ b/indra/newview/llviewerdisplayname.cpp @@ -0,0 +1,208 @@ +/** + * @file llviewerdisplayname.cpp + * @brief Wrapper for display name functionality + * + * $LicenseInfo:firstyear=2010&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 "llviewerdisplayname.h" + +// viewer includes +#include "llagent.h" +#include "llviewerregion.h" +#include "llvoavatar.h" + +// library includes +#include "llavatarnamecache.h" +#include "llhttpclient.h" +#include "llhttpnode.h" +#include "llnotificationsutil.h" +#include "llui.h" // getLanguage() + +namespace LLViewerDisplayName +{ + // Fired when viewer receives server response to display name change + set_name_signal_t sSetDisplayNameSignal; + + // Fired when there is a change in the agent's name + name_changed_signal_t sNameChangedSignal; + + void addNameChangedCallback(const name_changed_signal_t::slot_type& cb) + { + sNameChangedSignal.connect(cb); + } + +} + +class LLSetDisplayNameResponder : public LLHTTPClient::Responder +{ +public: + // only care about errors + /*virtual*/ void error(U32 status, const std::string& reason) + { + LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD()); + LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); + } +}; + +void LLViewerDisplayName::set(const std::string& display_name, const set_name_slot_t& slot) +{ + // TODO: simple validation here + + LLViewerRegion* region = gAgent.getRegion(); + llassert(region); + std::string cap_url = region->getCapability("SetDisplayName"); + if (cap_url.empty()) + { + // this server does not support display names, report error + slot(false, "unsupported", LLSD()); + return; + } + + // People API can return localized error messages. Indicate our + // language preference via header. + LLSD headers; + headers["Accept-Language"] = LLUI::getLanguage(); + + // People API requires both the old and new value to change a variable. + // Our display name will be in cache before the viewer's UI is available + // to request a change, so we can use direct lookup without callback. + LLAvatarName av_name; + if (!LLAvatarNameCache::get( gAgent.getID(), &av_name)) + { + slot(false, "name unavailable", LLSD()); + return; + } + + // People API expects array of [ "old value", "new value" ] + LLSD change_array = LLSD::emptyArray(); + change_array.append(av_name.mDisplayName); + change_array.append(display_name); + + llinfos << "Set name POST to " << cap_url << llendl; + + // Record our caller for when the server sends back a reply + sSetDisplayNameSignal.connect(slot); + + // POST the requested change. The sim will not send a response back to + // this request directly, rather it will send a separate message after it + // communicates with the back-end. + LLSD body; + body["display_name"] = change_array; + LLHTTPClient::post(cap_url, body, new LLSetDisplayNameResponder, headers); +} + +class LLSetDisplayNameReply : public LLHTTPNode +{ + LOG_CLASS(LLSetDisplayNameReply); +public: + /*virtual*/ void post( + LLHTTPNode::ResponsePtr response, + const LLSD& context, + const LLSD& input) const + { + LLSD body = input["body"]; + + S32 status = body["status"].asInteger(); + bool success = (status == 200); + std::string reason = body["reason"].asString(); + LLSD content = body["content"]; + + llinfos << "status " << status << " reason " << reason << llendl; + + // If viewer's concept of display name is out-of-date, the set request + // will fail with 409 Conflict. If that happens, fetch up-to-date + // name information. + if (status == 409) + { + LLUUID agent_id = gAgent.getID(); + // Flush stale data + LLAvatarNameCache::erase( agent_id ); + // Queue request for new data + LLAvatarName ignored; + LLAvatarNameCache::get( agent_id, &ignored ); + // Kill name tag, as it is wrong + LLVOAvatar::invalidateNameTag( agent_id ); + } + + // inform caller of result + LLViewerDisplayName::sSetDisplayNameSignal(success, reason, content); + LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots(); + } +}; + + +class LLDisplayNameUpdate : public LLHTTPNode +{ + /*virtual*/ void post( + LLHTTPNode::ResponsePtr response, + const LLSD& context, + const LLSD& input) const + { + LLSD body = input["body"]; + LLUUID agent_id = body["agent_id"]; + std::string old_display_name = body["old_display_name"]; + // By convention this record is called "agent" in the People API + LLSD name_data = body["agent"]; + + // Inject the new name data into cache + LLAvatarName av_name; + av_name.fromLLSD( name_data ); + + llinfos << "name-update now " << LLDate::now() + << " next_update " << LLDate(av_name.mNextUpdate) + << llendl; + + // Name expiration time may be provided in headers, or we may use a + // default value + // *TODO: get actual headers out of ResponsePtr + //LLSD headers = response->mHeaders; + LLSD headers; + av_name.mExpires = + LLAvatarNameCache::nameExpirationFromHeaders(headers); + + LLAvatarNameCache::insert(agent_id, av_name); + + // force name tag to update + LLVOAvatar::invalidateNameTag(agent_id); + + LLSD args; + args["OLD_NAME"] = old_display_name; + args["SLID"] = av_name.mUsername; + args["NEW_NAME"] = av_name.mDisplayName; + LLNotificationsUtil::add("DisplayNameUpdate", args); + if (agent_id == gAgent.getID()) + { + LLViewerDisplayName::sNameChangedSignal(); + } + } +}; + +LLHTTPRegistration<LLSetDisplayNameReply> + gHTTPRegistrationMessageSetDisplayNameReply( + "/message/SetDisplayNameReply"); + +LLHTTPRegistration<LLDisplayNameUpdate> + gHTTPRegistrationMessageDisplayNameUpdate( + "/message/DisplayNameUpdate"); diff --git a/indra/newview/llviewerdisplayname.h b/indra/newview/llviewerdisplayname.h new file mode 100644 index 0000000000..16d59ae43b --- /dev/null +++ b/indra/newview/llviewerdisplayname.h @@ -0,0 +1,53 @@ +/** + * @file llviewerdisplayname.h + * @brief Wrapper for display name functionality + * + * $LicenseInfo:firstyear=2010&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 LLVIEWERDISPLAYNAME_H +#define LLVIEWERDISPLAYNAME_H + +#include <boost/signals2.hpp> + +class LLSD; +class LLUUID; + +namespace LLViewerDisplayName +{ + typedef boost::signals2::signal< + void (bool success, const std::string& reason, const LLSD& content)> + set_name_signal_t; + typedef set_name_signal_t::slot_type set_name_slot_t; + + typedef boost::signals2::signal<void (void)> name_changed_signal_t; + typedef name_changed_signal_t::slot_type name_changed_slot_t; + + // Sends an update to the server to change a display name + // and call back when done. May not succeed due to service + // unavailable or name not available. + void set(const std::string& display_name, const set_name_slot_t& slot); + + void addNameChangedCallback(const name_changed_signal_t::slot_type& cb); +} + +#endif // LLVIEWERDISPLAYNAME_H diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 7490ccf77a..b3f14b441d 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -49,6 +49,7 @@ #include "llfloaterbump.h" #include "llfloatercamera.h" #include "llfloaterdaycycle.h" +#include "llfloaterdisplayname.h" #include "llfloaterevent.h" #include "llfloatersearch.h" #include "llfloaterenvsettings.h" @@ -176,6 +177,7 @@ void LLViewerFloaterReg::registerFloaters() LLInspectObjectUtil::registerFloater(); LLInspectRemoteObjectUtil::registerFloater(); LLNotificationsUI::registerFloater(); + LLFloaterDisplayNameUtil::registerFloater(); LLFloaterReg::add("lagmeter", "floater_lagmeter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLagMeter>); LLFloaterReg::add("land_holdings", "floater_land_holdings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLandHoldings>); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 75a5b14154..7dbaa4cf92 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1776,9 +1776,9 @@ PermissionMask LLViewerInventoryItem::getPermissionMask() const //---------- -void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name) +void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group) { - rename(first_name + " " + last_name); + rename(name); gInventory.addChangedMask(LLInventoryObserver::LABEL, getUUID()); gInventory.notifyObservers(); } diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 7f5a92eeab..1af06a1be8 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -157,7 +157,7 @@ public: PermissionMask getPermissionMask() const; // callback - void onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name); + void onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group); // If this is a broken link, try to fix it and any other identical link. BOOL regenerateLink(); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index ecb7e2064d..4e14824e69 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -32,6 +32,7 @@ #include "llviewercontrol.h" #include "lldrawable.h" #include "llgl.h" +#include "llhudtext.h" #include "llrender.h" #include "llvoavatarself.h" #include "llvolume.h" diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d4af5048c3..ccf3df827d 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -28,6 +28,7 @@ #include "llviewermenu.h" // linden library includes +#include "llavatarnamecache.h" // IDEVO #include "llfloaterreg.h" #include "llcombobox.h" #include "llinventorypanel.h" @@ -2801,9 +2802,8 @@ class LLObjectMute : public view_listener_t LLNameValue *lastname = avatar->getNVPair("LastName"); if (firstname && lastname) { - name = firstname->getString(); - name += " "; - name += lastname->getString(); + name = LLCacheName::buildFullName( + firstname->getString(), lastname->getString()); } type = LLMute::AGENT; @@ -3149,58 +3149,6 @@ bool enable_freeze_eject(const LLSD& avatar_id) return new_value; } -class LLAvatarGiveCard : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - llinfos << "handle_give_card()" << llendl; - LLViewerObject* dest = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); - if(dest && dest->isAvatar()) - { - bool found_name = false; - LLSD args; - LLSD old_args; - LLNameValue* nvfirst = dest->getNVPair("FirstName"); - LLNameValue* nvlast = dest->getNVPair("LastName"); - if(nvfirst && nvlast) - { - args["FIRST"] = nvfirst->getString(); - args["LAST"] = nvlast->getString(); - old_args["FIRST"] = nvfirst->getString(); - old_args["LAST"] = nvlast->getString(); - found_name = true; - } - LLViewerRegion* region = dest->getRegion(); - LLHost dest_host; - if(region) - { - dest_host = region->getHost(); - } - if(found_name && dest_host.isOk()) - { - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("OfferCallingCard"); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->nextBlockFast(_PREHASH_AgentBlock); - msg->addUUIDFast(_PREHASH_DestID, dest->getID()); - LLUUID transaction_id; - transaction_id.generate(); - msg->addUUIDFast(_PREHASH_TransactionID, transaction_id); - msg->sendReliable(dest_host); - LLNotificationsUtil::add("OfferedCard", args); - } - else - { - LLNotificationsUtil::add("CantOfferCallingCard", old_args); - } - } - return true; - } -}; - - void login_done(S32 which, void *user) { @@ -3623,21 +3571,17 @@ void request_friendship(const LLUUID& dest_id) LLViewerObject* dest = gObjectList.findObject(dest_id); if(dest && dest->isAvatar()) { - std::string fullname; - LLSD args; + std::string full_name; LLNameValue* nvfirst = dest->getNVPair("FirstName"); LLNameValue* nvlast = dest->getNVPair("LastName"); if(nvfirst && nvlast) { - args["FIRST"] = nvfirst->getString(); - args["LAST"] = nvlast->getString(); - fullname = nvfirst->getString(); - fullname += " "; - fullname += nvlast->getString(); + full_name = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); } - if (!fullname.empty()) + if (!full_name.empty()) { - LLAvatarActions::requestFriendshipDialog(dest_id, fullname); + LLAvatarActions::requestFriendshipDialog(dest_id, full_name); } else { @@ -7730,6 +7674,16 @@ class LLWorldToggleCameraControls : public view_listener_t } }; +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); + + if (gCacheName) gCacheName->clear(); +} + class LLUploadCostCalculator : public view_listener_t { std::string mCostStr; @@ -7973,6 +7927,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole"); view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole"); view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); + // Advanced > HUD Info view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo"); view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo"); @@ -8056,6 +8011,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames"); view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames"); view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs"); + commit.add("Advanced.FlushNameCaches", boost::bind(&handle_flush_name_caches)); // Advanced > Character > Grab Baked Texture view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture"); @@ -8156,7 +8112,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug"); view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug"); view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup"); - view_listener_t::addMenu(new LLAvatarGiveCard(), "Avatar.GiveCard"); commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD())); view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM"); view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call"); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 26b7e0fb6d..9b1f2e67c6 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -28,9 +28,11 @@ #include "llviewermessage.h" #include "boost/lexical_cast.hpp" +// Linden libraries #include "llanimationstates.h" #include "llaudioengine.h" #include "llavataractions.h" +#include "llavatarnamecache.h" // IDEVO HACK #include "lscript_byteformat.h" #include "lleconomy.h" #include "lleventtimer.h" @@ -80,6 +82,7 @@ #include "lltrans.h" #include "lltranslate.h" #include "llviewerfoldertype.h" +#include "llvoavatar.h" // IDEVO HACK #include "lluri.h" #include "llviewergenericmessage.h" #include "llviewermenu.h" @@ -129,6 +132,7 @@ extern BOOL gDebugClicks; // function prototypes bool check_offer_throttle(const std::string& from_name, bool check_only); +static void process_money_balance_reply_extended(LLMessageSystem* msg); //inventory offer throttle globals LLFrameTimer gThrottleTimer; @@ -1237,28 +1241,26 @@ bool highlight_offered_object(const LLUUID& obj_id) } void inventory_offer_mute_callback(const LLUUID& blocked_id, - const std::string& first_name, - const std::string& last_name, - BOOL is_group, boost::shared_ptr<LLNotificationResponderInterface> offer_ptr) + const std::string& full_name, + bool is_group, + boost::shared_ptr<LLNotificationResponderInterface> offer_ptr) { LLOfferInfo* offer = dynamic_cast<LLOfferInfo*>(offer_ptr.get()); - std::string from_name; + + std::string from_name = full_name; LLMute::EType type; if (is_group) { type = LLMute::GROUP; - from_name = first_name; } else if(offer && offer->mFromObject) { //we have to block object by name because blocked_id is an id of owner type = LLMute::BY_NAME; - from_name = offer->mFromName; } else { type = LLMute::AGENT; - from_name = first_name + " " + last_name; } // id should be null for BY_NAME mute, see LLMuteList::add for details @@ -1436,7 +1438,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& llassert(notification_ptr != NULL); if (notification_ptr != NULL) { - gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); + gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr())); } } @@ -1576,7 +1578,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const llassert(notification_ptr != NULL); if (notification_ptr != NULL) { - gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,_4, notification_ptr->getResponderPtr())); + gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback,_1,_2,_3,notification_ptr->getResponderPtr())); } } @@ -1625,12 +1627,12 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const } else { - std::string first_name, last_name; - if (gCacheName->getName(mFromID, first_name, last_name)) + std::string full_name; + if (gCacheName->getFullName(mFromID, full_name)) { from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName - + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + first_name + " " + last_name; - chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + first_name + " " + last_name; + + LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + full_name; + chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + full_name; } else { @@ -1834,7 +1836,14 @@ void inventory_offer_handler(LLOfferInfo* info) payload["give_inventory_notification"] = FALSE; args["OBJECTFROMNAME"] = info->mFromName; args["NAME"] = info->mFromName; - args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString(); + if (info->mFromGroup) + { + args["NAME_SLURL"] = LLSLURL("group", info->mFromID, "about").getSLURLString(); + } + else + { + args["NAME_SLURL"] = LLSLURL("agent", info->mFromID, "about").getSLURLString(); + } std::string verb = "select?name=" + LLURI::escape(msg); args["ITEM_SLURL"] = LLSLURL("inventory", info->mObjectID, verb.c_str()).getSLURLString(); @@ -1956,7 +1965,6 @@ protected: void modifyNotificationParams() { LLSD payload = mParams.payload; - payload["SESSION_NAME"] = mName; mParams.payload = payload; } }; @@ -2019,6 +2027,99 @@ static bool parse_lure_bucket(const std::string& bucket, return true; } +// Strip out "Resident" for display, but only if the message came from a user +// (rather than a script) +static std::string clean_name_from_im(const std::string& name, EInstantMessage type) +{ + switch(type) + { + case IM_NOTHING_SPECIAL: + case IM_MESSAGEBOX: + case IM_GROUP_INVITATION: + case IM_INVENTORY_OFFERED: + case IM_INVENTORY_ACCEPTED: + case IM_INVENTORY_DECLINED: + case IM_GROUP_VOTE: + case IM_GROUP_MESSAGE_DEPRECATED: + //IM_TASK_INVENTORY_OFFERED + //IM_TASK_INVENTORY_ACCEPTED + //IM_TASK_INVENTORY_DECLINED + case IM_NEW_USER_DEFAULT: + case IM_SESSION_INVITE: + case IM_SESSION_P2P_INVITE: + case IM_SESSION_GROUP_START: + case IM_SESSION_CONFERENCE_START: + case IM_SESSION_SEND: + case IM_SESSION_LEAVE: + //IM_FROM_TASK + case IM_BUSY_AUTO_RESPONSE: + case IM_CONSOLE_AND_CHAT_HISTORY: + case IM_LURE_USER: + case IM_LURE_ACCEPTED: + case IM_LURE_DECLINED: + case IM_GODLIKE_LURE_USER: + case IM_YET_TO_BE_USED: + case IM_GROUP_ELECTION_DEPRECATED: + //IM_GOTO_URL + //IM_FROM_TASK_AS_ALERT + case IM_GROUP_NOTICE: + case IM_GROUP_NOTICE_INVENTORY_ACCEPTED: + case IM_GROUP_NOTICE_INVENTORY_DECLINED: + case IM_GROUP_INVITATION_ACCEPT: + case IM_GROUP_INVITATION_DECLINE: + case IM_GROUP_NOTICE_REQUESTED: + case IM_FRIENDSHIP_OFFERED: + case IM_FRIENDSHIP_ACCEPTED: + case IM_FRIENDSHIP_DECLINED_DEPRECATED: + //IM_TYPING_START + //IM_TYPING_STOP + return LLCacheName::cleanFullName(name); + default: + return name; + } +} + +static std::string clean_name_from_task_im(const std::string& msg, + BOOL from_group) +{ + boost::smatch match; + static const boost::regex returned_exp( + "(.*been returned to your inventory lost and found folder by )(.+)( (from|near).*)"); + if (boost::regex_match(msg, match, returned_exp)) + { + // match objects are 1-based for groups + std::string final = match[1].str(); + std::string name = match[2].str(); + // 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 += match[3].str(); + return final; + } + return msg; +} + +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; + LLNotificationsUtil::add(name, substitutions, payload); +} + class LLPostponedIMSystemTipNotification: public LLPostponedNotification { protected: @@ -2029,8 +2130,28 @@ protected: payload["SESSION_NAME"] = mName; mParams.payload = payload; } + }; +// Callback for name resolution of a god/estate message +void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message) +{ + LLSD args; + args["NAME"] = av_name.getCompleteName(); + args["MESSAGE"] = message; + LLNotificationsUtil::add("GodMessage", args); + + // Treat like a system message and put in chat history. + chat.mText = av_name.getCompleteName() + ": " + message; + + LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); + if(nearby_chat) + { + nearby_chat->addMessage(chat); + } + +} + void process_improved_im(LLMessageSystem *msg, void **user_data) { if (gNoRender) @@ -2078,6 +2199,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { name = LLTrans::getString("Unnamed"); } + // IDEVO convert new-style "Resident" names for display + name = clean_name_from_im(name, dialog); BOOL is_busy = gAgent.getBusy(); BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat); @@ -2107,7 +2230,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) { case IM_CONSOLE_AND_CHAT_HISTORY: args["MESSAGE"] = message; - args["NAME"] = name; payload["from_id"] = from_id; params.name = "IMSystemMessageTip"; @@ -2177,21 +2299,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else if (to_id.isNull()) { - // Message to everyone from GOD - args["NAME"] = name; - args["MESSAGE"] = message; - LLNotificationsUtil::add("GodMessage", args); - - // Treat like a system message and put in chat history. - // Claim to be from a local agent so it doesn't go into - // console. - chat.mText = name + separator_string + message; - - LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD()); - if(nearby_chat) - { - nearby_chat->addMessage(chat); - } + // Message to everyone from GOD, look up the fullname since + // server always slams name to legacy names + LLAvatarNameCache::get(from_id, boost::bind(god_message_name_cb, _2, chat, message)); } else { @@ -2391,6 +2501,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) invite_bucket = (struct invite_bucket_t*) &binary_bucket[0]; S32 membership_fee = ntohl(invite_bucket->membership_fee); + // IDEVO Clean up legacy name "Resident" in message constructed in + // lldatagroups.cpp + U32 pos = message.find(" has invited you to join a group.\n"); + if (pos != std::string::npos) + { + // use cleaned-up name from above + message = name + message.substr(pos); + } + LLSD payload; payload["transaction_id"] = session_id; payload["group_id"] = from_id; @@ -2478,7 +2597,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) case IM_INVENTORY_ACCEPTED: { - args["NAME"] = name; + args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();; LLSD payload; payload["from_id"] = from_id; LLNotificationsUtil::add("InventoryAccepted", args, payload); @@ -2486,7 +2605,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } case IM_INVENTORY_DECLINED: { - args["NAME"] = name; + args["NAME"] = LLSLURL("agent", from_id, "completename").getSLURLString();; LLSD payload; payload["from_id"] = from_id; LLNotificationsUtil::add("InventoryDeclined", args, payload); @@ -2578,6 +2697,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) chat.mSourceType = CHAT_SOURCE_SYSTEM; } + // IDEVO Some messages have embedded resident names + message = clean_name_from_task_im(message, from_group); + LLSD query_string; query_string["owner"] = from_id; query_string["slurl"] = location; @@ -2786,7 +2908,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) args["NAME"] = name; LLSD payload; payload["from_id"] = from_id; - LLNotificationsUtil::add("FriendshipAccepted", args, payload); + LLAvatarNameCache::get(from_id, boost::bind(¬ification_display_name_callback, + _1, + _2, + "FriendshipAccepted", + args, + payload)); } break; @@ -2890,9 +3017,8 @@ void process_offer_callingcard(LLMessageSystem* msg, void**) LLNameValue* nvlast = source->getNVPair("LastName"); if (nvfirst && nvlast) { - args["FIRST"] = nvfirst->getString(); - args["LAST"] = nvlast->getString(); - source_name = std::string(nvfirst->getString()) + " " + nvlast->getString(); + source_name = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); } } @@ -2969,7 +3095,6 @@ private: std::string m_origMesg; LLSD m_toastArgs; }; - void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) { LLChat chat; @@ -2985,7 +3110,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) LLViewerObject* chatter; msg->getString("ChatData", "FromName", from_name); - chat.mFromName = from_name; msg->getUUID("ChatData", "SourceID", from_id); chat.mFromID = from_id; @@ -3004,6 +3128,27 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) chat.mTime = LLFrameTimer::getElapsedSeconds(); + // IDEVO Correct for new-style "Resident" names + if (chat.mSourceType == CHAT_SOURCE_AGENT) + { + // I don't know if it's OK to change this here, if + // anything downstream does lookups by name, for instance + + LLAvatarName av_name; + if (LLAvatarNameCache::get(from_id, &av_name)) + { + chat.mFromName = av_name.mDisplayName; + } + else + { + chat.mFromName = LLCacheName::cleanFullName(from_name); + } + } + else + { + chat.mFromName = from_name; + } + BOOL is_busy = gAgent.getBusy(); BOOL is_muted = FALSE; @@ -4885,168 +5030,287 @@ void process_time_dilation(LLMessageSystem *msg, void **user_data) */ - void process_money_balance_reply( LLMessageSystem* msg, void** ) { S32 balance = 0; S32 credit = 0; S32 committed = 0; std::string desc; + LLUUID tid; + msg->getUUID("MoneyData", "TransactionID", tid); msg->getS32("MoneyData", "MoneyBalance", balance); msg->getS32("MoneyData", "SquareMetersCredit", credit); msg->getS32("MoneyData", "SquareMetersCommitted", committed); msg->getStringFast(_PREHASH_MoneyData, _PREHASH_Description, desc); LL_INFOS("Messaging") << "L$, credit, committed: " << balance << " " << credit << " " << committed << LL_ENDL; - + if (gStatusBar) { - // S32 old_balance = gStatusBar->getBalance(); - - // This is an update, not the first transmission of balance - /* if (old_balance != 0) - { - // this is actually an update - if (balance > old_balance) - { - LLFirstUse::useBalanceIncrease(balance - old_balance); - } - else if (balance < old_balance) - { - LLFirstUse::useBalanceDecrease(balance - old_balance); - } - } - */ gStatusBar->setBalance(balance); gStatusBar->setLandCredit(credit); gStatusBar->setLandCommitted(committed); } - LLUUID tid; - msg->getUUID("MoneyData", "TransactionID", tid); + if (desc.empty() + || !gSavedSettings.getBOOL("NotifyMoneyChange")) + { + // ...nothing to display + return; + } + + // Suppress duplicate messages about the same transaction static std::deque<LLUUID> recent; - if(!desc.empty() && gSavedSettings.getBOOL("NotifyMoneyChange") - && (std::find(recent.rbegin(), recent.rend(), tid) == recent.rend())) + if (std::find(recent.rbegin(), recent.rend(), tid) != recent.rend()) { - // Make the user confirm the transaction, since they might - // have missed something during an event. - // *TODO: Translate - LLSD args; - + return; + } - // this is a marker to retrieve avatar name from server message: - // "<avatar name> paid you L$" - const std::string marker = "paid you L$"; + // Once the 'recent' container gets large enough, chop some + // off the beginning. + const U32 MAX_LOOKBACK = 30; + const S32 POP_FRONT_SIZE = 12; + if(recent.size() > MAX_LOOKBACK) + { + LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL; + recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE); + } + //LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL; + recent.push_back(tid); + if (msg->has("TransactionInfo")) + { + // ...message has extended info for localization + process_money_balance_reply_extended(msg); + } + else + { + // Only old dev grids will not supply the TransactionInfo block, + // so we can just use the hard-coded English string. + LLSD args; args["MESSAGE"] = desc; + LLNotificationsUtil::add("SystemMessage", args); + } +} + +static std::string reason_from_transaction_type(S32 transaction_type, + const std::string& item_desc) +{ + // *NOTE: The keys for the reason strings are unusual because + // an earlier version of the code used English language strings + // extracted from hard-coded server English descriptions. + // Keeping them so we don't have to re-localize them. + switch (transaction_type) + { + case TRANS_OBJECT_SALE: + { + LLStringUtil::format_map_t arg; + arg["ITEM"] = item_desc; + return LLTrans::getString("for item", arg); + } + case TRANS_LAND_SALE: + return LLTrans::getString("for a parcel of land"); + + case TRANS_LAND_PASS_SALE: + return LLTrans::getString("for a land access pass"); + + case TRANS_GROUP_LAND_DEED: + return LLTrans::getString("for deeding land"); + + case TRANS_GROUP_CREATE: + return LLTrans::getString("to create a group"); + + case TRANS_GROUP_JOIN: + return LLTrans::getString("to join a group"); + + case TRANS_UPLOAD_CHARGE: + return LLTrans::getString("to upload"); - // extract avatar name from system message - S32 marker_pos = desc.find(marker, 0); + case TRANS_CLASSIFIED_CHARGE: + return LLTrans::getString("to publish a classified ad"); + + // These have no reason to display, but are expected and should not + // generate warnings + case TRANS_GIFT: + case TRANS_PAY_OBJECT: + case TRANS_OBJECT_PAYS: + return std::string(); - std::string base_name = desc.substr(0, marker_pos); - - std::string name = base_name; - LLStringUtil::trim(name); + default: + llwarns << "Unknown transaction type " + << transaction_type << llendl; + return std::string(); + } +} - // if name extracted and name cache contains avatar id send loggable notification - LLUUID from_id; - if(name.size() > 0 && gCacheName->getUUID(name, from_id)) - { - //description always comes not localized. lets fix this +static void money_balance_group_notify(const LLUUID& group_id, + const std::string& name, + bool is_group, + std::string notification, + LLSD args, + LLSD payload) +{ + // Message uses name SLURLs, don't actually have to substitute in + // the name. We're just making sure it's available. + // Notification is either PaymentReceived or PaymentSent + LLNotificationsUtil::add(notification, args, payload); +} - //ammount paid - std::string ammount = desc.substr(marker_pos + marker.length(),desc.length() - marker.length() - marker_pos); - - //reform description - LLStringUtil::format_map_t str_args; - str_args["NAME"] = base_name; - str_args["AMOUNT"] = ammount; - std::string new_description = LLTrans::getString("paid_you_ldollars", str_args); +static void money_balance_avatar_notify(const LLUUID& agent_id, + const LLAvatarName& av_name, + std::string notification, + LLSD args, + LLSD payload) +{ + // Message uses name SLURLs, don't actually have to substitute in + // the name. We're just making sure it's available. + // Notification is either PaymentReceived or PaymentSent + LLNotificationsUtil::add(notification, args, payload); +} +static void process_money_balance_reply_extended(LLMessageSystem* msg) +{ + // Added in server 1.40 and viewer 2.1, support for localization + // and agent ids for name lookup. + S32 transaction_type = 0; + LLUUID source_id; + BOOL is_source_group = FALSE; + LLUUID dest_id; + BOOL is_dest_group = FALSE; + S32 amount = 0; + std::string item_description; + + msg->getS32("TransactionInfo", "TransactionType", transaction_type); + msg->getUUID("TransactionInfo", "SourceID", source_id); + msg->getBOOL("TransactionInfo", "IsSourceGroup", is_source_group); + msg->getUUID("TransactionInfo", "DestID", dest_id); + msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group); + msg->getS32("TransactionInfo", "Amount", amount); + msg->getString("TransactionInfo", "ItemDescription", item_description); + LL_INFOS("Money") << "MoneyBalanceReply source " << source_id + << " dest " << dest_id + << " type " << transaction_type + << " item " << item_description << LL_ENDL; + + if (source_id.isNull() && dest_id.isNull()) + { + // this is a pure balance update, no notification required + return; + } - args["MESSAGE"] = new_description; - args["NAME"] = name; - LLSD payload; - payload["from_id"] = from_id; - LLNotificationsUtil::add("PaymentRecived", args, payload); + std::string source_slurl; + if (is_source_group) + { + source_slurl = + LLSLURL( "group", source_id, "inspect").getSLURLString(); + } + else + { + source_slurl = + LLSLURL( "agent", source_id, "completename").getSLURLString(); + } + + std::string dest_slurl; + if (is_dest_group) + { + dest_slurl = + LLSLURL( "group", dest_id, "inspect").getSLURLString(); + } + else + { + dest_slurl = + LLSLURL( "agent", dest_id, "completename").getSLURLString(); + } + + std::string reason = + reason_from_transaction_type(transaction_type, item_description); + + LLStringUtil::format_map_t args; + args["REASON"] = reason; // could be empty + args["AMOUNT"] = llformat("%d", amount); + + // Need to delay until name looked up, so need to know whether or not + // is group + bool is_name_group = false; + LLUUID name_id; + std::string message; + std::string notification; + LLSD final_args; + LLSD payload; + + bool you_paid_someone = (source_id == gAgentID); + if (you_paid_someone) + { + args["NAME"] = dest_slurl; + is_name_group = is_dest_group; + name_id = dest_id; + if (!reason.empty()) + { + if (dest_id.notNull()) + { + message = LLTrans::getString("you_paid_ldollars", args); + } + else + { + // transaction fee to the system, eg, to create a group + message = LLTrans::getString("you_paid_ldollars_no_name", args); + } } - //AD *HACK: Parsing incoming string to localize messages that come from server! EXT-5986 - // It's only a temporarily and ineffective measure. It doesn't affect performance much - // because we get here only for specific type of messages, but anyway it is not right to do it! - // *TODO: Server-side changes should be made and this code removed. else { - if(desc.find("You paid")==0) + if (dest_id.notNull()) { - // Regular expression for message parsing- change it in case of server-side changes. - // Each set of parenthesis will later be used to find arguments of message we generate - // in the end of this if- (.*) gives us name of money receiver, (\\d+)-amount of money we pay - // and ([^$]*)- reason of payment - boost::regex expr("You paid (?:.{0}|(.*) )L\\$(\\d+)\\s?([^$]*)\\."); - boost::match_results <std::string::const_iterator> matches; - if(boost::regex_match(desc, matches, expr)) - { - // Name of full localizable notification string - // there are four types of this string- with name of receiver and reason of payment, - // without name and without reason (both may also be absent simultaneously). - // example of string without name - You paid L$100 to create a group. - // example of string without reason - You paid Smdby Linden L$100. - // example of string with reason and name - You paid Smbdy Linden L$100 for a land access pass. - // example of string with no info - You paid L$50. - std::string line = "you_paid_ldollars_no_name"; - - // arguments of string which will be in notification - LLStringUtil::format_map_t str_args; - - // extracting amount of money paid (without L$ symbols). It is always present. - str_args["[AMOUNT]"] = std::string(matches[2]); - - // extracting name of person/group you are paying (it may be absent) - std::string name = std::string(matches[1]); - if(!name.empty()) - { - str_args["[NAME]"] = name; - line = "you_paid_ldollars"; - } - - // extracting reason of payment (it may be absent) - std::string reason = std::string(matches[3]); - if (reason.empty()) - { - line = name.empty() ? "you_paid_ldollars_no_info" : "you_paid_ldollars_no_reason"; - } - else - { - std::string localized_reason; - // if we haven't found localized string for reason of payment leave it as it was - str_args["[REASON]"] = LLTrans::findString(localized_reason, reason) ? localized_reason : reason; - } - - // forming final message string by retrieving localized version from xml - // and applying previously found arguments - line = LLTrans::getString(line, str_args); - args["MESSAGE"] = line; - } + message = LLTrans::getString("you_paid_ldollars_no_reason", args); + } + else + { + // no target, no reason, you just paid money + message = LLTrans::getString("you_paid_ldollars_no_info", args); } - - LLNotificationsUtil::add("SystemMessage", args); } - - // Once the 'recent' container gets large enough, chop some - // off the beginning. - const U32 MAX_LOOKBACK = 30; - const S32 POP_FRONT_SIZE = 12; - if(recent.size() > MAX_LOOKBACK) + final_args["MESSAGE"] = message; + notification = "PaymentSent"; + } + else { + // ...someone paid you + args["NAME"] = source_slurl; + is_name_group = is_source_group; + name_id = source_id; + if (!reason.empty()) { - LL_DEBUGS("Messaging") << "Removing oldest transaction records" << LL_ENDL; - recent.erase(recent.begin(), recent.begin() + POP_FRONT_SIZE); + message = LLTrans::getString("paid_you_ldollars", args); } - //LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL; - recent.push_back(tid); + else { + message = LLTrans::getString("paid_you_ldollars_no_reason", args); + } + final_args["MESSAGE"] = message; + + // make notification loggable + payload["from_id"] = source_id; + notification = "PaymentReceived"; + } + + // Despite using SLURLs, wait until the name is available before + // showing the notification, otherwise the UI layout is strange and + // the user sees a "Loading..." message + if (is_name_group) + { + gCacheName->getGroup(name_id, + boost::bind(&money_balance_group_notify, + _1, _2, _3, + notification, final_args, payload)); + } + else { + LLAvatarNameCache::get(name_id, + boost::bind(&money_balance_avatar_notify, + _1, _2, + notification, final_args, payload)); } } + + bool handle_special_notification_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -5288,7 +5552,7 @@ void handle_show_mean_events(void *) //LLFloaterBump::showInstance(); } -void mean_name_callback(const LLUUID &id, const std::string& first, const std::string& last, BOOL always_false) +void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group) { if (gNoRender) { @@ -5310,8 +5574,7 @@ void mean_name_callback(const LLUUID &id, const std::string& first, const std::s LLMeanCollisionData *mcd = *iter; if (mcd->mPerp == id) { - mcd->mFirstName = first; - mcd->mLastName = last; + mcd->mFullName = full_name; } } } @@ -5365,8 +5628,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use { LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag); gMeanCollisionList.push_front(mcd); - const BOOL is_group = FALSE; - gCacheName->get(perp, is_group, &mean_name_callback); + gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3)); } } } @@ -5588,7 +5850,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data) // so we'll reuse the same namespace for both throttle types. std::string throttle_name = owner_name; std::string self_name; - LLAgentUI::buildName( self_name ); + LLAgentUI::buildFullname( self_name ); if( owner_name == self_name ) { throttle_name = taskid.getString(); @@ -5624,7 +5886,7 @@ void process_script_question(LLMessageSystem *msg, void **user_data) S32 count = 0; LLSD args; args["OBJECTNAME"] = object_name; - args["NAME"] = owner_name; + args["NAME"] = LLCacheName::cleanFullName(owner_name); // check the received permission flags against each permission for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++) @@ -6030,15 +6292,14 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response) // Record the offer. { std::string target_name; - gCacheName->getFullName(target_id, target_name); + gCacheName->getFullName(target_id, target_name); // for im log filenames LLSD args; - args["TO_NAME"] = target_name; + args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();; LLSD payload; //*TODO please rewrite all keys to the same case, lower or upper payload["from_id"] = target_id; - payload["SESSION_NAME"] = target_name; payload["SUPPRESS_TOAST"] = true; LLNotificationsUtil::add("TeleportOfferSent", args, payload); } @@ -6252,8 +6513,7 @@ void process_script_dialog(LLMessageSystem* msg, void**) LLNotificationPtr notification; if (!first_name.empty()) { - args["FIRST"] = first_name; - args["LAST"] = last_name; + args["NAME"] = LLCacheName::buildFullName(first_name, last_name); notification = LLNotifications::instance().add( LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD())); } @@ -6286,7 +6546,7 @@ static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", ca // We've got the name of the person who owns the object hurling the url. // Display confirmation dialog. -void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool is_group) { std::vector<LLSD>::iterator it; for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); ) @@ -6299,11 +6559,11 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st std::string owner_name; if (is_group) { - owner_name = first + LLTrans::getString("Group"); + owner_name = full_name + LLTrans::getString("Group"); } else { - owner_name = first + " " + last; + owner_name = full_name; } // For legacy name-only mutes. @@ -6363,7 +6623,8 @@ void process_load_url(LLMessageSystem* msg, void**) // Add to list of pending name lookups gLoadUrlList.push_back(payload); - gCacheName->get(owner_id, owner_is_group, &callback_load_url_name); + gCacheName->get(owner_id, owner_is_group, + boost::bind(&callback_load_url_name, _1, _2, _3)); } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index fd3e80d755..a58b0d68de 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -63,6 +63,7 @@ #include "llface.h" #include "llfloaterproperties.h" #include "llfollowcam.h" +#include "llhudtext.h" #include "llselectmgr.h" #include "llrendersphere.h" #include "lltooldraganddrop.h" @@ -1092,7 +1093,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, // alpha was flipped so that it zero encoded better coloru.mV[3] = 255 - coloru.mV[3]; mText->setColor(LLColor4(coloru)); - mText->setStringUTF8(temp_string); + mText->setString(temp_string); if (mDrawable.notNull()) { @@ -1484,7 +1485,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, dp->unpackBinaryDataFixed(coloru.mV, 4, "Color"); coloru.mV[3] = 255 - coloru.mV[3]; mText->setColor(LLColor4(coloru)); - mText->setStringUTF8(temp_string); + mText->setString(temp_string); setChanged(TEXTURE); } @@ -4150,7 +4151,7 @@ void LLViewerObject::setDebugText(const std::string &utf8text) mText->setOnHUDAttachment(isHUDAttachment()); } mText->setColor(LLColor4::white); - mText->setStringUTF8(utf8text); + mText->setString(utf8text); mText->setZCompare(FALSE); mText->setDoFade(FALSE); updateText(); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bcc2cb164f..7d697a4a5f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -31,7 +31,6 @@ #include "llassetstorage.h" #include "lldarrayptr.h" -#include "llhudtext.h" #include "llhudicon.h" #include "llinventory.h" #include "llrefcount.h" @@ -54,6 +53,7 @@ class LLColor4; class LLFrameTimer; class LLDrawable; class LLHost; +class LLHUDText; class LLWorld; class LLNameValue; class LLNetMap; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 05695193a5..b597e6148e 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -47,7 +47,7 @@ #include "lltooltip.h" #include "llworld.h" #include "llstring.h" -#include "llhudtext.h" +#include "llhudnametag.h" #include "lldrawable.h" #include "xform.h" #include "llsky.h" @@ -1195,7 +1195,7 @@ void LLViewerObjectList::generatePickList(LLCamera &camera) } } - LLHUDText::addPickable(mSelectPickList); + LLHUDNameTag::addPickable(mSelectPickList); for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin(); iter != LLCharacter::sInstances.end(); ++iter) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 660bb93562..11de377410 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -2069,10 +2069,7 @@ void LLViewerParcelMgr::deedLandToGroup() args["GROUP_NAME"] = group_name; if(mCurrentParcel->getContributeWithDeed()) { - std::string first_name, last_name; - gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name); - args["FIRST_NAME"] = first_name; - args["LAST_NAME"] = last_name; + args["NAME"] = LLSLURL("agent", mCurrentParcel->getOwnerID(), "completename").getSLURLString(); LLNotificationsUtil::add("DeedLandToGroupWithContribution",args, LLSD(), deedAlertCB); } else diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 98f16757b2..7fb259e012 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -28,7 +28,9 @@ #include "llviewerregion.h" +// linden libraries #include "indra_constants.h" +#include "llavatarnamecache.h" // name lookup cap url #include "llfloaterreg.h" #include "llmath.h" #include "llhttpclient.h" @@ -163,7 +165,9 @@ public: mRegion->showReleaseNotes(); } } - + + mRegion->setCapabilitiesReceived(true); + if (STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState()) { LLStartUp::setStartupState( STATE_SEED_CAP_GRANTED ); @@ -221,7 +225,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, // LLCapabilityListener binds all the globals it expects to need at // construction time. mCapabilityListener(host.getString(), gMessageSystem, *this, - gAgent.getID(), gAgent.getSessionID()) + gAgent.getID(), gAgent.getSessionID()), + mCapabilitiesReceived(false) { mWidth = region_width_meters; mOriginGlobal = from_region_handle(handle); @@ -1360,6 +1365,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) LLSD capabilityNames = LLSD::emptyArray(); capabilityNames.append("AttachmentResources"); + capabilityNames.append("AvatarPickerSearch"); capabilityNames.append("ChatSessionRequest"); capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("DispatchRegionInfo"); @@ -1370,6 +1376,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("ObjectMediaNavigate"); capabilityNames.append("FetchLib"); capabilityNames.append("FetchLibDescendents"); + capabilityNames.append("GetDisplayNames"); capabilityNames.append("GetTexture"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); @@ -1391,6 +1398,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url) capabilityNames.append("SendUserReport"); capabilityNames.append("SendUserReportWithScreenshot"); capabilityNames.append("ServerReleaseNotes"); + capabilityNames.append("SetDisplayName"); capabilityNames.append("StartGroupProposal"); capabilityNames.append("TextureStats"); capabilityNames.append("UntrustedSimulatorMessage"); @@ -1452,6 +1460,16 @@ std::string LLViewerRegion::getCapability(const std::string& name) const return iter->second; } +bool LLViewerRegion::capabilitiesReceived() const +{ + return mCapabilitiesReceived; +} + +void LLViewerRegion::setCapabilitiesReceived(bool received) +{ + mCapabilitiesReceived = received; +} + void LLViewerRegion::logActiveCapabilities() const { int count = 0; diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index 038c831e59..1ba025312b 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -228,6 +228,11 @@ public: void setCapability(const std::string& name, const std::string& url); // implements LLCapabilityProvider virtual std::string getCapability(const std::string& name) const; + + // has region received its final (not seed) capability list? + bool capabilitiesReceived() const; + void setCapabilitiesReceived(bool received); + static bool isSpecialCapabilityName(const std::string &name); void logActiveCapabilities() const; @@ -407,6 +412,7 @@ private: private: bool mAlive; // can become false if circuit disconnects + bool mCapabilitiesReceived; //spatial partitions for objects in this region std::vector<LLSpatialPartition*> mObjectPartition; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index e55808597c..42266ad233 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -847,6 +847,9 @@ void send_stats() llinfos << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << llendl; llinfos << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << llendl; + + body["DisplayNamesEnabled"] = gSavedSettings.getBOOL("UseDisplayNames"); + body["DisplayNamesShowUsername"] = gSavedSettings.getBOOL("NameTagShowUsernames"); LLViewerStats::getInstance()->addToMessage(body); LLHTTPClient::post(url, body, new ViewerStatsResponder()); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 983a2d25c8..a0a3380441 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -115,6 +115,7 @@ #include "llglheaders.h" #include "lltooltip.h" #include "llhudmanager.h" +#include "llhudobject.h" #include "llhudview.h" #include "llimagebmp.h" #include "llimagej2c.h" @@ -1174,12 +1175,8 @@ BOOL LLViewerWindow::handlePaint(LLWindow *window, S32 x, S32 y, S32 width, S //SetBKColor(hdc, RGB(255, 255, 255)); FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255))); - std::string name_str; - LLAgentUI::buildName(name_str); - std::string temp_str; - temp_str = llformat( "%s FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */ - name_str.c_str(), + temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f", /* Flawfinder: ignore */ LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(), LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0), LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0)); @@ -1874,7 +1871,7 @@ void LLViewerWindow::reshape(S32 width, S32 height) // clear font width caches if (display_scale_changed) { - LLHUDText::reshape(); + LLHUDObject::reshapeAll(); } sendShapeToSim(); @@ -3964,7 +3961,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei send_agent_pause(); //rescale fonts initFonts(scale_factor); - LLHUDText::reshape(); + LLHUDObject::reshapeAll(); } S32 output_buffer_offset_y = 0; @@ -4093,7 +4090,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei if (high_res) { initFonts(1.f); - LLHUDText::reshape(); + LLHUDObject::reshapeAll(); } // Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index c31714de5a..8738ad7687 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -38,6 +38,7 @@ #include <ctype.h> #include "llaudioengine.h" +#include "llcachename.h" #include "noise.h" #include "sound_ids.h" @@ -45,8 +46,10 @@ #include "llagentcamera.h" #include "llagentwearables.h" #include "llanimationstates.h" +#include "llavatarnamecache.h" #include "llavatarpropertiesprocessor.h" #include "llviewercontrol.h" +#include "llcallingcard.h" // IDEVO for LLAvatarTracker #include "lldrawpoolavatar.h" #include "lldriverparam.h" #include "lleditingmotion.h" @@ -55,6 +58,8 @@ #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" +#include "llhudnametag.h" +#include "llhudtext.h" // for mText/mDebugText #include "llkeyframefallmotion.h" #include "llkeyframestandmotion.h" #include "llkeyframewalkmotion.h" @@ -653,12 +658,14 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mAppearanceAnimating(FALSE), mNameString(), mTitle(), - mNameAway(FALSE), - mNameBusy(FALSE), - mNameMute(FALSE), + mNameAway(false), + mNameBusy(false), + mNameMute(false), + mNameAppearance(false), + mNameFriend(false), + mNameAlpha(0.f), mRenderGroupTitles(sRenderGroupTitles), - mNameAppearance(FALSE), - mNameCloud(FALSE), + mNameCloud(false), mFirstTEMessageReceived( FALSE ), mFirstAppearanceMessageReceived( FALSE ), mCulled( FALSE ), @@ -2772,8 +2779,18 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) && gSavedSettings.getS32("AvatarNameTagMode") )); } - if ( render_name ) + if ( !render_name ) { + if (mNameText) + { + // ...clean up old name tag + mNameText->markDead(); + mNameText = NULL; + sNumVisibleChatBubbles--; + } + return; + } + BOOL new_name = FALSE; if (visible_chat != mVisibleChat) { @@ -2789,7 +2806,6 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) // First Calculate Alpha // If alpha > 0, create mNameText if necessary, otherwise delete it - { F32 alpha = 0.f; if (mAppAngle > 5.f) { @@ -2810,66 +2826,62 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) alpha = (mAppAngle-2.f)/3.f; } - if (alpha > 0.f) + if (alpha <= 0.f) { + if (mNameText) + { + mNameText->markDead(); + mNameText = NULL; + sNumVisibleChatBubbles--; + } + return; + } + if (!mNameText) { - mNameText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT); - mNameText->setMass(10.f); + mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject( + LLHUDObject::LL_HUD_NAME_TAG) ); + //mNameText->setMass(10.f); mNameText->setSourceObject(this); - mNameText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP); + mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP); mNameText->setVisibleOffScreen(TRUE); mNameText->setMaxLines(11); mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); - mNameText->setUseBubble(TRUE); sNumVisibleChatBubbles++; new_name = TRUE; } - LLColor4 avatar_name_color = LLUIColorTable::instance().getColor( "AvatarNameColor" ); - avatar_name_color.setAlpha(alpha); - mNameText->setColor(avatar_name_color); + LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last); + mNameText->setPositionAgent(name_position); - LLQuaternion root_rot = mRoot.getWorldRotation(); - mNameText->setUsePixelSize(TRUE); - 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_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); - local_camera_up.normalize(); - local_camera_up = local_camera_up * ~root_rot; + idleUpdateNameTagText(new_name); - local_camera_up.scaleVec(mBodySize * 0.5f); - local_camera_at.scaleVec(mBodySize * 0.5f); + idleUpdateNameTagAlpha(new_name, alpha); +} - LLVector3 name_position = mRoot.getWorldPosition() + - (local_camera_up * root_rot) - - (projected_vec(local_camera_at * root_rot, camera_to_av)); - name_position += pixel_up_vec * 15.f; - mNameText->setPositionAgent(name_position); - } - else if (mNameText) +void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) { - mNameText->markDead(); - mNameText = NULL; - sNumVisibleChatBubbles--; - } - } - LLNameValue *title = getNVPair("Title"); LLNameValue* firstname = getNVPair("FirstName"); LLNameValue* lastname = getNVPair("LastName"); - if (mNameText.notNull() && firstname && 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_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); + bool is_muted; + if (isSelf()) + { + is_muted = false; + } + else { - const BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); - const BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); - const BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); - const BOOL is_muted = isSelf() ? FALSE : LLMuteList::getInstance()->isMuted(getID()); - const BOOL is_cloud = getIsCloud(); + is_muted = LLMuteList::getInstance()->isMuted(getID()); + } + bool is_friend = LLAvatarTracker::instance().isBuddy(getID()); + bool is_cloud = getIsCloud(); if (gSavedSettings.getBOOL("DebugAvatarRezTime")) { @@ -2894,105 +2906,125 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } } - if (mNameString.empty() || - new_name || - (!title && !mTitle.empty()) || - (title && mTitle != title->getString()) || - (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) + // Rebuild name tag if state change detected + if (mNameString.empty() + || new_name + || (!title && !mTitle.empty()) + || (title && mTitle != title->getString()) + || is_away != mNameAway + || is_busy != mNameBusy + || is_muted != mNameMute || is_appearance != mNameAppearance - || is_cloud != mNameCloud - ) - { - std::string line; - if (!sRenderGroupTitles) - { - // If all group titles are turned off, stack first name - // on a line above last name - line += firstname->getString(); - line += "\n"; - } - else if (title && title->getString() && title->getString()[0] != '\0') + || is_friend != mNameFriend + || is_cloud != mNameCloud) { - line += title->getString(); - LLStringFn::replace_ascii_controlchars(line,LL_UNKNOWN_CHAR); - line += "\n"; - line += firstname->getString(); - } - else - { - line += firstname->getString(); - } + LLColor4 name_tag_color = getNameTagColor(is_friend); - line += " "; - line += lastname->getString(); - BOOL need_comma = FALSE; + clearNameTag(); - if (is_away || is_muted || is_busy) + if (is_away || is_muted || is_busy || is_appearance) { - line += " ("; + std::string line; if (is_away) { line += LLTrans::getString("AvatarAway"); - need_comma = TRUE; + line += ", "; } if (is_busy) { - if (need_comma) + line += LLTrans::getString("AvatarBusy"); + line += ", "; + } + if (is_muted) { + line += LLTrans::getString("AvatarMuted"); line += ", "; } - line += LLTrans::getString("AvatarBusy"); - need_comma = TRUE; + if (is_appearance) + { + line += LLTrans::getString("AvatarEditingAppearance"); + line += ", "; } - if (is_muted) + if (is_cloud) { - if (need_comma) + line += LLTrans::getString("LoadingData"); + line += ", "; + } + // trim last ", " + line.resize( line.length() - 2 ); + addNameTagLine(line, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifSmall()); + } + + if (sRenderGroupTitles + && title && title->getString() && title->getString()[0] != '\0') { - line += ", "; + 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()); } - line += LLTrans::getString("AvatarMuted"); - need_comma = TRUE; + + static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames"); + static LLUICachedControl<bool> show_usernames("NameTagShowUsernames"); + + if (LLAvatarNameCache::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)); } - line += ")"; + + // Might be blank if name not available yet, that's OK + if (show_display_names) + { + addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerif()); } - if (is_cloud) + // Suppress SLID display if display name matches exactly (ugh) + if (show_usernames && !av_name.mIsDisplayNameDefault) { - line += "\n"; - line += "(" + LLTrans::getString("LoadingData") + ")"; + // *HACK: Desaturate the color + LLColor4 username_color = name_tag_color * 0.83f; + addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL, + LLFontGL::getFontSansSerifSmall()); + } } - else if (is_appearance) + else { - line += "\n"; - line += LLTrans::getString("AvatarEditingAppearance"); + const LLFontGL* font = LLFontGL::getFontSansSerif(); + 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; + mNameFriend = is_friend; mNameCloud = is_cloud; mTitle = title ? title->getString() : ""; LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR); - mNameString = utf8str_to_wstring(line); new_name = TRUE; } - if (visible_chat) + if (mVisibleChat) { - mNameText->setDropShadow(TRUE); mNameText->setFont(LLFontGL::getFontSansSerif()); - mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_LEFT); + mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT); mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); - if (new_name) - { - mNameText->setLabel(mNameString); - } 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( "AvatarNameColor" ); + LLColor4 new_chat = LLUIColorTable::instance().getColor( "NameTagChat" ); 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) @@ -3019,17 +3051,17 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) if (chat_fade_amt < 1.f) { F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); - mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(new_chat, normal_chat, u), style); + 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(utf8str_to_wstring(chat_iter->mText), lerp(normal_chat, old_chat, u), style); + 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(utf8str_to_wstring(chat_iter->mText), old_chat, style); + mNameText->addLine(chat_iter->mText, old_chat, style); } } mNameText->setVisibleOffScreen(TRUE); @@ -3054,24 +3086,129 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last) } else { - mNameText->setFont(LLFontGL::getFontSansSerif()); - mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_CENTER); + // ...not using chat bubbles, just names + mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER); mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); mNameText->setVisibleOffScreen(FALSE); - if (new_name) + } +} + +void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font) +{ + llassert(mNameText); + if (mVisibleChat) + { + mNameText->addLabel(line); + } + else + { + mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font); + } + mNameString += line; + mNameString += '\n'; +} + +void LLVOAvatar::clearNameTag() +{ + mNameString.clear(); + if (mNameText) { mNameText->setLabel(""); - mNameText->setString(mNameString); + mNameText->setString( "" ); + } +} + +//static +void LLVOAvatar::invalidateNameTag(const LLUUID& agent_id) +{ + LLViewerObject* obj = gObjectList.findObject(agent_id); + if (!obj) return; + + LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(obj); + if (!avatar) return; + + avatar->clearNameTag(); +} + +//static +void LLVOAvatar::invalidateNameTags() +{ + std::vector<LLCharacter*>::iterator it = LLCharacter::sInstances.begin(); + for ( ; it != LLCharacter::sInstances.end(); ++it) + { + LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*it); + if (!avatar) continue; + if (avatar->isDead()) continue; + + avatar->clearNameTag(); } } + +// Compute name tag position during idle update +LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last) +{ + LLQuaternion root_rot = mRoot.getWorldRotation(); + 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_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis(); + local_camera_up.normalize(); + local_camera_up = local_camera_up * ~root_rot; + + local_camera_up.scaleVec(mBodySize * 0.5f); + local_camera_at.scaleVec(mBodySize * 0.5f); + + LLVector3 name_position = mRoot.getWorldPosition() + + (local_camera_up * root_rot) - + (projected_vec(local_camera_at * root_rot, camera_to_av)); + name_position += pixel_up_vec * 15.f; + return name_position; + } + +void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha) +{ + llassert(mNameText); + + if (new_name + || alpha != mNameAlpha) + { + mNameText->setAlpha(alpha); + mNameAlpha = alpha; + } +} + +LLColor4 LLVOAvatar::getNameTagColor(bool is_friend) +{ + static LLUICachedControl<bool> show_friends("NameTagShowFriends"); + const char* color_name; + if (show_friends && is_friend) + { + color_name = "NameTagFriend"; + } + else if (LLAvatarNameCache::useDisplayNames()) + { + // ...color based on whether username "matches" a computed display + // name + LLAvatarName av_name; + if (LLAvatarNameCache::get(getID(), &av_name) + && av_name.mIsDisplayNameDefault) + { + color_name = "NameTagMatch"; } + else + { + color_name = "NameTagMismatch"; } - else if (mNameText) + } + else { - mNameText->markDead(); - mNameText = NULL; - sNumVisibleChatBubbles--; + // ...not using display names + color_name = "NameTagLegacy"; } + return LLUIColorTable::getInstance()->getColor( color_name ); } void LLVOAvatar::idleUpdateBelowWater() @@ -6748,7 +6885,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) { releaseComponentTextures(); } - + // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); 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 @@ -6843,9 +6980,9 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) llinfos << "Re-requesting AvatarAppearance for object: " << getID() << llendl; LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(getID()); mRuthTimer.reset(); - } - else - { + } + else + { llinfos << "That's okay, we already have a non-default shape for object: " << getID() << llendl; // we don't really care. } @@ -7737,9 +7874,7 @@ std::string LLVOAvatar::getFullname() const LLNameValue* last = getNVPair("LastName"); if (first && last) { - name += first->getString(); - name += " "; - name += last->getString(); + name = LLCacheName::buildFullName( first->getString(), last->getString() ); } return name; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index d51b8701af..f4f1235d55 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -59,7 +59,7 @@ extern const LLUUID ANIM_AGENT_WALK_ADJUST; class LLTexLayerSet; class LLVoiceVisualizer; -class LLHUDText; +class LLHUDNameTag; class LLHUDEffectSpiral; class LLTexGlobalColor; class LLVOAvatarBoneInfo; @@ -207,6 +207,15 @@ public: void idleUpdateLoadingEffect(); void idleUpdateWindEffect(); void idleUpdateNameTag(const LLVector3& root_pos_last); + void idleUpdateNameTagText(BOOL new_name); + LLVector3 idleUpdateNameTagPosition(const LLVector3& root_pos_last); + void idleUpdateNameTagAlpha(BOOL new_name, F32 alpha); + LLColor4 getNameTagColor(bool is_friend); + void clearNameTag(); + static void invalidateNameTag(const LLUUID& agent_id); + // force all name tags to rebuild, useful when display names turned on/off + static void invalidateNameTags(); + void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font); void idleUpdateRenderCost(); void idleUpdateBelowWater(); @@ -827,13 +836,15 @@ protected: static void getAnimLabels(LLDynamicArray<std::string>* labels); static void getAnimNames(LLDynamicArray<std::string>* names); private: - LLWString mNameString; + std::string mNameString; // UTF-8 title + name + status std::string mTitle; - BOOL mNameAway; - BOOL mNameBusy; - BOOL mNameMute; - BOOL mNameAppearance; - BOOL mNameCloud; + bool mNameAway; + bool mNameBusy; + bool mNameMute; + bool mNameAppearance; + bool mNameFriend; + bool mNameCloud; + F32 mNameAlpha; BOOL mRenderGroupTitles; //-------------------------------------------------------------------- @@ -841,7 +852,7 @@ private: //-------------------------------------------------------------------- public: LLFrameTimer mChatTimer; - LLPointer<LLHUDText> mNameText; + LLPointer<LLHUDNameTag> mNameText; private: LLFrameTimer mTimeVisible; std::deque<LLChat> mChats; diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index 56b48ef705..ccdff5e96c 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -30,6 +30,7 @@ #include "lluuid.h" #include "lldatapacker.h" #include "lldlinked.h" +#include "lldir.h" //--------------------------------------------------------------------------- diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index c8d338b0a3..7cef3c13d1 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -76,6 +76,9 @@ public: virtual void getChannelInfo(); virtual BOOL isActive(); virtual BOOL callStarted(); + + // Session name is a UI label used for feedback about which person, + // group, or phone number you are talking to const std::string& getSessionName() const { return mSessionName; } boost::signals2::connection setStateChangedCallback(const state_changed_signal_t::slot_type& callback) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index e674fec053..019629084f 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -31,6 +31,8 @@ #include "llsdutil.h" +// Linden library includes +#include "llavatarnamecache.h" #include "llvoavatarself.h" #include "llbufferstream.h" #include "llfile.h" @@ -46,6 +48,8 @@ #include "llviewercontrol.h" #include "llkeyboard.h" #include "llappviewer.h" // for gDisconnected, gDisableVoice + +// Viewer includes #include "llmutelist.h" // to check for muted avatars #include "llagent.h" #include "llcachename.h" @@ -2807,12 +2811,16 @@ void LLVivoxVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream) void LLVivoxVoiceClient::checkFriend(const LLUUID& id) { - std::string name; buddyListEntry *buddy = findBuddy(id); // Make sure we don't add a name before it's been looked up. - if(gCacheName->getFullName(id, name)) + LLAvatarName av_name; + if(LLAvatarNameCache::get(id, &av_name)) { + // *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(); const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); bool canSeeMeOnline = false; @@ -6364,16 +6372,18 @@ void LLVivoxVoiceClient::notifyFriendObservers() void LLVivoxVoiceClient::lookupName(const LLUUID &id) { - BOOL is_group = FALSE; - gCacheName->get(id, is_group, &LLVivoxVoiceClient::onAvatarNameLookup); + LLAvatarNameCache::get(id, + boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, + this, _1, _2)); } -//static -void LLVivoxVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group) +void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id, + const LLAvatarName& av_name) { - std::string name = llformat("%s %s", first.c_str(), last.c_str()); - LLVivoxVoiceClient::getInstance()->avatarNameResolved(id, 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); } void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name) diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 08f2f75a39..3ba517bf36 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -45,7 +45,7 @@ class LLVivoxProtocolParser; #endif #include "llvoiceclient.h" - +class LLAvatarName; class LLVivoxVoiceAccountProvisionResponder; class LLVivoxVoiceClientMuteListObserver; class LLVivoxVoiceClientFriendsObserver; @@ -649,7 +649,7 @@ protected: void leaveAudioSession(); void lookupName(const LLUUID &id); - static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group); + void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name); void avatarNameResolved(const LLUUID &id, const std::string &name); ///////////////////////////// diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 0c17b5e297..8ef3a3b839 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -880,8 +880,10 @@ void LLWorldMapView::drawFrustum() F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; - F32 ctr_x = getLocalRect().getWidth() * 0.5f + sPanX; - F32 ctr_y = getLocalRect().getHeight() * 0.5f + sPanY; + // Compute the frustum coordinates. Take the UI scale into account. + F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor"); + F32 ctr_x = (getLocalRect().getWidth() * 0.5f + sPanX) * ui_scale_factor; + F32 ctr_y = (getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b4a5777f10..0c5735cdfc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -64,6 +64,8 @@ #include "llfloaterreg.h" #include "llgldbg.h" #include "llhudmanager.h" +#include "llhudnametag.h" +#include "llhudtext.h" #include "lllightconstants.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -2113,6 +2115,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) } LLHUDText::shiftAll(offset); + LLHUDNameTag::shiftAll(offset); display_update_camera(); } @@ -5332,7 +5335,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, ++iter) { LLVOAvatar* av = (LLVOAvatar*) *iter; - if (av->mNameText.notNull() && av->mNameText->lineSegmentIntersect(start, local_end, position)) + if (av->mNameText.notNull() + && av->mNameText->lineSegmentIntersect(start, local_end, position)) { drawable = av->mDrawable; local_end = position; diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index b489294f38..ddd2ff196b 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -121,9 +121,6 @@ name="AlertTextColor" value="0.58 0.66 0.84 1" /> <color - name="AvatarNameColor" - reference="White" /> - <color name="AvatarListItemIconDefaultColor" reference="White" /> <color @@ -534,6 +531,29 @@ <color name="MultiSliderTriangleColor" reference="Unused?" /> + <!-- + <color + name="NameTagBackground" + value="0.85 0.85 0.85 0.80" /> + --> + <color + name="NameTagBackground" + value="0 0 0 1" /> + <color + name="NameTagChat" + reference="White" /> + <color + name="NameTagFriend" + value="0.447 0.784 0.663 1" /> + <color + name="NameTagLegacy" + reference="White" /> + <color + name="NameTagMatch" + reference="White" /> + <color + name="NameTagMismatch" + reference="White" /> <color name="NetMapBackgroundColor" value="0 0 0 1" /> @@ -568,6 +588,9 @@ name="NotifyTextColor" reference="White" /> <color + name="ObjectBubbleColor" + reference="DkGray_66" /> + <color name="ObjectChatColor" reference="EmphasisColor" /> <color diff --git a/indra/newview/skins/default/textures/Rounded_Rect.png b/indra/newview/skins/default/textures/Rounded_Rect.png Binary files differnew file mode 100644 index 0000000000..c270c28039 --- /dev/null +++ b/indra/newview/skins/default/textures/Rounded_Rect.png diff --git a/indra/newview/skins/default/textures/icons/Copy.png b/indra/newview/skins/default/textures/icons/Copy.png Binary files differnew file mode 100644 index 0000000000..d45134e9dd --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Copy.png diff --git a/indra/newview/skins/default/textures/icons/Person_Check.png b/indra/newview/skins/default/textures/icons/Person_Check.png Binary files differnew file mode 100644 index 0000000000..f8638540d4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Person_Check.png diff --git a/indra/newview/skins/default/textures/icons/Person_Star.png b/indra/newview/skins/default/textures/icons/Person_Star.png Binary files differnew file mode 100644 index 0000000000..ad10580ac4 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Person_Star.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 925e2b5b04..b2658d2525 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -110,7 +110,8 @@ with the same filename but different name <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="Copy" file_name="icons/Copy.png" preload="false" /> + <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" /> <texture name="DownArrow" file_name="bottomtray/DownArrow.png" preload="false" /> @@ -359,6 +360,8 @@ with the same filename but different name <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" /> + <texture name="Person_Check" file_name="icons/Person_Check.png" preload="false" /> + <texture name="Person_Star" file_name="icons/Person_Star.png" preload="false" /> <texture name="Permission_Visible_Online" file_name="icons/see_me_online.png" preload="false" /> <texture name="Permission_Visible_Map" file_name="icons/see_on_map.png" preload="false" /> @@ -393,6 +396,7 @@ with the same filename but different name <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true" /> + <texture name="Rounded_Rect" file_name="Rounded_Rect.png" preload="true" scale.left="6" scale.top="24" scale.right="58" scale.bottom="6" /> <texture name="Rounded_Square" file_name="rounded_square.j2c" preload="true" scale.left="16" scale.top="16" scale.right="112" scale.bottom="16" /> <texture name="Row_Selection" file_name="navbar/Row_Selection.png" preload="false" /> diff --git a/indra/newview/skins/default/xui/da/floater_event.xml b/indra/newview/skins/default/xui/da/floater_event.xml index 1816144b45..58f2e555dd 100644 --- a/indra/newview/skins/default/xui/da/floater_event.xml +++ b/indra/newview/skins/default/xui/da/floater_event.xml @@ -1,72 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Event" name="Event" title="EVENT DETALJER"> - <floater.string name="none"> - ingen +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Henter... </floater.string> - <floater.string name="notify"> - Meddel - </floater.string> - <floater.string name="dont_notify"> - Meddel ikke - </floater.string> - <floater.string name="moderate"> - Moderat - </floater.string> - <floater.string name="adult"> - Voksent - </floater.string> - <floater.string name="general"> - Generelt - </floater.string> - <floater.string name="unknown"> - Ukendt - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Event uden navn. - </text> - <text name="event_category"> - (ingen kategori) - </text> - <text name="event_runby_label"> - Afholdt af: - </text> - <text initial_value="(henter)" name="event_runby"/> - <text name="event_date_label"> - Dato: - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - Varighed: - </text> - <text name="event_duration"> - 1 time - </text> - <text name="event_covercharge_label"> - Pris: - </text> - <text name="event_cover"> - Gratis - </text> - <text name="event_location_label"> - Lokation: - </text> - <text name="event_location" value="SampleParcel, Name Long (145, 228, 26)"/> - <text name="rating_label" value="Rating:"/> - <text name="rating_value" value="ukendt"/> - <expandable_text name="event_desc"> - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - </expandable_text> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="Opret event"/> - <button name="god_delete_event_btn" tool_tip="Slet event"/> - <button label="Giv besked" name="notify_btn"/> - <button label="Teleport" name="teleport_btn"/> - <button label="Kort" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/da/floater_windlight_options.xml b/indra/newview/skins/default/xui/da/floater_windlight_options.xml index 65f3f67a70..56f94b24e9 100644 --- a/indra/newview/skins/default/xui/da/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/da/floater_windlight_options.xml @@ -1,18 +1,18 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="WindLight floater" title="AVANCERET OPSÆTNING FOR HIMMEL"> <text name="KeyFramePresetsText"> Faste indstillinger: </text> - <button label="Ny" label_selected="Ny" name="WLNewPreset"/> - <button label="Gem" label_selected="Gem" name="WLSavePreset"/> - <button label="Slet" label_selected="Slet" name="WLDeletePreset"/> - <button label="Dags cyklus" label_selected="Dags cyklus" name="WLDayCycleMenuButton"/> + <button label="Ny" label_selected="Ny" name="WLNewPreset" /> + <button label="Gem" label_selected="Gem" name="WLSavePreset" /> + <button label="Slet" label_selected="Slet" name="WLDeletePreset" /> + <button label="Dags cyklus" label_selected="Dags cyklus" name="WLDayCycleMenuButton" /> <tab_container name="WindLight Tabs"> <panel label="ATMOSFÆRE" name="Atmosphere"> <text name="BHText"> Blå - horisont </text> - <button label="?" name="WLBlueHorizonHelp"/> + <button label="?" name="WLBlueHorizonHelp" /> <text name="BHText2"> R </text> @@ -25,19 +25,19 @@ <text name="BHText5"> I </text> - <slider label="" name="WLBlueHorizonR"/> - <slider label="" name="WLBlueHorizonG"/> - <slider label="" name="WLBlueHorizonB"/> - <slider label="" name="WLBlueHorizonI"/> + <slider label="" name="WLBlueHorizonR" /> + <slider label="" name="WLBlueHorizonG" /> + <slider label="" name="WLBlueHorizonB" /> + <slider label="" name="WLBlueHorizonI" /> <text name="BDensText"> Dis - horisont </text> - <button label="?" name="WLHazeHorizonHelp"/> - <slider label="" name="WLHazeHorizon"/> + <button label="?" name="WLHazeHorizonHelp" /> + <slider label="" name="WLHazeHorizon" /> <text name="BDensText2"> Blå - tæthed </text> - <button label="?" name="WLBlueDensityHelp"/> + <button label="?" name="WLBlueDensityHelp" /> <text name="BHText6"> R </text> @@ -50,36 +50,36 @@ <text name="BHText9"> I </text> - <slider label="" name="WLBlueDensityR"/> - <slider label="" name="WLBlueDensityG"/> - <slider label="" name="WLBlueDensityB"/> - <slider label="" name="WLBlueDensityI"/> + <slider label="" name="WLBlueDensityR" /> + <slider label="" name="WLBlueDensityG" /> + <slider label="" name="WLBlueDensityB" /> + <slider label="" name="WLBlueDensityI" /> <text name="HDText"> Dis - intensitet </text> - <button label="?" name="WLHazeDensityHelp"/> - <slider label="" name="WLHazeDensity"/> + <button label="?" name="WLHazeDensityHelp" /> + <slider label="" name="WLHazeDensity" /> <text name="DensMultText"> Densitet faktor </text> - <button label="?" name="WLDensityMultHelp"/> - <slider label="" name="WLDensityMult"/> + <button label="?" name="WLDensityMultHelp" /> + <slider label="" name="WLDensityMult" /> <text name="WLDistanceMultText"> Distance faktor </text> - <button label="?" name="WLDistanceMultHelp"/> - <slider label="" name="WLDistanceMult"/> + <button label="?" name="WLDistanceMultHelp" /> + <slider label="" name="WLDistanceMult" /> <text name="MaxAltText"> Maximum højde </text> - <button label="?" name="WLMaxAltitudeHelp"/> - <slider label="" name="WLMaxAltitude"/> + <button label="?" name="WLMaxAltitudeHelp" /> + <slider label="" name="WLMaxAltitude" /> </panel> <panel label="LYS" name="Lighting"> <text name="SLCText"> Sol/Måne farve </text> - <button label="?" name="WLSunlightColorHelp"/> + <button label="?" name="WLSunlightColorHelp" /> <text name="BHText"> R </text> @@ -92,19 +92,19 @@ <text name="BHText4"> I </text> - <slider label="" name="WLSunlightR"/> - <slider label="" name="WLSunlightG"/> - <slider label="" name="WLSunlightB"/> - <slider label="" name="WLSunlightI"/> + <slider label="" name="WLSunlightR" /> + <slider label="" name="WLSunlightG" /> + <slider label="" name="WLSunlightB" /> + <slider label="" name="WLSunlightI" /> <text name="TODText"> Sol/Måne position </text> - <button label="?" name="WLTimeOfDayHelp"/> - <slider label="" name="WLSunAngle"/> + <button label="?" name="WLTimeOfDayHelp" /> + <slider label="" name="WLSunAngle" /> <text name="WLAmbientText"> Omgivende </text> - <button label="?" name="WLAmbientHelp"/> + <button label="?" name="WLAmbientHelp" /> <text name="BHText5"> R </text> @@ -117,37 +117,37 @@ <text name="BHText8"> I </text> - <slider label="" name="WLAmbientR"/> - <slider label="" name="WLAmbientG"/> - <slider label="" name="WLAmbientB"/> - <slider label="" name="WLAmbientI"/> + <slider label="" name="WLAmbientR" /> + <slider label="" name="WLAmbientG" /> + <slider label="" name="WLAmbientB" /> + <slider label="" name="WLAmbientI" /> <text name="WLEastAngleText"> Øst vinkel </text> - <button label="?" name="WLEastAngleHelp"/> - <slider label="" name="WLEastAngle"/> + <button label="?" name="WLEastAngleHelp" /> + <slider label="" name="WLEastAngle" /> <text name="SunGlowText"> Sol glød </text> - <button label="?" name="WLSunGlowHelp"/> - <slider label="Fokus " name="WLGlowB"/> - <slider label="Størr. " name="WLGlowR"/> + <button label="?" name="WLSunGlowHelp" /> + <slider label="Fokus " name="WLGlowB" /> + <slider label="Størr. " name="WLGlowR" /> <text name="SceneGammaText"> Lysintensitet (gamma) </text> - <button label="?" name="WLSceneGammaHelp"/> - <slider label="" name="WLGamma"/> + <button label="?" name="WLSceneGammaHelp" /> + <slider label="" name="WLGamma" /> <text name="WLStarText"> Stjerne intensitet </text> - <button label="?" name="WLStarBrightnessHelp"/> - <slider label="" name="WLStarAlpha"/> + <button label="?" name="WLStarBrightnessHelp" /> + <slider label="" name="WLStarAlpha" /> </panel> <panel label="SKYER" name="Clouds"> <text name="WLCloudColorText"> Farve på skyer </text> - <button label="?" name="WLCloudColorHelp"/> + <button label="?" name="WLCloudColorHelp" /> <text name="BHText"> R </text> @@ -160,14 +160,14 @@ <text name="BHText4"> I </text> - <slider label="" name="WLCloudColorR"/> - <slider label="" name="WLCloudColorG"/> - <slider label="" name="WLCloudColorB"/> - <slider label="" name="WLCloudColorI"/> + <slider label="" name="WLCloudColorR" /> + <slider label="" name="WLCloudColorG" /> + <slider label="" name="WLCloudColorB" /> + <slider label="" name="WLCloudColorI" /> <text name="WLCloudColorText2"> Skyer XY/Tæthed </text> - <button label="?" name="WLCloudDensityHelp"/> + <button label="?" name="WLCloudDensityHelp" /> <text name="BHText5"> X </text> @@ -177,23 +177,23 @@ <text name="BHText7"> T </text> - <slider label="" name="WLCloudX"/> - <slider label="" name="WLCloudY"/> - <slider label="" name="WLCloudDensity"/> + <slider label="" name="WLCloudX" /> + <slider label="" name="WLCloudY" /> + <slider label="" name="WLCloudDensity" /> <text name="WLCloudCoverageText"> Skydække </text> - <button label="?" name="WLCloudCoverageHelp"/> - <slider label="" name="WLCloudCoverage"/> + <button label="?" name="WLCloudCoverageHelp" /> + <slider label="" name="WLCloudCoverage" /> <text name="WLCloudScaleText"> Skystørrelse </text> - <button label="?" name="WLCloudScaleHelp"/> - <slider label="" name="WLCloudScale"/> + <button label="?" name="WLCloudScaleHelp" /> + <slider label="" name="WLCloudScale" /> <text name="WLCloudDetailText"> Sky detaljer(XY/tæthed) </text> - <button label="?" name="WLCloudDetailHelp"/> + <button label="?" name="WLCloudDetailHelp" /> <text name="BHText8"> X </text> @@ -203,23 +203,23 @@ <text name="BHText10"> T </text> - <slider label="" name="WLCloudDetailX"/> - <slider label="" name="WLCloudDetailY"/> - <slider label="" name="WLCloudDetailDensity"/> + <slider label="" name="WLCloudDetailX" /> + <slider label="" name="WLCloudDetailY" /> + <slider label="" name="WLCloudDetailDensity" /> <text name="WLCloudScrollXText"> Sky drift X </text> - <button label="?" name="WLCloudScrollXHelp"/> - <check_box label="Lås" name="WLCloudLockX"/> - <slider label="" name="WLCloudScrollX"/> + <button label="?" name="WLCloudScrollXHelp" /> + <check_box label="Lås" name="WLCloudLockX" /> + <slider label="" name="WLCloudScrollX" /> <text name="WLCloudScrollYText"> Sky drift Y </text> - <button label="?" name="WLCloudScrollYHelp"/> - <check_box label="Lås" name="WLCloudLockY"/> - <slider label="" name="WLCloudScrollY"/> - <check_box label="Benyt simple skyer" name="DrawClassicClouds"/> - <button label="?" name="WLClassicCloudsHelp"/> + <button label="?" name="WLCloudScrollYHelp" /> + <check_box label="Lås" name="WLCloudLockY" /> + <slider label="" name="WLCloudScrollY" /> + <check_box label="Benyt simple skyer" name="DrawClassicClouds" /> + <button label="?" name="WLClassicCloudsHelp" /> </panel> </tab_container> <string name="WLDefaultSkyNames"> diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index eaae513e74..917b7cc21e 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1085,8 +1085,7 @@ Prøv at vælge mindre stykker land. [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Teleportér"/> - <button name="Description" text="Beskrivelse"/> + <button name="Details" text="Beskrivelse"/> <button name="Cancel" text="Annullér"/> </form> </notification> diff --git a/indra/newview/skins/default/xui/da/panel_classified_info.xml b/indra/newview/skins/default/xui/da/panel_classified_info.xml index 5790f1f19f..a54d320ffd 100644 --- a/indra/newview/skins/default/xui/da/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/da/panel_classified_info.xml @@ -40,7 +40,7 @@ </layout_panel> <layout_panel name="descr_layout_panel"> <text name="classified_desc_label" value="Beskrivelse:"/> - <text_editor name="classified_desc" value="[description]"/> + <text_editor name="classified_desc" value="[description]"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 9f4119e73b..afd933c7fa 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -774,7 +774,7 @@ <string name="xml_file"> XML Fil </string> - <string name="dot_raw_file"> + <string name="raw_file"> RAW Fil </string> <string name="compressed_image_files"> diff --git a/indra/newview/skins/default/xui/de/floater_customize.xml b/indra/newview/skins/default/xui/de/floater_customize.xml new file mode 100644 index 0000000000..3651577797 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_customize.xml @@ -0,0 +1,529 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater customize" title="AUSSEHEN"> + <tab_container name="customize tab container"> + <text label="Körperteile" name="body_parts_placeholder"> + Körperteile + </text> + <panel label="Form" name="Shape"> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + <button label="Körper" label_selected="Körper" name="Body"/> + <button label="Kopf" label_selected="Kopf" name="Head"/> + <button label="Augen" label_selected="Augen" name="Eyes"/> + <button label="Ohren" label_selected="Ohren" name="Ears"/> + <button label="Nase" label_selected="Nase" name="Nose"/> + <button label="Mund" label_selected="Mund" name="Mouth"/> + <button label="Kinn" label_selected="Kinn" name="Chin"/> + <button label="Oberkörper" label_selected="Oberkörper" name="Torso"/> + <button label="Beine" label_selected="Beine" name="Legs"/> + <radio_group name="sex radio"> + <radio_item label="Weiblich" name="radio" value="0"/> + <radio_item label="Männlich" name="radio2" value="1"/> + </radio_group> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie eine neue Form aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch eine neue erstellen und diese anlegen. + </text> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label"> + Form: + </text> + <button label="Neue Form/Gestalt" label_selected="Neue Form/Gestalt" name="Create New"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + </panel> + <panel label="Haut" name="Skin"> + <button label="Hautfarbe" label_selected="Hautfarbe" left="2" name="Skin Color" width="92"/> + <button label="Gesichtsdetails" label_selected="Gesichtsdetails" left="2" name="Face Detail" width="92"/> + <button label="Make-Up" label_selected="Make-Up" left="2" name="Makeup" width="92"/> + <button label="Körperdetails" label_selected="Körperdetails" left="2" name="Body Detail" width="92"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie eine neue Skin (Haut) aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch eine neue erstellen und diese anlegen. + </text> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Haut: + </text> + <texture_picker label="Kopftattoo" name="Head Tattoos" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <texture_picker label="Obere Tattoos" name="Upper Tattoos" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <texture_picker label="Untere Tattoos" name="Lower Tattoos" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <button label="Neue Haut" label_selected="Neue Haut" name="Create New"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Haar" name="Hair"> + <button label="Farbe" label_selected="Farbe" name="Color"/> + <button label="Stil" label_selected="Stil" name="Style"/> + <button label="Augenbrauen" label_selected="Augenbrauen" name="Eyebrows"/> + <button label="Gesichtshaar" label_selected="Gesichtshaar" name="Facial"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie Haar aus dem Inventar auf Ihren Avatar, um dieses anzulegen. Sie können aber auch neues Haar erstellen und anlegen. + </text> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Haare: + </text> + <texture_picker label="Textur" name="Texture" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <button label="Neue Haare" label_selected="Neue Haare" name="Create New"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Augen" name="Eyes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie neue Augen aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch neue Augen erstellen und diese anlegen. + </text> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Augen: + </text> + <texture_picker label="Iris" name="Iris" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <button label="Neue Augen" label_selected="Neue Augen" name="Create New"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <text label="Kleidung" name="clothes_placeholder"> + Kleidung + </text> + <panel label="Hemd" name="Shirt"> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button label="Neues Hemd" label_selected="Neues Hemd" name="Create New"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie ein neues Hemd aus dem Inventar auf Ihren Avatar, um dieses anzuziehen. Sie können aber auch ein neues Hemd erstellen und dieses anlegen. + </text> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Hemd: + </text> + </panel> + <panel label="Hose" name="Pants"> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button label="Neue Hose" label_selected="Neue Hose" name="Create New"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie eine neue Hose aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch eine neue erstellen und diese anziehen. + </text> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Hose: + </text> + </panel> + <panel label="Schuhe" name="Shoes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie neue Schuhe aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch neue Schuhe erstellen und diese anlegen. + </text> + <button label="Neue Schuhe" label_selected="Neue Schuhe" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Schuhe: + </text> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Socken" name="Socks"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie neue Socken aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch neue erstellen und diese anziehen. + </text> + <button label="Neue Socken" label_selected="Neue Socken" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Socken: + </text> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Jacke" name="Jacket"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie eine neue Jacke aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch eine neue erstellen und diese anziehen. + </text> + <button label="Neue Jacke" label_selected="Neue Jacke" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Jacke: + </text> + <texture_picker label="Stoff: oben" name="Upper Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <texture_picker label="Stoff: unten" name="Lower Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Handschuhe" name="Gloves"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie neue Handschuhe aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch neue erstellen und diese anziehen. + </text> + <button label="Neue Handschuhe" label_selected="Neue Handschuhe" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Handschuhe: + </text> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Unterhemd" name="Undershirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie ein neues Unterhemd aus dem Inventar auf Ihren Avatar, um dieses anzuziehen. Sie können aber auch ein neues Unterhemd erstellen und dieses anziehen. + </text> + <button label="Neues Unterhemd" label_selected="Neues Unterhemd" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Unterhemd: + </text> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Unterhose" name="Underpants"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie eine neue Unterhose aus dem Inventar auf Ihren Avatar, um diese anzuziehen. Sie können aber auch eine neue erstellen und diese anziehen. + </text> + <button label="Neue Unterhose" label_selected="Neue Unterhose" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Unterhose: + </text> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Rock" name="Skirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [DESC]: wird geladen... + </text> + <text name="title_not_worn"> + [DESC]: nicht getragen + </text> + <text name="path"> + In [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie einen neuen Rock aus dem Inventar auf Ihren Avatar, um diesen anzuziehen. Sie können aber auch einen neuen Rock erstellen und diesen anziehen. + </text> + <button label="Neuer Rock" label_selected="Neuer Rock" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label" right="100"> + Rock: + </text> + <texture_picker label="Stoff" name="Fabric" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> + <color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/> + <button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/> + <button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Tätowierung" name="Tattoo"> + <text name="title"> + Tätowierung + </text> + <text name="title_no_modify"> + [BESCHR]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [BESCHR]: wird geladen... + </text> + <text name="title_not_worn"> + [BESCHR]: nicht getragen + </text> + <text name="path"> + Befindet sich in [PATH] + </text> + <text name="not worn instructions"> + Ziehen Sie eine neue Tätowierung aus dem Inventar auf Ihren Avatar, um diese anzulegen. Sie können aber auch eine neue erstellen und diese anlegen. + </text> + <button label="Neue Tätowierung erstellen" label_selected="Neue Tätowierung erstellen" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label"> + Tätowierung: + </text> + <texture_picker label="Kopftattoo" name="Head Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <texture_picker label="Obere Tattoos" name="Upper Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <texture_picker label="Untere Tattoos" name="Lower Tattoo" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <button label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button label="Speichern" label_selected="Speichern" name="Save"/> + <button label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + <panel label="Alpha" name="Alpha"> + <text name="title"> + Alpha + </text> + <text name="title_no_modify"> + [BESCHR]: bearbeiten nicht möglich + </text> + <text name="title_loading"> + [BESCHR]: wird geladen... + </text> + <text name="title_not_worn"> + [BESCHR]: nicht getragen + </text> + <text name="path"> + Befindet sich in [PATH] + </text> + <text name="not worn instructions"> + Sie können eine neue Alpha-Maske anlegen, indem Sie eine von Ihrem Inventar auf Ihren Avatar ziehen. Sie können aber auch eine neue erstellen und diese anlegen. + </text> + <button label="Neue Alpha erstellen" label_selected="Neue Alpha erstellen" name="Create New"/> + <text name="no modify instructions"> + Sie sind nicht berechtigt, diese Kleidung zu bearbeiten. + </text> + <text name="Item Action Label"> + Alpha: + </text> + <texture_picker label="Alpha: Unten" name="Lower Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <texture_picker label="Alpha: Oben" name="Upper Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <texture_picker label="Kopf: Alpha" name="Head Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <texture_picker label="Alpha: Augen" name="Eye Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <texture_picker label="Alpha: Haare" name="Hair Alpha" tool_tip="Zum Auswählen eines Bildes hier klicken"/> + <button label="Ausziehen" label_selected="Ausziehen" name="Take Off"/> + <button label="Speichern" label_selected="Speichern" name="Save"/> + <button label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/> + <button label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/> + </panel> + </tab_container> + <button label="Skriptinfo" label_selected="Skriptinfo" name="script_info" tool_tip="Skripts, die an Ihren Avatar angehängt sind, anzeigen"/> + <button label="Outfit erstellen" label_selected="Outfit erstellen" name="make_outfit_btn"/> + <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> + <button label="OK" label_selected="OK" name="Ok"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_event.xml b/indra/newview/skins/default/xui/de/floater_event.xml index cf663e2e1b..87fb580aba 100644 --- a/indra/newview/skins/default/xui/de/floater_event.xml +++ b/indra/newview/skins/default/xui/de/floater_event.xml @@ -1,69 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Event" name="Event" title="EVENT-DETAILS"> - <floater.string name="none"> - keines +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Wird geladen... </floater.string> - <floater.string name="notify"> - Benachrichtigen - </floater.string> - <floater.string name="dont_notify"> - Nicht benachrichtigen - </floater.string> - <floater.string name="moderate"> - Moderat - </floater.string> - <floater.string name="adult"> - Adult - </floater.string> - <floater.string name="general"> - Allgemein - </floater.string> - <floater.string name="unknown"> - Unbekannt - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Namenloses Event....namenlos! Tadaaa! Tadatadaaaah! - </text> - <text name="event_category"> - (keine Kategorie) - </text> - <text name="event_runby_label"> - Ausgeführt von: - </text> - <text initial_value="(wird in Datenbank gesucht)" name="event_runby"/> - <text name="event_date_label"> - Datum: - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - Dauer: - </text> - <text name="event_duration"> - 1 Stunde - </text> - <text name="event_covercharge_label"> - Eintritt: - </text> - <text name="event_cover"> - Kostenlos - </text> - <text name="event_location_label"> - Standort: - </text> - <text name="event_location" value="SampleParcel, Name Long (145, 228, 26)"/> - <text name="rating_label" value="Einstufung:"/> - <text name="rating_value" value="unbekannt"/> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="Event erstellen"/> - <button name="god_delete_event_btn" tool_tip="Event löschen"/> - <button label="Mich benachrichtigen" name="notify_btn"/> - <button label="Teleportieren" name="teleport_btn"/> - <button label="Karte" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/de/floater_map.xml b/indra/newview/skins/default/xui/de/floater_map.xml index d4358fa8e9..217a641dec 100644 --- a/indra/newview/skins/default/xui/de/floater_map.xml +++ b/indra/newview/skins/default/xui/de/floater_map.xml @@ -25,7 +25,7 @@ NW </floater.string> <floater.string name="ToolTipMsg"> - [AGENT][REGION](Karte mit Doppelklick öffnen) + [REGION](Doppelklicken, um Karte zu öffnen; Umschalt-Taste gedrückt halten und ziehen, um zu schwenken) </floater.string> <floater.string name="mini_map_caption"> MINI-KARTE diff --git a/indra/newview/skins/default/xui/de/floater_nearby_chat.xml b/indra/newview/skins/default/xui/de/floater_nearby_chat.xml index e362273396..bbb4114200 100644 --- a/indra/newview/skins/default/xui/de/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/de/floater_nearby_chat.xml @@ -1,2 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT IN DER NÄHE"/> +<floater name="nearby_chat" title="CHAT IN DER NÄHE"> + <check_box label="Chat übersetzen (Service von Google)" name="translate_chat_checkbox"/> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml new file mode 100644 index 0000000000..8c110e5516 --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_outfit_save_as.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container" title="Outfit speichern"> + <button label="Speichern" label_selected="Speichern" name="Save"/> + <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> + <text name="Save item as:"> + Meine aktuelle Kleidung +als neues Outfit speichern: + </text> + <line_editor name="name ed"> + [DESC] (neu) + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index 3de3718f66..fe4c505cee 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -182,10 +182,10 @@ <text name="Group:"> Gruppe: </text> - <button label="Festlegen..." label_selected="Festlegen..." name="button set group" tool_tip="Eine Gruppe auswählen, um die Berechtigungen des Objekts zu teilen."/> <name_box initial_value="Wird geladen..." name="Group Name Proxy"/> - <button label="Übertragung" label_selected="Übertragung" name="button deed" tool_tip="Eine Übertragung bedeutet, dass das Objekt mit den Berechtigungen „Nächster Eigentümer“ weitergegeben wird. Mit der Gruppe geteilte Objekte können von einem Gruppen-Officer übertragen werden."/> + <button label="Festlegen..." label_selected="Festlegen..." name="button set group" tool_tip="Eine Gruppe auswählen, um die Berechtigungen des Objekts zu teilen."/> <check_box label="Teilen" name="checkbox share with group" tool_tip="Mit allen Mitgliedern der zugeordneten Gruppe, Ihre Berechtigungen dieses Objekt zu ändern teilen. Sie müssen Übereignen, um Rollenbeschränkungen zu aktivieren."/> + <button label="Übertragung" label_selected="Übertragung" name="button deed" tool_tip="Eine Übertragung bedeutet, dass das Objekt mit den Berechtigungen „Nächster Eigentümer“ weitergegeben wird. Mit der Gruppe geteilte Objekte können von einem Gruppen-Officer übertragen werden."/> <text name="label click action"> Bei Linksklick: </text> @@ -440,8 +440,9 @@ <combo_box.item label="Saugen" name="suction"/> <combo_box.item label="gewoben" name="weave"/> </combo_box> - <text name="tex scale"> - Wiederholungen / Fläche + <check_box initial_value="falsch" label="Flache Oberflächen ausrichten" name="checkbox planar align" tool_tip="Texturen auf allen ausgewählten Oberflächen an der zuletzt ausgewählten Oberfläche ausrichten. Planar Texture Mapping erforderlich."/> + <text name="rpt"> + Wiederholungen / Oberfläche </text> <spinner label="Horizontal (U)" name="TexScaleU"/> <check_box label="Umkehren" name="checkbox flip s"/> diff --git a/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml new file mode 100644 index 0000000000..f9b3552e8b --- /dev/null +++ b/indra/newview/skins/default/xui/de/floater_wearable_save_as.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container" title=" "> + <button label="Speichern" label_selected="Speichern" name="Save"/> + <button label="Abbrechen" label_selected="Abbrechen" name="Cancel"/> + <text name="Save item as:"> + Objekt in meinem Inventar speichern als: + </text> + <line_editor name="name ed"> + Neu [DESC] + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml new file mode 100644 index 0000000000..f3775a05ec --- /dev/null +++ b/indra/newview/skins/default/xui/de/menu_add_wearable_gear.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Add Wearable Gear Menu"> + <menu_item_check label="Nach aktuellesten Objekten sortieren" name="sort_by_most_recent"/> + <menu_item_check label="Nach Name sortieren" name="sort_by_name"/> + <menu_item_check label="Nach Typ sortieren" name="sort_by_type"/> +</menu> diff --git a/indra/newview/skins/default/xui/de/menu_attachment_self.xml b/indra/newview/skins/default/xui/de/menu_attachment_self.xml index a47c633d57..644fc68ba4 100644 --- a/indra/newview/skins/default/xui/de/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/de/menu_attachment_self.xml @@ -3,6 +3,7 @@ <menu_item_call label="Berühren" name="Attachment Object Touch"/> <menu_item_call label="Bearbeiten" name="Edit..."/> <menu_item_call label="Abnehmen" name="Detach"/> + <menu_item_call label="Hinsetzen" name="Sit Down Here"/> <menu_item_call label="Aufstehen" name="Stand Up"/> <menu_item_call label="Outfit ändern" name="Change Outfit"/> <menu_item_call label="Mein Outfit bearbeiten" name="Edit Outfit"/> diff --git a/indra/newview/skins/default/xui/de/menu_avatar_self.xml b/indra/newview/skins/default/xui/de/menu_avatar_self.xml index c74f646abb..582c76ac94 100644 --- a/indra/newview/skins/default/xui/de/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/de/menu_avatar_self.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Self Pie"> + <menu_item_call label="Hinsetzen" name="Sit Down Here"/> <menu_item_call label="Aufstehen" name="Stand Up"/> <context_menu label="Ausziehen" name="Take Off >"> <context_menu label="Kleidung" name="Clothes >"> 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 634ef0b198..7c47913e30 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 @@ -9,6 +9,7 @@ <menu_item_call label="Öffnen" name="open"/> <menu_item_call label="Bearbeiten" name="edit"/> <menu_item_call label="Anziehen" name="wear"/> + <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="Hineinzoomen" name="zoom_in"/> diff --git a/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml index b28e83c3e3..851a96cc09 100644 --- a/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/de/menu_inspect_self_gear.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <menu name="Gear Menu"> + <menu_item_call label="Hinsetzen" name="sit_down_here"/> <menu_item_call label="Aufstehen" name="stand_up"/> <menu_item_call label="Outfit ändern" name="change_outfit"/> <menu_item_call label="Mein Profil" name="my_profile"/> diff --git a/indra/newview/skins/default/xui/de/menu_mini_map.xml b/indra/newview/skins/default/xui/de/menu_mini_map.xml index 7139b98965..bec79be34d 100644 --- a/indra/newview/skins/default/xui/de/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/de/menu_mini_map.xml @@ -4,6 +4,7 @@ <menu_item_call label="Zoom Mittel" name="Zoom Medium"/> <menu_item_call label="Zoom Weit" name="Zoom Far"/> <menu_item_check label="Karte drehen" name="Rotate Map"/> + <menu_item_check label="Automatisch zentrieren" name="Auto Center"/> <menu_item_call label="Verfolgung abschalten" name="Stop Tracking"/> <menu_item_call label="Weltkarte" name="World Map"/> </menu> diff --git a/indra/newview/skins/default/xui/de/menu_object.xml b/indra/newview/skins/default/xui/de/menu_object.xml index 5003939fb6..19057d4228 100644 --- a/indra/newview/skins/default/xui/de/menu_object.xml +++ b/indra/newview/skins/default/xui/de/menu_object.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Object Pie"> <menu_item_call label="Berühren" name="Object Touch"> - <on_enable parameter="Berühren" name="EnableTouch"/> + <menu_item_call.on_enable name="EnableTouch" parameter="Berühren"/> </menu_item_call> <menu_item_call label="Bearbeiten" name="Edit..."/> <menu_item_call label="Bauen" name="Build"/> @@ -12,6 +12,7 @@ <menu_item_call label="Hineinzoomen" name="Zoom In"/> <context_menu label="Anziehen" name="Put On"> <menu_item_call label="Anziehen" name="Wear"/> + <menu_item_call label="Hinzufügen" name="Add"/> <context_menu label="Anhängen" name="Object Attach"/> <context_menu label="HUD anhängen" name="Object Attach HUD"/> </context_menu> @@ -21,7 +22,6 @@ <menu_item_call label="Zurückgeben" name="Return..."/> <menu_item_call label="Löschen" name="Delete"/> </context_menu> - <menu_item_call label="Kaufen" name="Pie Object Bye"/> <menu_item_call label="Nehmen" name="Pie Object Take"/> <menu_item_call label="Kopie nehmen" name="Take Copy"/> <menu_item_call label="Bezahlen" name="Pay..."/> diff --git a/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml index 9d50a42ed4..84d9d8938c 100644 --- a/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/de/menu_people_friends_view_sort.xml @@ -3,5 +3,6 @@ <menu_item_check label="Nach Name sortieren" name="sort_name"/> <menu_item_check label="Nach Status sortieren" name="sort_status"/> <menu_item_check label="Symbole für Personen anzeigen" name="view_icons"/> + <menu_item_check label="Erteilte Genehmigungen anzeigen" name="view_permissions"/> <menu_item_call label="Ignorierte Einwohner & Objekte anzeigen" name="show_blocked_list"/> </menu> diff --git a/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml index d978d9e40c..b6e99edfe1 100644 --- a/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml +++ b/indra/newview/skins/default/xui/de/menu_people_nearby_multiselect.xml @@ -6,4 +6,5 @@ <menu_item_call label="Anrufen" name="Call"/> <menu_item_call label="Teilen" name="Share"/> <menu_item_call label="Bezahlen" name="Pay"/> + <menu_item_call label="Teleport anbieten" name="teleport"/> </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 b9b6a8ed50..bb9a4c8354 100644 --- a/indra/newview/skins/default/xui/de/menu_viewer.xml +++ b/indra/newview/skins/default/xui/de/menu_viewer.xml @@ -94,7 +94,6 @@ <menu_item_call label="Skripts auf nicht ausführen einstellen" name="Set Scripts to Not Running"/> </menu> <menu label="Optionen" name="Options"> - <menu_item_call label="Hochlade-Berechtigungen (Standard) festlegen" name="perm prefs"/> <menu_item_check label="Erweiterte Berechtigungen anzeigen" name="DebugPermissions"/> <menu_item_check label="Nur meine Objekte auswählen" name="Select Only My Objects"/> <menu_item_check label="Nur bewegliche Objekte auswählen" name="Select Only Movable Objects"/> @@ -121,7 +120,6 @@ <menu_item_call label="INFO ÜBER [APP_NAME]" name="About Second Life"/> </menu> <menu label="Erweitert" name="Advanced"> - <menu_item_check label="Menü „Erweitert“ anzeigen" name="Show Advanced Menu"/> <menu_item_call label="Animation meines Avatars stoppen" name="Stop Animating My Avatar"/> <menu_item_call label="Textur neu laden" name="Rebake Texture"/> <menu_item_call label="UI-Größe auf Standard setzen" name="Set UI Size to Default"/> @@ -169,7 +167,6 @@ <menu_item_check label="FRInfo testen" name="Test FRInfo"/> <menu_item_check label="Flexible Objekte" name="Flexible Objects"/> </menu> - <menu_item_check label="Mehrere Threads ausführen" name="Run Multiple Threads"/> <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"/> @@ -178,7 +175,6 @@ <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_check label="Immer rennen" name="Always Run"/> <menu_item_check label="Fliegen" name="Fly"/> <menu_item_call label="Fenster schließen" name="Close Window"/> @@ -198,6 +194,7 @@ <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"/> + <menu_item_check label="Menü „Erweitert“ anzeigen" name="Show Advanced Menu"/> </menu> <menu_item_call label="Debug-Einstellungen anzeigen" name="Debug Settings"/> <menu_item_check label="Menü „Entwickler“ anzeigen" name="Debug Mode"/> @@ -263,16 +260,19 @@ <menu_item_check label="Wireframe" name="Wireframe"/> <menu_item_check label="Objekt-Objekt Okklusion" name="Object-Object Occlusion"/> <menu_item_check label="Framebuffer-Objekte" name="Framebuffer Objects"/> - <menu_item_check label="Deferred Rendering" name="Deferred Rendering"/> - <menu_item_check label="Globale Beleuchtung" name="Global Illumination"/> + <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="Schnelles Alpha" name="Fast Alpha"/> + <menu_item_check label="Automatische Alpha-Masken (aufgeschoben)" name="Automatic Alpha Masks (deferred)"/> + <menu_item_check label="Automatische Alpha-Masken (nicht aufgeschoben)" name="Automatic Alpha Masks (non-deferred)"/> <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" name="Texture Atlas"/> + <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"/> <menu_item_check label="Leucht-Objekte schweben lassen" name="Hover Glow Objects"/> @@ -309,7 +309,8 @@ <menu_item_call label="Ausgewählte Objektinfo drucken" name="Print Selected Object Info"/> <menu_item_call label="Agent-Info drucken" name="Print Agent Info"/> <menu_item_call label="Speicher-Stats" name="Memory Stats"/> - <menu_item_check label="Double-ClickAuto-Pilot" name="Double-ClickAuto-Pilot"/> + <menu_item_check label="Doppelklicken: Auto-Pilot" name="Double-Click Auto-Pilot"/> + <menu_item_check label="Doppelklicken: Teleport" name="DoubleClick Teleport"/> <menu_item_check label="Fehler in SelectMgr beseitigen" name="Debug SelectMgr"/> <menu_item_check label="Fehler in Klicks beseitigen" name="Debug Clicks"/> <menu_item_check label="Debug-Ansichten" name="Debug Views"/> diff --git a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml index d994571f01..80d4ff4d9f 100644 --- a/indra/newview/skins/default/xui/de/menu_wearing_gear.xml +++ b/indra/newview/skins/default/xui/de/menu_wearing_gear.xml @@ -1,4 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="Gear Wearing"> <menu_item_call label="Outfit bearbeiten" name="edit"/> + <menu_item_call label="Ausziehen" name="takeoff"/> </menu> diff --git a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml index d690572c8e..695451a105 100644 --- a/indra/newview/skins/default/xui/de/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/de/menu_wearing_tab.xml @@ -1,4 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Wearing"> + <menu_item_call label="Ausziehen" name="take_off"/> + <menu_item_call label="Abnehmen" name="detach"/> <menu_item_call label="Outfit bearbeiten" name="edit"/> </context_menu> diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index e5baf0f98f..c518c193a0 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -1831,6 +1831,10 @@ Inventarobjekt(e) verschieben? Wirklich beenden? <usetemplate ignoretext="Bestätigen, bevor Sitzung beendet wird" name="okcancelignore" notext="Nicht beenden" yestext="Beenden"/> </notification> + <notification name="DeleteItems"> + [QUESTION] + <usetemplate ignoretext="Vor dem Löschen von Objekten bestätigen" name="okcancelignore" notext="Abbrechen" yestext="OK"/> + </notification> <notification name="HelpReportAbuseEmailLL"> Mit dieser Funktion können Sie Verstöße gegen die [http://secondlife.com/corporate/tos.php Servicebedingungen (EN)] und [http://secondlife.com/corporate/cs.php Community-Standards] melden. @@ -2195,8 +2199,7 @@ Wählen Sie eine kleinere Landfläche. [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Teleportieren"/> - <button name="Description" text="Beschreibung"/> + <button name="Details" text="Beschreibung"/> <button name="Cancel" text="Abbrechen"/> </form> </notification> @@ -2763,9 +2766,13 @@ Bitte überprüfen Sie Ihr Netzwerk- und Firewall-Setup. (Seit [EXISTENCE] Sekunden inworld ) Avatar '[NAME]' hat als vollständig gerezzter Avatar die Welt verlassen. </notification> - <notification name="AvatarRezSelfBakeNotification"> - (Seit [EXISTENCE] Sekunden inworld ) -Die [RESOLUTION]-gebakene Textur für '[BODYREGION]' wurde in [TIME] Sekunden [ACTION]. + <notification name="AvatarRezSelfBakedTextureUploadNotification"> + ( [EXISTENCE] Sekunden am Leben) +Sie haben eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME] Sekunden hochgeladen. + </notification> + <notification name="AvatarRezSelfBakedTextureUpdateNotification"> + ( [EXISTENCE] Sekunden am Leben) +Sie haben lokal eine [RESOLUTION]-gebackene Textur für „[BODYREGION]“ nach [TIME] Sekunden aktualisiert. </notification> <notification name="ConfirmLeaveCall"> Möchten Sie dieses Gespräch wirklich verlassen ? diff --git a/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml index 0715175dd9..2db8cf7c09 100644 --- a/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/de/panel_avatar_list_item.xml @@ -23,5 +23,9 @@ </string> <text name="avatar_name" value="Unbekannt"/> <text name="last_interaction" value="0s"/> + <icon name="permission_edit_theirs_icon" tool_tip="Sie können die Objekte dieses Freunds bearbeiten"/> + <icon name="permission_edit_mine_icon" tool_tip="Dieser Freund kann Ihre Objekte bearbeiten, löschen und an sich nehmen"/> + <icon name="permission_map_icon" tool_tip="Dieser Freund kann Sie auf der Karte finden"/> + <icon name="permission_online_icon" tool_tip="Dieser Freund kann sehen, wenn Sie online sind"/> <button name="profile_btn" tool_tip="Profil anzeigen"/> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_bottomtray.xml b/indra/newview/skins/default/xui/de/panel_bottomtray.xml index ea15c88380..afe9836401 100644 --- a/indra/newview/skins/default/xui/de/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/de/panel_bottomtray.xml @@ -1,5 +1,6 @@ <?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"> @@ -12,28 +13,25 @@ <gesture_combo_list label="Gesten" name="Gesture" tool_tip="Gesten anzeigen/ausblenden"/> </layout_panel> <layout_panel name="movement_panel"> - <button label="Bewegen" name="movement_btn" tool_tip="Bewegungssteuerung anzeigen/ausblenden"/> + <bottomtray_button label="Bewegen" name="movement_btn" tool_tip="Bewegungssteuerung anzeigen/ausblenden"/> </layout_panel> <layout_panel name="cam_panel"> - <button label="Ansicht" name="camera_btn" tool_tip="Kamerasteuerung anzeigen/ausblenden"/> + <bottomtray_button label="Ansicht" name="camera_btn" tool_tip="Kamerasteuerung anzeigen/ausblenden"/> </layout_panel> <layout_panel name="snapshot_panel"> - <button label="" name="snapshots" tool_tip="Foto machen"/> - </layout_panel> - <layout_panel name="sidebar_btn_panel"> - <button label="Seitenleiste" name="sidebar_btn" tool_tip="Seitenleiste anzeigen/ausblenden"/> + <bottomtray_button label="" name="snapshots" tool_tip="Foto machen"/> </layout_panel> <layout_panel name="build_btn_panel"> - <button label="Bauen" name="build_btn" tool_tip="Bauwerkzeuge ein-/ausblenden"/> + <bottomtray_button label="Bauen" name="build_btn" tool_tip="Bauwerkzeuge ein-/ausblenden"/> </layout_panel> <layout_panel name="search_btn_panel"> - <button label="Suche" name="search_btn" tool_tip="Suche anzeigen/ausblenden"/> + <bottomtray_button label="Suche" name="search_btn" tool_tip="Suche anzeigen/ausblenden"/> </layout_panel> <layout_panel name="world_map_btn_panel"> - <button label="Karte" name="world_map_btn" tool_tip="Karte ein-/ausblenden"/> + <bottomtray_button label="Karte" name="world_map_btn" tool_tip="Karte ein-/ausblenden"/> </layout_panel> <layout_panel name="mini_map_btn_panel"> - <button label="Minikarte" name="mini_map_btn" tool_tip="Minikarte ein-/ausblenden"/> + <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"> diff --git a/indra/newview/skins/default/xui/de/panel_classified_info.xml b/indra/newview/skins/default/xui/de/panel_classified_info.xml index ac1cd7ba88..007e9d69f0 100644 --- a/indra/newview/skins/default/xui/de/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/de/panel_classified_info.xml @@ -52,8 +52,16 @@ </panel> </scroll_container> <panel name="buttons"> - <button label="Teleportieren" name="teleport_btn"/> - <button label="Karte" name="show_on_map_btn"/> - <button label="Bearbeiten" name="edit_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Teleportieren" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Karte" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="Bearbeiten" name="edit_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_edit_classified.xml b/indra/newview/skins/default/xui/de/panel_edit_classified.xml index 0d9487e895..bd270697ea 100644 --- a/indra/newview/skins/default/xui/de/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/de/panel_edit_classified.xml @@ -36,13 +36,19 @@ <icons_combo_box.item label="Moderater Inhalt" name="mature_ci" value="Moderat"/> <icons_combo_box.item label="Genereller Inhalt" name="pg_ci" value="G"/> </icons_combo_box> + <check_box label="Jede Woche automatisch erneuern" name="auto_renew"/> <text name="price_for_listing_label" value="Preis für Anzeige:"/> <spinner label="L$" name="price_for_listing" tool_tip="Preis für Anzeige." value="50"/> - <check_box label="Jede Woche automatisch erneuern" name="auto_renew"/> </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> - <button label="[LABEL]" name="save_changes_btn"/> - <button label="Abbrechen" name="cancel_btn"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="[LABEL]" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Abbrechen" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_edit_pick.xml b/indra/newview/skins/default/xui/de/panel_edit_pick.xml index 1ec4f09161..3c56df763d 100644 --- a/indra/newview/skins/default/xui/de/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/de/panel_edit_pick.xml @@ -25,7 +25,13 @@ </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> - <button label="Auswahl speichern" name="save_changes_btn"/> - <button label="Abbrechen" name="cancel_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Auswahl speichern" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="layout_panel1"> + <button label="Abbrechen" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_edit_profile.xml b/indra/newview/skins/default/xui/de/panel_edit_profile.xml index bf74abaeba..b689856f8c 100644 --- a/indra/newview/skins/default/xui/de/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/de/panel_edit_profile.xml @@ -53,7 +53,13 @@ </panel> </scroll_container> <panel name="profile_me_buttons_panel"> - <button label="Änderungen speichern" name="save_btn"/> - <button label="Abbrechen" name="cancel_btn"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="Änderungen speichern" name="save_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Abbrechen" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_edit_wearable.xml b/indra/newview/skins/default/xui/de/panel_edit_wearable.xml index faeea3a5de..271db4c15c 100644 --- a/indra/newview/skins/default/xui/de/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/de/panel_edit_wearable.xml @@ -102,7 +102,13 @@ <icon name="female_icon" tool_tip="Weiblich"/> </panel> <panel name="button_panel"> - <button label="Speichern unter" name="save_as_button"/> - <button label="Änderungen rückgängig machen" name="revert_button"/> + <layout_stack name="button_panel_ls"> + <layout_panel name="save_as_btn_lp"> + <button label="Speichern unter" name="save_as_button"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="Änderungen rückgängig machen" name="revert_button"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_friends.xml b/indra/newview/skins/default/xui/de/panel_friends.xml new file mode 100644 index 0000000000..50013a2b24 --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_friends.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="friends"> + <string name="Multiple"> + Mehrere Freunde + </string> + <scroll_list name="friend_list" tool_tip="Halten Sie die Tasten „Umschalt“ oder „Strg“ gedrückt, um durch Klicken mehrere Freunde auszuwählen."> + <column name="icon_online_status" tool_tip="Online-Status"/> + <column label="Name" name="friend_name" tool_tip="Name"/> + <column name="icon_visible_online" tool_tip="Freund kann sehen, wenn Sie online sind"/> + <column name="icon_visible_map" tool_tip="Freund kann Sie auf der Karte finden"/> + <column name="icon_edit_mine" tool_tip="Freunde können Objekte bearbeiten, löschen und an sich nehmen"/> + <column name="icon_edit_theirs" tool_tip="Sie können die Objekte dieses Freunds bearbeiten"/> + </scroll_list> + <panel name="rights_container"> + <text name="friend_name_label"> + Wählen Sie den/die Freund(e) aus, dessen/deren Rechte Sie ändern möchten... + </text> + <check_box label="Kann meinen Online-Status sehen" name="online_status_cb" tool_tip="Festlegen, ob dieser Freund meinen Online-Status auf seiner Freundesliste oder Visitenkarte einsehen kann"/> + <check_box label="Kann mich auf der Weltkarte sehen" name="map_status_cb" tool_tip="Festlegen, ob dieser Freund auf seiner Karte meinen Standort sehen kann"/> + <check_box label="Kann meine Objekte verändern" name="modify_status_cb" tool_tip="Festlegen, ob dieser Freund meine Objekte verändern kann"/> + <text name="process_rights_label"> + Rechte werden geändert... + </text> + </panel> + <button label="IM/Anruf" name="im_btn" tool_tip="Beginnt eine Instant Message-Sitzung"/> + <button label="Profil" name="profile_btn" tool_tip="Bilder, Gruppen und andere Informationen anzeigen"/> + <button label="Teleportieren" name="offer_teleport_btn" tool_tip="Bieten Sie diesem Freund einen Teleport an Ihre Position an"/> + <button label="Bezahlen" name="pay_btn" tool_tip="Diesem Freund Linden-Dollar (L$) geben"/> + <button label="Entfernen" name="remove_btn" tool_tip="Diese Person von Ihrer Freundesliste entfernen"/> + <button label="Hinzufügen" name="add_btn" tool_tip="Bieten Sie einem Einwohner die Freundschaft an"/> +</panel> diff --git a/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml index b89e4f90de..bf4d44af52 100644 --- a/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/de/panel_group_info_sidetray.xml @@ -13,7 +13,7 @@ Kostenlos </panel.string> <panel name="group_info_top"> - <text name="group_name" value="(wird geladen...)"/> + <text_editor name="group_name" value="(wird geladen...)"/> <line_editor label="Neuen Gruppennamen hier eingeben" name="group_name_editor"/> </panel> <layout_stack name="layout"> @@ -25,9 +25,15 @@ <accordion_tab name="group_land_tab" title="Land/Kapital"/> </accordion> </layout_panel> - <layout_panel name="button_row"> + </layout_stack> + <layout_stack name="button_row_ls"> + <layout_panel name="btn_chat_lp"> <button label="Chat" name="btn_chat"/> + </layout_panel> + <layout_panel name="call_btn_lp"> <button label="Gruppe anrufen" name="btn_call" tool_tip="Diese Gruppe anrufen"/> + </layout_panel> + <layout_panel name="btn_apply_lp"> <button label="Speichern" label_selected="Speichern" name="btn_apply"/> <button label="Gruppe erstellen" name="btn_create" tool_tip="Neue Gruppe erstellen"/> </layout_panel> diff --git a/indra/newview/skins/default/xui/de/panel_landmarks.xml b/indra/newview/skins/default/xui/de/panel_landmarks.xml index db12462a31..c1f8a20728 100644 --- a/indra/newview/skins/default/xui/de/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/de/panel_landmarks.xml @@ -7,8 +7,16 @@ <accordion_tab name="tab_library" title="Bibliothek"/> </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="Zusätzliche Optionen anzeigen"/> - <button name="add_btn" tool_tip="Neue Landmarke hinzufügen"/> - <dnd_button name="trash_btn" tool_tip="Ausgewählte Landmarke hinzufügen"/> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <button name="options_gear_btn" tool_tip="Zusätzliche Optionen anzeigen"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="Neue Landmarke hinzufügen"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="Ausgewählte Landmarke hinzufügen"/> + </layout_panel> + </layout_stack> </panel> </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 index 55eed89848..aea87cc2c4 100644 --- a/indra/newview/skins/default/xui/de/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/de/panel_my_profile.xml @@ -42,9 +42,8 @@ </panel> </scroll_container> </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Profil bearbeiten" name="edit_profile_btn" tool_tip="Ihre persönlichen Informationen bearbeiten"/> - <button label="Aussehen bearbeiten" name="edit_appearance_btn" tool_tip="Ihr Aussehen bearbeiten: Körpermaße, Bekleidung, usw."/> - </layout_panel> </layout_stack> + <panel name="profile_me_buttons_panel"> + <button label="Profil bearbeiten" name="edit_profile_btn" tool_tip="Ihre persönlichen Informationen bearbeiten"/> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_notes.xml b/indra/newview/skins/default/xui/de/panel_notes.xml index 374c117cdd..ef1961b63d 100644 --- a/indra/newview/skins/default/xui/de/panel_notes.xml +++ b/indra/newview/skins/default/xui/de/panel_notes.xml @@ -13,11 +13,23 @@ </scroll_container> </layout_panel> <layout_panel name="notes_buttons_panel"> - <button label="Freund hinzufügen" name="add_friend" tool_tip="Bieten Sie dem Einwohner die Freundschaft an" width="109"/> - <button label="IM" name="im" tool_tip="Instant Messenger öffnen" width="24"/> - <button label="Anrufen" name="call" tool_tip="Diesen Einwohner anrufen"/> - <button label="Karte" name="show_on_map_btn" tool_tip="Einwohner auf Karte anzeigen" width="40"/> - <button label="Teleportieren" name="teleport" tool_tip="Teleport anbieten"/> + <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_outfit_edit.xml b/indra/newview/skins/default/xui/de/panel_outfit_edit.xml index b38e07f3e1..632f414747 100644 --- a/indra/newview/skins/default/xui/de/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/de/panel_outfit_edit.xml @@ -45,7 +45,13 @@ <button name="shop_btn_2" tool_tip="Besuchen Sie den Marktplatz. Sie können auch einen Teil Ihres Outfits auswählen, und dann hier klicken, um ähnliche Artikel anzuzeigen."/> </panel> <panel name="save_revert_button_bar"> - <button label="Speichern" name="save_btn"/> - <button label="Änderungen rückgängig machen" name="revert_btn" tool_tip="Zur zuletzt gespeicherten Version zurücksetzen"/> + <layout_stack name="button_bar_ls"> + <layout_panel name="save_btn_lp"> + <button label="Speichern" name="save_btn"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="Änderungen rückgängig machen" name="revert_btn" tool_tip="Zur zuletzt gespeicherten Version zurückkehren"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml index e25d7d412b..d5158b2d97 100644 --- a/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/de/panel_outfits_inventory.xml @@ -11,7 +11,13 @@ <panel label="AKTUELLES OUTFIT" name="cof_tab"/> </tab_container> <panel name="bottom_panel"> - <button label="Speichern unter" name="save_btn"/> - <button label="Anziehen" name="wear_btn" tool_tip="Ausgewähltes Outfit tragen"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_btn_lp"> + <button label="Speichern unter" name="save_btn"/> + </layout_panel> + <layout_panel name="wear_btn_lp"> + <button label="Anziehen" name="wear_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml index 8acb680175..6c859da4d6 100644 --- a/indra/newview/skins/default/xui/de/panel_people.xml +++ b/indra/newview/skins/default/xui/de/panel_people.xml @@ -32,9 +32,17 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte]. <accordion_tab name="tab_all" title="Alle"/> </accordion> <panel label="bottom_panel" name="bottom_panel"> - <button name="friends_viewsort_btn" tool_tip="Optionen"/> - <button name="add_btn" tool_tip="Bieten Sie einem Einwohner die Freundschaft an"/> - <button name="del_btn" tool_tip="Ausgewählte Person von Ihrer Freundesliste entfernen"/> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <button name="friends_viewsort_btn" tool_tip="Zusätzliche Optionen anzeigen"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="Bieten Sie einem Einwohner die Freundschaft an"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="Ausgewählte Person von Ihrer Freundesliste entfernen"/> + </layout_panel> + </layout_stack> </panel> </panel> <panel label="MEINE GRUPPEN" name="groups_panel"> @@ -52,13 +60,33 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte]. </panel> </tab_container> <panel name="button_bar"> - <button label="Profil" name="view_profile_btn" tool_tip="Bilder, Gruppen und andere Einwohner-Informationen anzeigen"/> - <button label="IM" name="im_btn" tool_tip="Instant Messenger öffnen"/> - <button label="Anrufen" name="call_btn" tool_tip="Diesen Einwohner anrufen"/> - <button label="Teilen" name="share_btn" tool_tip="Inventarobjekt teilen"/> - <button label="Teleport" name="teleport_btn" tool_tip="Teleport anbieten"/> - <button label="Gruppenprofil" name="group_info_btn" tool_tip="Gruppeninformationen anzeigen"/> - <button label="Gruppen-Chat" name="chat_btn" tool_tip="Chat öffnen"/> - <button label="Gruppe anrufen" name="group_call_btn" tool_tip="Diese Gruppe anrufen"/> + <layout_stack name="bottom_bar_ls"> + <layout_panel name="view_profile_btn_lp"> + <button label="Profil" name="view_profile_btn" tool_tip="Bilder, Gruppen und andere Einwohner-Informationen anzeigen"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="IM" name="im_btn" tool_tip="Instant Messenger öffnen"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Anrufen" name="call_btn" tool_tip="Diesen Einwohner anrufen"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Teilen" name="share_btn" tool_tip="Inventarobjekt teilen"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Teleportieren" name="teleport_btn" tool_tip="Teleport anbieten"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="group_info_btn_lp"> + <button label="Gruppenprofil" name="group_info_btn" tool_tip="Gruppeninformationen anzeigen"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Gruppen-Chat" name="chat_btn" tool_tip="Chat öffnen"/> + </layout_panel> + <layout_panel name="group_call_btn_lp"> + <button label="Gruppe anrufen" name="group_call_btn" tool_tip="Diese Gruppe anrufen"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_pick_info.xml b/indra/newview/skins/default/xui/de/panel_pick_info.xml index d8939a8ed1..f215c43a3d 100644 --- a/indra/newview/skins/default/xui/de/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/de/panel_pick_info.xml @@ -3,14 +3,22 @@ <text name="title" value="Auswahl-Info"/> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> - <text name="pick_name" value="[name]"/> - <text name="pick_location" value="[wird geladen...]"/> - <text name="pick_desc" value="[description]"/> + <text_editor name="pick_name" value="[name]"/> + <text_editor name="pick_location" value="[wird geladen...]"/> + <text_editor name="pick_desc" value="[description]"/> </panel> </scroll_container> <panel name="buttons"> - <button label="Teleportieren" name="teleport_btn"/> - <button label="Karte" name="show_on_map_btn"/> - <button label="Bearbeiten" name="edit_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Teleportieren" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Karte" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="Bearbeiten" name="edit_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_picks.xml b/indra/newview/skins/default/xui/de/panel_picks.xml index df68381082..6aaa3151a8 100644 --- a/indra/newview/skins/default/xui/de/panel_picks.xml +++ b/indra/newview/skins/default/xui/de/panel_picks.xml @@ -7,11 +7,23 @@ <accordion_tab name="tab_classifieds" title="Anzeigen"/> </accordion> <panel label="bottom_panel" name="edit_panel"> - <button name="new_btn" tool_tip="An aktuellem Standort neue Auswahl oder Anzeige erstellen"/> + <layout_stack name="edit_panel_ls"> + <layout_panel name="gear_menu_btn"> + <button name="new_btn" tool_tip="An aktuellem Standort neue Auswahl oder Anzeige erstellen"/> + </layout_panel> + </layout_stack> </panel> <panel name="buttons_cucks"> - <button label="Info" name="info_btn" tool_tip="Auswahl-Information anzeigen"/> - <button label="Teleportieren" name="teleport_btn" tool_tip="Zu entsprechendem Standort teleportieren" width="100"/> - <button label="Karte" name="show_on_map_btn" tool_tip="Den entsprechenden Standort auf der Karte anzeigen"/> + <layout_stack name="buttons_cucks_ls"> + <layout_panel name="info_btn_lp"> + <button label="Info" name="info_btn" tool_tip="Informationen zur Auswahl anzeigen"/> + </layout_panel> + <layout_panel name="teleport_btn_lp"> + <button label="Teleportieren" name="teleport_btn" tool_tip="Zu entsprechendem Standort teleportieren"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Karte" name="show_on_map_btn" tool_tip="Den entsprechenden Standort auf der Karte anzeigen"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_places.xml b/indra/newview/skins/default/xui/de/panel_places.xml index bd5c1c8ffe..0e85829a0b 100644 --- a/indra/newview/skins/default/xui/de/panel_places.xml +++ b/indra/newview/skins/default/xui/de/panel_places.xml @@ -4,13 +4,45 @@ <string name="teleport_history_tab_title" value="TELEPORT-LISTE"/> <filter_editor label="Meine Orte filtern" name="Filter"/> <panel name="button_panel"> - <button label="Teleportieren" name="teleport_btn" tool_tip="Zu ausgewähltem Standort teleportieren"/> - <button label="Karte" name="map_btn" tool_tip="Den entsprechenden Standort auf der Karte anzeigen" width="60"/> - <button label="Bearbeiten" name="edit_btn" tool_tip="Landmarken-Info bearbeiten"/> - <button label="▼" name="overflow_btn" tool_tip="Zusätzliche Optionen anzeigen"/> - <button label="Speichern" name="save_btn" width="66"/> - <button label="Abbrechen" name="cancel_btn" width="66"/> - <button label="Schließen" name="close_btn"/> - <button label="Profil" name="profile_btn" tool_tip="Ortsprofil anzeigen"/> + <layout_stack name="bottom_bar_ls0"> + <layout_panel name="lp1"> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="teleport_btn_lp"> + <button label="Teleportieren" name="teleport_btn" tool_tip="Zu ausgewähltem Standort teleportieren"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Karte" name="map_btn" tool_tip="Den entsprechenden Standort auf der Karte anzeigen"/> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="lp2"> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="edit_btn_lp"> + <button label="Bearbeiten" name="edit_btn" tool_tip="Landmarken-Info bearbeiten"/> + </layout_panel> + <layout_panel name="overflow_btn_lp"> + <button label="▼" name="overflow_btn" tool_tip="Zusätzliche Optionen anzeigen"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="profile_btn_lp"> + <button label="Profil" name="profile_btn" tool_tip="Ortsprofil anzeigen"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_close_ls3"> + <layout_panel name="close_btn_lp"> + <button label="Schließen" name="close_btn"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls2"> + <layout_panel name="save_btn_lp"> + <button label="Speichern" name="save_btn"/> + </layout_panel> + <layout_panel name="cancel_btn_lp"> + <button label="Abbrechen" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </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 064eb3895b..aa314a1a57 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml @@ -56,27 +56,27 @@ <radio_item label="Getrennte Fenster" name="radio" value="0"/> <radio_item label="Registerkarten" name="radio2" value="1"/> </radio_group> - <check_box label="Ãbersetzen Chat" name="translate_chat_checkbox" /> + <check_box label="Bei Chat Maschinenübersetzung verwenden (Service von Google)" name="translate_chat_checkbox"/> <text name="translate_language_text"> - Chat-Sprache: + Chat übersetzen in: </text> <combo_box name="translate_language_combobox" width="200"> - <combo_box.item name="System Default Language" label="Betriebssystem-Einstellung" /> - <combo_box.item name="English" label="English (Englisch)" /> - <combo_box.item name="Danish" label="Danks (Dänisch)" /> - <combo_box.item name="German" label="Deutsch" /> - <combo_box.item name="Spanish" label="Español (Spanisch)" /> - <combo_box.item name="French" label="Français (Französisch)" /> - <combo_box.item name="Italian" label="Italiano (Italienisch)" /> - <combo_box.item name="Hungarian" label="Magyar (Ungarisch)" /> - <combo_box.item name="Dutch" label="Nederlands (Niederländisch)" /> - <combo_box.item name="Polish" label="Polski (Polnisch)" /> - <combo_box.item name="Portugese" label="Português (Portugiesisch)" /> - <combo_box.item name="Russian" label="Русский (Russian)" /> - <combo_box.item name="Turkish" label="Türkçe (Türkisch)" /> - <combo_box.item name="Ukrainian" label="Українська (Ukrainisch)" /> - <combo_box.item name="Chinese" label="中文 (简体) (Chinesisch)" /> - <combo_box.item name="Japanese" label="日本語 (Japanisch)" /> - <combo_box.item name="Korean" label="한국어 (Koreanisch)" /> + <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> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml index 7077534719..ae3c791ab9 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml @@ -28,22 +28,16 @@ <check_box initial_value="true" label="Bumpmapping und Glanz" name="BumpShiny"/> <check_box initial_value="true" label="Einfache Shader" name="BasicShaders" tool_tip="Deaktivieren Sie diese Option, wenn der Grafikkartentreiber Abstürze verursacht"/> <check_box initial_value="true" label="Atmosphären-Shader" name="WindLightUseAtmosShaders"/> - <check_box initial_value="true" label="Wasserreflexionen" name="Reflections"/> - <text name="ReflectionDetailText"> - Spiegelung: + <text name="reflection_label"> + Wasserreflexionen: </text> - <radio_group name="ReflectionDetailRadio"> - <radio_item label="Terrain und Bäume" name="0"/> - <radio_item label="Alle statischen Objekte" name="1"/> - <radio_item label="Alle Avatare und Objekte" name="2"/> - <radio_item label="Alles" name="3"/> - </radio_group> - <text name="AvatarRenderingText"> - Avatar-Darstellung: - </text> - <check_box initial_value="true" label="Vereinfachte Avatardarstellung" name="AvatarImpostors"/> - <check_box initial_value="true" label="Hardware-Hautberechnung" name="AvatarVertexProgram"/> - <check_box initial_value="true" label="Avatar-Kleidung" name="AvatarCloth"/> + <combo_box initial_value="true" label="Wasserreflexionen" name="Reflections"> + <combo_box.item label="Minimal" name="0"/> + <combo_box.item label="Terrain und Bäume" name="1"/> + <combo_box.item label="Alle statischen Objekte" name="2"/> + <combo_box.item label="Alle Avatare und Objekte" name="3"/> + <combo_box.item label="Alles" name="4"/> + </combo_box> <slider label="Sichtweite:" name="DrawDistance"/> <text name="DrawDistanceMeterText2"> m @@ -81,13 +75,12 @@ <text name="SkyMeshDetailText"> Niedrig </text> - <text name="LightingDetailText"> - Beleuchtungsdetails: + <text name="AvatarRenderingText"> + Avatar-Darstellung: </text> - <radio_group name="LightingDetailRadio"> - <radio_item label="Nur Sonne und Mond" name="SunMoon" value="0"/> - <radio_item label="Lokale Lichtquellen" name="LocalLights" value="1"/> - </radio_group> + <check_box initial_value="true" label="Vereinfachte Avatardarstellung" name="AvatarImpostors"/> + <check_box initial_value="true" label="Hardware-Hautberechnung" name="AvatarVertexProgram"/> + <check_box initial_value="true" label="Avatar-Kleidung" name="AvatarCloth"/> <text name="TerrainDetailText"> Terraindetails: </text> @@ -95,6 +88,7 @@ <radio_item label="Niedrig" name="0"/> <radio_item label="Hoch" name="2"/> </radio_group> + --> </panel> <button label="Übernehmen" label_selected="Übernehmen" name="Apply"/> <button label="Zurücksetzen" name="Defaults"/> diff --git a/indra/newview/skins/default/xui/de/panel_profile.xml b/indra/newview/skins/default/xui/de/panel_profile.xml index cda2788e40..40fa2f922a 100644 --- a/indra/newview/skins/default/xui/de/panel_profile.xml +++ b/indra/newview/skins/default/xui/de/panel_profile.xml @@ -40,17 +40,29 @@ </panel> </scroll_container> </layout_panel> + </layout_stack> + <layout_stack name="layout_verb_buttons"> <layout_panel name="profile_buttons_panel"> - <button label="Freund hinzufügen" name="add_friend" tool_tip="Bieten Sie dem Einwohner die Freundschaft an"/> - <button label="IM" name="im" tool_tip="Instant Messenger öffnen"/> - <button label="Anrufen" name="call" tool_tip="Diesen Einwohner anrufen"/> - <button label="Karte" name="show_on_map_btn" tool_tip="Einwohner auf Karte anzeigen"/> - <button label="Teleportieren" name="teleport" tool_tip="Teleport anbieten"/> - <button label="▼" name="overflow_btn" tool_tip="Dem Einwohner Geld geben oder Inventar an den Einwohner schicken"/> + <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"> + <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"/> - <button label="Aussehen bearbeiten" name="edit_appearance_btn" tool_tip="Ihr Aussehen bearbeiten: Körpermaße, Bekleidung, usw."/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml index 93fff56f84..652fb7c836 100644 --- a/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml +++ b/indra/newview/skins/default/xui/de/panel_side_tray_tab_caption.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="sidetray_tab_panel"> <text name="sidetray_tab_title" value="Klappmenü??"/> + <button name="undock" tool_tip="Abkoppeln"/> + <button name="dock" tool_tip="Andocken"/> <button name="show_help" tool_tip="Hilfe anzeigen"/> </panel> diff --git a/indra/newview/skins/default/xui/de/sidepanel_inventory.xml b/indra/newview/skins/default/xui/de/sidepanel_inventory.xml index f9bf2fe081..d817d1df90 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_inventory.xml @@ -2,12 +2,20 @@ <panel label="Sonstiges" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <panel name="button_panel"> - <button label="Profil" name="info_btn" tool_tip="Objektprofil anzeigen"/> - <button label="Teilen" name="share_btn" tool_tip="Inventarobjekt teilen"/> - <button label="Einkaufen" name="shop_btn" tool_tip="Marktplatz-Webseite öffnen"/> - <button label="Anziehen" name="wear_btn" tool_tip="Ausgewähltes Outfit tragen"/> - <button label="Wiedergeben" name="play_btn"/> - <button label="Teleportieren" name="teleport_btn" tool_tip="Zu ausgewähltem Standort teleportieren"/> + <layout_stack name="button_panel_ls"> + <layout_panel name="info_btn_lp"> + <button label="Profil" name="info_btn" tool_tip="Objektprofil anzeigen"/> + </layout_panel> + <layout_panel name="share_btn_lp"> + <button label="Teilen" name="share_btn" tool_tip="Inventarobjekt teilen"/> + </layout_panel> + <layout_panel name="shop_btn_lp"> + <button label="Einkaufen" name="shop_btn" tool_tip="Marktplatz-Webseite öffnen"/> + <button label="Anziehen" name="wear_btn" tool_tip="Ausgewähltes Outfit tragen"/> + <button label="Wiedergeben" name="play_btn"/> + <button label="Teleportieren" name="teleport_btn" tool_tip="Zu ausgewähltem Standort teleportieren"/> + </layout_panel> + </layout_stack> </panel> </panel> </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 4ba187dbd6..18241dea32 100644 --- a/indra/newview/skins/default/xui/de/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/de/sidepanel_item_info.xml @@ -23,56 +23,53 @@ </panel.string> <text name="title" value="Objektprofil"/> <text name="origin" value="(Inventar)"/> - <panel label="" name="item_profile"> - <text name="LabelItemNameTitle"> - Name: - </text> - <text name="LabelItemDescTitle"> - Beschreibung: - </text> - <text name="LabelCreatorTitle"> - Ersteller: - </text> - <text name="LabelCreatorName"/> - <button label="Profil" name="BtnCreator"/> - <text name="LabelOwnerTitle"> - Eigentümer: - </text> - <text name="LabelOwnerName"/> - <button label="Profil" name="BtnOwner"/> - <text name="LabelAcquiredTitle"> - Erworben: - </text> - <text name="LabelAcquiredDate"/> - <panel name="perms_inv"> - <text name="perm_modify"> - Sie können: + <scroll_container name="item_profile_scroll"> + <panel label="" name="item_profile"> + <text name="LabelItemNameTitle"> + Name: </text> - <check_box label="Bearbeiten" name="CheckOwnerModify"/> - <check_box label="Kopieren" name="CheckOwnerCopy"/> - <check_box label="Übertragen" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel"> - Jeder: + <text name="LabelItemDescTitle"> + Beschreibung: </text> - <check_box label="Kopieren" name="CheckEveryoneCopy"/> - <text name="GroupLabel"> - Gruppe: + <text name="LabelCreatorTitle"> + Ersteller: </text> - <check_box label="Teilen" name="CheckShareWithGroup" tool_tip="Mit allen Mitgliedern der zugeordneten Gruppe, Ihre Berechtigungen dieses Objekt zu ändern, teilen. Sie müssen Übereignen, um Rollenbeschränkungen zu aktivieren."/> - <text name="NextOwnerLabel"> - Nächster Eigentümer: + <text name="LabelOwnerTitle"> + Eigentümer: </text> - <check_box label="Bearbeiten" name="CheckNextOwnerModify"/> - <check_box label="Kopieren" name="CheckNextOwnerCopy"/> - <check_box label="Übertragen" name="CheckNextOwnerTransfer" tool_tip="Nächster Eigentümer kann dieses Objekt weitergeben oder -verkaufen"/> + <text name="LabelAcquiredTitle"> + Erworben: + </text> + <panel name="perms_inv"> + <text name="perm_modify"> + Sie können: + </text> + <check_box label="Bearbeiten" name="CheckOwnerModify"/> + <check_box label="Kopieren" name="CheckOwnerCopy"/> + <check_box label="Übertragen" name="CheckOwnerTransfer"/> + <text name="AnyoneLabel"> + Jeder: + </text> + <check_box label="Kopieren" name="CheckEveryoneCopy"/> + <text name="GroupLabel"> + Gruppe: + </text> + <check_box label="Teilen" name="CheckShareWithGroup" tool_tip="Mit allen Mitgliedern der zugeordneten Gruppe, Ihre Berechtigungen dieses Objekt zu ändern, teilen. Sie müssen eine Übereignung durchführen, um Rollenbeschränkungen zu aktivieren."/> + <text name="NextOwnerLabel"> + Nächster Eigentümer: + </text> + <check_box label="Bearbeiten" name="CheckNextOwnerModify"/> + <check_box label="Kopieren" name="CheckNextOwnerCopy"/> + <check_box label="Übertragen" name="CheckNextOwnerTransfer" tool_tip="Nächster Eigentümer kann dieses Objekt weitergeben oder -verkaufen"/> + </panel> + <check_box label="Zum Verkauf" name="CheckPurchase"/> + <combo_box name="combobox sale copy"> + <combo_box.item label="Kopieren" name="Copy"/> + <combo_box.item label="Original" name="Original"/> + </combo_box> + <spinner label="Preis: L$" name="Edit Cost"/> </panel> - <check_box label="Zum Verkauf" name="CheckPurchase"/> - <combo_box name="combobox sale copy"> - <combo_box.item label="Kopieren" name="Copy"/> - <combo_box.item label="Original" name="Original"/> - </combo_box> - <spinner label="Preis: L$" name="Edit Cost"/> - </panel> + </scroll_container> <panel name="button_panel"> <button label="Abbrechen" name="cancel_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 1adc4e3db1..afcb68f537 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -798,7 +798,7 @@ <string name="xml_file"> XML-Datei </string> - <string name="dot_raw_file"> + <string name="raw_file"> RAW-Datei </string> <string name="compressed_image_files"> @@ -1294,6 +1294,9 @@ <string name="Right Pec"> Rechts </string> + <string name="Invalid Attachment"> + Ungültige Stelle für Anhang + </string> <string name="YearsMonthsOld"> [AGEYEARS] [AGEMONTHS] alt </string> @@ -1671,9 +1674,6 @@ <string name="ATTACH_HUD_BOTTOM_RIGHT"> HUD unten rechts </string> - <string name="Bad attachment point"> - Ungültige Stelle für Anhang - </string> <string name="CursorPos"> Zeile [LINE], Spalte [COLUMN] </string> @@ -1695,12 +1695,6 @@ <string name="BusyModeResponseDefault"> Der Einwohner/Die Einwohnerin ist „beschäftigt”, d.h. er/sie möchte im Moment nicht gestört werden. Ihre Nachricht wird dem Einwohner/der Einwohnerin als IM angezeigt, und kann später beantwortet werden. </string> - <string name="NoOutfits"> - Sie haben noch keine Outfits. Versuchen Sie es mit der [secondlife:///app/search/all Suche]. - </string> - <string name="NoOutfitsTabsMatched"> - Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/all/[SEARCH_TERM] Suche]. - </string> <string name="MuteByName"> (Nach Namen) </string> @@ -1741,7 +1735,7 @@ Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus"-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen. </string> <string name="NoAvatarPicksClassifiedsText"> - Der Einwohner hat eine Auswahl oder Anzeigen im Profil. + Der Einwohner hat keine Auswahl oder Anzeigen </string> <string name="PicksClassifiedsLoadingText"> Wird geladen... @@ -1864,6 +1858,12 @@ Gültige Formate: .wav, .tga, .bmp, .jpg, .jpeg oder .bvh <string name="accel-win-shift"> Umschalt+ </string> + <string name="Esc"> + Esc + </string> + <string name="Home"> + Zuhause + </string> <string name="FileSaved"> Datei wurde gespeichert </string> @@ -3528,6 +3528,9 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="IM_moderator_label"> (Moderator) </string> + <string name="Saved_message"> + (Gespeichert am [LONG_TIMESTAMP]) + </string> <string name="answered_call"> Ihr Anruf wurde entgegengenommen </string> @@ -3555,12 +3558,18 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_ <string name="conference-title"> Ad-hoc-Konferenz </string> + <string name="conference-title-incoming"> + Konferenz mit [AGENT_NAME] + </string> <string name="inventory_item_offered-im"> Inventarobjekt angeboten </string> <string name="share_alert"> Objekte aus dem Inventar hier her ziehen </string> + <string name="no_session_message"> + (IM-Session nicht vorhanden) + </string> <string name="only_user_message"> Sie sind der einzige Benutzer in dieser Sitzung. </string> @@ -3945,4 +3954,13 @@ Missbrauchsbericht <string name="Chat"> Chat </string> + <string name="DeleteItems"> + Ausgewählte Objekte löschen? + </string> + <string name="DeleteItem"> + Ausgewähltes Objekt löschen? + </string> + <string name="EmptyOutfitText"> + Keine Objekte in diesem Outfit + </string> </strings> 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 e6f11cac60..89ed16e7c2 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -220,7 +220,8 @@ layout="topleft" left_pad="2" name="OwnerText" - width="240"> + use_ellipses="true" + width="360"> Leyla Linden </text> <button @@ -374,7 +375,8 @@ Leyla Linden </text> left_delta="-199" name="For sale to" top_delta="20" - width="186"> + use_ellipses="true" + width="340"> For sale to: [BUYER] </text> <text @@ -410,7 +412,7 @@ Leyla Linden </text> right="-10" name="Cancel Land Sale" left_pad="5" - top_pad="-25" + top_pad="-15" width="180" /> <text type="string" @@ -541,7 +543,7 @@ Leyla Linden </text> layout="topleft" left_delta="0" name="Reclaim Land..." - top_delta="-61" + top_delta="-50" width="180" /> <button enabled="false" 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 f59badfcb4..a11946d352 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml @@ -5,11 +5,11 @@ height="350" layout="topleft" min_height="200" - min_width="265" + min_width="400" name="avatarpicker" help_topic="avatarpicker" title="CHOOSE RESIDENT" - width="265"> + width="500"> <floater.string name="not_found"> '[TEXT]' not found @@ -40,7 +40,7 @@ name="ResidentChooserTabs" tab_position="top" top="20" - width="265"> + width="500"> <panel border="none" height="150" @@ -83,14 +83,24 @@ left_pad="5" name="Find" width="45" /> - <scroll_list - follows="all" - height="98" - layout="topleft" - left="0" - name="SearchResults" - top="52" - width="132" /> + <scroll_list + draw_heading="true" + follows="all" + height="98" + layout="topleft" + left="0" + name="SearchResults" + top="52" + width="132"> + <columns + label="Name" + name="name" + width="150" /> + <columns + label="Username" + name="username" + width="150" /> + </scroll_list> </panel> <panel border="none" @@ -128,7 +138,7 @@ </button> <scroll_list follows="all" - height="100" + height="120" border="false" layout="topleft" left="0" @@ -194,7 +204,8 @@ width="28" name="Refresh" image_overlay="Refresh_Off" /> - <scroll_list + <scroll_list + draw_heading="true" follows="all" height="100" border="false" @@ -202,21 +213,30 @@ left="0" name="NearMe" sort_column="0" - top="50" - width="132" /> + top="52" + width="132"> + <columns + label="Name" + name="name" + width="150" /> + <columns + label="Username" + name="username" + width="150" /> + </scroll_list> </panel> </tab_container> <button - follows="right|bottom" + follows="left|bottom" height="23" label="OK" label_selected="OK" name="ok_btn" top_pad="3" - left="46" + left="10" width="100" /> <button - follows="right|bottom" + follows="left|bottom" height="23" label="Cancel" label_selected="Cancel" diff --git a/indra/newview/skins/default/xui/en/floater_bumps.xml b/indra/newview/skins/default/xui/en/floater_bumps.xml index 303c28d7c8..1f2fe62b3c 100644 --- a/indra/newview/skins/default/xui/en/floater_bumps.xml +++ b/indra/newview/skins/default/xui/en/floater_bumps.xml @@ -14,23 +14,23 @@ </floater.string> <floater.string name="bump"> - [TIME] [FIRST] [LAST] bumped you + [TIME] [NAME] bumped you </floater.string> <floater.string name="llpushobject"> - [TIME] [FIRST] [LAST] pushed you with a script + [TIME] [NAME] pushed you with a script </floater.string> <floater.string name="selected_object_collide"> - [TIME] [FIRST] [LAST] hit you with an object + [TIME] [NAME] hit you with an object </floater.string> <floater.string name="scripted_object_collide"> - [TIME] [FIRST] [LAST] hit you with a scripted object + [TIME] [NAME] hit you with a scripted object </floater.string> <floater.string name="physical_object_collide"> - [TIME] [FIRST] [LAST] hit you with a physical object + [TIME] [NAME] hit you with a physical object </floater.string> <floater.string name="timeStr"> 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 77a0e9b91b..babbf0f5ca 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_contents.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_contents.xml @@ -56,7 +56,7 @@ <text type="string" length="1" - follows="left|bottom" + follows="left|right|bottom" font="SansSerif" height="16" layout="topleft" @@ -64,6 +64,7 @@ name="buy_text" text_color="white" top="220" + use_ellipses="true" width="260"> Buy for L$[AMOUNT] from [NAME]? </text> diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml index c88de878f4..d5d4565ca1 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml @@ -569,7 +569,7 @@ sold with objects name="US$6.00/month,billedannually" /> </combo_box> <locate - height="10" + height="5" layout="topleft" /> <icon follows="top|left" @@ -590,7 +590,7 @@ sold with objects left="72" name="land_use_action" right="438" - top="284" + top="279" width="218" wrap="true"> Increase your monthly land use fees to US$ 40/month. @@ -610,7 +610,7 @@ sold with objects This parcel is 512 m² of land. </text> <locate - height="10" + height="5" layout="topleft" /> <icon follows="top|left" @@ -654,7 +654,7 @@ This parcel is 512 m² of land. left_delta="0" name="currency_action" top_pad="9" - width="90"> + width="95"> Buy additional L$ </text> <locate 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 3d8f5d678b..8dfb6ba00c 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_object.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_resize="true" - height="290" + height="310" layout="topleft" min_height="150" min_width="225" @@ -84,16 +84,34 @@ length="1" follows="left|right|bottom" font="SansSerif" - height="16" + height="15" layout="topleft" left_delta="0" + line_spacing.pixels="7" name="buy_text" text_color="white" top_pad="5" use_ellipses="true" - width="260"> - Buy for L$[AMOUNT] from [NAME]? + width="260" + word_wrap="true"> +Buy for L$[AMOUNT] from: </text> + <text + type="string" + length="1" + follows="left|right|bottom" + font="SansSerif" + height="15" + layout="topleft" + left_delta="0" + line_spacing.pixels="7" + name="buy_name_text" + text_color="white" + top_pad="5" + use_ellipses="true" + width="260"> + [NAME]? + </text> <button follows="right|bottom" height="23" diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml new file mode 100644 index 0000000000..7a3fb9334a --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_display_name.xml @@ -0,0 +1,103 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_minimize="false" + can_close="false" + height="300" + layout="topleft" + name="Display Name" + help_topic="display_name" + save_rect="false" + title="CHANGE DISPLAY NAME" + width="445"> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="40" + layout="topleft" + left="25" + name="info_text" + top="40" + use_ellipses="true" + width="380" + wrap="true"> + The name you give your avatar is called your Display Name. You can change it once a week. + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="25" + layout="topleft" + left="25" + text_color="EmphasisColor" + name="lockout_text" + top="80" + use_ellipses="true" + visible="false" + width="410" + wrap="true"> + You cannot change your Display Name until: [TIME]. + </text> + <text + top_pad="10" + width="150" + height="20" + font="SansSerif" + name="set_name_label"> + New Display Name: + </text> + <line_editor + width="330" + name="display_name_editor" + max_length_chars="31" + height="20" + top_pad="5" + left="50" /> + <text + top_pad="15" + left="25" + width="300" + height="20" + font="SansSerif" + name="set_name_label"> + Type your new name again to confirm: + </text> + <line_editor + width="330" + name="display_name_confirm" + max_length_chars="31" + height="20" + top_pad="5" + left="50" /> + <button + height="23" + label="Save" + layout="topleft" + font="SansSerif" + left="35" + name="save_btn" + tool_tip="Save your new Display Name" + top_pad="40" + width="120" /> + <button + height="23" + label="Reset" + layout="topleft" + font="SansSerif" + left_pad="5" + name="reset_btn" + tool_tip="Make Display Name the same as Username" + width="120" /> + <button + height="23" + label="Cancel" + font="SansSerif" + layout="topleft" + left_pad="5" + name="cancel_btn" + width="120" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_event.xml b/indra/newview/skins/default/xui/en/floater_event.xml index 9864083442..7ed020f832 100644 --- a/indra/newview/skins/default/xui/en/floater_event.xml +++ b/indra/newview/skins/default/xui/en/floater_event.xml @@ -1,311 +1,40 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater follows="all" - height="350" + height="400" + can_resize="true" help_topic="event_details" label="Event" layout="topleft" name="Event" + save_rect="true" + save_visibility="false" title="EVENT DETAILS" - width="330"> - <floater.string - name="none"> - none - </floater.string> - <floater.string - name="notify"> - Notify - </floater.string> - <floater.string - name="dont_notify"> - Don't Notify - </floater.string> - <floater.string - name="moderate"> - Moderate - </floater.string> - <floater.string - name="adult"> - Adult - </floater.string> - <floater.string - name="general"> - General - </floater.string> - <floater.string - name="unknown"> - Unknown - </floater.string> - <layout_stack - name="layout" - orientation="vertical" - follows="all" - layout="topleft" - left="0" - top="0" - height="350" - width="330" - border_size="0"> - <layout_panel - name="profile_stack" - follows="top|left" - layout="topleft" - top="0" - left="0" - height="305" - width="330"> - <text - follows="top|left|right" - font="SansSerifLarge" - text_color="white" - height="17" - layout="topleft" - left="10" - name="event_name" - top="5" - use_ellipses="true" - width="310"> - Nameless Event...of Doom! De doom! Doom doom. - </text> - <text - type="string" - length="1" - follows="top|left" - height="13" - text_color="LtGray_50" - layout="topleft" - left="25" - name="event_category" - width="300"> - (no category) - </text> - - <text - type="string" - length="1" - follows="top|left" - layout="topleft" - left="10" - top_pad="7" - name="event_runby_label" - width="90"> - Run by: - </text> - <text - follows="left|top" - height="20" - initial_value="(retrieving)" - layout="topleft" - left_pad="0" - link="true" - name="event_runby" - top_delta="0" - use_ellipses="true" - width="240" /> - <text - type="string" - length="1" - follows="top|left" - layout="topleft" - left="10" - top_pad="5" - name="event_date_label" - width="90"> - Date: - </text> - <text - type="string" - length="1" - left_pad="0" - height="17" - top_delta="0" - follows="top|left" + width="600"> + <floater.string + name="loading_text"> + Loading... + </floater.string> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" layout="topleft" - name="event_date" - width="240"> - 10/10/2010 - </text> - <text - type="string" - length="1" - follows="top|left" - layout="topleft" - left="10" - top_pad="5" - name="event_duration_label" - width="90"> - Duration: - </text> - <text - type="string" - height="14" - length="1" - left_pad="0" - follows="top|left" - layout="topleft" - name="event_duration" - top_delta="0" - width="240"> - 1 hour - </text> - <text - type="string" - length="1" - follows="top|left" - layout="topleft" - left="10" - top_pad="5" - name="event_covercharge_label" - width="90"> - Cover charge: - </text> - <text - type="string" - follows="left|top" - height="16" - layout="topleft" - left_pad="0" - name="event_cover" - visible="true" - width="240" - top_delta="0"> - Free - </text> - <text - type="string" - length="1" - follows="top|left" - layout="topleft" - left="10" - top_pad="5" - name="event_location_label" - width="90"> - Location: - </text> - <text - type="string" - length="1" - height="20" - left_pad="0" - follows="top|left" - layout="topleft" - name="event_location" - use_ellipses="true" - top_delta="0" - value="SampleParcel, Name Long (145, 228, 26)" - width="240" /> - <icon - follows="top|left" - height="16" - image_name="Parcel_PG_Dark" - layout="topleft" - left="10" - name="rating_icon_pg" - width="18" /> - <icon - follows="top|left" - height="16" - image_name="Parcel_M_Dark" - layout="topleft" - left="10" - name="rating_icon_m" - top_delta="0" - width="18" /> - <icon - follows="top|left" - height="16" - image_name="Parcel_R_Dark" - layout="topleft" - left="10" - name="rating_icon_r" - top_delta="0" - width="18" /> - <text - follows="left|top" - height="16" - layout="topleft" - left_pad="12" - name="rating_label" - top_delta="3" - value="Rating:" - width="90" /> - <text - follows="left|right|top" - height="16" - layout="topleft" - left_pad="2" - name="rating_value" - top_delta="0" - value="unknown" - width="240" /> - <expandable_text - follows="left|top|right" - height="65" - layout="topleft" - left="6" - name="event_desc" - width="322"> - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</expandable_text> - </layout_panel> - <layout_panel - follows="left|right" - height="24" - layout="topleft" - mouse_opaque="false" - name="button_panel" - top="0" - left="0" - user_resize="false"> - <button - follows="left|top" - height="18" - image_selected="AddItem_Press" - image_unselected="AddItem_Off" - image_disabled="AddItem_Disabled" - layout="topleft" - left="6" - name="create_event_btn" - tool_tip="Create Event" - width="18" /> - <button - follows="left|top" - height="18" - image_selected="MinusItem_Press" - image_unselected="MinusItem_Off" - image_disabled="MinusItem_Disabled" - layout="topleft" - visible="false" - left="6" - top_pad="-7" - name="god_delete_event_btn" - tool_tip="Delete Event" - width="18" /> - <button - follows="left|top" - height="23" - label="Notify Me" - layout="topleft" - left_pad="3" - top_delta="-12" - name="notify_btn" - width="100" /> - <button - follows="left|top" - height="23" - label="Teleport" - layout="topleft" - left_pad="5" - name="teleport_btn" - width="100" /> - <button - follows="left|top" - height="23" - label="Map" - layout="topleft" - left_pad="5" - name="map_btn" - width="85" /> - </layout_panel> - </layout_stack> - </floater> + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> +</floater> 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 24fff6d4ae..81194f61cf 100644 --- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml @@ -8,7 +8,7 @@ layout="topleft" name="incoming call" help_topic="incoming_call" - title="UNKNOWN PERSON IS CALLING" + title="Incoming call" width="410"> <floater.string name="lifetime"> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml index 366098013b..2ef52bf539 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml @@ -106,6 +106,7 @@ left_delta="78" name="LabelCreatorName" top_delta="0" + use_ellipses="true" width="170"> Nicole Linden </text> @@ -139,8 +140,9 @@ left_delta="78" name="LabelOwnerName" top_delta="0" + use_ellipses="true" width="170"> - Thrax Linden + Thrax Linden </text> <button follows="top|right" diff --git a/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml new file mode 100644 index 0000000000..1d73d516d0 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_outfit_save_as.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + can_close="false" + can_minimize="false" + height="100" + layout="topleft" + title="Save Outfit" + name="modal container" + width="240"> + <button + height="23" + label="Save" + label_selected="Save" + layout="topleft" + left="20" + name="Save" + top="70" + width="82" /> + <button + height="23" + label="Cancel" + label_selected="Cancel" + layout="topleft" + left_pad="36" + name="Cancel" + top_delta="0" + width="82" /> + <text + type="string" + length="1" + follows="left|top" + height="30" + layout="topleft" + left="20" + word_wrap="true" + name="Save item as:" + top="10" + width="200"> + Save what I'm wearing +as a new Outfit: + </text> + <line_editor + type="string" + length="1" + border_style="line" + border_thickness="1" + follows="left|top" + height="23" + layout="topleft" + left_delta="0" + show_text_as_tentative="false" + top_pad="0" + max_length="63" + name="name ed" + width="200"> + [DESC] (new) + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml index 509cffe490..7ab565313e 100644 --- a/indra/newview/skins/default/xui/en/floater_pay.xml +++ b/indra/newview/skins/default/xui/en/floater_pay.xml @@ -7,7 +7,7 @@ name="Give Money" help_topic="give_money" save_rect="true" - width="225"> + width="250"> <string name="payee_group"> Pay Group @@ -16,28 +16,7 @@ name="payee_resident"> Pay Resident </string> - <text - type="string" - length="1" - follows="left|top" - height="18" - layout="topleft" - left="12" - name="payee_label" - top="22" - width="75"> - Pay: - </text> - <icon - height="16" - width="16" - image_name="Generic_Person" - mouse_opaque="true" - name="icon_person" - tool_tip="Person" - top_pad="0" - left="10" - /> + <text type="string" length="1" @@ -45,17 +24,19 @@ font="SansSerifSmall" height="16" layout="topleft" - left_pad="7" + left="10" name="payee_name" - width="210"> - [FIRST] [LAST] + top="25" + use_ellipses="true" + width="230"> + Test Name That Is Extremely Long To Check Clipping </text> <button height="23" label="L$1" label_selected="L$1" layout="topleft" - left="25" + left="35" name="fastpay 1" top_pad="8" width="80" /> @@ -72,7 +53,7 @@ label="L$10" label_selected="L$10" layout="topleft" - left="25" + left="35" name="fastpay 10" top_pad="8" width="80" /> @@ -90,7 +71,7 @@ follows="left|top" height="18" layout="topleft" - left="25" + left="35" name="amount text" top_pad="8" width="180"> @@ -102,7 +83,7 @@ height="19" top_pad="0" layout="topleft" - left="120" + left="130" max_length="9" name="amount" width="80" /> @@ -112,16 +93,16 @@ label="Pay" label_selected="Pay" layout="topleft" - left="10" + left="20" name="pay btn" - top_pad="5" + top_pad="15" width="100" /> <button height="23" label="Cancel" label_selected="Cancel" layout="topleft" - left_pad="5" + left_pad="10" name="cancel btn" width="100" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_pay_object.xml b/indra/newview/skins/default/xui/en/floater_pay_object.xml index d09a0a0535..d8cfed7b09 100644 --- a/indra/newview/skins/default/xui/en/floater_pay_object.xml +++ b/indra/newview/skins/default/xui/en/floater_pay_object.xml @@ -2,12 +2,12 @@ <floater legacy_header_height="18" can_minimize="false" - height="220" + height="225" layout="topleft" name="Give Money" help_topic="give_money" save_rect="true" - width="225"> + width="250"> <string name="payee_group"> Pay Group @@ -16,27 +16,16 @@ name="payee_resident"> Pay Resident </string> - <icon - height="16" - width="16" - image_name="Generic_Person" - mouse_opaque="true" - name="icon_person" - tool_tip="Person" - top_pad="24" - left="10" - /> <text - type="string" - length="1" follows="left|top" height="16" layout="topleft" - left_pad="7" - top_delta="3" + left="10" + top_pad="24" name="payee_name" - width="184"> - [FIRST] [LAST] + use_ellipses="true" + width="225"> + Ericacita Moostopolison </text> <text type="string" @@ -45,9 +34,9 @@ halign="left" height="14" layout="topleft" - left="34" + left="10" name="object_name_label" - top_pad="0" + top_pad="5" width="180"> Via object: </text> @@ -58,7 +47,7 @@ mouse_opaque="true" name="icon_object" tool_tip="Objects" - top_pad="0" + top_pad="5" left="10" /> <text 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 21c0bfef48..47383c8010 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -373,7 +373,6 @@ height="23" layout="topleft" left_delta="0" - max_length="32" name="abuser_name_edit" top_pad="0" width="195" /> diff --git a/indra/newview/skins/default/xui/en/floater_sell_land.xml b/indra/newview/skins/default/xui/en/floater_sell_land.xml index 4cae42bcfe..619669d28a 100644 --- a/indra/newview/skins/default/xui/en/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/en/floater_sell_land.xml @@ -164,7 +164,7 @@ left_delta="0" name="sell_to_agent" top_pad="4" - width="130" /> + width="170" /> <button height="20" label="Select" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index cea2ba2c7f..4c508035be 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -253,7 +253,7 @@ height="28" control_name="EditLinkedParts" label="Edit linked" - layout="topleft" + layout="topleft" name="checkbox edit linked parts" top_pad="2"> <check_box.commit_callback @@ -770,7 +770,7 @@ name="General" top="16" width="295"> -<panel.string + <panel.string name="text deed continued"> Deed </panel.string> @@ -862,19 +862,23 @@ height="19" layout="topleft" name="Creator:" + top_pad="7" width="90"> Creator: </text> + <!-- *NOTE: Intentionally wide for long names --> <text type="string" length="1" follows="left|top" left_pad="0" - height="19" + height="30" layout="topleft" name="Creator Name" - width="175"> - Esbee Linden + top_delta="0" + width="190" + word_wrap="true"> + Mrs. Esbee Linden (esbee.linden) </text> <text type="string" @@ -884,19 +888,23 @@ height="19" layout="topleft" name="Owner:" + top_pad="3" width="90"> Owner: </text> + <!-- *NOTE: Intentionally wide for long names --> <text type="string" length="1" follows="left|top" - height="19" + height="30" layout="topleft" name="Owner Name" left_pad="0" - width="175"> - Erica Linden + top_delta="0" + width="190" + word_wrap="true"> + Mrs. Erica "Moose" Linden (erica.linden) </text> <text type="string" @@ -906,7 +914,7 @@ left="10" height="18" name="Group:" - top_pad="4" + top_pad="7" width="75"> Group: </text> @@ -1060,8 +1068,8 @@ even though the user gets a free copy. bg_alpha_color="DkGray" name="perms_build" left="0" - top="241" - height="130" + top_pad="4" + height="105" width="290"> <text type="string" @@ -1132,14 +1140,16 @@ even though the user gets a free copy. top_delta="0" tool_tip="Next owner can give away or resell this object" width="100" /> +<!-- *NOTE: These "B/O/G/E/N/F fields may overlap "perm_modify" above, + but that's OK, this is used only for debugging. --> <text type="string" text_color="EmphasisColor" length="1" - top_pad="5" + top="9" follows="left|top" layout="topleft" - left="10" + left="230" name="B:" height="10" width="80"> @@ -1151,7 +1161,8 @@ even though the user gets a free copy. length="1" follows="left|top" layout="topleft" - left_pad="0" + left_delta="0" + top_pad="2" name="O:" height="10" width="80"> @@ -1163,7 +1174,8 @@ even though the user gets a free copy. length="1" follows="left|top" layout="topleft" - left_pad="0" + left_delta="0" + top_pad="2" name="G:" height="10" width="80"> @@ -1174,7 +1186,7 @@ even though the user gets a free copy. text_color="White" length="1" follows="left|top" - left="10" + left_delta="0" top_pad="2" layout="topleft" name="E:" @@ -1188,7 +1200,8 @@ even though the user gets a free copy. length="1" follows="left|top" layout="topleft" - left_pad="0" + left_delta="0" + top_pad="2" name="N:" height="10" width="80"> @@ -1200,7 +1213,8 @@ even though the user gets a free copy. length="1" follows="left|top" layout="topleft" - left_pad="0" + left_delta="0" + top_pad="2" name="F:" height="10" width="80"> @@ -1208,6 +1222,7 @@ even though the user gets a free copy. </text> </panel> </panel> + <!-- Object tab --> <panel border="false" follows="all" @@ -2975,4 +2990,5 @@ even though the user gets a free copy. top_pad="4" width="125" /> </panel> +<!-- end of tabs --> </floater> diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index 194ae151d2..853d5f8735 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -9,13 +9,13 @@ bg_opaque_image="Inspector_Background" can_close="false" can_minimize="false" - height="148" + height="164" layout="topleft" name="inspect_avatar" single_instance="true" sound_flags="0" visible="true" - width="228"> + width="245"> <!-- Allowed fields include: [BORN_ON] ("12/3/2008") [SL_PROFILE] (Second Life profile), @@ -34,15 +34,38 @@ </string> <text follows="top|left" - font="SansSerifLarge" - height="16" + font="SansSerif" + height="20" left="8" - name="user_name" - top="10" + name="user_name_small" + top="7" text_color="White" use_ellipses="true" - value="Grumpity ProductEngine" - width="175" /> + word_wrap="true" + visible="false" + value="Grumpity ProductEngine with a long name" + width="185" /> + <text + follows="top|left" + font="SansSerifBigLarge" + height="21" + left="8" + name="user_name" + top="10" + text_color="White" + use_ellipses="true" + value="Grumpity ProductEngine" + width="190" /> + <text + follows="top|left" + height="16" + left="8" + name="user_slid" + font="SansSerifSmallBold" + text_color="EmphasisColor" + value="james.linden" + width="185" + use_ellipses="true" /> <text follows="top|left" height="16" @@ -50,6 +73,7 @@ name="user_subtitle" font="SansSerifSmall" text_color="White" + top_pad="0" value="11 Months, 3 days old" width="175" use_ellipses="true" /> @@ -60,9 +84,9 @@ name="user_details" right="-10" word_wrap="true" - top_pad="6" + top_pad="4" use_ellipses="true" - width="220">This is my second life description and I really think it is great. + width="220">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 follows="top|left" @@ -76,7 +100,7 @@ tool_tip="Voice volume" top_pad="0" value="0.5" - width="195" /> + width="200" /> <button follows="top|left" height="16" @@ -108,7 +132,7 @@ height="20" label="Add Friend" left="8" - top="119" + top="135" name="add_friend_btn" width="90" /> <button @@ -152,7 +176,7 @@ width="35" /> <panel follows="top|left" - top="148" + top="164" left="0" height="60" width="228" diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 8d9ebf6e06..520a604bde 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -20,7 +20,6 @@ mouse_opaque="false" name="nav_bar_container" tab_stop="false" - min_height="10" width="1024" user_resize="false" visible="false"> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index af241862b6..ce628d93b5 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2788,6 +2788,12 @@ <menu_item_call.on_click function="Advanced.SendTestIMs" /> </menu_item_call> + <menu_item_call + label="Flush Names Caches" + name="Flush Names Caches"> + <menu_item_call.on_click + function="Advanced.FlushNameCaches" /> + </menu_item_call> </menu> <menu create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index e1aecda151..83cbcb3344 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -256,7 +256,7 @@ Save all changes to clothing/body parts? name="GrantModifyRights" type="alertmodal"> 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 [FIRST_NAME] [LAST_NAME]? +Do you want to grant modify rights for [NAME]? <usetemplate name="okcancelbuttons" notext="No" @@ -279,7 +279,7 @@ Do you want to grant modify rights for the selected Residents? icon="alertmodal.tga" name="RevokeModifyRights" type="alertmodal"> -Do you want to revoke modify rights for [FIRST_NAME] [LAST_NAME]? +Do you want to revoke modify rights for [NAME]? <usetemplate name="okcancelbuttons" notext="No" @@ -716,7 +716,7 @@ You can not wear that item because it has not yet loaded. Please try again in a name="MustHaveAccountToLogIn" type="alertmodal"> Oops! Something was left blank. -You need to enter both the First and Last name of your avatar. +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? <url @@ -736,7 +736,7 @@ You need an account to enter [SECOND_LIFE]. Would you like to create one now? icon="alertmodal.tga" name="InvalidCredentialFormat" type="alertmodal"> -You need to enter both the First and Last name of your avatar into the Username field, then login again. +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> @@ -2020,20 +2020,6 @@ You do not have permission to buy land for your active group. <notification icon="alertmodal.tga" label="Add Friend" - name="AddFriend" - type="alertmodal"> -Friends can give permissions to track each other on the map and receive online status updates. - -Offer friendship to [NAME]? - <usetemplate - name="okcancelbuttons" - notext="Cancel" - yestext="OK"/> - </notification> - - <notification - icon="alertmodal.tga" - label="Add Friend" name="AddFriendWithMessage" type="alertmodal"> Friends can give permissions to track each other on the map and receive online status updates. @@ -2127,7 +2113,7 @@ Would you be my friend? icon="alertmodal.tga" name="RemoveFromFriends" type="alertmodal"> -Do you want to remove [FIRST_NAME] [LAST_NAME] from your Friends List? +Do you want to remove [NAME] from your Friends List? <usetemplate name="okcancelbuttons" notext="Cancel" @@ -2380,7 +2366,7 @@ Deed this [AREA] m² of land to the group '[GROUP_NAME]'? name="DeedLandToGroupWithContribution" type="alertmodal"> 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 '[FIRST_NAME] [LAST_NAME]'. +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. Deed this [AREA] m² of land to the group '[GROUP_NAME]'? @@ -3200,6 +3186,88 @@ You are no longer frozen. <notification icon="alertmodal.tga" + name="SetDisplayNameSuccess" + type="alert"> +Hi [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. + </notification> + + <notification + icon="alertmodal.tga" + name="SetDisplayNameBlocked" + type="alert"> +Sorry, you cannot change your display name. If you feel this is in error, please contact support. + </notification> + + <notification + icon="alertmodal.tga" + name="SetDisplayNameFailedLength" + type="alertmodal"> +Sorry, that name is too long. Display names can have a maximum of [LENGTH] characters. + +Please try a shorter name. + </notification> + + <notification + icon="alertmodal.tga" + name="SetDisplayNameFailedGeneric" + type="alertmodal"> + Sorry, we could not set your display name. Please try again later. + </notification> + + <notification + icon="alertmodal.tga" + name="SetDisplayNameMismatch" + type="alertmodal"> + The display names you entered do not match. Please re-enter. + </notification> + + <!-- *NOTE: This should never happen --> + <notification + icon="alertmodal.tga" + name="AgentDisplayNameUpdateThresholdExceeded" + type="alertmodal"> +Sorry, you have to wait longer before you can change your display name. + +See http://wiki.secondlife.com/wiki/Setting_your_display_name + +Please try again later. + </notification> + + <notification + icon="alertmodal.tga" + name="AgentDisplayNameSetBlocked" + type="alertmodal"> + Sorry, we could not set your requested name because it contains a banned word. + + Please try a different name. + </notification> + + <notification + icon="alertmodal.tga" + name="AgentDisplayNameSetInvalidUnicode" + type="alertmodal"> + The display name you wish to set contains invalid characters. + </notification> + + <notification + icon="alertmodal.tga" + name="AgentDisplayNameSetOnlyPunctuation" + type="alertmodal"> + Your display name must contain letters other than punctuation. + </notification> + + + <notification + icon="notifytip.tga" + name="DisplayNameUpdate" + type="notifytip"> + [OLD_NAME] ([SLID]) is now known as [NEW_NAME]. + </notification> + + <notification + icon="alertmodal.tga" name="OfferTeleport" type="alertmodal"> Offer a teleport to your location with the following message? @@ -4515,14 +4583,14 @@ Topic: [SUBJECT], Message: [MESSAGE] icon="notifytip.tga" name="FriendOnline" type="notifytip"> -[FIRST] [LAST] is Online +[NAME] is Online </notification> <notification icon="notifytip.tga" name="FriendOffline" type="notifytip"> -[FIRST] [LAST] is Offline +[NAME] is Offline </notification> <notification @@ -4678,13 +4746,6 @@ You cannot remove protected categories. <notification icon="notifytip.tga" - name="OfferedCard" - type="notifytip"> -You have offered a calling card to [FIRST] [LAST] - </notification> - - <notification - icon="notifytip.tga" name="UnableToBuyWhileDownloading" type="notifytip"> Unable to buy while downloading object data. @@ -4838,7 +4899,15 @@ Please select at least one type of content to search (General, Moderate, or Adul <notification icon="notify.tga" - name="PaymentRecived" + name="PaymentReceived" + persist="true" + type="notify"> +[MESSAGE] + </notification> + + <notification + icon="notify.tga" + name="PaymentSent" persist="true" type="notify"> [MESSAGE] @@ -4857,14 +4926,10 @@ Event Notification: <form name="form"> <button index="0" - name="Teleport" - text="Teleport"/> + name="Details" + text="Details"/> <button index="1" - name="Description" - text="Description"/> - <button - index="2" name="Cancel" text="Cancel"/> </form> @@ -4940,7 +5005,7 @@ The objects you own on the selected parcel of land have been returned back to yo name="OtherObjectsReturned" persist="true" type="notify"> -The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory. +The objects on the selected parcel of land that is owned by [NAME] have been returned to his or her inventory. </notification> <notification @@ -5266,7 +5331,7 @@ No valid parcel could be found. icon="notify.tga" name="ObjectGiveItem" type="offer"> -An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you this [OBJECTTYPE]: +An object named <nolink>[OBJECTFROMNAME]</nolink> owned by [NAME_SLURL] has given you this [OBJECTTYPE]: [ITEM_SLURL] <form name="form"> <button @@ -5417,7 +5482,7 @@ An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you this [OBJEC name="OfferFriendshipNoMessage" persist="true" type="notify"> -[NAME] is offering friendship. +[NAME_SLURL] is offering friendship. (By default, you will be able to see each other's online status.) <form name="form"> @@ -5510,7 +5575,7 @@ Load web page [URL]? [MESSAGE] -From object: [OBJECTNAME], owner: [NAME]? +From object: <nolink>[OBJECTNAME]</nolink>, owner: [NAME]? <form name="form"> <button index="0" @@ -5552,7 +5617,7 @@ The item you are trying to wear uses a feature that your Viewer can't read. name="ScriptQuestion" persist="true" type="notify"> -'[OBJECTNAME]', an object owned by '[NAME]', would like to: +'<nolink>[OBJECTNAME]</nolink>', an object owned by '[NAME]', would like to: [QUESTIONS] Is this OK? @@ -5578,7 +5643,7 @@ Is this OK? priority="high" persist="true" type="notify"> -An object named '[OBJECTNAME]', owned by '[NAME]' would like to: +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. @@ -5605,7 +5670,7 @@ Grant this request? icon="notify.tga" name="ScriptDialog" type="notify"> -[FIRST] [LAST]'s '[TITLE]' +[NAME]'s '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> <button @@ -5619,7 +5684,7 @@ Grant this request? icon="notify.tga" name="ScriptDialogGroup" type="notify"> -[GROUPNAME]'s '[TITLE]' +[GROUPNAME]'s '<nolink>[TITLE]</nolink>' [MESSAGE] <form name="form"> <button @@ -5835,7 +5900,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block name="AutoUnmuteByIM" persist="true" type="notify"> -[FIRST] [LAST] was sent an instant message and has been automatically unblocked. +[NAME] was sent an instant message and has been automatically unblocked. </notification> <notification @@ -5843,7 +5908,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block name="AutoUnmuteByMoney" persist="true" type="notify"> -[FIRST] [LAST] was given money and has been automatically unblocked. +[NAME] was given money and has been automatically unblocked. </notification> <notification @@ -5851,7 +5916,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block name="AutoUnmuteByInventory" persist="true" type="notify"> -[FIRST] [LAST] was offered inventory and has been automatically unblocked. +[NAME] was offered inventory and has been automatically unblocked. </notification> <notification @@ -6436,6 +6501,14 @@ Mute everyone? </notification> <notification + name="HintDisplayName" + label="Display Name" + type="hint" + unique="true"> + 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 name="HintInventory" label="Inventory" type="hint" diff --git a/indra/newview/skins/default/xui/en/panel_active_object_row.xml b/indra/newview/skins/default/xui/en/panel_active_object_row.xml index bef5f8dafd..3e3271b181 100644 --- a/indra/newview/skins/default/xui/en/panel_active_object_row.xml +++ b/indra/newview/skins/default/xui/en/panel_active_object_row.xml @@ -53,6 +53,7 @@ top="10" left_pad="20" height="14" + parse_urls="false" width="245" length="1" follows="right|left" diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml index 3416b2369d..72f41c62f4 100644 --- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml +++ b/indra/newview/skins/default/xui/en/panel_activeim_row.xml @@ -71,7 +71,7 @@ top="10" left_pad="10" height="14" - width="255" + width="250" length="1" follows="right|left" use_ellipses="true" 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 6781a76120..90dbddaff7 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -3,7 +3,7 @@ background_visible="true" class="edit_profile_panel" follows="all" - height="535" + height="585" label="Profile Edit" layout="topleft" left="0" @@ -60,7 +60,7 @@ <scroll_container color="DkGray2" follows="all" - height="494" + height="537" min_height="300" layout="topleft" left="8" @@ -74,7 +74,7 @@ follows="left|top|right" layout="topleft" top="0" - height="494" + height="537" min_height="300" left="0" width="292"> @@ -83,16 +83,110 @@ follows="left|top|right" layout="topleft" top="0" - height="494" + height="537" min_height="300" left="0" width="292"> + <text + top="5" + follows="top|left" + height="13" + layout="topleft" + left="10" + name="display_name_label" + text_color="LtGray" + value="Display Name:" + width="80" /> + <text + top="5" + follows="top|left" + height="13" + layout="topleft" + left="10" + name="solo_username_label" + text_color="LtGray" + value="Username:" + visible="false" + width="80" /> + <button + name="set_name" + layout="topleft" + follows="top|left" + image_overlay="Edit_Wrench" + top="21" + left="10" + height="23" + width="23" + tool_tip="Set Display Name"/> + <text + follows="top|left" + font="SansSerifBigBold" + height="20" + layout="topleft" + left="10" + name="solo_user_name" + text_color="white" + top_delta="3" + value="Hamilton Hitchings" + use_ellipses="true" + visible="false" + width="275" /> + <text + follows="top|left" + font="SansSerifBigBold" + height="20" + layout="topleft" + left="43" + name="user_name" + text_color="white" + top_delta="0" + value="Hamilton Hitchings" + use_ellipses="true" + visible="true" + width="250" /> + <text + follows="top|left" + font="SansSerifBold" + height="20" + layout="topleft" + left_delta="0" + name="user_name_small" + text_color="white" + top_delta="-4" + value="Hamilton Hitchings" + use_ellipses="true" + visible="false" + wrap="true" + width="245" /> + <text + follows="top|left" + height="13" + layout="topleft" + left="10" + name="user_label" + text_color="LtGray" + top_pad="8" + 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" + use_ellipses="true" + value="hamilton.linden" + wrap="true" + width="205" /> <panel name="lifes_images_panel" follows="left|top|right" height="244" layout="topleft" - top="0" + top="65" left="0" width="292"> <panel @@ -146,8 +240,8 @@ height="102" layout="topleft" left="123" - top="25" - max_length="511" + top="90" + max_length="512" name="sl_description_edit" width="157" word_wrap="true"> @@ -202,8 +296,8 @@ height="102" layout="topleft" left="123" - max_length="254" - top="157" + max_length="512" + top="223" name="fl_description_edit" width="157" word_wrap="true"> @@ -301,22 +395,22 @@ left="10" name="partner_data_panel" width="200"> - <name_box - follows="left|top|right" - height="30" - initial_value="(retrieving)" - layout="topleft" - left="0" - link="true" - name="partner_text" - top="0" - width="200" - word_wrap="true" /> + <text + follows="left|top|right" + height="12" + initial_value="(retrieving)" + layout="topleft" + left="0" + name="partner_text" + top="0" + use_ellipses="true" + width="280"/> </panel> <text follows="left|top" height="15" layout="topleft" + link="true" left="10" name="partner_edit_link" value="[[URL] Edit]" 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 95c1c822b8..b8ef612c6c 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -463,9 +463,10 @@ height="23" label="Undo Changes" layout="topleft" - left_pad="7" + left="1" name="revert_button" - width="152" /> + top="0" + width="148" /> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 2af1a84400..70b96ca5eb 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -33,7 +33,7 @@ Hover your mouse over the options for more help. height="110" label="" layout="topleft" - left="10" + left="5" name="insignia" no_commit_on_selection="true" tool_tip="Click to choose a picture" @@ -49,22 +49,20 @@ Hover your mouse over the options for more help. type="string" height="16" length="1" - left_pad="10" + left_pad="8" name="prepend_founded_by" top_delta="0"> Founder: </text> - <name_box - follows="left|top" + <text + follows="left|top" height="16" - initial_value="(retrieving)" layout="topleft" - left_delta="0" - link="true" + left_delta="-2" name="founder_name" top_pad="2" use_ellipses="true" - width="190" /> + width="168" /> <text font="SansSerifMedium" text_color="EmphasisColor" @@ -92,13 +90,13 @@ Hover your mouse over the options for more help. <text_editor type="string" follows="left|top|right" - left="5" + left="3" height="80" layout="topleft" max_length="511" name="charter" top="105" - right="-1" + right="-4" bg_readonly_color="DkGray2" text_readonly_color="White" word_wrap="true"> @@ -113,6 +111,7 @@ Hover your mouse over the options for more help. layout="topleft" left="0" name="visible_members" + short_names="false" top_pad="2"> <name_list.columns label="Member" 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 4af4774304..074e9bf5e5 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -85,6 +85,7 @@ clicking on their names. right="-1" multi_select="true" name="member_list" + short_names="false" top_pad="5"> <name_list.columns label="Member" diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml index aa0edbfb8a..9f73b7c540 100644 --- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml @@ -24,25 +24,15 @@ top_pad="5" width="145"> <layout_panel - mouse_opaque="false" - auto_resize="true" - follows="top|left" - height="0" - layout="topleft" - left="2" - min_height="0" - width="140" - top="0" - name="spacer" - user_resize="false" /> - <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" @@ -171,5 +161,15 @@ 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_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml index 34fd3352a3..021cf00d03 100644 --- a/indra/newview/skins/default/xui/en/panel_instant_message.xml +++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml @@ -67,7 +67,7 @@ top="8" use_ellipses="true" value="Erica Vader" - width="212" /> + width="205" /> <!-- TIME STAMP --> <text font="SansSerifSmall" 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 f8ae238148..f8635b9edb 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -184,7 +184,8 @@ left="70" name="owner" top_delta="0" - width="200" /> + use_ellipses="true" + width="215" /> <text follows="left|top" height="15" @@ -200,7 +201,8 @@ left="70" name="creator" top_delta="0" - width="200" /> + use_ellipses="true" + width="215" /> <text follows="left|top" height="15" diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml index 7e415f45a4..2a5933e3e9 100644 --- a/indra/newview/skins/default/xui/en/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml @@ -3,7 +3,7 @@ name="Landmarks" top="0" height="400" - layout="topleft" + layout="topleft" left="0" width="313" help_topic="panel_landmarks" @@ -88,7 +88,7 @@ </accordion_tab> </accordion> <panel - background_visible="true" + background_visible="true" bevel_style="none" bottom="0" follows="left|right|bottom" @@ -115,7 +115,7 @@ layout="topleft" name="options_gear_btn_panel" width="32"> - <button + <menu_button follows="bottom|left" tool_tip="Show additional options" height="25" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index 891616b838..a5d730711c 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -67,12 +67,13 @@ Username: <line_editor follows="left|bottom" height="22" -label="Username" +label="bobsmith12 or Steller Sunshine" left_delta="0" -max_length="31" +max_length="63" name="username_edit" +prevalidate_callback="ascii" select_on_focus="true" -tool_tip="[SECOND_LIFE] Username" +tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" top_pad="0" width="150" /> <text @@ -161,8 +162,8 @@ width="135" tab_stop="false" follows="right|bottom" name="links" -width="200" -min_width="200" +width="205" +min_width="205" user_resize="false" height="80"> <text @@ -174,7 +175,7 @@ height="16" top="12" right="-10" name="create_new_account_text" - width="180"> + width="200"> Sign up </text> <text @@ -186,8 +187,8 @@ height="16" name="forgot_password_text" top_pad="12" right="-10" - width="180"> - Forgot your name or password? + width="200"> + Forgot your username or password? </text> <text follows="right|bottom" @@ -198,7 +199,7 @@ height="16" name="login_help" top_pad="2" right="-10" - width="180"> + width="200"> Need help logging in? </text> <!-- <text follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index 16529f4064..2b6e082542 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -119,7 +119,7 @@ layout="topleft" name="options_gear_btn_panel" width="32"> - <button + <menu_button follows="bottom|left" tool_tip="Show additional options" height="25" diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml index 37a1ed3048..1b41f602cd 100644 --- a/indra/newview/skins/default/xui/en/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml @@ -284,7 +284,7 @@ name="partner_data_panel" top_pad="0" width="300"> - <name_box + <text follows="left|top" height="10" initial_value="(retrieving)" @@ -293,8 +293,8 @@ link="true" name="partner_text" top="0" - width="300" - word_wrap="true" /> + use_ellipses="true" + width="300" /> </panel> <text follows="left|top" 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 a48a9ce626..f4dee9cd55 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -57,6 +57,7 @@ <string name="replace_body_part" value="Click to replace your existing shape"/> + <button follows="top|left" @@ -199,19 +200,19 @@ It is calculated as border_size + 2*UIResizeBarOverlap user_resize="false" visible="true"> - <!-- List containing items from the COF and Base outfit --> - <panel - background_visible="false" - class="cof_wearables" - filename="panel_cof_wearables.xml" + <!-- List containing items from the COF and Base outfit --> + <panel + background_visible="false" + class="cof_wearables" + filename="panel_cof_wearables.xml" follows="all" height="129" - layout="topleft" - left="1" - name="cof_wearables_list" - top="0" - width="311" /> - + layout="topleft" + left="1" + name="cof_wearables_list" + top="0" + width="311" /> + <button follows="left|bottom" height="22" @@ -230,7 +231,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap <combo_box follows="left|right|bottom" height="22" - layout="topleft" + layout="topleft" left_pad="5" name="list_view_filter_combobox" top_delta="0" @@ -246,20 +247,20 @@ It is calculated as border_size + 2*UIResizeBarOverlap visible="false" width="152"/> - <button + <button follows="bottom|right" height="22" - image_overlay="Search_Icon" + image_overlay="Search_Icon" image_pressed="PushButton_Press" image_pressed_selected="PushButton_Selected_Press" image_selected="PushButton_Selected_Press" - is_toggle="true" - layout="topleft" - name="filter_button" + is_toggle="true" + layout="topleft" + name="filter_button" right="-5" - top_delta="0" + top_delta="0" visible="false" - width="20" /> + width="20" /> </layout_panel> <layout_panel @@ -288,13 +289,13 @@ It is calculated as border_size + 2*UIResizeBarOverlap </layout_panel> </layout_stack> - </layout_panel> + </layout_panel> - <layout_panel + <layout_panel background_visible="false" bg_alpha_color="DkGray2" - auto_resize="true" + auto_resize="true" default_tab_group="3" height="450" min_height="80" @@ -314,44 +315,44 @@ It is calculated as border_size + 2*UIResizeBarOverlap top_pad="-9" width="313" /> - <inventory_panel - allow_multi_select="true" - background_visible="false" - border="false" - follows="left|top|right|bottom" + <inventory_panel + allow_multi_select="true" + background_visible="false" + border="false" + follows="left|top|right|bottom" height="418" - layout="topleft" - left="0" - mouse_opaque="false" + layout="topleft" + left="0" + mouse_opaque="false" name="folder_view" top_pad="0" width="313" - visible="false"/> - <panel - name="filtered_wearables_panel" - background_opaque="true" - background_visible="false" - layout="topleft" - follows="left|top|right|bottom" - border="false" + visible="false"/> + <panel + name="filtered_wearables_panel" + background_opaque="true" + background_visible="false" + layout="topleft" + follows="left|top|right|bottom" + border="false" height="418" - left="0" - mouse_opaque="false" + left="0" + mouse_opaque="false" width="310" - top_delta="0" - visible="true"> - <wearable_items_list - color="0.107 0.107 0.107 1" + top_delta="0" + visible="true"> + <wearable_items_list + color="0.107 0.107 0.107 1" name="list_view" - allow_select="true" - layout="topleft" - follows="all" - multi_select="true" + allow_select="true" + layout="topleft" + follows="all" + multi_select="true" width="313" height="418" - left="0" - top="0"/> - </panel> + left="0" + top="0"/> + </panel> <button follows="bottom|left" height="22" @@ -362,7 +363,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap top_pad="5" width="130" /> - </layout_panel> + </layout_panel> </layout_stack> @@ -377,7 +378,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap name="no_add_wearables_button_bar" top_pad="0" width="313"> - <button + <menu_button follows="bottom|left" height="25" image_hover_unselected="Toolbar_Left_Over" @@ -425,7 +426,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap top_delta="0" visible="false" width="313"> - <button + <menu_button follows="bottom|left" height="25" image_hover_unselected="Toolbar_Left_Over" @@ -463,15 +464,15 @@ It is calculated as border_size + 2*UIResizeBarOverlap name="list_view_btn" top="1" width="31" /> - <icon - follows="bottom|left|right" - height="25" + <icon + follows="bottom|left|right" + height="25" image_name="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" + layout="topleft" + left_pad="1" name="dummy_right_icon" width="186" > - </icon> + </icon> <button follows="bottom|right" height="25" @@ -486,7 +487,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap tool_tip="Visit the SL Marketplace. You can also select something you are wearing, then click here to see more things like it" width="31" /> </panel> - + <!-- SAVE AND REVERT BUTTONS --> <panel follows="left|right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_list.xml b/indra/newview/skins/default/xui/en/panel_outfits_list.xml index d18f0d57ca..9f98019c94 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_list.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_list.xml @@ -35,7 +35,7 @@ visible="true" name="bottom_panel" width="312"> - <button + <menu_button follows="bottom|left" tool_tip="Show additional options" height="25" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml index 2fbbf6610c..d85b778db2 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml @@ -29,7 +29,7 @@ name="bottom_panel" top_pad="0" width="312"> - <button + <menu_button follows="bottom|left" height="25" image_hover_unselected="Toolbar_Left_Over" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index ab8930c967..d34c0c29a8 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -81,7 +81,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M width="317"> <panel background_opaque="true" - background_visible="true" + background_visible="true" bg_alpha_color="DkGray" bg_opaque_color="DkGray" follows="all" @@ -114,7 +114,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M name="bottom_panel" top_pad="0" width="313"> - <button + <menu_button follows="bottom|left" height="25" image_hover_unselected="Toolbar_Left_Over" @@ -155,7 +155,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M </panel> <panel background_opaque="true" - background_visible="true" + background_visible="true" bg_alpha_color="DkGray" bg_opaque_color="DkGray" follows="all" @@ -242,7 +242,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M layout="topleft" name="options_gear_btn_panel" width="32"> - <button + <menu_button follows="bottom|left" tool_tip="Show additional options" height="25" @@ -372,7 +372,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M </panel> <panel background_opaque="true" - background_visible="true" + background_visible="true" bg_alpha_color="DkGray" bg_opaque_color="DkGray" follows="all" @@ -407,7 +407,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M name="bottom_panel" top_pad="0" width="313"> - <button + <menu_button follows="bottom|left" tool_tip="Options" height="25" @@ -457,7 +457,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M </panel> <panel background_opaque="true" - background_visible="true" + background_visible="true" bg_alpha_color="DkGray" bg_opaque_color="DkGray" follows="all" @@ -490,7 +490,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M name="bottom_panel" top_pad="0" width="313"> - <button + <menu_button follows="bottom|left" tool_tip="Options" height="25" @@ -499,7 +499,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M image_selected="Toolbar_Left_Selected" image_unselected="Toolbar_Left_Off" layout="topleft" - left="3" name="recent_viewsort_btn" top="1" width="31" /> 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 01d1e48ba1..8036411d2b 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -315,7 +315,8 @@ name="owner_value" top_delta="0" value="Alex Superduperlongenamenton" - width="205" /> + use_ellipses="true" + width="200" /> <icon follows="top|left" height="16" @@ -649,7 +650,8 @@ left_pad="0" name="region_owner" top_delta="0" - value="moose Van Moose" + value="moose Van Moose extra long name moose" + use_ellipses="true" width="187" /> <text follows="left|top" @@ -710,7 +712,7 @@ name="estate_name_label" top_pad="5" value="Estate:" - width="90" /> + width="80" /> <text follows="left|top|right" height="15" @@ -727,7 +729,7 @@ name="estate_rating_label" top_pad="5" value="Rating:" - width="90" /> + width="80" /> <text follows="left|top|right" height="15" @@ -744,15 +746,17 @@ name="estate_owner_label" top_pad="5" value="Owner:" - width="90" /> + width="80" /> <text follows="left|top|right" height="15" layout="topleft" left_pad="0" name="estate_owner" + value="Testing owner name length with long name" top_delta="0" - width="187" /> + use_ellipses="true" + width="190" /> <text follows="left|top" height="15" 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 31d8ea27d9..7d9bd1bf2a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -125,6 +125,7 @@ Automatic position for: left_pad="30" name="first_person_avatar_visible" width="256" /> + <check_box control_name="ArrowKeysAlwaysMove" follows="left|top" @@ -206,7 +207,7 @@ Automatic position for: left="80" name="UI Size:" top_pad="25" - width="160"> + width="300"> UI size </text> <slider @@ -302,6 +303,7 @@ Automatic position for: halign="center" height="23" image_overlay="Refresh_Off" + layout="topleft" tool_tip="Reset to Middle Mouse Button" mouse_opaque="true" name="set_voice_middlemouse_button" @@ -315,7 +317,7 @@ Automatic position for: label="Other Devices" left="30" name="joystick_setup_button" - top="27" + top_pad="27" width="155"> <button.commit_callback function="Floater.Show" 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 17eebffa02..392d50fc42 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -106,7 +106,7 @@ height="15" layout="topleft" left="30" - top_pad="15" + top_pad="14" name="maturity_desired_prompt" width="200"> I want to access content rated: @@ -216,7 +216,7 @@ layout="topleft" left="30" name="name_tags_textbox" - top_pad="15" + top_pad="14" width="400"> Name tags: </text> @@ -225,25 +225,33 @@ height="20" layout="topleft" left="50" + top_pad="5" name="Name_Tag_Preference"> <radio_item label="Off" - layout="topleft" name="radio" + top_delta="20" + layout="topleft" + height="16" + left="0" value="0" width="75" /> <radio_item label="On" + left_pad="0" layout="topleft" - left_pad="12" + top_delta="0" + height="16" name="radio2" value="1" width="75" /> <radio_item label="Show briefly" - layout="topleft" - left_pad="12" + left_pad="0" name="radio3" + height="16" + layout="topleft" + top_delta="0" value="2" width="160" /> </radio_group> @@ -251,20 +259,45 @@ enabled_control="AvatarNameTagMode" control_name="RenderNameShowSelf" height="16" - label="Show my name" + label="My name" layout="topleft" - left="50" + left="70" name="show_my_name_checkbox1" - width="300" /> + top_pad="0" + width="100" /> <check_box + control_name="NameTagShowUsernames" + enabled_control="AvatarNameTagMode" + height="16" + label="Usernames" + layout="topleft" + left_pad="70" + name="show_slids" + tool_tip="Show username, like bobsmith123" + top_delta="0" /> + <check_box + control_name="NameTagShowGroupTitles" enabled_control="AvatarNameTagMode" - control_name="RenderShowGroupTitleAll" height="16" - label="Show group titles" + label="Group titles" layout="topleft" - left_delta="175" + left="70" + width="100" name="show_all_title_checkbox1" - width="200" /> + tool_tip="Show group titles, like Officer or Member" + top_pad="5" /> + + <check_box + control_name="NameTagShowFriends" + enabled_control="AvatarNameTagMode" + height="16" + label="Highlight friends" + layout="topleft" + left_pad="70" + name="show_friends" + tool_tip="Highlight the name tags of your friends" + top_delta="0" /> + <text type="string" length="1" @@ -273,7 +306,7 @@ layout="topleft" left="30" name="effects_color_textbox" - top_pad="15" + top_pad="9" width="200"> My effects: </text> @@ -285,6 +318,7 @@ layout="topleft" left_pad="5" name="title_afk_text" + top_delta="0" width="190"> Away timeout: </text> @@ -334,6 +368,17 @@ name="item4" value="0" /> </combo_box> + <check_box +control_name="UseDisplayNames" +follows="top|left" +height="14" +label="View Display Names" +layout="topleft" +left="30" +name="display_names_check" +width="237" +tool_tip="Check to use display names in chat, IM, name tags, etc." +top_pad="20"/> <text type="string" length="1" @@ -343,7 +388,7 @@ left="30" mouse_opaque="false" name="text_box3" - top_pad="15" + top_pad="10" width="240"> Busy mode response: </text> @@ -353,8 +398,8 @@ bg_writeable_color="LtGray" use_ellipses="false" commit_on_focus_lost = "true" - follows="left|top|right" - height="60" + follows="left|top" + height="42" layout="topleft" left="50" name="busy_response" 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 7ae717d0e3..7d49a671e6 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -155,7 +155,7 @@ visiblity_control="ShowAdvancedGraphicsSettings" border="false" follows="top|left" - height="283" + height="300" label="CustomGraphics" layout="topleft" left="5" diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 78b192d4af..efc37c2127 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -263,7 +263,7 @@ name="partner_data_panel" top_pad="0" width="300"> - <name_box + <text follows="left|top" height="10" initial_value="(retrieving)" @@ -272,8 +272,8 @@ link="true" name="partner_text" top="0" - width="300" - word_wrap="true" /> + use_ellipses="true" + width="300" /> </panel> <text follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index 3b4d6ae58d..97229c413c 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -8,85 +8,152 @@ 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" + <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" /> + <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" + top="25" + value="Jack Linden" + 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" + use_ellipses="true" + value="jack.linden" + 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" - name="back" - left="10" - tab_stop="false" - top="2" - width="30" /> - <text_editor - h_pad="0" - v_pad="0" - allow_scroll="false" - bg_visible="false" - read_only = "true" - follows="top|left|right" - font="SansSerifHugeBold" - height="26" - layout="topleft" - left_pad="5" - name="user_name" - text_color="LtGray" - top="2" - value="(Loading...)" - use_ellipses="true" - width="275" /> - <text - follows="top|left" - height="13" + help_topic="profile_profile_tab" + name="panel_profile" /> + <panel + class="panel_picks" + filename="panel_picks.xml" + label="PICKS" layout="topleft" - left="45" - name="status" - text_color="LtGray_50" - value="Online" - width="150" /> - <tab_container - follows="all" - height="515" - halign="center" + help_topic="profile_picks_tab" + name="panel_picks" /> + <panel + class="panel_notes" + filename="panel_notes.xml" + label="NOTES & PRIVACY" 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> + help_topic="profile_notes_tab" + name="panel_notes" /> + </tab_container> </panel> 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 a6b4ddd01e..15df095efa 100644 --- a/indra/newview/skins/default/xui/en/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml @@ -103,7 +103,7 @@ mouse_opaque="false" name="target_avatar_name" top_delta="-2" - width="180"> + width="270"> (none) </line_editor> <button diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml index 08e36d5e57..1307d807e2 100644 --- a/indra/newview/skins/default/xui/en/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml @@ -72,7 +72,8 @@ left_delta="0" name="estate_owner" top_delta="16" - width="150"> + use_ellipses="true" + width="290"> (unknown) </text> <view_border diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index bf09836e87..768efc2f3f 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -157,7 +157,7 @@ left="3" name="bottom_panel" width="313"> - <button + <menu_button follows="bottom|left" tool_tip="Show additional options" height="25" diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml index a6036f8b78..89aef57cca 100644 --- a/indra/newview/skins/default/xui/en/role_actions.xml +++ b/indra/newview/skins/default/xui/en/role_actions.xml @@ -108,6 +108,9 @@ <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> <action_set description="These Abilities include powers to allow or restrict access to group-owned parcels, including freezing and ejecting Residents." 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 182bc29e27..8760c911dc 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -174,8 +174,9 @@ layout="topleft" left_pad="5" name="LabelCreatorName" - top_delta="6" - width="140"> + top_delta="6" + use_ellipses="true" + width="165"> </text> <button follows="top|right" @@ -217,7 +218,8 @@ left_pad="5" name="LabelOwnerName" top_delta="6" - width="140"> + use_ellipses="true" + width="165"> </text> <button follows="top|right" 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 843015cb8b..a2f7edb167 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -167,7 +167,8 @@ left_pad="0" name="Creator Name" top_delta="0" - width="140"> + use_ellipses="true" + width="225"> Erica Linden </text> <text @@ -191,7 +192,8 @@ left_pad="0" name="Owner Name" top_delta="0" - width="140"> + use_ellipses="true" + width="225"> Erica Linden </text> <text diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 8470d91b8c..403d976350 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -89,6 +89,7 @@ <string name="TooltipHttpUrl">Click to view this web page</string> <string name="TooltipSLURL">Click to view this location's information</string> <string name="TooltipAgentUrl">Click to view this Resident's profile</string> + <string name="TooltipAgentInspect">Learn more about this Resident</string> <string name="TooltipAgentMute">Click to mute this Resident</string> <string name="TooltipAgentUnmute">Click to unmute this Resident</string> <string name="TooltipAgentIM">Click to IM this Resident</string> @@ -337,7 +338,7 @@ <string name="avi_movie_file">AVI Movie File</string> <string name="xaf_animation_file">XAF Anim File</string> <string name="xml_file">XML File</string> - <string name="dot_raw_file">RAW File</string> + <string name="raw_file">RAW File</string> <string name="compressed_image_files">Compressed Images</string> <string name="load_files">Load Files</string> <string name="choose_the_directory">Choose Directory</string> @@ -3048,7 +3049,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. You are the only user in this session. </string> <string name="offline_message"> - [FIRST] [LAST] is offline. + [NAME] is offline. </string> <string name="invite_message"> Click the [BUTTON NAME] button to accept/connect to this voice chat. @@ -3134,17 +3135,20 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="voice_morphing_url">http://secondlife.com/landing/voicemorphing</string> <!-- Financial operations strings --> - <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT]</string> + <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string> + <string name="paid_you_ldollars_no_reason">[NAME] paid you L$[AMOUNT].</string> <string name="you_paid_ldollars">You paid [NAME] L$[AMOUNT] [REASON].</string> <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="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> <string name="for deeding land">for deeding land</string> <string name="to create a group">to create a group</string> <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> diff --git a/indra/newview/skins/default/xui/en/widgets/chat_history.xml b/indra/newview/skins/default/xui/en/widgets/chat_history.xml index ef885e8045..c0a948931c 100644 --- a/indra/newview/skins/default/xui/en/widgets/chat_history.xml +++ b/indra/newview/skins/default/xui/en/widgets/chat_history.xml @@ -19,6 +19,7 @@ font="SansSerif"> <more_chat_text mouse_opaque="true" + parse_urls="false" word_wrap="true" /> </chat_history>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/widgets/inspector.xml b/indra/newview/skins/default/xui/en/widgets/inspector.xml index 428b2ce03b..8c171c387f 100644 --- a/indra/newview/skins/default/xui/en/widgets/inspector.xml +++ b/indra/newview/skins/default/xui/en/widgets/inspector.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <inspector name="inspector" + max_width="300" bg_opaque_color="DkGray_66" background_visible="true" bg_opaque_image="Inspector_Hover" diff --git a/indra/newview/skins/default/xui/es/floater_customize.xml b/indra/newview/skins/default/xui/es/floater_customize.xml new file mode 100644 index 0000000000..77b670d5f0 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_customize.xml @@ -0,0 +1,530 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater customize" title="APARIENCIA"> + <tab_container name="customize tab container"> + <text label="Partes del cuerpo" name="body_parts_placeholder"> + Partes del cuerpo + </text> + <panel label="Forma" name="Shape"> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + <button label="Cuerpo" label_selected="Cuerpo" name="Body"/> + <button label="Cabeza" label_selected="Cabeza" name="Head"/> + <button label="Ojos" label_selected="Ojos" name="Eyes"/> + <button label="Orejas" label_selected="Orejas" name="Ears"/> + <button label="Nariz" label_selected="Nariz" name="Nose"/> + <button label="Boca" label_selected="Boca" name="Mouth"/> + <button label="Barbilla" label_selected="Barbilla" name="Chin"/> + <button label="Torso" label_selected="Torso" name="Torso"/> + <button label="Piernas" label_selected="Piernas" name="Legs"/> + <radio_group name="sex radio"> + <radio_item label="Mujer" name="radio" value="0"/> + <radio_item label="Varón" name="radio2" value="1"/> + </radio_group> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situada en [PATH] + </text> + <text name="not worn instructions"> + Ponte una anatomía nueva arrastrándola desde tu inventario hasta tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label"> + Forma: + </text> + <button label="Crear una forma nueva" label_selected="Crear una forma nueva" name="Create New"/> + <button label="Guardar" label_selected="Guardar" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + </panel> + <panel label="Piel" name="Skin"> + <button label="Color de piel" label_selected="Color de piel" name="Skin Color" width="115"/> + <button label="Detalles faciales" label_selected="Detalles faciales" name="Face Detail" width="115"/> + <button label="Maquillaje" label_selected="Maquillaje" name="Makeup" width="115"/> + <button label="Detalles del cuerpo" label_selected="Detalles del cuerpo" name="Body Detail" width="115"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situada en [PATH] + </text> + <text name="not worn instructions"> + Ponte una piel nueva arrastrándola desde tu inventario hasta tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Piel: + </text> + <texture_picker label="Tatuaje: cabeza" name="Head Tattoos" tool_tip="Pulse para elegir una imagen" width="90"/> + <texture_picker label="Tatuaje: superior" name="Upper Tattoos" tool_tip="Pulse para elegir una imagen" width="90"/> + <texture_picker label="Tatuaje: inferior" name="Lower Tattoos" tool_tip="Pulse para elegir una imagen" width="90"/> + <button label="Crear una piel nueva" label_selected="Crear una piel nueva" name="Create New"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Pelo" name="Hair"> + <button label="Color" label_selected="Color" name="Color"/> + <button label="Peinado" label_selected="Peinado" name="Style"/> + <button label="Cejas" label_selected="Cejas" name="Eyebrows"/> + <button label="Facial" label_selected="Facial" name="Facial"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situado en [PATH] + </text> + <text name="not worn instructions"> + Ponte un pelo nuevo arrastrándolo desde tu inventario hasta tu avatar. O bien puedes crear uno nuevo partiendo de cero. + </text> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Pelo: + </text> + <texture_picker label="Textura" name="Texture" tool_tip="Pulse para elegir una imagen"/> + <button label="Crear un pelo nuevo" label_selected="Crear un pelo nuevo" name="Create New"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Ojos" name="Eyes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificables + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situados en [PATH] + </text> + <text name="not worn instructions"> + Ponte unos ojos nuevos arrastrándolos desde tu inventario hasta tu avatar. O bien puedes crear unos nuevos partiendo de cero. + </text> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Ojos: + </text> + <texture_picker label="Iris" name="Iris" tool_tip="Pulse para elegir una imagen"/> + <button label="Crear unos ojos nuevos" label_selected="Crear unos ojos nuevos" name="Create New"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <text label="Ropa" name="clothes_placeholder"> + Ropas + </text> + <panel label="Camisa" name="Shirt"> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarla" label_selected="Quitarla" name="Take Off"/> + <button label="Crear una falda nueva" label_selected="Crear una falda nueva" name="Create New"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situada en [PATH] + </text> + <text name="not worn instructions"> + Ponte una camisa nueva arrastrándola desde tu inventario hasta tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Camisa: + </text> + </panel> + <panel label="Pantalones" name="Pants"> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/> + <button label="Crear unos pantalones nuevos" label_selected="Crear unos pantalones nuevos" name="Create New" width="185"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificables + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situados en [PATH] + </text> + <text name="not worn instructions"> + Ponte unos pantalones nuevos arrastrándolos desde tu inventario hasta tu avatar. O bien puedes crear unos nuevos partiendo de cero. + </text> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Pantalones: + </text> + </panel> + <panel label="Zapatos" name="Shoes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificables + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situados en [PATH] + </text> + <text name="not worn instructions"> + Ponte unos zapatos nuevos arrastrándolos desde tu inventario hasta tu avatar. O bien puedes crear unos nuevos partiendo de cero. + </text> + <button label="Crear unos zapatos nuevos" label_selected="Crear unos zapatos nuevos" name="Create New"/> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Zapatos: + </text> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Calcetines" name="Socks"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificables + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situados en [PATH] + </text> + <text name="not worn instructions"> + Ponte unos calcetines nuevos arrastrándolos desde tu inventario hasta tu avatar. O bien puedes crear unos nuevos partiendo de cero. + </text> + <button label="Crear unos calcetines nuevos" label_selected="Crear unos calcetines nuevos" name="Create New" width="185"/> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Calcetines: + </text> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Chaqueta" name="Jacket"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situada en [PATH] + </text> + <text name="not worn instructions"> + Ponte una chaqueta nueva arrastrándola desde tu inventario hasta tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <button label="Crear una chaqueta nueva" label_selected="Crear una chaqueta nueva" name="Create New"/> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Chaqueta: + </text> + <texture_picker label="Tela superior" name="Upper Fabric" tool_tip="Pulse para elegir una imagen"/> + <texture_picker label="Tela inferior" name="Lower Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarla" label_selected="Quitarla" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Guantes" name="Gloves"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificables + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situados en [PATH] + </text> + <text name="not worn instructions"> + Ponte unos guantes nuevos arrastrándolos desde tu inventario hasta tu avatar. O bien puedes crear unos nuevos partiendo de cero. + </text> + <button label="Crear unos guantes nuevos" label_selected="Crear unos guantes nuevos" name="Create New"/> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Guantes: + </text> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Camiseta" name="Undershirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situada en [PATH] + </text> + <text name="not worn instructions"> + Ponte una camiseta nueva arrastrándola desde tu inventario hasta tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <button label="Crear una camiseta nueva" label_selected="Crear una camiseta nueva" name="Create New"/> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Camiseta: + </text> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarla" label_selected="Quitarla" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Ropa interior" name="Underpants"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situada en [PATH] + </text> + <text name="not worn instructions"> + Ponte una ropa interior nueva arrastrándola desde tu inventario hasta tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <button label="Crear una ropa interior nueva" label_selected="Crear una ropa interior nueva" name="Create New" width="185"/> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Ropa interior: + </text> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarla" label_selected="Quitarla" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Falda" name="Skirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no lleva + </text> + <text name="path"> + Situada en [PATH] + </text> + <text name="not worn instructions"> + Ponte una falda nueva arrastrándola desde tu inventario hasta tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <button label="Crear una falda nueva" label_selected="Crear una falda nueva" name="Create New"/> + <text name="no modify instructions"> + No tiene permiso para modificar este ítem. + </text> + <text name="Item Action Label" right="107"> + Falda: + </text> + <texture_picker label="Tela" name="Fabric" tool_tip="Pulse para elegir una imagen"/> + <color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/> + <button label="Quitarla" label_selected="Quitarla" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" left="113" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Restablecer" label_selected="Restablecer" name="Revert"/> + </panel> + <panel label="Tatuaje" name="Tattoo"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no puesto + </text> + <text name="path"> + Situado en [PATH] + </text> + <text name="not worn instructions"> + Pon un tatuaje nuevo arrastrándolo desde tu inventario a tu avatar. O bien puedes crear uno nuevo partiendo de cero. + </text> + <button label="Crear un tatuaje nuevo" label_selected="Crear un tatuaje nuevo" name="Create New"/> + <text name="no modify instructions"> + No tienes permiso para modificar este artículo. + </text> + <text name="Item Action Label"> + Tatuaje: + </text> + <texture_picker label="Tatuaje de la cabeza" name="Head Tattoo" tool_tip="Pulsa para elegir una imagen"/> + <texture_picker label="Tatuaje superior" name="Upper Tattoo" tool_tip="Pulsa para elegir una imagen"/> + <texture_picker label="Tatuaje inferior" name="Lower Tattoo" tool_tip="Pulsa para elegir una imagen"/> + <button label="Quitarme" label_selected="Quitarme" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Revertir" label_selected="Revertir" name="Revert"/> + </panel> + <panel label="Alfa" name="Alpha"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: no modificable + </text> + <text name="title_loading"> + [DESC]: cargando... + </text> + <text name="title_not_worn"> + [DESC]: no puesto + </text> + <text name="path"> + Situado en [PATH] + </text> + <text name="not worn instructions"> + Pon una capa Alfa nueva arrastrándola desde tu inventario a tu avatar. O bien puedes crear una nueva partiendo de cero. + </text> + <button label="Crear una capa Alfa nueva" label_selected="Crear una capa Alfa nueva" name="Create New"/> + <text name="no modify instructions"> + No tienes permiso para modificar este artículo. + </text> + <text name="Item Action Label"> + Alfa: + </text> + <texture_picker label="Alfa inferior" name="Lower Alpha" tool_tip="Pulsa para elegir una imagen"/> + <texture_picker label="Alfa superior" name="Upper Alpha" tool_tip="Pulsa para elegir una imagen"/> + <texture_picker label="Alfa de la cabeza" name="Head Alpha" tool_tip="Pulsa para elegir una imagen"/> + <texture_picker label="Alfa de los ojos" name="Eye Alpha" tool_tip="Pulsa para elegir una imagen"/> + <texture_picker label="Alfa del pelo" name="Hair Alpha" tool_tip="Pulsa para elegir una imagen"/> + <button label="Quitarme" label_selected="Quitarme" name="Take Off"/> + <button label="Guardar" label_selected="Guardar" name="Save"/> + <button label="Guardar como..." label_selected="Guardar como..." name="Save As"/> + <button label="Revertir" label_selected="Revertir" name="Revert"/> + </panel> + </tab_container> + <scroll_container name="panel_container"/> + <button label="Información del script" label_selected="Información del script" name="script_info" tool_tip="Mostrar los scripts anexados a tu avatar"/> + <button label="Hacer un vestuario" label_selected="Hacer un vestuario" name="make_outfit_btn"/> + <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> + <button label="OK" label_selected="OK" name="Ok"/> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_event.xml b/indra/newview/skins/default/xui/es/floater_event.xml index 4bc5221796..8bca7783ab 100644 --- a/indra/newview/skins/default/xui/es/floater_event.xml +++ b/indra/newview/skins/default/xui/es/floater_event.xml @@ -1,72 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Evento" name="Event" title="DETALLES DEL EVENTO"> - <floater.string name="none"> - ninguno +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Cargando... </floater.string> - <floater.string name="notify"> - Notificar - </floater.string> - <floater.string name="dont_notify"> - No notificar - </floater.string> - <floater.string name="moderate"> - Moderado - </floater.string> - <floater.string name="adult"> - Adulto - </floater.string> - <floater.string name="general"> - General - </floater.string> - <floater.string name="unknown"> - desconocida - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Evento sin nombre... - </text> - <text name="event_category"> - (sin categoría) - </text> - <text name="event_runby_label"> - Organizado por: - </text> - <text initial_value="(obteniendo)" name="event_runby"/> - <text name="event_date_label"> - Fecha: - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - Duración: - </text> - <text name="event_duration"> - 1 hora - </text> - <text name="event_covercharge_label"> - Entrada: - </text> - <text name="event_cover"> - Gratis - </text> - <text name="event_location_label"> - Localización: - </text> - <text name="event_location" value="SampleParcel, Name Long (145, 228, 26)"/> - <text name="rating_label" value="Calificación:"/> - <text name="rating_value" value="desconocida"/> - <expandable_text name="event_desc"> - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - </expandable_text> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="Crear el evento"/> - <button name="god_delete_event_btn" tool_tip="Borrar el evento"/> - <button label="Notificarme" name="notify_btn"/> - <button label="Teleportar" name="teleport_btn"/> - <button label="Mapa" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/es/floater_im.xml b/indra/newview/skins/default/xui/es/floater_im.xml new file mode 100644 index 0000000000..3850b94fd6 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_im.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<multi_floater name="im_floater" title="Mensaje Instantáneo"> + <string name="only_user_message"> + Eres el único Residente en esta sesión. + </string> + <string name="offline_message"> + [FIRST] [LAST] no está conectado. + </string> + <string name="invite_message"> + Pulse el botón [BUTTON NAME] para aceptar/conectar este chat de voz. + </string> + <string name="muted_message"> + Has ignorado a este Residente. Enviándole un mensaje, automáticamente dejarás de ignorarle. + </string> + <string name="generic_request_error"> + Error al hacer lo solicitado; por favor, inténtelo más tarde. + </string> + <string name="insufficient_perms_error"> + Usted no tiene permisos suficientes. + </string> + <string name="session_does_not_exist_error"> + La sesión ya acabó + </string> + <string name="no_ability_error"> + Usted no tiene esa capacidad. + </string> + <string name="not_a_mod_error"> + Usted no es un moderador de la sesión. + </string> + <string name="muted_error"> + Un moderador del grupo le ha desactivado el chat de texto. + </string> + <string name="add_session_event"> + No es posible añadir Residentes a la sesión de chat con [RECIPIENT]. + </string> + <string name="message_session_event"> + No se ha podido enviar su mensaje a la sesión de chat con [RECIPIENT]. + </string> + <string name="removed_from_group"> + Ha sido eliminado del grupo. + </string> + <string name="close_on_no_ability"> + Usted ya no tendrá más la capacidad de estar en la sesión de chat. + </string> +</multi_floater> diff --git a/indra/newview/skins/default/xui/es/floater_preview_classified.xml b/indra/newview/skins/default/xui/es/floater_preview_classified.xml new file mode 100644 index 0000000000..d9c9c51ba8 --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_preview_classified.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="classified_preview" title="INFORMACIÓN DEL CLASIFICADO"> + <floater.string name="Title"> + Clasificado: [NAME] + </floater.string> +</floater> diff --git a/indra/newview/skins/default/xui/es/floater_preview_event.xml b/indra/newview/skins/default/xui/es/floater_preview_event.xml new file mode 100644 index 0000000000..7edd4f9e3f --- /dev/null +++ b/indra/newview/skins/default/xui/es/floater_preview_event.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="event_preview" title="INFORMACIÓN DEL EVENTO"> + <floater.string name="Title"> + Evento: [NAME] + </floater.string> +</floater> diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index 91d47061c4..6379722553 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -1419,7 +1419,7 @@ Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar </notification> <notification name="BusyModeSet"> Pasar al modo ocupado. -Se ocultará el chat y los mensajes instantáneos (éstos recibirán tu Respuesta en el modo ocupado). Se rehusarán todos los ofrecimientos de teleporte. Todas las ofertas de inventario irán a tu Papelera. +Se ocultará el chat y los mensajes instantáneos (éstos recibirán tu Respuesta en el modo ocupado). Se rehusarán todos los ofrecimientos de teleporte. Todas las ofertas de inventario irán a tu Papelera. <usetemplate ignoretext="Cambio mi estado al modo ocupado" name="okignore" yestext="OK"/> </notification> <notification name="JoinedTooManyGroupsMember"> @@ -1890,7 +1890,7 @@ Linden Lab </form> </notification> <notification name="ConfirmDeleteProtectedCategory"> - La carpeta '[FOLDERNAME]' pertenece al sistema, y borrar carpetas del sistema puede provocar inestabilidad. ¿Estás seguro de que quieres borrarla? + La carpeta '[FOLDERNAME]' pertenece al sistema, y borrar carpetas del sistema puede provocar inestabilidad. ¿Estás seguro de que quieres borrarla? <usetemplate ignoretext="Confirmar antes de borrar una carpeta del sistema" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> <notification name="ConfirmEmptyTrash"> @@ -2190,8 +2190,7 @@ Inténtalo seleccionando un trozo más pequeño de terreno. [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Teleportar"/> - <button name="Description" text="Descripción"/> + <button name="Details" text="Detalles"/> <button name="Cancel" text="Cancelar"/> </form> </notification> @@ -2449,7 +2448,7 @@ Esto añadirá un marcador en tu inventario para que puedas enviarle rápidament Si permaneces en esta región serás desconectado. </notification> <notification name="RegionRestartSeconds"> - Esta región se reiniciará en [SECONDS] segundos. + Esta región se reiniciará en [SECONDS] segundos. Si permaneces en esta región serás desconectado. </notification> <notification name="LoadWebPage"> @@ -2513,7 +2512,7 @@ Si no confias en este objeto y en su creador, deberías rehusar esta petición. <notification name="BuyLindenDollarSuccess"> ¡Gracias por tu pago! -Tu saldo de L$ se actualizará cuando se complete el proceso. Si el proceso tarda más de 20 minutos, se cancelará tu transacción, y la cantidad se cargará en tu saldo de US$. +Tu saldo de L$ se actualizará cuando se complete el proceso. Si el proceso tarda más de 20 minutos, se cancelará tu transacción, y la cantidad se cargará en tu saldo de US$. Puedes revisar el estado de tu pago en el Historial de transacciones de tu [http://secondlife.com/account/ Panel de Control] </notification> diff --git a/indra/newview/skins/default/xui/es/panel_friends.xml b/indra/newview/skins/default/xui/es/panel_friends.xml new file mode 100644 index 0000000000..e1cac7c2c3 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_friends.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="friends"> + <string name="Multiple"> + Varios amigos + </string> + <scroll_list name="friend_list" tool_tip="Para seleccionar a varios amigos, mantenga pulsado Ctrl o Mays. mientras les va pulsando."> + <column name="icon_online_status" tool_tip="Estado de conexión"/> + <column label="Nombre" name="friend_name" tool_tip="Nombre"/> + <column name="icon_visible_online" tool_tip="El amigo puede ver cuándo está conectado"/> + <column name="icon_visible_map" tool_tip="El amigo puede localizarle en el mapa"/> + <column name="icon_edit_mine" tool_tip="El amigo puede editar, borrar o tomar sus objetos"/> + <column name="icon_edit_theirs" tool_tip="Puede editar los objetos de este amigo"/> + </scroll_list> + <button label="MI/Llamada" name="im_btn" tool_tip="Abrir sesión de mensajes instantáneos"/> + <button label="Perfil" name="profile_btn" tool_tip="Mostrar la imagen, los grupos, y otra información"/> + <button label="Teleporte" name="offer_teleport_btn" tool_tip="Ofrecer a este amigo teleportarle hasta su posición"/> + <button label="Pagar" name="pay_btn" tool_tip="Dar dólares Linden (L$) a este amigo"/> + <button label="Quitar" name="remove_btn" tool_tip="Quitar a esta persona de su lista de amigos"/> + <button label="Añadir" name="add_btn" tool_tip="Ofrecer amistad a un Residente"/> +</panel> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index ac12b700ee..5fa3d54de2 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -777,7 +777,7 @@ <string name="xml_file"> Archivo XML </string> - <string name="dot_raw_file"> + <string name="raw_file"> Archivo RAW </string> <string name="compressed_image_files"> diff --git a/indra/newview/skins/default/xui/fr/floater_customize.xml b/indra/newview/skins/default/xui/fr/floater_customize.xml new file mode 100644 index 0000000000..ff407b25c1 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_customize.xml @@ -0,0 +1,530 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater customize" title="APPARENCE"> + <tab_container name="customize tab container" tab_min_width="150"> + <text label="Parties du corps" name="body_parts_placeholder"> + Parties du corps + </text> + <panel label="Silhouette" left="154" name="Shape" width="389"> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + <button label="Corps" label_selected="Corps" name="Body"/> + <button label="Tête" label_selected="Tête" name="Head"/> + <button label="Yeux" label_selected="Yeux" name="Eyes"/> + <button label="Oreilles" label_selected="Oreilles" name="Ears"/> + <button label="Nez" label_selected="Nez" name="Nose"/> + <button label="Bouche" label_selected="Bouche" name="Mouth"/> + <button label="Menton" label_selected="Menton" name="Chin"/> + <button label="Torse" label_selected="Torse" name="Torso"/> + <button label="Jambes" label_selected="Jambes" name="Legs"/> + <radio_group name="sex radio"> + <radio_item label="Femme" name="radio" value="0"/> + <radio_item label="Homme" name="radio2" value="1"/> + </radio_group> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portée + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de silhouette, faites-en glisser une de votre inventaire à votre avatar. Vous pouvez aussi en créer une nouvelle et la porter. + </text> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Silhouette : + </text> + <button label="Créer une silhouette" label_selected="Créer une silhouette" name="Create New"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + </panel> + <panel label="Peau" name="Skin"> + <button label="Couleur" label_selected="Couleur" name="Skin Color" width="84"/> + <button label="Détails visage" label_selected="Détails visage" name="Face Detail" width="84"/> + <button label="Maquillage" label_selected="Maquillage" name="Makeup" width="84"/> + <button label="Détails corps" label_selected="Détails corps" name="Body Detail" width="84"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portée + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de peau, faites-en glisser une à partir de votre inventaire. Vous pouvez aussi en créer une nouvelle et la porter. + </text> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Peau : + </text> + <texture_picker label="Tatouages tête" name="Head Tattoos" tool_tip="Cliquez pour sélectionner une image" width="78"/> + <texture_picker label="Tatouages haut" name="Upper Tattoos" tool_tip="Cliquez pour sélectionner une image" width="78"/> + <texture_picker label="Tatouages bas" name="Lower Tattoos" tool_tip="Cliquez pour sélectionner une image" width="78"/> + <button label="Créer une peau" label_selected="Créer une peau" name="Create New"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Cheveux" name="Hair"> + <button label="Couleur" label_selected="Couleur" name="Color"/> + <button label="Style" label_selected="Style" name="Style"/> + <button label="Sourcils" label_selected="Sourcils" name="Eyebrows"/> + <button label="Pilosité" label_selected="Pilosité" name="Facial"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portés + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de cheveux, faites-en glisser à partir de votre inventaire. Vous pouvez aussi en créer de nouveaux et les porter. + </text> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Cheveux : + </text> + <texture_picker label="Texture" name="Texture" tool_tip="Cliquez pour sélectionner une image"/> + <button label="Créer des cheveux" label_selected="Créer des cheveux" name="Create New"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Yeux" name="Eyes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portés + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer d'yeux, faites-en glisser une paire de votre inventaire à votre avatar. Vous pouvez aussi en créer de nouveaux et les porter. + </text> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Yeux : + </text> + <texture_picker label="Iris" name="Iris" tool_tip="Cliquez pour sélectionner une image"/> + <button label="Créer des yeux" label_selected="Créer des yeux" name="Create New"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <text label="Habits" name="clothes_placeholder"> + Habits + </text> + <panel label="Chemise" name="Shirt"> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Créer une chemise" label_selected="Créer une chemise" name="Create New"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portée + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de chemise, faites-en glisser une à partir de votre inventaire. Vous pouvez aussi en créer une nouvelle et la porter. + </text> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Chemise : + </text> + </panel> + <panel label="Pantalon" name="Pants"> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Créer un pantalon" label_selected="Créer un pantalon" name="Create New"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non porté + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de pantalon, faites-en glisser un à partir de votre inventaire. Vous pouvez aussi en créer un nouveau et le porter. + </text> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Pantalon : + </text> + </panel> + <panel label="Chaussures" name="Shoes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portées + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de chaussures, faites-en glisser une paire de votre inventaire à votre avatar. Vous pouvez aussi en créer des nouvelles et les porter. + </text> + <button label="Créer des chaussures" label_selected="Créer des chaussures" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Chaussures : + </text> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Chaussettes" name="Socks"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portées + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de chaussettes, faites-en glisser une paire à partir de votre inventaire. Vous pouvez aussi en créer des nouvelles et les porter. + </text> + <button label="Créer des chaussettes" label_selected="Créer des chaussettes" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Chaussettes : + </text> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Veste" name="Jacket"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portée + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de veste, faites-en glisser une à partir de votre inventaire. Vous pouvez aussi en créer une nouvelle et la porter. + </text> + <button label="Créer une veste" label_selected="Créer une veste" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Veste : + </text> + <texture_picker label="Tissu (dessus)" name="Upper Fabric" tool_tip="Cliquez pour sélectionner une image" width="81"/> + <texture_picker label="Tissu (dessous)" name="Lower Fabric" tool_tip="Cliquez pour sélectionner une image" width="81"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="81"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Gants" name="Gloves"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portés + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de gants, faites-en glisser une paire à partir de votre inventaire. Vous pouvez aussi en créer de nouveaux et les porter. + </text> + <button label="Créer des gants" label_selected="Créer des gants" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Gants : + </text> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Débardeur" name="Undershirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non porté + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de débardeur, faites-en glisser un à partir de votre inventaire. Vous pouvez aussi en créer un nouveau et le porter. + </text> + <button label="Créer un débardeur" label_selected="Créer un débardeur" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label"> + Débardeur : + </text> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Caleçon" name="Underpants"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non porté + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de caleçon, faites-en glisser un à partir de votre inventaire. Vous pouvez aussi en créer un nouveau et le porter. + </text> + <button label="Créer un caleçon" label_selected="Créer un caleçon" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label"> + Caleçon : + </text> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Jupe" name="Skirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non portée + </text> + <text name="path"> + Emplacement : [PATH] + </text> + <text name="not worn instructions"> + Pour changer de jupe, faites-en glisser une à partir de votre inventaire. Vous pouvez aussi en créer une nouvelle et la porter. + </text> + <button label="Créer une jupe" label_selected="Créer une jupe" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas la permission de modifier cet objet. + </text> + <text name="Item Action Label" right="92"> + Jupe : + </text> + <texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/> + <color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/> + <button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Tatouage" name="Tattoo"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non porté + </text> + <text name="path"> + Dans [PATH] + </text> + <text name="not worn instructions"> + Pour changer de tatouage, faites-en glisser un de votre inventaire à votre avatar. Vous pouvez aussi en créer un nouveau et le porter. + </text> + <button label="Créer un nouveau tatouage" label_selected="Créer un nouveau tatouage" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas le droit de modifier cet objet. + </text> + <text name="Item Action Label"> + Tatouage : + </text> + <texture_picker label="Tatouage tête" name="Head Tattoo" tool_tip="Cliquez pour sélectionner une image"/> + <texture_picker label="Tatouage haut" name="Upper Tattoo" tool_tip="Cliquez pour sélectionner une image"/> + <texture_picker label="Tatouage bas" name="Lower Tattoo" tool_tip="Cliquez pour sélectionner une image"/> + <button label="Enlever" label_selected="Enlever" name="Take Off"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + <panel label="Alpha" name="Alpha"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: impossible de modifier + </text> + <text name="title_loading"> + [DESC]: en cours de chargement... + </text> + <text name="title_not_worn"> + [DESC]: non porté + </text> + <text name="path"> + Dans [PATH] + </text> + <text name="not worn instructions"> + Pour changer de masque alpha, faites-en glisser un de votre inventaire à votre avatar. Vous pouvez aussi en créer un nouveau et le porter. + </text> + <button label="Créer un nouvel alpha" label_selected="Créer un nouvel alpha" name="Create New"/> + <text name="no modify instructions"> + Vous n'avez pas le droit de modifier cet objet. + </text> + <text name="Item Action Label"> + Alpha : + </text> + <texture_picker label="Alpha bas" name="Lower Alpha" tool_tip="Cliquez pour sélectionner une image"/> + <texture_picker label="Alpha haut" name="Upper Alpha" tool_tip="Cliquez pour sélectionner une image"/> + <texture_picker label="Alpha tête" name="Head Alpha" tool_tip="Cliquez pour sélectionner une image"/> + <texture_picker label="Alpha yeux" name="Eye Alpha" tool_tip="Cliquez pour sélectionner une image"/> + <texture_picker label="Alpha cheveux" name="Hair Alpha" tool_tip="Cliquez pour sélectionner une image"/> + <button label="Enlever" label_selected="Enlever" name="Take Off"/> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/> + <button label="Rétablir" label_selected="Rétablir" name="Revert"/> + </panel> + </tab_container> + <scroll_container left="251" name="panel_container"/> + <button label="Infos scripts" label_selected="Infos scripts" name="script_info" tool_tip="Afficher les scripts attachés à votre avatar"/> + <button label="Créer tenue" label_selected="Créer une tenue..." name="make_outfit_btn"/> + <button label="Annuler" label_selected="Annuler" name="Cancel"/> + <button label="OK" label_selected="OK" name="Ok"/> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_event.xml b/indra/newview/skins/default/xui/fr/floater_event.xml index b005ce3b36..3527d89973 100644 --- a/indra/newview/skins/default/xui/fr/floater_event.xml +++ b/indra/newview/skins/default/xui/fr/floater_event.xml @@ -1,69 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Événement" name="Event" title="DÉTAILS SUR L'ÉVÉNEMENT"> - <floater.string name="none"> - aucun +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Chargement... </floater.string> - <floater.string name="notify"> - Prévenir - </floater.string> - <floater.string name="dont_notify"> - Ne pas prévenir - </floater.string> - <floater.string name="moderate"> - Modéré - </floater.string> - <floater.string name="adult"> - Adulte - </floater.string> - <floater.string name="general"> - Général - </floater.string> - <floater.string name="unknown"> - Inconnu - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Nameless Event...of Doom! De doom! Doom doom. - </text> - <text name="event_category"> - (pas de catégorie) - </text> - <text name="event_runby_label"> - Organisé par : - </text> - <text initial_value="(récupération en cours)" name="event_runby"/> - <text name="event_date_label"> - Date : - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - Durée : - </text> - <text name="event_duration"> - 1 heure - </text> - <text name="event_covercharge_label"> - Prix : - </text> - <text name="event_cover"> - Gratuit - </text> - <text name="event_location_label"> - Lieu : - </text> - <text name="event_location" value="SampleParcel, Name Long (145, 228, 26)"/> - <text name="rating_label" value="Catégorie :"/> - <text name="rating_value" value="inconnu"/> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="Créer un événement"/> - <button name="god_delete_event_btn" tool_tip="Supprimer l'événement"/> - <button label="Me prévenir" name="notify_btn"/> - <button label="Téléporter" name="teleport_btn"/> - <button label="Carte" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml new file mode 100644 index 0000000000..d77dfbdf82 --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_outfit_save_as.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container" title="Enregistrer la tenue"> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Annuler" label_selected="Annuler" name="Cancel"/> + <text name="Save item as:"> + Enregistrer ce que je porte +comme une nouvelle tenue : + </text> + <line_editor name="name ed"> + [DESC] (nouv.) + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/fr/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/fr/floater_wearable_save_as.xml new file mode 100644 index 0000000000..5dda347fcf --- /dev/null +++ b/indra/newview/skins/default/xui/fr/floater_wearable_save_as.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container"> + <button label="Enregistrer" label_selected="Enregistrer" name="Save"/> + <button label="Annuler" label_selected="Annuler" name="Cancel"/> + <text name="Save item as:"> + Enregistrer l'objet dans mon inventaire comme : + </text> + <line_editor name="name ed"> + Nouveau [DESC] + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 2a7d1d1a5d..243bad8f8a 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -178,7 +178,7 @@ Voulez-vous continuer ? <notification name="JoinGroupNoCost"> Vous vous apprêtez à rejoindre le groupe [NAME]. Voulez-vous continuer ? - <usetemplate name="okcancelbuttons" notext="Annuler" yestext="Rejoindre"/> + <usetemplate name="okcancelbuttons" notext="Annuler" yestext="Fusionner"/> </notification> <notification name="JoinGroupCannotAfford"> Rejoindre ce groupe coûte [COST] L$. @@ -2181,8 +2181,7 @@ Veuillez sélectionner un terrain plus petit. [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Téléporter"/> - <button name="Description" text="Description"/> + <button name="Description" text="Détails"/> <button name="Cancel" text="Annuler"/> </form> </notification> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index a7a766f6a6..af70048106 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -798,7 +798,7 @@ <string name="xml_file"> Fichier XML </string> - <string name="dot_raw_file"> + <string name="raw_file"> Fichier RAW </string> <string name="compressed_image_files"> diff --git a/indra/newview/skins/default/xui/it/floater_event.xml b/indra/newview/skins/default/xui/it/floater_event.xml index a0807e04c9..9a0105a589 100644 --- a/indra/newview/skins/default/xui/it/floater_event.xml +++ b/indra/newview/skins/default/xui/it/floater_event.xml @@ -1,72 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Evento" name="Event" title="DETTAGLI DELL'EVENTO"> - <floater.string name="none"> - nessuno +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Caricamento in corso... </floater.string> - <floater.string name="notify"> - Avvisare - </floater.string> - <floater.string name="dont_notify"> - Non avvisare - </floater.string> - <floater.string name="moderate"> - Moderato - </floater.string> - <floater.string name="adult"> - Adulto - </floater.string> - <floater.string name="general"> - Generale - </floater.string> - <floater.string name="unknown"> - Sconosciuto - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Evento senza nome...di Doom De doom! Doom doom. - </text> - <text name="event_category"> - (nessuna categoria) - </text> - <text name="event_runby_label"> - Organizzato da: - </text> - <text initial_value="(recupero)" name="event_runby"/> - <text name="event_date_label"> - Data: - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - Durata: - </text> - <text name="event_duration"> - 1 ora - </text> - <text name="event_covercharge_label"> - Costo: - </text> - <text name="event_cover"> - Gratis - </text> - <text name="event_location_label"> - Luogo: - </text> - <text name="event_location" value="SampleParcel, Name Long (145, 228, 26)"/> - <text name="rating_label" value="Categoria:"/> - <text name="rating_value" value="sconosciuto"/> - <expandable_text name="event_desc"> - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - </expandable_text> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="Crea evento"/> - <button name="god_delete_event_btn" tool_tip="Elimina evento"/> - <button label="Avvisami" name="notify_btn"/> - <button label="Teleport" name="teleport_btn"/> - <button label="Mappa" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/it/floater_map.xml b/indra/newview/skins/default/xui/it/floater_map.xml index ca537efba9..3dcfdd4662 100644 --- a/indra/newview/skins/default/xui/it/floater_map.xml +++ b/indra/newview/skins/default/xui/it/floater_map.xml @@ -1,28 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="Map" title=""> - <floater.string name="mini_map_north"> - N - </floater.string> - <floater.string name="mini_map_east"> - E - </floater.string> - <floater.string name="mini_map_west"> - O - </floater.string> - <floater.string name="mini_map_south"> - S - </floater.string> - <floater.string name="mini_map_southeast"> - SE - </floater.string> - <floater.string name="mini_map_northeast"> - NE - </floater.string> - <floater.string name="mini_map_southwest"> - SO - </floater.string> - <floater.string name="mini_map_northwest"> - NO + <floater.string name="ToolTipMsg"> + [REGION](Fai doppio clic per aprire la Mappa, premi il tasto Maiusc e trascina per la panoramica) </floater.string> <floater.string name="mini_map_caption"> MINI MAPPA diff --git a/indra/newview/skins/default/xui/it/floater_nearby_chat.xml b/indra/newview/skins/default/xui/it/floater_nearby_chat.xml index 9878fe85ea..4c41df8a62 100644 --- a/indra/newview/skins/default/xui/it/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/it/floater_nearby_chat.xml @@ -1,2 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="CHAT NEI DINTORNI"/> +<floater name="nearby_chat" title="CHAT NEI DINTORNI"> + <check_box label="Traduci chat (tecnologia Google)" name="translate_chat_checkbox"/> +</floater> diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index 68d193ff33..fbe611407e 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -183,10 +183,10 @@ <text name="Group:"> Gruppo: </text> - <button label="Imposta..." label_selected="Imposta..." name="button set group" tool_tip="Scegli un gruppo con cui condividere i diritti relativi all'oggetto"/> <name_box initial_value="Caricamento in corso..." name="Group Name Proxy"/> - <button label="Cessione" label_selected="Cessione" name="button deed" tool_tip="Con una cessione si trasferisce il bene con i diritti al proprietario successivo Gli oggetti in proprietà condivisa di gruppo possono essere ceduti soltanto da un funzionario del gruppo."/> + <button label="Imposta..." label_selected="Imposta..." name="button set group" tool_tip="Scegli un gruppo con cui condividere i diritti relativi all'oggetto"/> <check_box label="Condividi" name="checkbox share with group" tool_tip="Consenti a tutti i membri del gruppo selezionato di condividere i tuoi diritti di modifica di questo oggetto. Per attivare le restrizioni per ruolo devi prima effettuare la cessione."/> + <button label="Cessione" label_selected="Cessione" name="button deed" tool_tip="Con una cessione si trasferisce il bene con i diritti al proprietario successivo Gli oggetti in proprietà condivisa di gruppo possono essere ceduti soltanto da un funzionario del gruppo."/> <text name="label click action"> Fai clic per: </text> @@ -438,7 +438,8 @@ <combo_box.item label="Cerchi rialzati" name="suction"/> <combo_box.item label="Trama" name="weave"/> </combo_box> - <text name="tex scale"> + <check_box initial_value="falso" label="Allinea facce planari" name="checkbox planar align" tool_tip="Allinea le texture su tutte le facce selezionate con l’ultima faccia selezionata. È richiesta la mappatura planare delle texture."/> + <text name="rpt"> Ripetizioni / Faccia </text> <spinner label="Orizzontale (U)" name="TexScaleU"/> diff --git a/indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml new file mode 100644 index 0000000000..46abd7deed --- /dev/null +++ b/indra/newview/skins/default/xui/it/menu_add_wearable_gear.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Add Wearable Gear Menu"> + <menu_item_check label="Mostra prima i più recenti" name="sort_by_most_recent"/> + <menu_item_check label="Ordina in base al nome" name="sort_by_name"/> + <menu_item_check label="Ordina in base al tipo" name="sort_by_type"/> +</menu> diff --git a/indra/newview/skins/default/xui/it/menu_attachment_self.xml b/indra/newview/skins/default/xui/it/menu_attachment_self.xml index fe5464b156..489d6af1d7 100644 --- a/indra/newview/skins/default/xui/it/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/it/menu_attachment_self.xml @@ -3,6 +3,7 @@ <menu_item_call label="Tocca" name="Attachment Object Touch"/> <menu_item_call label="Modifica" name="Edit..."/> <menu_item_call label="Stacca" name="Detach"/> + <menu_item_call label="Siedi" name="Sit Down Here"/> <menu_item_call label="Alzati" name="Stand Up"/> <menu_item_call label="Cambia vestiario" name="Change Outfit"/> <menu_item_call label="Modifica il mio vestiario" name="Edit Outfit"/> diff --git a/indra/newview/skins/default/xui/it/menu_avatar_self.xml b/indra/newview/skins/default/xui/it/menu_avatar_self.xml index 7d918423c3..977503dace 100644 --- a/indra/newview/skins/default/xui/it/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/it/menu_avatar_self.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Self Pie"> + <menu_item_call label="Siedi" name="Sit Down Here"/> <menu_item_call label="Alzati" name="Stand Up"/> <context_menu label="Togli" name="Take Off >"> <context_menu label="Abiti" name="Clothes >"> 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 eb10ebd0b6..ede4a507c0 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 @@ -9,6 +9,7 @@ <menu_item_call label="Apri" name="open"/> <menu_item_call label="Modifica" name="edit"/> <menu_item_call label="Indossa" name="wear"/> + <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="Zoom avanti" name="zoom_in"/> diff --git a/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml index 80edae8a2b..8b4ed607e7 100644 --- a/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <menu name="Gear Menu"> + <menu_item_call label="Siedi" name="sit_down_here"/> <menu_item_call label="Alzati" name="stand_up"/> <menu_item_call label="Cambia vestiario" name="change_outfit"/> <menu_item_call label="Il mio profilo" name="my_profile"/> diff --git a/indra/newview/skins/default/xui/it/menu_mini_map.xml b/indra/newview/skins/default/xui/it/menu_mini_map.xml index fa574230e0..ecc2bef06a 100644 --- a/indra/newview/skins/default/xui/it/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/it/menu_mini_map.xml @@ -4,6 +4,7 @@ <menu_item_call label="Zoom Medio" name="Zoom Medium"/> <menu_item_call label="Zoom Distante" name="Zoom Far"/> <menu_item_check label="Ruota la mappa" name="Rotate Map"/> + <menu_item_check label="Centra automaticamente" name="Auto Center"/> <menu_item_call label="Ferma il puntamento" name="Stop Tracking"/> <menu_item_call label="Mappa del mondo" name="World Map"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_object.xml b/indra/newview/skins/default/xui/it/menu_object.xml index 413fcfdc8a..4c7402ea08 100644 --- a/indra/newview/skins/default/xui/it/menu_object.xml +++ b/indra/newview/skins/default/xui/it/menu_object.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Object Pie"> <menu_item_call label="Tocca" name="Object Touch"> - <on_enable parameter="Tocca" name="EnableTouch"/> + <menu_item_call.on_enable name="EnableTouch" parameter="Tocca"/> </menu_item_call> <menu_item_call label="Modifica" name="Edit..."/> <menu_item_call label="Costruisci" name="Build"/> @@ -10,18 +10,18 @@ <menu_item_call label="Alzati" name="Object Stand Up"/> <menu_item_call label="Profilo dell'oggetto" name="Object Inspect"/> <menu_item_call label="Zoom avanti" name="Zoom In"/> - <context_menu label="Indossa" name="Put On"> + <context_menu label="Metti" name="Put On"> <menu_item_call label="Indossa" name="Wear"/> + <menu_item_call label="Aggiungi" name="Add"/> <context_menu label="Attacca" name="Object Attach"/> <context_menu label="Attacca HUD" name="Object Attach HUD"/> </context_menu> - <context_menu label="Togli" name="Remove"> + <context_menu label="Rimuovi" name="Remove"> <menu_item_call label="Segnala abuso" name="Report Abuse..."/> <menu_item_call label="Blocca" name="Object Mute"/> <menu_item_call label="Restituisci" name="Return..."/> <menu_item_call label="Elimina" name="Delete"/> </context_menu> - <menu_item_call label="Acquista" name="Pie Object Bye"/> <menu_item_call label="Prendi" name="Pie Object Take"/> <menu_item_call label="Prendi copia" name="Take Copy"/> <menu_item_call label="Paga" name="Pay..."/> diff --git a/indra/newview/skins/default/xui/it/menu_participant_list.xml b/indra/newview/skins/default/xui/it/menu_participant_list.xml index 52e3c933da..1b057c4077 100644 --- a/indra/newview/skins/default/xui/it/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/it/menu_participant_list.xml @@ -11,7 +11,7 @@ <menu_item_check label="Icone persone" name="View Icons"/> <menu_item_check label="Blocca voce" name="Block/Unblock"/> <menu_item_check label="Blocca testo" name="MuteText"/> - <context_menu label="Opzioni moderatore " name="Moderator Options"> + <context_menu label="Opzioni moderatore" name="Moderator Options"> <menu_item_check label="Consenti chat di testo" name="AllowTextChat"/> <menu_item_call label="Disattiva audio di questo participante" name="ModerateVoiceMuteSelected"/> <menu_item_call label="Riattiva audio di questo participante" name="ModerateVoiceUnMuteSelected"/> diff --git a/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml index 1f987890c4..3a799f44eb 100644 --- a/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/it/menu_people_friends_view_sort.xml @@ -3,5 +3,6 @@ <menu_item_check label="Ordina in base al nome" name="sort_name"/> <menu_item_check label="Ordina in base allo stato" name="sort_status"/> <menu_item_check label="Icone persone" name="view_icons"/> + <menu_item_check label="Visualizza autorizzazioni concesse" name="view_permissions"/> <menu_item_call label="Mostra oggetti e residenti bloccati" name="show_blocked_list"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml index 9784a4cc9a..e0b9ceb63d 100644 --- a/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml +++ b/indra/newview/skins/default/xui/it/menu_people_nearby_multiselect.xml @@ -6,4 +6,5 @@ <menu_item_call label="Chiama" name="Call"/> <menu_item_call label="Condividi" name="Share"/> <menu_item_call label="Paga" name="Pay"/> + <menu_item_call label="Offri Teleport" name="teleport"/> </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 6290b79211..72dfbeecb6 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -94,7 +94,6 @@ <menu_item_call label="Imposta script come non in esecuzione" name="Set Scripts to Not Running"/> </menu> <menu label="Opzioni" name="Options"> - <menu_item_call label="Definisci diritti di caricamento predefiniti" name="perm prefs"/> <menu_item_check label="Mostra autorizzazioni avanzate" name="DebugPermissions"/> <menu_item_check label="Seleziona solo i miei oggetti" name="Select Only My Objects"/> <menu_item_check label="Seleziona solo gli oggetti spostabili" name="Select Only Movable Objects"/> @@ -121,7 +120,6 @@ <menu_item_call label="Informazioni su [APP_NAME]" name="About Second Life"/> </menu> <menu label="Avanzate" name="Advanced"> - <menu_item_check label="Mostra menu Avanzato" name="Show Advanced Menu"/> <menu_item_call label="Ferma animazione" name="Stop Animating My Avatar"/> <menu_item_call label="Ridisegna le texture" name="Rebake Texture"/> <menu_item_call label="Imposta dimensioni dell'interfaccia sui valori predefiniti" name="Set UI Size to Default"/> @@ -168,7 +166,6 @@ <menu_item_check label="Nebbia" name="Fog"/> <menu_item_check label="Oggetti flessibili" name="Flexible Objects"/> </menu> - <menu_item_check label="Esegui thread multipli" name="Run Multiple Threads"/> <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"/> @@ -177,7 +174,6 @@ <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_check label="Corri sempre" name="Always Run"/> <menu_item_check label="Vola" name="Fly"/> <menu_item_call label="Chiudi finestra" name="Close Window"/> @@ -197,6 +193,7 @@ <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"/> + <menu_item_check label="Mostra menu Avanzato" name="Show Advanced Menu"/> </menu> <menu_item_call label="Mostra impostazioni di debug" name="Debug Settings"/> <menu_item_check label="Mostra menu sviluppo" name="Debug Mode"/> @@ -239,9 +236,15 @@ <menu label="Rendering" name="Rendering"> <menu_item_check label="Assi" name="Axes"/> <menu_item_check label="Wireframe" name="Wireframe"/> - <menu_item_check label="Illuminazione globale" name="Global Illumination"/> + <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"/> <menu_item_check label="Disabilita texture" name="Disable Textures"/> + <menu_item_check label="Atlante tessitura (sperimentale)" name="Texture Atlas"/> <menu_item_check label="Rendering delle luci unite" name="Render Attached Lights"/> <menu_item_check label="Rendering particelle unite" name="Render Attached Particles"/> <menu_item_check label="Gli oggetti brillano quando sono sotto il cursore" name="Hover Glow Objects"/> @@ -261,7 +264,8 @@ <menu_item_call label="Test browser Web" name="Web Browser Test"/> <menu_item_call label="Stampa informazioni oggetto selezionato" name="Print Selected Object Info"/> <menu_item_call label="Statistiche memoria" name="Memory Stats"/> - <menu_item_check label="Doppio clic pilota automatico" name="Double-ClickAuto-Pilot"/> + <menu_item_check label="Doppio clic pilota automatico" name="Double-Click Auto-Pilot"/> + <menu_item_check label="Doppio clic per teleport" name="DoubleClick Teleport"/> <menu_item_check label="Debug clic" name="Debug Clicks"/> <menu_item_check label="Debug eventi mouse" name="Debug Mouse Events"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml index b0bd68966d..c9a02d8a86 100644 --- a/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/it/menu_wearable_list_item.xml @@ -9,6 +9,6 @@ <context_menu label="Attacca a HUD" name="wearable_attach_to_hud"/> <menu_item_call label="Togli" name="take_off"/> <menu_item_call label="Modifica" name="edit"/> - <menu_item_call label="Profilo dell'oggetto" name="object_profile"/> + <menu_item_call label="Profilo articolo" name="object_profile"/> <menu_item_call label="Mostra originale" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml index 40eea8f03c..7c8eef64e5 100644 --- a/indra/newview/skins/default/xui/it/menu_wearing_gear.xml +++ b/indra/newview/skins/default/xui/it/menu_wearing_gear.xml @@ -1,4 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="Gear Wearing"> <menu_item_call label="Modifica vestiario" name="edit"/> + <menu_item_call label="Togli" name="takeoff"/> </menu> diff --git a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml index 48ff0a2160..4a5366091f 100644 --- a/indra/newview/skins/default/xui/it/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/it/menu_wearing_tab.xml @@ -1,4 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Wearing"> + <menu_item_call label="Togli" name="take_off"/> + <menu_item_call label="Stacca" name="detach"/> <menu_item_call label="Modifica vestiario" name="edit"/> </context_menu> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 474bdca55f..ffd27d55e8 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -1818,6 +1818,10 @@ Trasferisci gli elementi nell'inventario? Confermi di voler uscire? <usetemplate ignoretext="Conferma prima di uscire" name="okcancelignore" notext="Non uscire" yestext="Esci"/> </notification> + <notification name="DeleteItems"> + [QUESTION] + <usetemplate ignoretext="Conferma prima di cancellare gli elementi" name="okcancelignore" notext="Annulla" yestext="OK"/> + </notification> <notification name="HelpReportAbuseEmailLL"> Usa questo strumento per segnalare violazioni a [http://secondlife.com/corporate/tos.php Terms of Service] e [http://secondlife.com/corporate/cs.php Community Standards]. @@ -2183,8 +2187,7 @@ Prova a selezionare una parte di terreno più piccola. [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Teleport"/> - <button name="Description" text="Descrizione"/> + <button name="Details" text="Descrizione"/> <button name="Cancel" text="Cancella"/> </form> </notification> @@ -2747,9 +2750,13 @@ Ti consigliamo di controllare le tue impostazioni di rete e della firewall. ( presente da [EXISTENCE] secondi ) Avatar '[NAME]' è partito completamente caricato. </notification> - <notification name="AvatarRezSelfBakeNotification"> - ( in esistenza da [EXISTENCE] secondi ) -Effettuata l'azione: [ACTION] di una texture [RESOLUTION] completata per '[BODYREGION]' dopo [TIME] secondi. + <notification name="AvatarRezSelfBakedTextureUploadNotification"> + ( In esistenza da [EXISTENCE] secondi) +Hai caricato una texture [RESOLUTION] completata per '[BODYREGION]' dopo [TIME] secondi. + </notification> + <notification name="AvatarRezSelfBakedTextureUpdateNotification"> + ( In esistenza da [EXISTENCE] secondi) +Hai aggiornato localmente una texture [RESOLUTION] completata per '[BODYREGION]' dopo [TIME] secondi. </notification> <notification name="ConfirmLeaveCall"> Sei sicuro di volere uscire dalla chiamata? diff --git a/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml index 4c7f298590..3e604ca775 100644 --- a/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/it/panel_avatar_list_item.xml @@ -22,5 +22,9 @@ [COUNT] a </string> <text name="avatar_name" value="Sconosciuto"/> + <icon name="permission_edit_theirs_icon" tool_tip="Puoi modificare gli oggetti di questo amico"/> + <icon name="permission_edit_mine_icon" tool_tip="Questo amico può modificare, cancellare o prendere i tuoi oggetti"/> + <icon name="permission_map_icon" tool_tip="Questo amico può identificarti sulla mappa"/> + <icon name="permission_online_icon" tool_tip="Questo amico può vedere se sei online"/> <button name="profile_btn" tool_tip="Vedi profilo"/> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_bottomtray.xml b/indra/newview/skins/default/xui/it/panel_bottomtray.xml index e4d99cc402..3d12473c87 100644 --- a/indra/newview/skins/default/xui/it/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/it/panel_bottomtray.xml @@ -1,5 +1,6 @@ <?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"> @@ -12,28 +13,25 @@ <gesture_combo_list label="Gesture" name="Gesture" tool_tip="Mostra o nasconde le gesture"/> </layout_panel> <layout_panel name="movement_panel"> - <button label="Sposta" name="movement_btn" tool_tip="Mostra o nasconde i comandi del movimento"/> + <bottomtray_button label="Sposta" name="movement_btn" tool_tip="Mostra o nasconde i comandi del movimento"/> </layout_panel> <layout_panel name="cam_panel"> - <button label="Visuale" name="camera_btn" tool_tip="Mostra o nasconde le regolazioni della visuale"/> + <bottomtray_button label="Visuale" name="camera_btn" tool_tip="Mostra o nasconde le regolazioni della visuale"/> </layout_panel> <layout_panel name="snapshot_panel"> - <button label="" name="snapshots" tool_tip="Scatta una foto"/> - </layout_panel> - <layout_panel name="sidebar_btn_panel"> - <button label="Barra laterale" name="sidebar_btn" tool_tip="Mostra o nasconde la barra laterale"/> + <bottomtray_button label="" name="snapshots" tool_tip="Scatta una foto"/> </layout_panel> <layout_panel name="build_btn_panel"> - <button label="Costruisci" name="build_btn" tool_tip="Mostra o nasconde gli strumenti di costruzione"/> + <bottomtray_button label="Costruisci" name="build_btn" tool_tip="Mostra o nasconde gli strumenti di costruzione"/> </layout_panel> <layout_panel name="search_btn_panel"> - <button label="Cerca" name="search_btn" tool_tip="Mostra o nasconde la ricerca"/> + <bottomtray_button label="Cerca" name="search_btn" tool_tip="Mostra o nasconde la ricerca"/> </layout_panel> <layout_panel name="world_map_btn_panel"> - <button label="Mappa" name="world_map_btn" tool_tip="Mostra o nasconde la mappa del mondo"/> + <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"> - <button label="Mini mappa" name="mini_map_btn" tool_tip="Mostra o nasconde la mini mappa"/> + <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"> diff --git a/indra/newview/skins/default/xui/it/panel_classified_info.xml b/indra/newview/skins/default/xui/it/panel_classified_info.xml index 3d363d9c75..a7cf51c4b9 100644 --- a/indra/newview/skins/default/xui/it/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/it/panel_classified_info.xml @@ -46,8 +46,16 @@ </panel> </scroll_container> <panel name="buttons"> - <button label="Teleport" name="teleport_btn"/> - <button label="Mappa" name="show_on_map_btn"/> - <button label="Modifica" name="edit_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Teleport" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Mappa" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="Modifica" name="edit_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_edit_classified.xml b/indra/newview/skins/default/xui/it/panel_edit_classified.xml index bbe8ebbc32..ad827696ff 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_classified.xml @@ -36,13 +36,19 @@ <icons_combo_box.item label="Contenuto moderato" name="mature_ci" value="Moderato"/> <icons_combo_box.item label="Contenuto generale" name="pg_ci" value="Generale"/> </icons_combo_box> + <check_box label="Rinnovo automatico ogni settimana" name="auto_renew"/> <text name="price_for_listing_label" value="Prezzo per inserzione:"/> <spinner label="L$" name="price_for_listing" tool_tip="Prezzo per inserzione:" value="50"/> - <check_box label="Rinnovo automatico ogni settimana" name="auto_renew"/> </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> - <button label="[LABEL]" name="save_changes_btn"/> - <button label="Annulla" name="cancel_btn"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="[LABEL]" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Annulla" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_edit_pick.xml b/indra/newview/skins/default/xui/it/panel_edit_pick.xml index f93b953eac..8e464ca037 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_pick.xml @@ -25,7 +25,13 @@ </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> - <button label="Salva luogo preferito" name="save_changes_btn"/> - <button label="Annulla" name="cancel_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Salva luogo preferito" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="layout_panel1"> + <button label="Annulla" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_edit_profile.xml b/indra/newview/skins/default/xui/it/panel_edit_profile.xml index 3ecf4bcaf2..263ae105dc 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_profile.xml @@ -45,7 +45,13 @@ </panel> </scroll_container> <panel name="profile_me_buttons_panel"> - <button label="Salva modifiche" name="save_btn"/> - <button label="Annulla" name="cancel_btn"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="Salva modifiche" name="save_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Annulla" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml index 19456281bb..94bda7b2a6 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml @@ -102,7 +102,13 @@ <icon name="female_icon" tool_tip="Femmina"/> </panel> <panel name="button_panel"> - <button label="Salva con nome" name="save_as_button"/> - <button label="Annulla modifiche" name="revert_button"/> + <layout_stack name="button_panel_ls"> + <layout_panel name="save_as_btn_lp"> + <button label="Salva con nome" name="save_as_button"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="Annulla modifiche" name="revert_button"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml index da797b309f..34ee3c2dca 100644 --- a/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/it/panel_group_info_sidetray.xml @@ -13,7 +13,7 @@ Gratis </panel.string> <panel name="group_info_top"> - <text name="group_name" value="(Caricamento in corso...)"/> + <text_editor name="group_name" value="(Caricamento in corso...)"/> <line_editor label="Scrivi qui il nome del gruppo" name="group_name_editor"/> </panel> <layout_stack name="layout"> @@ -25,9 +25,15 @@ <accordion_tab name="group_land_tab" title="Terra/Beni"/> </accordion> </layout_panel> - <layout_panel name="button_row"> + </layout_stack> + <layout_stack name="button_row_ls"> + <layout_panel name="btn_chat_lp"> <button label="Chat" name="btn_chat"/> + </layout_panel> + <layout_panel name="call_btn_lp"> <button label="Chiamata al gruppo" name="btn_call" tool_tip="Chiama questo gruppo"/> + </layout_panel> + <layout_panel name="btn_apply_lp"> <button label="Salva" label_selected="Salva" name="btn_apply"/> <button label="Crea un gruppo" name="btn_create" tool_tip="Crea un nuovo gruppo"/> </layout_panel> diff --git a/indra/newview/skins/default/xui/it/panel_landmarks.xml b/indra/newview/skins/default/xui/it/panel_landmarks.xml index 74cd9e6fb1..5617105c31 100644 --- a/indra/newview/skins/default/xui/it/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/it/panel_landmarks.xml @@ -7,8 +7,16 @@ <accordion_tab name="tab_library" title="Libreria"/> </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="Mostra opzioni addizionali"/> - <button name="add_btn" tool_tip="Aggiungi un nuovo punto di riferimento"/> - <dnd_button name="trash_btn" tool_tip="Rimuovi il punto di riferimento selezionato"/> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <button name="options_gear_btn" tool_tip="Mostra ulteriori opzioni"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="Aggiungi un nuovo punto di riferimento"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="Rimuovi il punto di riferimento selezionato"/> + </layout_panel> + </layout_stack> </panel> </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 index 08c050228f..3e6683beb8 100644 --- a/indra/newview/skins/default/xui/it/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/it/panel_my_profile.xml @@ -27,9 +27,8 @@ </panel> </scroll_container> </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="Modifica profilo" name="edit_profile_btn" tool_tip="Modifica le tue informazioni personali"/> - <button label="Modifica aspetto fisico" name="edit_appearance_btn" tool_tip="Crea/modifica il tuo aspetto: parti del corpo, abiti ecc."/> - </layout_panel> </layout_stack> + <panel name="profile_me_buttons_panel"> + <button label="Modifica profilo" name="edit_profile_btn" tool_tip="Modifica le tue informazioni personali"/> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_notes.xml b/indra/newview/skins/default/xui/it/panel_notes.xml index 945bff1603..e127138277 100644 --- a/indra/newview/skins/default/xui/it/panel_notes.xml +++ b/indra/newview/skins/default/xui/it/panel_notes.xml @@ -13,11 +13,23 @@ </scroll_container> </layout_panel> <layout_panel name="notes_buttons_panel"> - <button label="Aggiungi amico" name="add_friend" tool_tip="Offri amicizia a questo residente"/> - <button label="IM" name="im" tool_tip="Apri una sessione messaggio istantaneo"/> - <button label="Chiama" name="call" tool_tip="Chiama questo residente"/> - <button label="Mappa" name="show_on_map_btn" tool_tip="Mostra il residente sulla mappa"/> - <button label="Teleport" name="teleport" tool_tip="Offri teleport"/> + <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_outfit_edit.xml b/indra/newview/skins/default/xui/it/panel_outfit_edit.xml index 6628d4f730..446c211b1c 100644 --- a/indra/newview/skins/default/xui/it/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/it/panel_outfit_edit.xml @@ -45,7 +45,13 @@ <button name="shop_btn_2" tool_tip="Visita Marketplace di SL. In alternativa puoi scegliere un capo che stai indossando, poi fare clic qui per vedere altri capi simili"/> </panel> <panel name="save_revert_button_bar"> - <button label="Salva" name="save_btn"/> - <button label="Annulla modifiche" name="revert_btn" tool_tip="Ripristina l'ultima versione salvata"/> + <layout_stack name="button_bar_ls"> + <layout_panel name="save_btn_lp"> + <button label="Salva" name="save_btn"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="Annulla modifiche" name="revert_btn" tool_tip="Ripristina l'ultima versione salvata"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml index 8f6ca38767..c7821bc363 100644 --- a/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/it/panel_outfits_inventory.xml @@ -11,7 +11,13 @@ <panel label="INDOSSA" name="cof_tab"/> </tab_container> <panel name="bottom_panel"> - <button label="Salva con nome" name="save_btn"/> - <button label="Indossa" name="wear_btn" tool_tip="Indossa il vestiario selezionato"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_btn_lp"> + <button label="Salva con nome" name="save_btn"/> + </layout_panel> + <layout_panel name="wear_btn_lp"> + <button label="Indossa" name="wear_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml index 3d07ff45ba..a8f60e556e 100644 --- a/indra/newview/skins/default/xui/it/panel_people.xml +++ b/indra/newview/skins/default/xui/it/panel_people.xml @@ -32,9 +32,17 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa <accordion_tab name="tab_all" title="Tutto"/> </accordion> <panel label="bottom_panel" name="bottom_panel"> - <button name="friends_viewsort_btn" tool_tip="Opzioni"/> - <button name="add_btn" tool_tip="Offri amicizia a un residente"/> - <button name="del_btn" tool_tip="Rimuovi la persona selezionata dalla lista degli amici"/> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <button name="friends_viewsort_btn" tool_tip="Mostra ulteriori opzioni"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="Offri amicizia a un residente"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="Rimuovi la persona selezionata dalla lista degli amici"/> + </layout_panel> + </layout_stack> </panel> </panel> <panel label="I MIEI GRUPPI" name="groups_panel"> @@ -52,13 +60,33 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa </panel> </tab_container> <panel name="button_bar"> - <button label="Profilo" name="view_profile_btn" tool_tip="Mostra immagine, gruppi e altre informazioni del residente"/> - <button label="IM" name="im_btn" tool_tip="Apri una sessione messaggio istantaneo"/> - <button label="Chiama" name="call_btn" tool_tip="Chiama questo residente"/> - <button label="Condividi" name="share_btn" tool_tip="Condividi un oggetto dell'inventario"/> - <button label="Teleport" name="teleport_btn" tool_tip="Offri teleport"/> - <button label="Profilo del gruppo" name="group_info_btn" tool_tip="Mostra informazioni gruppo"/> - <button label="Chat di gruppo" name="chat_btn" tool_tip="Apri sessione chat"/> - <button label="Chiamata al gruppo" name="group_call_btn" tool_tip="Chiama questo gruppo"/> + <layout_stack name="bottom_bar_ls"> + <layout_panel name="view_profile_btn_lp"> + <button label="Profilo" name="view_profile_btn" tool_tip="Mostra immagine, gruppi e altre informazioni del residente"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="IM" name="im_btn" tool_tip="Apri una sessione messaggio istantaneo"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Chiama" name="call_btn" tool_tip="Chiama questo residente"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Condividi" name="share_btn" tool_tip="Condividi un oggetto dell'inventario"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Teleport" name="teleport_btn" tool_tip="Offri teleport"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="group_info_btn_lp"> + <button label="Profilo del gruppo" name="group_info_btn" tool_tip="Mostra informazioni gruppo"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Chat di gruppo" name="chat_btn" tool_tip="Apri sessione chat"/> + </layout_panel> + <layout_panel name="group_call_btn_lp"> + <button label="Chiamata al gruppo" name="group_call_btn" tool_tip="Chiama questo gruppo"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_pick_info.xml b/indra/newview/skins/default/xui/it/panel_pick_info.xml index 7c059b443d..ca9959a581 100644 --- a/indra/newview/skins/default/xui/it/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/it/panel_pick_info.xml @@ -3,14 +3,22 @@ <text name="title" value="Scegli Info"/> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> - <text name="pick_name" value="[nome]"/> - <text name="pick_location" value="[caricamento...]"/> - <text name="pick_desc" value="[descrizione]"/> + <text_editor name="pick_name" value="[nome]"/> + <text_editor name="pick_location" value="[caricamento...]"/> + <text_editor name="pick_desc" value="[descrizione]"/> </panel> </scroll_container> <panel name="buttons"> - <button label="Teleport" name="teleport_btn"/> - <button label="Mappa" name="show_on_map_btn"/> - <button label="Modifica" name="edit_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="Teleport" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Mappa" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="Modifica" name="edit_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_picks.xml b/indra/newview/skins/default/xui/it/panel_picks.xml index 823e0fcd03..3faf28a948 100644 --- a/indra/newview/skins/default/xui/it/panel_picks.xml +++ b/indra/newview/skins/default/xui/it/panel_picks.xml @@ -2,19 +2,28 @@ <panel label="Preferiti" name="panel_picks"> <string name="no_picks" value="Nessun luogo preferito"/> <string name="no_classifieds" value="Nessun annuncio"/> - <text name="empty_picks_panel_text"> - Nessuna foto/annuncio qui - </text> <accordion name="accordion"> <accordion_tab name="tab_picks" title="Preferiti"/> <accordion_tab name="tab_classifieds" title="Annunci pubblicitari"/> </accordion> <panel label="bottom_panel" name="edit_panel"> - <button name="new_btn" tool_tip="Crea un nuovo luogo preferito o annuncio in questo luogo"/> + <layout_stack name="edit_panel_ls"> + <layout_panel name="gear_menu_btn"> + <button name="new_btn" tool_tip="Crea un nuovo luogo preferito o annuncio in questo luogo"/> + </layout_panel> + </layout_stack> </panel> <panel name="buttons_cucks"> - <button label="Informazioni" name="info_btn" tool_tip="Mostra informazioni sul luogo preferito"/> - <button label="Teleport" name="teleport_btn" tool_tip="Teleport alla zona corrispondente"/> - <button label="Mappa" name="show_on_map_btn" tool_tip="Mostra la zona corrispondente nella mappa del Mondo"/> + <layout_stack name="buttons_cucks_ls"> + <layout_panel name="info_btn_lp"> + <button label="Informazioni" name="info_btn" tool_tip="Mostra informazioni sul luogo preferito"/> + </layout_panel> + <layout_panel name="teleport_btn_lp"> + <button label="Teleport" name="teleport_btn" tool_tip="Teleport alla zona corrispondente"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="Mappa" name="show_on_map_btn" tool_tip="Mostra la zona corrispondente nella mappa del Mondo"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_places.xml b/indra/newview/skins/default/xui/it/panel_places.xml index 9a052068f7..e33f8190eb 100644 --- a/indra/newview/skins/default/xui/it/panel_places.xml +++ b/indra/newview/skins/default/xui/it/panel_places.xml @@ -4,13 +4,45 @@ <string name="teleport_history_tab_title" value="CRONOLOGIA TELEPORT"/> <filter_editor label="Filtra i miei luoghi" name="Filter"/> <panel name="button_panel"> - <button label="Teleport" name="teleport_btn" tool_tip="Teleport alla zona selezionata"/> - <button label="Mappa" name="map_btn" tool_tip="Mostra la zona corrispondente nella mappa del Mondo"/> - <button label="Modifica" name="edit_btn" tool_tip="Modifica le informazioni del punto di riferimento"/> - <button label="▼" name="overflow_btn" tool_tip="Mostra opzioni addizionali"/> - <button label="Salva" name="save_btn"/> - <button label="Annulla" name="cancel_btn"/> - <button label="Chiudi" name="close_btn"/> - <button label="Profilo" name="profile_btn" tool_tip="Mostra il profilo del luogo"/> + <layout_stack name="bottom_bar_ls0"> + <layout_panel name="lp1"> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="teleport_btn_lp"> + <button label="Teleport" name="teleport_btn" tool_tip="Teleport alla zona selezionata"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="Mappa" name="map_btn" tool_tip="Mostra la zona corrispondente nella mappa del Mondo"/> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="lp2"> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="edit_btn_lp"> + <button label="Modifica" name="edit_btn" tool_tip="Modifica le informazioni del punto di riferimento"/> + </layout_panel> + <layout_panel name="overflow_btn_lp"> + <button label="▼" name="overflow_btn" tool_tip="Mostra ulteriori opzioni"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="profile_btn_lp"> + <button label="Profilo" name="profile_btn" tool_tip="Mostra il profilo del luogo"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_close_ls3"> + <layout_panel name="close_btn_lp"> + <button label="Chiudi" name="close_btn"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls2"> + <layout_panel name="save_btn_lp"> + <button label="Salva" name="save_btn"/> + </layout_panel> + <layout_panel name="cancel_btn_lp"> + <button label="Annulla" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </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 d28ed41698..4a1bbdf64a 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml @@ -56,27 +56,27 @@ <radio_item label="Finestre separate" name="radio" value="0"/> <radio_item label="Schede" name="radio2" value="1"/> </radio_group> - <check_box label="Traduci Chat" name="translate_chat_checkbox" /> + <check_box label="Usa la traduzione meccanica durante le chat (tecnologia Google)" name="translate_chat_checkbox"/> <text name="translate_language_text" width="110"> - Chat Lingua: + Traduci chat in: </text> <combo_box name="translate_language_combobox" width="146"> - <combo_box.item name="System Default Language" label="Default di sistema" /> - <combo_box.item name="English" label="English" /> - <combo_box.item name="Danish" label="Dansk (Danese)" /> - <combo_box.item name="German" label="Deutsch (Tedesco)" /> - <combo_box.item name="Spanish" label="Español (Spagnolo)" /> - <combo_box.item name="French" label="Français (Francese)" /> - <combo_box.item name="Italian" label="Italiano" /> - <combo_box.item name="Hungarian" label="Magyar (Ungherese)" /> - <combo_box.item name="Dutch" label="Nederlands (Olandese)" /> - <combo_box.item name="Polish" label="Polski (Polacco)" /> - <combo_box.item name="Portugese" label="Português (Portoghese)" /> - <combo_box.item name="Russian" label="Русский (Russo)" /> - <combo_box.item name="Turkish" label="Türkçe (Turco)" /> - <combo_box.item name="Ukrainian" label="Українська (Ukraino)" /> - <combo_box.item name="Chinese" label="中文 (简体) (Cinese)" /> - <combo_box.item name="Japanese" label="日本語 (Giapponese)" /> - <combo_box.item name="Korean" label="한국어 (Coreano)" /> + <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> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_general.xml b/indra/newview/skins/default/xui/it/panel_preferences_general.xml index 60c4ed5211..95c73f482d 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_general.xml @@ -32,8 +32,8 @@ Luogo di partenza: </text> <combo_box name="start_location_combo"> - <combo_box.item label="Ultimo luogo visitato" name="MyLastLocation" tool_tip="Vai automaticamente all'ultimo luogo visitato quando effettui l'accesso."/> - <combo_box.item label="Casa mia" name="MyHome" tool_tip="Vai automaticamente a casa quando effettui l'accesso"/> + <combo_box.item label="Ultimo luogo visitato" name="MyLastLocation" tool_tip="Vai automaticamente all'ultimo luogo visitato quando effettui l'accesso."/> + <combo_box.item label="Casa mia" name="MyHome" tool_tip="Vai automaticamente a casa quando effettui l'accesso"/> </combo_box> <check_box initial_value="true" label="Mostra con il login" name="show_location_checkbox"/> <text name="name_tags_textbox"> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml index 71980695b6..67b3c61a47 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml @@ -28,22 +28,16 @@ <check_box initial_value="true" label="Piccoli rilievi e scintillii" name="BumpShiny"/> <check_box initial_value="true" label="Effetti grafici base" name="BasicShaders" tool_tip="Disabilitare questa opzione può evitare che qualche scheda grafica vada in crash."/> <check_box initial_value="true" label="Effetti grafici atmosferici" name="WindLightUseAtmosShaders"/> - <check_box initial_value="true" label="Riflessi dell'acqua" name="Reflections"/> - <text name="ReflectionDetailText"> - Dettaglio dei riflessi + <text name="reflection_label"> + Riflessi nell’acqua: </text> - <radio_group name="ReflectionDetailRadio"> - <radio_item label="Terreno e alberi" name="0"/> - <radio_item label="Tutti gli aggetti statici" name="1"/> - <radio_item label="Tutti gli avatar e gli oggetti" name="2"/> - <radio_item label="Tutto" name="3"/> - </radio_group> - <text name="AvatarRenderingText"> - Rendering dell'avatar: - </text> - <check_box initial_value="true" label="Avatar bidimensionali (Impostor)" name="AvatarImpostors"/> - <check_box initial_value="true" label="Hardware Skinning" name="AvatarVertexProgram"/> - <check_box initial_value="true" label="Abiti dell'avatar" name="AvatarCloth"/> + <combo_box initial_value="true" label="Riflessi dell'acqua" name="Reflections"> + <combo_box.item label="Minimo" name="0"/> + <combo_box.item label="Terreno e alberi" name="1"/> + <combo_box.item label="Tutti gli oggetti statici" name="2"/> + <combo_box.item label="Tutti gli avatar e gli oggetti" name="3"/> + <combo_box.item label="Tutto" name="4"/> + </combo_box> <slider label="Distanza di disegno:" name="DrawDistance"/> <text name="DrawDistanceMeterText2"> m @@ -81,13 +75,12 @@ <text name="SkyMeshDetailText"> Basso </text> - <text name="LightingDetailText"> - Dettagli illuminazione: + <text name="AvatarRenderingText"> + Rendering dell'avatar: </text> - <radio_group name="LightingDetailRadio"> - <radio_item label="Solo il sole e la luna" name="SunMoon" value="0"/> - <radio_item label="Luci locali" name="LocalLights" value="1"/> - </radio_group> + <check_box initial_value="true" label="Avatar bidimensionali (Impostor)" name="AvatarImpostors"/> + <check_box initial_value="true" label="Hardware Skinning" name="AvatarVertexProgram"/> + <check_box initial_value="true" label="Abiti dell'avatar" name="AvatarCloth"/> <text name="TerrainDetailText"> Dettagli terreno: </text> @@ -95,6 +88,7 @@ <radio_item label="Basso" name="0"/> <radio_item label="Alto" name="2"/> </radio_group> + --> </panel> <button label="Applica" label_selected="Applica" name="Apply"/> <button label="Reimposta" name="Defaults"/> diff --git a/indra/newview/skins/default/xui/it/panel_profile.xml b/indra/newview/skins/default/xui/it/panel_profile.xml index 9927ecbb88..8a8d8f5846 100644 --- a/indra/newview/skins/default/xui/it/panel_profile.xml +++ b/indra/newview/skins/default/xui/it/panel_profile.xml @@ -36,17 +36,29 @@ </panel> </scroll_container> </layout_panel> + </layout_stack> + <layout_stack name="layout_verb_buttons"> <layout_panel name="profile_buttons_panel"> - <button label="Aggiungi amico" name="add_friend" tool_tip="Offri amicizia a questo residente"/> - <button label="IM" name="im" tool_tip="Apri una sessione messaggio istantaneo"/> - <button label="Chiama" name="call" tool_tip="Chiama questo residente"/> - <button label="Mappa" name="show_on_map_btn" tool_tip="Mostra il residente sulla mappa"/> - <button label="Teleport" name="teleport" tool_tip="Offri teleport"/> - <button label="▼" name="overflow_btn" tool_tip="Paga del denaro o condividi qualcosa dall'inventario con il residente"/> + <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"> + <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"/> - <button label="Modifica aspetto fisico" name="edit_appearance_btn" tool_tip="Crea/modifica il tuo aspetto: parti del corpo, abiti ecc."/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml index 753e89f2fd..3c7874e093 100644 --- a/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml +++ b/indra/newview/skins/default/xui/it/panel_side_tray_tab_caption.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="sidetray_tab_panel"> <text name="sidetray_tab_title" value="Pannello laterale"/> + <button name="undock" tool_tip="Disàncora"/> + <button name="dock" tool_tip="Àncora"/> <button name="show_help" tool_tip="Mostra Aiuto"/> </panel> diff --git a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml index 3944f8e306..1c1744d94b 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml @@ -2,12 +2,20 @@ <panel label="Cose" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <panel name="button_panel"> - <button label="Profilo" name="info_btn" tool_tip="Mostra profilo dell'oggetto"/> - <button label="Condividi" name="share_btn" tool_tip="Condividi un oggetto dell'inventario"/> - <button label="Acquisti" name="shop_btn" tool_tip="Apri pagina web di Marketplace"/> - <button label="Indossa" name="wear_btn" tool_tip="Indossa il vestiario selezionato"/> - <button label="Riproduci" name="play_btn"/> - <button label="Teleport" name="teleport_btn" tool_tip="Teleport alla zona selezionata"/> + <layout_stack name="button_panel_ls"> + <layout_panel name="info_btn_lp"> + <button label="Profilo" name="info_btn" tool_tip="Mostra profilo dell'oggetto"/> + </layout_panel> + <layout_panel name="share_btn_lp"> + <button label="Condividi" name="share_btn" tool_tip="Condividi un oggetto dell'inventario"/> + </layout_panel> + <layout_panel name="shop_btn_lp"> + <button label="Acquisti" name="shop_btn" tool_tip="Apri pagina web di Marketplace"/> + <button label="Indossa" name="wear_btn" tool_tip="Indossa il vestiario selezionato"/> + <button label="Riproduci" name="play_btn"/> + <button label="Teleport" name="teleport_btn" tool_tip="Teleport alla zona selezionata"/> + </layout_panel> + </layout_stack> </panel> </panel> </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 6f650ea55d..900a65956b 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_item_info.xml @@ -23,54 +23,53 @@ </panel.string> <text name="title" value="Profilo articolo"/> <text name="origin" value="(Inventario)"/> - <panel label="" name="item_profile"> - <text name="LabelItemNameTitle"> - Nome: - </text> - <text name="LabelItemDescTitle"> - Descrizione: - </text> - <text name="LabelCreatorTitle"> - Ideatore: - </text> - <button label="Profilo..." name="BtnCreator"/> - <text name="LabelOwnerTitle"> - Proprietario: - </text> - <button label="Profilo..." name="BtnOwner"/> - <text name="LabelAcquiredTitle"> - Acquisito: - </text> - <text name="LabelAcquiredDate"/> - <panel name="perms_inv"> - <text name="perm_modify"> - Tu puoi: + <scroll_container name="item_profile_scroll"> + <panel label="" name="item_profile"> + <text name="LabelItemNameTitle"> + Nome: </text> - <check_box label="Modifica" name="CheckOwnerModify"/> - <check_box label="Copia" name="CheckOwnerCopy"/> - <check_box label="Trasferisci" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel"> - Chiunque: + <text name="LabelItemDescTitle"> + Descrizione: </text> - <check_box label="Copia" name="CheckEveryoneCopy"/> - <text name="GroupLabel"> - Gruppo: + <text name="LabelCreatorTitle"> + Ideatore: </text> - <check_box label="Condividi" name="CheckShareWithGroup" tool_tip="Consenti a tutti i membri del gruppo selezionato di condividere i tuoi diritti di modifica di questo oggetto. Per attivare le restrizioni per ruolo devi prima effettuare la cessione."/> - <text name="NextOwnerLabel"> - Proprietario successivo: + <text name="LabelOwnerTitle"> + Proprietario: </text> - <check_box label="Modifica" name="CheckNextOwnerModify"/> - <check_box label="Copia" name="CheckNextOwnerCopy"/> - <check_box label="Trasferisci" name="CheckNextOwnerTransfer" tool_tip="Il prossimo proprietario può regalare o rivendere questo oggetto"/> + <text name="LabelAcquiredTitle"> + Acquisito: + </text> + <panel name="perms_inv"> + <text name="perm_modify"> + Tu puoi: + </text> + <check_box label="Modifica" name="CheckOwnerModify"/> + <check_box label="Copia" name="CheckOwnerCopy"/> + <check_box label="Trasferisci" name="CheckOwnerTransfer"/> + <text name="AnyoneLabel"> + Chiunque: + </text> + <check_box label="Copia" name="CheckEveryoneCopy"/> + <text name="GroupLabel"> + Gruppo: + </text> + <check_box label="Condividi" name="CheckShareWithGroup" tool_tip="Consenti a tutti i membri del gruppo selezionato di condividere i tuoi diritti di modifica di questo oggetto. Per attivare le restrizioni per ruolo devi prima effettuare la cessione."/> + <text name="NextOwnerLabel"> + Proprietario successivo: + </text> + <check_box label="Modifica" name="CheckNextOwnerModify"/> + <check_box label="Copia" name="CheckNextOwnerCopy"/> + <check_box label="Trasferisci" name="CheckNextOwnerTransfer" tool_tip="Il prossimo proprietario può regalare o rivendere questo oggetto"/> + </panel> + <check_box label="In vendita" name="CheckPurchase"/> + <combo_box name="combobox sale copy"> + <combo_box.item label="Copia" name="Copy"/> + <combo_box.item label="Originale" name="Original"/> + </combo_box> + <spinner label="Prezzo: L$" name="Edit Cost"/> </panel> - <check_box label="In vendita" name="CheckPurchase"/> - <combo_box name="combobox sale copy"> - <combo_box.item label="Copia" name="Copy"/> - <combo_box.item label="Originale" name="Original"/> - </combo_box> - <spinner label="Prezzo: L$" name="Edit Cost"/> - </panel> + </scroll_container> <panel name="button_panel"> <button label="Annulla" name="cancel_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index fa465ee9c2..9dbfc2b79c 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -783,7 +783,7 @@ <string name="xml_file"> File XML </string> - <string name="dot_raw_file"> + <string name="raw_file"> File RAW </string> <string name="compressed_image_files"> @@ -1273,6 +1273,9 @@ <string name="Right Pec"> Petto destro </string> + <string name="Invalid Attachment"> + Punto di collegamento non valido + </string> <string name="YearsMonthsOld"> Nato da [AGEYEARS] [AGEMONTHS] </string> @@ -1650,9 +1653,6 @@ <string name="ATTACH_HUD_BOTTOM_RIGHT"> HUD basso a destra </string> - <string name="Bad attachment point"> - Punto di collegamento non valido - </string> <string name="CursorPos"> Riga [LINE], Colonna [COLUMN] </string> @@ -1668,12 +1668,6 @@ <string name="BusyModeResponseDefault"> Il residente al quale hai inviato un messaggio è in modalità 'occupato', ovvero ha chiesto di non essere disturbato. Il tuo messaggio comparirà nel suo pannello IM, dove potrà essere letto in un secondo momento. </string> - <string name="NoOutfits"> - Non hai ancora vestiario da indossare. Prova [secondlife:///app/search/all Cerca]. - </string> - <string name="NoOutfitsTabsMatched"> - Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/all/[SEARCH_TERM] Cerca]. - </string> <string name="MuteByName"> (In base al nome) </string> @@ -1828,6 +1822,12 @@ Tipi conosciuti .wav, .tga, .bmp, .jpg, .jpeg, or .bvh <string name="accel-win-shift"> Shift+ </string> + <string name="Esc"> + Esc + </string> + <string name="Home"> + Home + </string> <string name="FileSaved"> File salvato </string> @@ -3444,6 +3444,9 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="IM_moderator_label"> (Moderatore) </string> + <string name="Saved_message"> + (Salvato [LONG_TIMESTAMP]) + </string> <string name="answered_call"> Risposto alla chiamata </string> @@ -3465,6 +3468,12 @@ Se il messaggio persiste, contatta [SUPPORT_SITE]. <string name="hang_up-im"> Chiusa la chiamata </string> + <string name="conference-title-incoming"> + Chiamata in conferenza con [AGENT_NAME] + </string> + <string name="no_session_message"> + (La sessione IM non esiste) + </string> <string name="only_user_message"> Sei l'unico utente di questa sessione. </string> @@ -3849,4 +3858,13 @@ Segnala abuso <string name="Chat"> Chat </string> + <string name="DeleteItems"> + Cancellare gli elementi selezionati? + </string> + <string name="DeleteItem"> + Cancellare l’elemento selezionato? + </string> + <string name="EmptyOutfitText"> + Questo vestiario non contiene alcun elemento + </string> </strings> diff --git a/indra/newview/skins/default/xui/ja/floater_customize.xml b/indra/newview/skins/default/xui/ja/floater_customize.xml new file mode 100644 index 0000000000..cc0032e1ab --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_customize.xml @@ -0,0 +1,529 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater customize" title="容姿"> + <tab_container name="customize tab container"> + <text label="身体部位" name="body_parts_placeholder"> + 身体部位 + </text> + <panel label="シェイプ" name="Shape"> + <button label="戻す" label_selected="戻す" name="Revert"/> + <button label="身体" label_selected="身体" name="Body"/> + <button label="頭" label_selected="頭" name="Head"/> + <button label="眼" label_selected="眼" name="Eyes"/> + <button label="耳" label_selected="耳" name="Ears"/> + <button label="鼻" label_selected="鼻" name="Nose"/> + <button label="口" label_selected="口" name="Mouth"/> + <button label="あご" label_selected="あご" name="Chin"/> + <button label="胴体" label_selected="胴体" name="Torso"/> + <button label="両脚" label_selected="両脚" name="Legs"/> + <radio_group name="sex radio"> + <radio_item label="女性" name="radio" value="0"/> + <radio_item label="男性" name="radio2" value="1"/> + </radio_group> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + 持ち物からあなたのアバターに 1 つドラッグして、新しいシェイプをつけます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + シェイプ: + </text> + <button label="新しいシェイプ(体型)を作成" label_selected="新しいシェイプ(体型)を作成" name="Create New"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + </panel> + <panel label="スキン" name="Skin"> + <button label="スキンの色" label_selected="スキンの色" name="Skin Color"/> + <button label="顔の細部" label_selected="顔の細部" name="Face Detail"/> + <button label="メイク" label_selected="メイク" name="Makeup"/> + <button label="身体細部" label_selected="身体細部" name="Body Detail"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + 持ち物からあなたのアバターに 1 つドラッグして、新しいスキンをつけます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + スキン: + </text> + <texture_picker label="頭部のタトゥー" name="Head Tattoos" tool_tip="写真をクリックして選択"/> + <texture_picker label="上半身のタトゥー" name="Upper Tattoos" tool_tip="写真をクリックして選択"/> + <texture_picker label="下部のタトゥー" name="Lower Tattoos" tool_tip="写真をクリックして選択"/> + <button label="新しいスキンを作成" label_selected="新しいスキンを作成" name="Create New"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="髪" name="Hair"> + <button label="色" label_selected="色" name="Color"/> + <button label="スタイル" label_selected="スタイル" name="Style"/> + <button label="眉毛" label_selected="眉毛" name="Eyebrows"/> + <button label="顔" label_selected="顔" name="Facial"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + 持ち物からあなたのアバターに 1 つドラッグして、新しい髪をつけます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 髪型: + </text> + <texture_picker label="テクスチャ" name="Texture" tool_tip="写真をクリックして選択"/> + <button label="新しい髪を作成" label_selected="新しい髪を作成" name="Create New"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="眼" name="Eyes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しい目をつけます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 目: + </text> + <texture_picker label="虹彩" name="Iris" tool_tip="写真をクリックして選択"/> + <button label="新しい眼を作成" label_selected="新しい眼を作成" name="Create New"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <text label="服" name="clothes_placeholder"> + 衣類 + </text> + <panel label="シャツ" name="Shirt"> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="新しいシャツを作成" label_selected="新しいシャツを作成" name="Create New"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + 持ち物からあなたのアバターに 1 つドラッグして、新しいシャツを着ます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + シャツ: + </text> + </panel> + <panel label="パンツ" name="Pants"> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="新しいパンツを作成" label_selected="新しいパンツを作成" name="Create New"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しいパンツを履きます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + パンツ: + </text> + </panel> + <panel label="靴" name="Shoes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しい靴を履きます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しい靴を作成" label_selected="新しい靴を作成" name="Create New"/> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 靴: + </text> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="靴下" name="Socks"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しい靴下を履きます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しい靴下を作成" label_selected="新しい靴下を作成" name="Create New"/> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 靴下: + </text> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="上着" name="Jacket"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + 持ち物からあなたのアバターに 1 つドラッグして、新しいジャケットを着ます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しい上着を作成" label_selected="新しい上着を作成" name="Create New"/> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 上着: + </text> + <texture_picker label="上半身の生地" name="Upper Fabric" tool_tip="写真をクリックして選択"/> + <texture_picker label="下層生地" name="Lower Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="手袋" name="Gloves"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しい手袋をつけます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しい手袋を作成" label_selected="新しい手袋を作成" name="Create New"/> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 手袋: + </text> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="下着シャツ" name="Undershirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + 持ち物からあなたのアバターに1つドラッグして、新しい下着(上)を着ます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しい下着シャツを作成" label_selected="新しい下着シャツを作成" name="Create New"/> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 下着シャツ: + </text> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="下着パンツ" name="Underpants"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しい下着(下)を履きます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しいパンツを作成" label_selected="新しいパンツを作成" name="Create New"/> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + 下着パンツ: + </text> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="スカート" name="Skirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正できません。 + </text> + <text name="title_loading"> + [DESC]: ロード中... + </text> + <text name="title_not_worn"> + [DESC]: 未装着。 + </text> + <text name="path"> + [PATH] に所在 + </text> + <text name="not worn instructions"> + 持ち物からあなたのアバターに 1 つドラッグして、新しいスカートを履きます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="スカートを作成" label_selected="スカートを作成" name="Create New"/> + <text name="no modify instructions"> + あなたはこの服の修正を許されていません。 + </text> + <text name="Item Action Label"> + スカート: + </text> + <texture_picker label="生地" name="Fabric" tool_tip="写真をクリックして選択"/> + <color_swatch label="色/明暗" name="Color/Tint" tool_tip="クリックしてカラーピッカーを開きます"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="戻す" label_selected="戻す" name="Revert"/> + </panel> + <panel label="タトゥ" name="Tattoo"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正不可 + </text> + <text name="title_loading"> + [DESC]: ローディング... + </text> + <text name="title_not_worn"> + [DESC]: 未着用 + </text> + <text name="path"> + 参照 [PATH] + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しいタトゥをつけます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しいタトゥを作成" label_selected="新しいタトゥを作成" name="Create New"/> + <text name="no modify instructions"> + この着用物を修正する権限がありません。 + </text> + <text name="Item Action Label"> + タトゥ: + </text> + <texture_picker label="頭部のタトゥー" name="Head Tattoo" tool_tip="クリックして写真を選択します"/> + <texture_picker label="上部のタトゥー" name="Upper Tattoo" tool_tip="クリックして写真を選択します"/> + <texture_picker label="下部のタトゥー" name="Lower Tattoo" tool_tip="クリックして写真を選択します"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="元に戻す" label_selected="元に戻す" name="Revert"/> + </panel> + <panel label="アルファ" name="Alpha"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: 修正不可 + </text> + <text name="title_loading"> + [DESC]: ローディング... + </text> + <text name="title_not_worn"> + [DESC]: 未着用 + </text> + <text name="path"> + 参照 [PATH] + </text> + <text name="not worn instructions"> + あなたの持ち物からアバターにドラッグして、新しいアルファマスクをつけます。 代わりに、はじめから新しく作成して着用することもできます。 + </text> + <button label="新しいアルファを作成" label_selected="新しいアルファを作成" name="Create New"/> + <text name="no modify instructions"> + この着用物を修正する権限がありません。 + </text> + <text name="Item Action Label"> + アルファ: + </text> + <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="クリックして写真を選択します"/> + <button label="取り外す" label_selected="取り外す" name="Take Off"/> + <button label="保存" label_selected="保存" name="Save"/> + <button label="別名で保存..." label_selected="別名で保存..." name="Save As"/> + <button label="元に戻す" label_selected="元に戻す" name="Revert"/> + </panel> + </tab_container> + <button label="スクリプト情報" label_selected="スクリプト情報" name="script_info" tool_tip="あなたのアバターに付いているスクリプトを表示します"/> + <button label="アウトフィット作成" label_selected="アウトフィット作成" name="make_outfit_btn"/> + <button label="キャンセル" label_selected="キャンセル" name="Cancel"/> + <button label="OK" label_selected="OK" name="Ok"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_event.xml b/indra/newview/skins/default/xui/ja/floater_event.xml index 671f9077d9..9e99c4a931 100644 --- a/indra/newview/skins/default/xui/ja/floater_event.xml +++ b/indra/newview/skins/default/xui/ja/floater_event.xml @@ -1,69 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="イベント" name="Event" title="イベント詳細"> - <floater.string name="none"> - なし +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + ローディング... </floater.string> - <floater.string name="notify"> - 知らせる - </floater.string> - <floater.string name="dont_notify"> - 知らせない - </floater.string> - <floater.string name="moderate"> - Moderate - </floater.string> - <floater.string name="adult"> - Adult - </floater.string> - <floater.string name="general"> - General - </floater.string> - <floater.string name="unknown"> - 不明 - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Nameless Event...of Doom! De doom! Doom doom. - </text> - <text name="event_category"> - (カテゴリなし) - </text> - <text name="event_runby_label"> - 主催者: - </text> - <text initial_value="(取得中)" name="event_runby"/> - <text name="event_date_label"> - 日付: - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - 期間: - </text> - <text name="event_duration"> - 1 時間 - </text> - <text name="event_covercharge_label"> - カバーチャージ: - </text> - <text name="event_cover"> - 無料 - </text> - <text name="event_location_label"> - 場所: - </text> - <text name="event_location" value="SampleParcel, Name Long (145, 228, 26)"/> - <text name="rating_label" value="レーティング区分:"/> - <text name="rating_value" value="不明"/> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="イベント作成"/> - <button name="god_delete_event_btn" tool_tip="イベント削除"/> - <button label="知らせる" name="notify_btn"/> - <button label="テレポート" name="teleport_btn"/> - <button label="地図" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/ja/floater_map.xml b/indra/newview/skins/default/xui/ja/floater_map.xml index 0676e86703..82b49df221 100644 --- a/indra/newview/skins/default/xui/ja/floater_map.xml +++ b/indra/newview/skins/default/xui/ja/floater_map.xml @@ -25,7 +25,7 @@ 北西 </floater.string> <floater.string name="ToolTipMsg"> - [AGENT][REGION] (ダブルクリックで地図を開きます) + [REGION](ダブルクリックで地図を開く。Shift‐ドラッグで水平・垂直移動) </floater.string> <floater.string name="mini_map_caption"> ミニマップ diff --git a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml b/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml index a3cc105048..a29c6a0630 100644 --- a/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/ja/floater_nearby_chat.xml @@ -1,2 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="nearby_chat" title="近くのチャット"/> +<floater name="nearby_chat" title="近くのチャット"> + <check_box label="チャットを翻訳(Google翻訳)" name="translate_chat_checkbox"/> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml b/indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml new file mode 100644 index 0000000000..70555e6ded --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_outfit_save_as.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container" title="アウトフィットを保存する"> + <button label="保存" label_selected="保存" name="Save"/> + <button label="キャンセル" label_selected="キャンセル" name="Cancel"/> + <text name="Save item as:"> + 着用しているものを +新しいアウトフィットに保存: + </text> + <line_editor name="name ed"> + [DESC] (新) + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml index d095dee974..bbd78fb818 100644 --- a/indra/newview/skins/default/xui/ja/floater_tools.xml +++ b/indra/newview/skins/default/xui/ja/floater_tools.xml @@ -182,10 +182,10 @@ <text name="Group:"> グループ: </text> - <button label="設定..." label_selected="設定..." name="button set group" tool_tip="このオブジェクト権限を共有するグループを選択します"/> <name_box initial_value="ローディング..." name="Group Name Proxy"/> - <button label="譲渡" label_selected="譲渡" name="button deed" tool_tip="このアイテムを譲渡すると「次の所有者」の権限が適用されます。 グループ共有オブジェクトは、グループのオフィサーが譲渡できます"/> + <button label="設定..." label_selected="設定..." 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> @@ -437,7 +437,8 @@ <combo_box.item label="吸い込み" name="suction"/> <combo_box.item label="織目" name="weave"/> </combo_box> - <text name="tex scale"> + <check_box initial_value="false" label="平面を揃える" name="checkbox planar align" tool_tip="選択面全てのテクスチャを、最後に選択された面に揃えます。 平面テクスチャのマッピングが必要です。"/> + <text name="rpt"> 反復 / 面 </text> <spinner label="水平(U)" name="TexScaleU"/> diff --git a/indra/newview/skins/default/xui/ja/floater_wearable_save_as.xml b/indra/newview/skins/default/xui/ja/floater_wearable_save_as.xml new file mode 100644 index 0000000000..de8b590a80 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/floater_wearable_save_as.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="modal container" title=" "> + <button label="保存" label_selected="保存" name="Save"/> + <button label="取り消し" label_selected="取り消し" name="Cancel"/> + <text name="Save item as:"> + アイテムを別名で持ち物に保存: + </text> + <line_editor name="name ed"> + New [DESC] + </line_editor> +</floater> diff --git a/indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml b/indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml new file mode 100644 index 0000000000..982a03c6a8 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/menu_add_wearable_gear.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<menu name="Add Wearable Gear Menu"> + <menu_item_check label="新しい順に並べ替え" name="sort_by_most_recent"/> + <menu_item_check label="名前で並べ替え" name="sort_by_name"/> + <menu_item_check label="タイプによる並べ替え" name="sort_by_type"/> +</menu> diff --git a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml index 6b1319e584..5d95949189 100644 --- a/indra/newview/skins/default/xui/ja/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_attachment_self.xml @@ -3,6 +3,7 @@ <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"/> <menu_item_call label="立ち上がる" name="Stand Up"/> <menu_item_call label="アウトフィットを変更" name="Change Outfit"/> <menu_item_call label="アウトフィットの編集" name="Edit Outfit"/> diff --git a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml index bca90cf5e4..fc9c8caf51 100644 --- a/indra/newview/skins/default/xui/ja/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/ja/menu_avatar_self.xml @@ -1,7 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Self Pie"> + <menu_item_call label="座る" name="Sit Down Here"/> <menu_item_call label="立ち上がる" name="Stand Up"/> - <context_menu label="脱ぐ" name="Take Off >"> + <context_menu label="取り外す" name="Take Off >"> <context_menu label="衣類" name="Clothes >"> <menu_item_call label="シャツ" name="Shirt"/> <menu_item_call label="パンツ" name="Pants"/> 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 506614316e..2edade70bf 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 @@ -9,6 +9,7 @@ <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="ブロック" name="block"/> <menu_item_call label="ズームイン" name="zoom_in"/> diff --git a/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml index ee054673c5..90b3efd144 100644 --- a/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/ja/menu_inspect_self_gear.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <menu name="Gear Menu"> + <menu_item_call label="座る" name="sit_down_here"/> <menu_item_call label="立ち上がる" name="stand_up"/> <menu_item_call label="アウトフィットを変更" name="change_outfit"/> <menu_item_call label="プロフィール" name="my_profile"/> diff --git a/indra/newview/skins/default/xui/ja/menu_mini_map.xml b/indra/newview/skins/default/xui/ja/menu_mini_map.xml index 0a89c5e63a..12ea6e2299 100644 --- a/indra/newview/skins/default/xui/ja/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/ja/menu_mini_map.xml @@ -4,6 +4,7 @@ <menu_item_call label="ズーム(中)" name="Zoom Medium"/> <menu_item_call label="ズーム(遠)" name="Zoom Far"/> <menu_item_check label="地図を回転" name="Rotate Map"/> + <menu_item_check label="中央へ自動移動" name="Auto Center"/> <menu_item_call label="追跡をやめる" name="Stop Tracking"/> <menu_item_call label="世界地図" name="World Map"/> </menu> diff --git a/indra/newview/skins/default/xui/ja/menu_object.xml b/indra/newview/skins/default/xui/ja/menu_object.xml index 6724f2d109..c11dc9bb3e 100644 --- a/indra/newview/skins/default/xui/ja/menu_object.xml +++ b/indra/newview/skins/default/xui/ja/menu_object.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Object Pie"> <menu_item_call label="触る" name="Object Touch"> - <on_enable parameter="触る" name="EnableTouch"/> + <menu_item_call.on_enable name="EnableTouch" parameter="触る"/> </menu_item_call> <menu_item_call label="編集" name="Edit..."/> <menu_item_call label="制作" name="Build"/> @@ -12,16 +12,16 @@ <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="取り付ける" name="Object Attach"/> <context_menu label="HUD を取り付ける" name="Object Attach HUD"/> </context_menu> - <context_menu label="取り除く" name="Remove"> + <context_menu label="取り外す" name="Remove"> <menu_item_call label="嫌がらせの報告" name="Report Abuse..."/> <menu_item_call label="ブロック" name="Object Mute"/> <menu_item_call label="返却" name="Return..."/> <menu_item_call label="削除" name="Delete"/> </context_menu> - <menu_item_call label="買う" name="Pie Object Bye"/> <menu_item_call label="取る" name="Pie Object Take"/> <menu_item_call label="コピーを取る" name="Take Copy"/> <menu_item_call label="支払う" name="Pay..."/> diff --git a/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml index 5eaad31898..76340e4d76 100644 --- a/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/ja/menu_people_friends_view_sort.xml @@ -3,5 +3,6 @@ <menu_item_check label="名前で並べ替え" name="sort_name"/> <menu_item_check label="オンライン状態で並べ替え" name="sort_status"/> <menu_item_check label="人のアイコン表示" name="view_icons"/> + <menu_item_check label="与えられた権限を表示" name="view_permissions"/> <menu_item_call label="ブロックされた住人とオブジェクトを表示" name="show_blocked_list"/> </menu> diff --git a/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml index 238bfc4af9..3f20e5d3ab 100644 --- a/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml +++ b/indra/newview/skins/default/xui/ja/menu_people_nearby_multiselect.xml @@ -6,4 +6,5 @@ <menu_item_call label="コール" name="Call"/> <menu_item_call label="共有" name="Share"/> <menu_item_call label="支払う" name="Pay"/> + <menu_item_call label="テレポートを送る" name="teleport"/> </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 f6476857d2..85aaf17256 100644 --- a/indra/newview/skins/default/xui/ja/menu_viewer.xml +++ b/indra/newview/skins/default/xui/ja/menu_viewer.xml @@ -94,7 +94,6 @@ <menu_item_call label="スクリプトを実行停止にする" name="Set Scripts to Not Running"/> </menu> <menu label="オプション" name="Options"> - <menu_item_call label="デフォルトのアップロード権限を設定" name="perm prefs"/> <menu_item_check label="権限の詳細を表示する" name="DebugPermissions"/> <menu_item_check label="私のオブジェクトだけを選択する" name="Select Only My Objects"/> <menu_item_check label="動的オブジェクトだけを選択する" name="Select Only Movable Objects"/> @@ -121,7 +120,6 @@ <menu_item_call label="[APP_NAME] について" name="About Second Life"/> </menu> <menu label="アドバンス" name="Advanced"> - <menu_item_check label="アドバンスメニューを表示する" name="Show Advanced Menu"/> <menu_item_call label="自分のアニメーションを停止する" name="Stop Animating My Avatar"/> <menu_item_call label="テクスチャのリベークをする" name="Rebake Texture"/> <menu_item_call label="UI のサイズをデフォルトに設定する" name="Set UI Size to Default"/> @@ -169,7 +167,6 @@ <menu_item_check label="FRInfo のテスト" name="Test FRInfo"/> <menu_item_check label="フレキシブルオブジェクト" name="Flexible Objects"/> </menu> - <menu_item_check label="マルチスレッド処理" name="Run Multiple Threads"/> <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"/> @@ -178,7 +175,6 @@ <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_check label="常に走る" name="Always Run"/> <menu_item_check label="飛行する" name="Fly"/> <menu_item_call label="ウィンドウを閉じる" name="Close Window"/> @@ -198,6 +194,7 @@ <menu_item_call label="ズームイン" name="Zoom In"/> <menu_item_call label="ズーム(デフォルト)" name="Zoom Default"/> <menu_item_call label="ズームアウト" name="Zoom Out"/> + <menu_item_check label="アドバンスメニューを表示する" name="Show Advanced Menu"/> </menu> <menu_item_call label="デバッグ設定を表示する" name="Debug Settings"/> <menu_item_check label="開発メニューを表示する" name="Debug Mode"/> @@ -263,16 +260,19 @@ <menu_item_check label="ワイヤーフレーム" name="Wireframe"/> <menu_item_check label="オブジェクト間オクルージョン" name="Object-Object Occlusion"/> <menu_item_check label="フレームバッファオブジェクト" name="Framebuffer Objects"/> - <menu_item_check label="遅延レンダリング" name="Deferred Rendering"/> - <menu_item_check label="グローバルイルミネーション" name="Global Illumination"/> + <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="Fast Alpha"/> + <menu_item_check label="自動アルファマスク(遅延)" name="Automatic Alpha Masks (deferred)"/> + <menu_item_check label="自動アルファマスク(遅延なし)" name="Automatic Alpha Masks (non-deferred)"/> <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="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"/> @@ -309,7 +309,8 @@ <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="ダブルクリックした場所に自動操作で移動する" name="Double-ClickAuto-Pilot"/> + <menu_item_check label="ダブルクリックで自動追跡を行う" name="Double-Click Auto-Pilot"/> + <menu_item_check label="ダブルクリックでテレポート" name="DoubleClick Teleport"/> <menu_item_check label="SelectMgr のデバッグ" name="Debug SelectMgr"/> <menu_item_check label="ダブルクリック" name="Debug Clicks"/> <menu_item_check label="デバッグ表示" name="Debug Views"/> diff --git a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml index 273fbd856c..c402fa0b6d 100644 --- a/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/ja/menu_wearable_list_item.xml @@ -5,10 +5,10 @@ <menu_item_call label="追加" name="wear_add"/> <menu_item_call label="取り外す" name="take_off_or_detach"/> <menu_item_call label="取り外す" name="detach"/> - <context_menu label="装着" name="wearable_attach_to"/> - <context_menu label="HUDに装着" name="wearable_attach_to_hud"/> + <context_menu label="装着:" name="wearable_attach_to"/> + <context_menu label="HUD に装着" 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"/> + <menu_item_call label="アイテムのプロフィール" name="object_profile"/> <menu_item_call label="オリジナルを表示" name="show_original"/> </context_menu> diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml index f79b59ee05..7a97538117 100644 --- a/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml +++ b/indra/newview/skins/default/xui/ja/menu_wearing_gear.xml @@ -1,4 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <menu name="Gear Wearing"> <menu_item_call label="アウトフットの編集" name="edit"/> + <menu_item_call label="取り外す" name="takeoff"/> </menu> diff --git a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml index 1336df94b0..9effed1f42 100644 --- a/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/ja/menu_wearing_tab.xml @@ -1,4 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <context_menu name="Wearing"> + <menu_item_call label="取り外す" name="take_off"/> + <menu_item_call label="取り外す" name="detach"/> <menu_item_call label="アウトフットの編集" name="edit"/> </context_menu> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 709797cb58..93d6644902 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -1861,6 +1861,10 @@ Adult 専用リージョンに入るには、住人のアカウントが年齢 終了しようとしています。続けますか? <usetemplate ignoretext="終了時の確認" name="okcancelignore" notext="終了しない" yestext="終了"/> </notification> + <notification name="DeleteItems"> + [QUESTION] + <usetemplate ignoretext="アイテムを削除する前の確認" name="okcancelignore" notext="取り消し" yestext="OK"/> + </notification> <notification name="HelpReportAbuseEmailLL"> このツールを利用して [http://secondlife.com/corporate/tos.php 利用規約] や [http://jp.secondlife.com/corporate/cs.php コミュニティスタンダード] の違反を報告してください。 @@ -2231,8 +2235,7 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ [NAME] [DATE] <form name="form"> - <button name="Teleport" text="テレポート"/> - <button name="Description" text="説明"/> + <button name="Details" text="説明"/> <button name="Cancel" text="取り消し"/> </form> </notification> @@ -2799,9 +2802,13 @@ M キーを押して変更します。 ( [EXISTENCE] 秒) アバター「 NAME 」が完全に読み込まれました。 </notification> - <notification name="AvatarRezSelfBakeNotification"> + <notification name="AvatarRezSelfBakedTextureUploadNotification"> + ( 作成後[EXISTENCE]秒経過) +'[BODYREGION]'の[RESOLUTION]のベークドテクスチャは[TIME]秒後にアップロードされました。 + </notification> + <notification name="AvatarRezSelfBakedTextureUpdateNotification"> ( 作成後[EXISTENCE]秒経過) -'[BODYREGION]' の[RESOLUTION]のベークドテクスチャは[TIME]秒後に[ACTION]されました。 +'[BODYREGION]'の[RESOLUTION]のベークドテクスチャは[TIME]秒後にローカルに更新されました。 </notification> <notification name="ConfirmLeaveCall"> このコールから抜けますか? diff --git a/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml index 03eaf33d92..25864ec629 100644 --- a/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/ja/panel_avatar_list_item.xml @@ -23,5 +23,9 @@ </string> <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="このフレンドは地図上であなたの位置を表示できます"/> + <icon name="permission_online_icon" tool_tip="このフレンドはあなたがオンラインにいることを確認できます"/> <button name="profile_btn" tool_tip="プロフィールの表示"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml b/indra/newview/skins/default/xui/ja/panel_bottomtray.xml index 04b4893026..3529abbf36 100644 --- a/indra/newview/skins/default/xui/ja/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/ja/panel_bottomtray.xml @@ -1,5 +1,6 @@ <?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"> @@ -12,28 +13,25 @@ <gesture_combo_list label="ジェスチャー" name="Gesture" tool_tip="ジェスチャーの表示・非表示"/> </layout_panel> <layout_panel name="movement_panel"> - <button label="移動" name="movement_btn" tool_tip="移動コントロールの表示・非表示"/> + <bottomtray_button label="移動" name="movement_btn" tool_tip="移動コントロールの表示・非表示"/> </layout_panel> <layout_panel name="cam_panel"> - <button label="視界" name="camera_btn" tool_tip="カメラコントロールの表示・非表示"/> + <bottomtray_button label="視界" name="camera_btn" tool_tip="カメラコントロールの表示・非表示"/> </layout_panel> <layout_panel name="snapshot_panel"> - <button label="" name="snapshots" tool_tip="スナップショットを撮ります"/> - </layout_panel> - <layout_panel name="sidebar_btn_panel"> - <button label="サイドバー" name="sidebar_btn" tool_tip="サイドバーの表示・非表示"/> + <bottomtray_button label="" name="snapshots" tool_tip="スナップショットを撮ります"/> </layout_panel> <layout_panel name="build_btn_panel"> - <button label="制作" name="build_btn" tool_tip="制作ツールの表示・非表示"/> + <bottomtray_button label="制作" name="build_btn" tool_tip="制作ツールの表示・非表示"/> </layout_panel> <layout_panel name="search_btn_panel"> - <button label="検索" name="search_btn" tool_tip="検索の表示・非表示"/> + <bottomtray_button label="検索" name="search_btn" tool_tip="検索の表示・非表示"/> </layout_panel> <layout_panel name="world_map_btn_panel"> - <button label="地図" name="world_map_btn" tool_tip="世界地図の表示・非表示"/> + <bottomtray_button label="地図" name="world_map_btn" tool_tip="世界地図の表示・非表示"/> </layout_panel> <layout_panel name="mini_map_btn_panel"> - <button label="ミニマップ" name="mini_map_btn" tool_tip="ミニマップの表示・非表示"/> + <bottomtray_button label="ミニマップ" name="mini_map_btn" tool_tip="ミニマップの表示・非表示"/> </layout_panel> <layout_panel name="im_well_panel"> <chiclet_im_well name="im_well"> diff --git a/indra/newview/skins/default/xui/ja/panel_classified_info.xml b/indra/newview/skins/default/xui/ja/panel_classified_info.xml index 0aa0e8a8a9..57a255afde 100644 --- a/indra/newview/skins/default/xui/ja/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/ja/panel_classified_info.xml @@ -52,8 +52,16 @@ </panel> </scroll_container> <panel name="buttons"> - <button label="テレポート" name="teleport_btn"/> - <button label="地図" name="show_on_map_btn"/> - <button label="編集" name="edit_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="テレポート" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="地図" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="編集" name="edit_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml index 5e90076a74..b556b68e02 100644 --- a/indra/newview/skins/default/xui/ja/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/ja/panel_edit_classified.xml @@ -36,13 +36,19 @@ <icons_combo_box.item label="「Moderate」コンテンツ" name="mature_ci" value="Mature"/> <icons_combo_box.item label="「General」コンテンツ" name="pg_ci" value="PG"/> </icons_combo_box> + <check_box label="毎週自動更新" name="auto_renew"/> <text name="price_for_listing_label" value="掲載価格:"/> <spinner label="L$" name="price_for_listing" tool_tip="掲載価格" value="50"/> - <check_box label="毎週自動更新" name="auto_renew"/> </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> - <button label="[LABEL]" name="save_changes_btn"/> - <button label="キャンセル" name="cancel_btn"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="[LABEL]" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="取り消し" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_edit_pick.xml b/indra/newview/skins/default/xui/ja/panel_edit_pick.xml index e58fa979d7..4fb031b677 100644 --- a/indra/newview/skins/default/xui/ja/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/ja/panel_edit_pick.xml @@ -25,7 +25,13 @@ </panel> </scroll_container> <panel label="bottom_panel" name="bottom_panel"> - <button label="ピックを保存" name="save_changes_btn"/> - <button label="キャンセル" name="cancel_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="ピックを保存" name="save_changes_btn"/> + </layout_panel> + <layout_panel name="layout_panel1"> + <button label="取り消し" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml index cd81565acb..2aba4edc0d 100644 --- a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml @@ -53,7 +53,13 @@ </panel> </scroll_container> <panel name="profile_me_buttons_panel"> - <button label="変更を保存" name="save_btn"/> - <button label="キャンセル" name="cancel_btn"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_changes_btn_lp"> + <button label="変更を保存" name="save_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="取り消し" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml b/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml index 426f738b33..6cbed88ebc 100644 --- a/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/ja/panel_edit_wearable.xml @@ -102,7 +102,13 @@ <icon name="female_icon" tool_tip="女性"/> </panel> <panel name="button_panel"> - <button label="別名で保存" name="save_as_button"/> - <button label="変更を元に戻す" name="revert_button"/> + <layout_stack name="button_panel_ls"> + <layout_panel name="save_as_btn_lp"> + <button label="別名で保存" name="save_as_button"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="変更を元に戻す" name="revert_button"/> + </layout_panel> + </layout_stack> </panel> </panel> 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 4166108472..85406702bc 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 @@ -13,7 +13,7 @@ 無料 </panel.string> <panel name="group_info_top"> - <text name="group_name" value="(ローディング...)"/> + <text_editor name="group_name" value="(ローディング...)"/> <line_editor label="新しいグループの名前を入力してください" name="group_name_editor"/> </panel> <layout_stack name="layout"> @@ -25,9 +25,15 @@ <accordion_tab name="group_land_tab" title="土地・資産"/> </accordion> </layout_panel> - <layout_panel name="button_row"> + </layout_stack> + <layout_stack name="button_row_ls"> + <layout_panel name="btn_chat_lp"> <button label="チャット" name="btn_chat"/> + </layout_panel> + <layout_panel name="call_btn_lp"> <button label="グループコール" name="btn_call" tool_tip="このグループにコールする"/> + </layout_panel> + <layout_panel name="btn_apply_lp"> <button label="保存" label_selected="保存" name="btn_apply"/> <button label="グループを作成" name="btn_create" tool_tip="新しいグループを作成"/> </layout_panel> diff --git a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml index 4b3a7f880b..016dc97ab6 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml @@ -48,7 +48,7 @@ あなたの貢献: </text> <text name="your_contribution_units"> - m² + 平方メートル </text> <text name="your_contribution_max_value"> (最大 [AMOUNT]) diff --git a/indra/newview/skins/default/xui/ja/panel_group_roles.xml b/indra/newview/skins/default/xui/ja/panel_group_roles.xml index be203b0761..d40dedf566 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_roles.xml @@ -20,7 +20,7 @@ Ctrl キーを押しながらメンバー名をクリックすると <name_list name="member_list"> <name_list.columns label="メンバー" name="name"/> <name_list.columns label="寄付" name="donated"/> - <name_list.columns label="ログイン" name="online"/> + <name_list.columns label="ステータス" name="online"/> </name_list> <button label="招待" name="member_invite"/> <button label="追放" name="member_eject"/> @@ -47,7 +47,7 @@ Ctrl キーを押しながらメンバー名をクリックすると <filter_editor label="役割を選別" name="filter_input"/> <scroll_list name="role_list"> <scroll_list.columns label="役割" name="name"/> - <scroll_list.columns label="タイトル" name="title"/> + <scroll_list.columns label="肩書き" name="title"/> <scroll_list.columns label="#" name="members"/> </scroll_list> <button label="新しい役割" name="role_create"/> diff --git a/indra/newview/skins/default/xui/ja/panel_landmarks.xml b/indra/newview/skins/default/xui/ja/panel_landmarks.xml index 993c52b561..e3b716c35b 100644 --- a/indra/newview/skins/default/xui/ja/panel_landmarks.xml +++ b/indra/newview/skins/default/xui/ja/panel_landmarks.xml @@ -7,8 +7,16 @@ <accordion_tab name="tab_library" title="ライブラリ"/> </accordion> <panel name="bottom_panel"> - <button name="options_gear_btn" tool_tip="その他のオプションを表示します"/> - <button name="add_btn" tool_tip="新しいランドマークを追加します"/> - <dnd_button name="trash_btn" tool_tip="選択したランドマークを削除します"/> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <button name="options_gear_btn" tool_tip="オプションを表示します"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="新しいランドマークを追加"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="選択したランドマークを削除します"/> + </layout_panel> + </layout_stack> </panel> </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 index 17461ef771..94c5a6a4b7 100644 --- a/indra/newview/skins/default/xui/ja/panel_my_profile.xml +++ b/indra/newview/skins/default/xui/ja/panel_my_profile.xml @@ -42,9 +42,8 @@ </panel> </scroll_container> </layout_panel> - <layout_panel name="profile_me_buttons_panel"> - <button label="プロフィールの編集" name="edit_profile_btn" tool_tip="個人的な情報を編集します"/> - <button label="容姿の編集" name="edit_appearance_btn" tool_tip="見た目を作成・編集します: (身体的データ、衣類など)"/> - </layout_panel> </layout_stack> + <panel name="profile_me_buttons_panel"> + <button label="プロフィールの編集" name="edit_profile_btn" tool_tip="個人的な情報を編集します"/> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_notes.xml b/indra/newview/skins/default/xui/ja/panel_notes.xml index cbeb5a7f97..aa6d823c59 100644 --- a/indra/newview/skins/default/xui/ja/panel_notes.xml +++ b/indra/newview/skins/default/xui/ja/panel_notes.xml @@ -13,11 +13,23 @@ </scroll_container> </layout_panel> <layout_panel name="notes_buttons_panel"> - <button label="フレンド登録" name="add_friend" tool_tip="フレンド登録を申し出ます"/> - <button label="IM" name="im" tool_tip="インスタントメッセージを開きます"/> - <button label="コール" name="call" tool_tip="この住人にコールします"/> - <button label="地図" name="show_on_map_btn" tool_tip="住人を地図上で表示します"/> - <button label="テレポート" name="teleport" tool_tip="テレポートを送ります"/> + <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_outfit_edit.xml b/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml index 8d1da51be5..6897660214 100644 --- a/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/ja/panel_outfit_edit.xml @@ -45,7 +45,13 @@ <button name="shop_btn_2" tool_tip="「SL マーケットプレイス」ページをご覧ください。また、いま着用しているアイテムを選択してここをクリックすると、それに似たアイテムが表示されます。"/> </panel> <panel name="save_revert_button_bar"> - <button label="保存" name="save_btn"/> - <button label="変更を元に戻す" name="revert_btn" tool_tip="前回保存された状態に戻す"/> + <layout_stack name="button_bar_ls"> + <layout_panel name="save_btn_lp"> + <button label="保存" name="save_btn"/> + </layout_panel> + <layout_panel name="revert_btn_lp"> + <button label="変更を元に戻す" name="revert_btn" tool_tip="前回保存された状態に戻す"/> + </layout_panel> + </layout_stack> </panel> </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 c649113000..2a0647653d 100644 --- a/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/ja/panel_outfits_inventory.xml @@ -11,7 +11,13 @@ <panel label="着用中" name="cof_tab"/> </tab_container> <panel name="bottom_panel"> - <button label="別名で保存" name="save_btn"/> - <button label="装着" name="wear_btn" tool_tip="選択したアウトフィットを着用します"/> + <layout_stack name="bottom_panel_ls"> + <layout_panel name="save_btn_lp"> + <button label="別名で保存" name="save_btn"/> + </layout_panel> + <layout_panel name="wear_btn_lp"> + <button label="装着" name="wear_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_people.xml b/indra/newview/skins/default/xui/ja/panel_people.xml index 68af19910a..f2ccddc9de 100644 --- a/indra/newview/skins/default/xui/ja/panel_people.xml +++ b/indra/newview/skins/default/xui/ja/panel_people.xml @@ -32,9 +32,17 @@ <accordion_tab name="tab_all" title="全員"/> </accordion> <panel label="bottom_panel" name="bottom_panel"> - <button name="friends_viewsort_btn" tool_tip="オプション"/> - <button name="add_btn" tool_tip="フレンド登録を申し出ます"/> - <button name="del_btn" tool_tip="選択した人をフレンドリストから削除します"/> + <layout_stack name="bottom_panel"> + <layout_panel name="options_gear_btn_panel"> + <button name="friends_viewsort_btn" tool_tip="オプションを表示します"/> + </layout_panel> + <layout_panel name="add_btn_panel"> + <button name="add_btn" tool_tip="フレンド登録を申し出る"/> + </layout_panel> + <layout_panel name="trash_btn_panel"> + <dnd_button name="trash_btn" tool_tip="選択した人をフレンドリストから削除"/> + </layout_panel> + </layout_stack> </panel> </panel> <panel label="マイ グループ" name="groups_panel"> @@ -52,13 +60,33 @@ </panel> </tab_container> <panel name="button_bar"> - <button label="プロフィール" name="view_profile_btn" tool_tip="写真、グループ、その他住人情報を表示します"/> - <button label="IM" name="im_btn" tool_tip="インスタントメッセージを開きます"/> - <button label="コール" name="call_btn" tool_tip="この住人にコールします"/> - <button label="共有" name="share_btn" tool_tip="持ち物アイテムを共有"/> - <button label="テレポート" name="teleport_btn" tool_tip="テレポートを送ります"/> - <button label="グループ情報" name="group_info_btn" tool_tip="グループ情報を表示します"/> - <button label="グループチャット" name="chat_btn" tool_tip="チャットを開始します"/> - <button label="グループコール" name="group_call_btn" tool_tip="このグループにコールします"/> + <layout_stack name="bottom_bar_ls"> + <layout_panel name="view_profile_btn_lp"> + <button label="プロフィール" name="view_profile_btn" tool_tip="写真、グループ、その他住人情報を表示"/> + </layout_panel> + <layout_panel name="chat_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> + <layout_panel name="chat_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> + </layout_stack> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="group_info_btn_lp"> + <button label="グループ情報" name="group_info_btn" tool_tip="グループ情報を表示します"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="グループチャット" name="chat_btn" tool_tip="チャットを開始します"/> + </layout_panel> + <layout_panel name="group_call_btn_lp"> + <button label="グループコール" name="group_call_btn" tool_tip="このグループにコールする"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_pick_info.xml b/indra/newview/skins/default/xui/ja/panel_pick_info.xml index 30fd8d1adc..e7b5d1929d 100644 --- a/indra/newview/skins/default/xui/ja/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/ja/panel_pick_info.xml @@ -3,14 +3,22 @@ <text name="title" value="ピックの情報"/> <scroll_container name="profile_scroll"> <panel name="scroll_content_panel"> - <text name="pick_name" value="[name]"/> - <text name="pick_location" value="[loading...]"/> - <text name="pick_desc" value="[description]"/> + <text_editor name="pick_name" value="[name]"/> + <text_editor name="pick_location" value="[loading...]"/> + <text_editor name="pick_desc" value="[description]"/> </panel> </scroll_container> <panel name="buttons"> - <button label="テレポート" name="teleport_btn"/> - <button label="地図" name="show_on_map_btn"/> - <button label="編集" name="edit_btn"/> + <layout_stack name="layout_stack1"> + <layout_panel name="layout_panel1"> + <button label="テレポート" name="teleport_btn"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="地図" name="show_on_map_btn"/> + </layout_panel> + <layout_panel name="edit_btn_lp"> + <button label="編集" name="edit_btn"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_picks.xml b/indra/newview/skins/default/xui/ja/panel_picks.xml index 4f58c032da..c6eaaeef41 100644 --- a/indra/newview/skins/default/xui/ja/panel_picks.xml +++ b/indra/newview/skins/default/xui/ja/panel_picks.xml @@ -7,11 +7,23 @@ <accordion_tab name="tab_classifieds" title="クラシファイド広告"/> </accordion> <panel label="bottom_panel" name="edit_panel"> - <button name="new_btn" tool_tip="現在地の新しいピック、またはクラシファイド広告を作成します"/> + <layout_stack name="edit_panel_ls"> + <layout_panel name="gear_menu_btn"> + <button name="new_btn" tool_tip="現在地の新しいピック、またはクラシファイド広告を作成します"/> + </layout_panel> + </layout_stack> </panel> <panel name="buttons_cucks"> - <button label="情報" name="info_btn" tool_tip="ピックの情報を表示します"/> - <button label="テレポート" name="teleport_btn" tool_tip="該当するエリアにテレポートします"/> - <button label="地図" name="show_on_map_btn" tool_tip="世界地図に該当するエリアを表示します"/> + <layout_stack name="buttons_cucks_ls"> + <layout_panel name="info_btn_lp"> + <button label="情報" name="info_btn" tool_tip="ピックの情報を表示"/> + </layout_panel> + <layout_panel name="teleport_btn_lp"> + <button label="テレポート" name="teleport_btn" tool_tip="該当するエリアにテレポート"/> + </layout_panel> + <layout_panel name="show_on_map_btn_lp"> + <button label="地図" name="show_on_map_btn" tool_tip="世界地図に該当するエリアを表示"/> + </layout_panel> + </layout_stack> </panel> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_places.xml b/indra/newview/skins/default/xui/ja/panel_places.xml index c83e3591a7..3e364c9b3a 100644 --- a/indra/newview/skins/default/xui/ja/panel_places.xml +++ b/indra/newview/skins/default/xui/ja/panel_places.xml @@ -4,13 +4,45 @@ <string name="teleport_history_tab_title" value="テレポートの履歴"/> <filter_editor label="場所をフィルター" name="Filter"/> <panel name="button_panel"> - <button label="テレポート" name="teleport_btn" tool_tip="該当するエリアにテレポートします"/> - <button label="地図" name="map_btn" tool_tip="世界地図に該当するエリアを表示"/> - <button label="編集" name="edit_btn" tool_tip="ランドマークの情報を編集します"/> - <button label="▼" name="overflow_btn" tool_tip="その他のオプションを表示"/> - <button label="保存" name="save_btn"/> - <button label="キャンセル" name="cancel_btn"/> - <button label="閉じる" name="close_btn"/> - <button label="プロフィール" name="profile_btn" tool_tip="場所のプロフィールを表示"/> + <layout_stack name="bottom_bar_ls0"> + <layout_panel name="lp1"> + <layout_stack name="bottom_bar_ls1"> + <layout_panel name="teleport_btn_lp"> + <button label="テレポート" name="teleport_btn" tool_tip="該当するエリアにテレポートする"/> + </layout_panel> + <layout_panel name="chat_btn_lp"> + <button label="地図" name="map_btn" tool_tip="世界地図に該当するエリアを表示"/> + </layout_panel> + </layout_stack> + </layout_panel> + <layout_panel name="lp2"> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="edit_btn_lp"> + <button label="編集" name="edit_btn" tool_tip="ランドマークの情報を編集します"/> + </layout_panel> + <layout_panel name="overflow_btn_lp"> + <button label="▼" name="overflow_btn" tool_tip="オプションを表示します"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls3"> + <layout_panel name="profile_btn_lp"> + <button label="プロフィール" name="profile_btn" tool_tip="場所のプロフィールを表示"/> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_close_ls3"> + <layout_panel name="close_btn_lp"> + <button label="閉じる" name="close_btn"/> + </layout_panel> + </layout_stack> + </layout_panel> + </layout_stack> + <layout_stack name="bottom_bar_ls2"> + <layout_panel name="save_btn_lp"> + <button label="保存" name="save_btn"/> + </layout_panel> + <layout_panel name="cancel_btn_lp"> + <button label="取り消し" name="cancel_btn"/> + </layout_panel> + </layout_stack> </panel> </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 4082f71a76..c260cebef8 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_chat.xml @@ -56,27 +56,27 @@ <radio_item label="別々のウィンドウ" name="radio" value="0"/> <radio_item label="タブ" name="radio2" value="1"/> </radio_group> - <check_box label="翻訳チャット" name="translate_chat_checkbox" /> + <check_box label="チャット中に内容を機械翻訳する(Google翻訳)" name="translate_chat_checkbox"/> <text name="translate_language_text"> - チャット言語: + 翻訳する言語: </text> <combo_box name="translate_language_combobox"> - <combo_box.item name="System Default Language" label="システム・デフォルト" /> - <combo_box.item name="English" label="English (英語)" /> - <combo_box.item name="Danish" label="Dansk (デンマーク語)" /> - <combo_box.item name="German" label="Deutsch (ドイツ語)" /> - <combo_box.item name="Spanish" label="Español (スペイン語)" /> - <combo_box.item name="French" label="Français (フランス語)" /> - <combo_box.item name="Italian" label="Italiano (イタリア語)" /> - <combo_box.item name="Hungarian" label="Magyar (ハンガリー語)" /> - <combo_box.item name="Dutch" label="Nederlands (オランダ語)" /> - <combo_box.item name="Polish" label="Polski (ポーランド語)" /> - <combo_box.item name="Portugese" label="Português (ポルトガル語)" /> - <combo_box.item name="Russian" label="Русский (ロシア語)" /> - <combo_box.item name="Turkish" label="Türkçe (トルコ語)" /> - <combo_box.item name="Ukrainian" label="Українська (ウクライナ語)" /> - <combo_box.item name="Chinese" label="中文 (简体) (中国語)" /> - <combo_box.item name="Japanese" label="日本語" /> - <combo_box.item name="Korean" label="한국어 (韓国語)" /> + <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="日本語" name="Japanese"/> + <combo_box.item label="한국어(韓国語)" name="Korean"/> </combo_box> </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 4ccb70b321..751faff1d8 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml @@ -13,7 +13,7 @@ <combo_box.item label="Italiano (イタリア語) - ベータ" name="Italian"/> <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="Português(ポルトガル語) - ベータ" name="Portugese"/> <combo_box.item label="日本語 – ベータ" name="(Japanese)"/> </combo_box> <text name="language_textbox2"> diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml index 8a50581075..92635182c8 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_graphics1.xml @@ -28,22 +28,16 @@ <check_box initial_value="true" label="バンプマッピングと光沢" name="BumpShiny"/> <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="Reflections"/> - <text name="ReflectionDetailText"> - 反射詳細: + <text name="reflection_label"> + 水の反射: </text> - <radio_group name="ReflectionDetailRadio"> - <radio_item label="地形と樹木" name="0"/> - <radio_item label="すべての静止オブジェクト" name="1"/> - <radio_item label="すべてのアバターとオブジェクト" name="2"/> - <radio_item label="すべて" name="3"/> - </radio_group> - <text name="AvatarRenderingText"> - アバター表示: - </text> - <check_box initial_value="true" label="アバターの描画を簡略化" name="AvatarImpostors"/> - <check_box initial_value="true" label="ハードウェアスキニング" name="AvatarVertexProgram"/> - <check_box initial_value="true" label="アバターの布" name="AvatarCloth"/> + <combo_box initial_value="true" label="水の反射" name="Reflections"> + <combo_box.item label="最小" name="0"/> + <combo_box.item label="地形と樹木" name="1"/> + <combo_box.item label="すべての静止オブジェクト" name="2"/> + <combo_box.item label="すべてのアバターとオブジェクト" name="3"/> + <combo_box.item label="すべて" name="4"/> + </combo_box> <slider label="描画距離:" name="DrawDistance"/> <text name="DrawDistanceMeterText2"> m @@ -81,13 +75,12 @@ <text name="SkyMeshDetailText"> 低 </text> - <text name="LightingDetailText"> - ライティング詳細: + <text name="AvatarRenderingText"> + アバター表示: </text> - <radio_group name="LightingDetailRadio"> - <radio_item label="太陽と月のみ" name="SunMoon" value="0"/> - <radio_item label="近くのローカルサイト" name="LocalLights" value="1"/> - </radio_group> + <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"> 地形詳細: </text> @@ -95,6 +88,7 @@ <radio_item label="低" name="0"/> <radio_item label="高" name="2"/> </radio_group> + --> </panel> <button label="適用" label_selected="適用" name="Apply"/> <button label="リセット" name="Defaults"/> diff --git a/indra/newview/skins/default/xui/ja/panel_profile.xml b/indra/newview/skins/default/xui/ja/panel_profile.xml index e7bc989c52..860020c87c 100644 --- a/indra/newview/skins/default/xui/ja/panel_profile.xml +++ b/indra/newview/skins/default/xui/ja/panel_profile.xml @@ -40,17 +40,29 @@ </panel> </scroll_container> </layout_panel> + </layout_stack> + <layout_stack name="layout_verb_buttons"> <layout_panel name="profile_buttons_panel"> - <button label="フレンド登録" name="add_friend" tool_tip="フレンド登録を申し出ます"/> - <button label="IM" name="im" tool_tip="インスタントメッセージを開きます"/> - <button label="コール" name="call" tool_tip="この住人にコールします"/> - <button label="地図" name="show_on_map_btn" tool_tip="住人を地図上で表示します"/> - <button label="テレポート" name="teleport" tool_tip="テレポートを送ります"/> - <button label="▼" name="overflow_btn" tool_tip="住人にお金を渡すか持ち物を共有します"/> + <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"> + <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="個人的な情報を編集します"/> - <button label="容姿の編集" name="edit_appearance_btn" tool_tip="見た目を作成・編集します: (身体的データ、衣類など)"/> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml index 8f4a76fd43..d06db8ccb1 100644 --- a/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml +++ b/indra/newview/skins/default/xui/ja/panel_side_tray_tab_caption.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="sidetray_tab_panel"> <text name="sidetray_tab_title" value="サイドパネル"/> + <button name="undock" tool_tip="切り離す"/> + <button name="dock" tool_tip="ドッキング"/> <button name="show_help" tool_tip="ヘルプを表示"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml b/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml index 648719b6bd..e26d8717d1 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_inventory.xml @@ -2,12 +2,20 @@ <panel label="もの" name="objects panel"> <panel label="" name="sidepanel__inventory_panel"> <panel name="button_panel"> - <button label="プロフィール" name="info_btn" tool_tip="オブジェクトのプロフィールを表示する"/> - <button label="共有" name="share_btn" tool_tip="「持ち物」のアイテムを共有する"/> - <button label="ショッピング" name="shop_btn" tool_tip="マーケットプレイスのサイトを開く"/> - <button label="装着" name="wear_btn" tool_tip="選択したアウトフィットを着用する"/> - <button label="プレイ" name="play_btn"/> - <button label="テレポート" name="teleport_btn" tool_tip="該当するエリアにテレポートする"/> + <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="「持ち物」のアイテムを共有する"/> + </layout_panel> + <layout_panel name="shop_btn_lp"> + <button label="店" name="shop_btn" tool_tip="マーケットプレイスのサイトを開く"/> + <button label="装着" name="wear_btn" tool_tip="選択したアウトフィットを着用する"/> + <button label="プレイ" name="play_btn"/> + <button label="テレポート" name="teleport_btn" tool_tip="該当するエリアにテレポートする"/> + </layout_panel> + </layout_stack> </panel> </panel> </panel> 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 519b69799b..d820994b59 100644 --- a/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/ja/sidepanel_item_info.xml @@ -23,56 +23,53 @@ </panel.string> <text name="title" value="アイテムのプロフィール"/> <text name="origin" value="(持ち物)"/> - <panel label="" name="item_profile"> - <text name="LabelItemNameTitle"> - 名前: - </text> - <text name="LabelItemDescTitle"> - 説明: - </text> - <text name="LabelCreatorTitle"> - 制作者: - </text> - <text name="LabelCreatorName"/> - <button label="プロフィール" name="BtnCreator"/> - <text name="LabelOwnerTitle"> - 所有者: - </text> - <text name="LabelOwnerName"/> - <button label="プロフィール" name="BtnOwner"/> - <text name="LabelAcquiredTitle"> - 取得: - </text> - <text name="LabelAcquiredDate"/> - <panel name="perms_inv"> - <text name="perm_modify"> - あなたができること: + <scroll_container name="item_profile_scroll"> + <panel label="" name="item_profile"> + <text name="LabelItemNameTitle"> + 名前: </text> - <check_box label="修正" name="CheckOwnerModify"/> - <check_box label="コピー" name="CheckOwnerCopy"/> - <check_box label="再販・プレゼント" name="CheckOwnerTransfer"/> - <text name="AnyoneLabel"> - 全員: + <text name="LabelItemDescTitle"> + 説明: </text> - <check_box label="コピー" name="CheckEveryoneCopy"/> - <text name="GroupLabel"> - グループ: + <text name="LabelCreatorTitle"> + 制作者: </text> - <check_box label="共有" name="CheckShareWithGroup" tool_tip="設定したグループのメンバー全員にこのオブジェクトの修正権限を与えます。譲渡しない限り、役割制限を有効にはできません。"/> - <text name="NextOwnerLabel"> - 次の所有者: + <text name="LabelOwnerTitle"> + 所有者: </text> - <check_box label="修正" name="CheckNextOwnerModify"/> - <check_box label="コピー" name="CheckNextOwnerCopy"/> - <check_box label="再販・プレゼント" name="CheckNextOwnerTransfer" tool_tip="次の所有者はこのオブジェクトを他人にあげたり再販できます"/> + <text name="LabelAcquiredTitle"> + 取得: + </text> + <panel name="perms_inv"> + <text name="perm_modify"> + あなたができること: + </text> + <check_box label="修正" name="CheckOwnerModify"/> + <check_box label="コピー" name="CheckOwnerCopy"/> + <check_box label="再販・プレゼント" name="CheckOwnerTransfer"/> + <text name="AnyoneLabel"> + 全員: + </text> + <check_box label="コピー" name="CheckEveryoneCopy"/> + <text name="GroupLabel"> + グループ: + </text> + <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="次の所有者はこのオブジェクトを他人にあげたり再販できます"/> + </panel> + <check_box label="販売中" name="CheckPurchase"/> + <combo_box name="combobox sale copy"> + <combo_box.item label="コピー" name="Copy"/> + <combo_box.item label="オリジナル" name="Original"/> + </combo_box> + <spinner label="価格: L$" name="Edit Cost"/> </panel> - <check_box label="販売中" name="CheckPurchase"/> - <combo_box name="combobox sale copy"> - <combo_box.item label="コピー" name="Copy"/> - <combo_box.item label="オリジナル" name="Original"/> - </combo_box> - <spinner label="価格:L$" name="Edit Cost"/> - </panel> + </scroll_container> <panel name="button_panel"> <button label="キャンセル" name="cancel_btn"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index dd59065a9d..92bbedaee5 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -798,7 +798,7 @@ <string name="xml_file"> XML ファイル </string> - <string name="dot_raw_file"> + <string name="raw_file"> RAW ファイル </string> <string name="compressed_image_files"> @@ -1294,6 +1294,9 @@ <string name="Right Pec"> 右胸筋 </string> + <string name="Invalid Attachment"> + 装着先が正しくありません + </string> <string name="YearsMonthsOld"> [AGEYEARS] [AGEMONTHS] </string> @@ -1671,9 +1674,6 @@ <string name="ATTACH_HUD_BOTTOM_RIGHT"> HUD(右下) </string> - <string name="Bad attachment point"> - 装着先が正しくありません - </string> <string name="CursorPos"> [LINE] 行目、[COLUMN] 列目 </string> @@ -1695,12 +1695,6 @@ <string name="BusyModeResponseDefault"> メッセージを送った住人は、誰にも邪魔をされたくないため現在「取り込み中」モードです。 あなたのメッセージは、あとで確認できるように IM パネルに表示されます。 </string> - <string name="NoOutfits"> - アウトフィットがまだありません。[secondlife:///app/search/all/ Search]をお試しください - </string> - <string name="NoOutfitsTabsMatched"> - お探しのものは見つかりましたか?[secondlife:///app/search/all/[SEARCH_TERM]をお試しください。 - </string> <string name="MuteByName"> (名称別) </string> @@ -1864,6 +1858,12 @@ <string name="accel-win-shift"> Shift+ </string> + <string name="Esc"> + Esc + </string> + <string name="Home"> + ホーム + </string> <string name="FileSaved"> ファイルが保存されました </string> @@ -3528,6 +3528,9 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ <string name="IM_moderator_label"> (モデレータ) </string> + <string name="Saved_message"> + (保存日時:[LONG_TIMESTAMP]) + </string> <string name="answered_call"> 相手がコールを受けました </string> @@ -3555,12 +3558,18 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ <string name="conference-title"> アドホックコンファレンス </string> + <string name="conference-title-incoming"> + [AGENT_NAME]とコンファレンスする + </string> <string name="inventory_item_offered-im"> 持ち物アイテムを送りました </string> <string name="share_alert"> 持ち物からここにアイテムをドラッグします </string> + <string name="no_session_message"> + (IM セッションが存在しません) + </string> <string name="only_user_message"> このセッションにいるユーザーはあなただけです。 </string> @@ -3945,4 +3954,13 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ <string name="Chat"> チャット </string> + <string name="DeleteItems"> + 選択したアイテムを削除しますか + </string> + <string name="DeleteItem"> + 選択したアイテムを削除しますか + </string> + <string name="EmptyOutfitText"> + このアウトフィットにはアイテムがありません + </string> </strings> diff --git a/indra/newview/skins/default/xui/nl/floater_event.xml b/indra/newview/skins/default/xui/nl/floater_event.xml new file mode 100644 index 0000000000..45ec58abdf --- /dev/null +++ b/indra/newview/skins/default/xui/nl/floater_event.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Laden... + </floater.string> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> +</floater> + diff --git a/indra/newview/skins/default/xui/nl/notifications.xml b/indra/newview/skins/default/xui/nl/notifications.xml index a282c267a1..a282c70364 100644 --- a/indra/newview/skins/default/xui/nl/notifications.xml +++ b/indra/newview/skins/default/xui/nl/notifications.xml @@ -2550,8 +2550,7 @@ Probeer een kleiner stuk land te selecteren. [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Teleport"/> - <button name="Description" text="Omschrijving"/> + <button name="Details" text="Omschrijving"/> <button name="Cancel" text="Annuleren"/> </form> </notification> diff --git a/indra/newview/skins/default/xui/nl/strings.xml b/indra/newview/skins/default/xui/nl/strings.xml index 1ee26c3f24..844945913f 100644 --- a/indra/newview/skins/default/xui/nl/strings.xml +++ b/indra/newview/skins/default/xui/nl/strings.xml @@ -665,7 +665,7 @@ <string name="xml_file"> XML bestand </string> - <string name="dot_raw_file"> + <string name="raw_file"> RAW bestand </string> <string name="compressed_image_files"> diff --git a/indra/newview/skins/default/xui/pl/floater_event.xml b/indra/newview/skins/default/xui/pl/floater_event.xml index 80862bfd2f..6b24720d86 100644 --- a/indra/newview/skins/default/xui/pl/floater_event.xml +++ b/indra/newview/skins/default/xui/pl/floater_event.xml @@ -1,72 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="IMPREZA" name="Event" title="IMPREZA"> - <floater.string name="none"> - żadne +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Ładowanie... </floater.string> - <floater.string name="notify"> - Zawiadom - </floater.string> - <floater.string name="dont_notify"> - Nie zawiadamiaj - </floater.string> - <floater.string name="moderate"> - Mature - </floater.string> - <floater.string name="adult"> - Adult - </floater.string> - <floater.string name="general"> - General - </floater.string> - <floater.string name="unknown"> - Nieznana - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Brak nazwy dla wydarzenia. - </text> - <text name="event_category"> - (bez kategorii) - </text> - <text name="event_runby_label"> - Prowadzona przez: - </text> - <text initial_value="(przetwarzanie)" name="event_runby"/> - <text name="event_date_label"> - Data: - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - Długość: - </text> - <text name="event_duration"> - 1 godzina - </text> - <text name="event_covercharge_label"> - Opłata: - </text> - <text name="event_cover"> - Bez opłaty - </text> - <text name="event_location_label"> - Lokalizacja: - </text> - <text name="event_location" value="SampleParcel, Name Long (145, 228, 26)"/> - <text name="rating_label" value="Rodzaj:"/> - <text name="rating_value" value="nieznane"/> - <expandable_text name="event_desc"> - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - </expandable_text> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="Stwórz imprezę"/> - <button name="god_delete_event_btn" tool_tip="Skasuj imprezę"/> - <button label="Zawiadom mnie" name="notify_btn"/> - <button label="Teleportuj" name="teleport_btn"/> - <button label="Mapa" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index 7fda575c29..36c662394e 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -2157,8 +2157,7 @@ Spróbuj wybrać mniejszy obszar. [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Teleportuj"/> - <button name="Description" text="Opis"/> + <button name="Details" text="Opis"/> <button name="Cancel" text="Anuluj"/> </form> </notification> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index c9fe22f3c8..e355bdbb96 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -774,7 +774,7 @@ <string name="xml_file"> Plik XML </string> - <string name="dot_raw_file"> + <string name="raw_file"> Plik RAW </string> <string name="compressed_image_files"> diff --git a/indra/newview/skins/default/xui/pt/floater_customize.xml b/indra/newview/skins/default/xui/pt/floater_customize.xml new file mode 100644 index 0000000000..a9ec0b9b1f --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_customize.xml @@ -0,0 +1,530 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater customize" title="APARÊNCIA"> + <tab_container name="customize tab container" tab_min_width="115"> + <text label="Corpo" name="body_parts_placeholder"> + Partes do corpo + </text> + <panel label="Forma" name="Shape"> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + <button label="Corpo" label_selected="Corpo" name="Body"/> + <button label="Cabeça" label_selected="Cabeça" name="Head"/> + <button label="Olhos" label_selected="Olhos" name="Eyes"/> + <button label="Orelhas" label_selected="Orelhas" name="Ears"/> + <button label="Nariz" label_selected="Nariz" name="Nose"/> + <button label="Boca" label_selected="Boca" name="Mouth"/> + <button label="Queixo" label_selected="Queixo" name="Chin"/> + <button label="Tórax" label_selected="Tórax" name="Torso"/> + <button label="Pernas" label_selected="Pernas" name="Legs"/> + <radio_group name="sex radio"> + <radio_item label="Feminino" name="radio" value="0"/> + <radio_item label="Masculino" name="radio2" value="1"/> + </radio_group> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter um físico novo, arraste um do inventário para o seu avatar. Ou crie um novo. + </text> + <text name="no modify instructions"> + Você não tem permissão para modificar esta vestimenta. + </text> + <text name="Item Action Label"> + Forma: + </text> + <button label="Nova" label_selected="Nova" name="Create New"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + </panel> + <panel label="Pele" name="Skin"> + <button label="Cor de pele" label_selected="Cor de pele" name="Skin Color" width="115"/> + <button label="Detalhes faciais" label_selected="Detalhes faciais" name="Face Detail" width="115"/> + <button label="Maquilagem" label_selected="Maquilagem" name="Makeup" width="115"/> + <button label="Detalhes do corpo" label_selected="Detalhes do corpo" name="Body Detail" width="115"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando.. + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizada em [PATH] + </text> + <text name="not worn instructions"> + Para obter uma pele nova, arraste uma do inventário para o seu avatar. Ou crie uma pele nova. + </text> + <text name="no modify instructions"> + Você não tem permissão para modificar esta vestimenta. + </text> + <text name="Item Action Label"> + Pele: + </text> + <texture_picker label="Tattoo: cabeça" name="Head Tattoos" tool_tip="Clique para escolher um desenho" width="86"/> + <texture_picker label="Tattoo: superior" name="Upper Tattoos" tool_tip="Clique para escolher um desenho" width="86"/> + <texture_picker label="Tattoo: inferior" name="Lower Tattoos" tool_tip="Clique para escolher um desenho" width="86"/> + <button label="Novo" label_selected="Novo" name="Create New"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Cabelo" name="Hair"> + <button label="Cor" label_selected="Cor" name="Color" width="115"/> + <button label="Estilo" label_selected="Estilo" name="Style" width="115"/> + <button label="Sombrancelhas" label_selected="Sombrancelhas" name="Eyebrows" width="115"/> + <button label="Rosto" label_selected="Rosto" name="Facial" width="115"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter um cabelo novo, arraste um tipo de cabelo do inventário para o seu avatar. Ou crie um cabelo novo. + </text> + <text name="no modify instructions"> + Você não ter permissão para modificar essa vestimenta. + </text> + <text name="Item Action Label"> + Cabelo: + </text> + <texture_picker label="Texture" name="Texture" tool_tip="Clique para escolher uma imagem"/> + <button label="Criar novo cabelo" label_selected="Criar novo cabelo" name="Create New"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Olhos" name="Eyes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter novos olhos, arraste um tipo de olhos do inventário para o seu avatar. Ou crie olhos novos. + </text> + <text name="no modify instructions"> + Você não tem permissão para alterar esta vestimenta. + </text> + <text name="Item Action Label"> + Olhos: + </text> + <texture_picker label="Íris" name="Iris" tool_tip="Clique para escolher uma imagem"/> + <button label="Criar novos olhos" label_selected="Criar novos olhos" name="Create New"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <text label="Roupas" name="clothes_placeholder"> + Roupa + </text> + <panel label="Camisa" name="Shirt"> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Criar nova camisa" label_selected="Criar nova camisa" name="Create New"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter uma camisa nova, arraste uma do inventário para o seu avatar. Ou crie uma camisa nova. + </text> + <text name="no modify instructions"> + Você não ter permissão para modificar esta vestimenta. + </text> + <text name="Item Action Label"> + Camisa: + </text> + </panel> + <panel label="Calças" name="Pants"> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Criar novas calças" label_selected="Criar novas calças" name="Create New"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestindo + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter calças novas, arraste uma do inventário para o seu avatar. Ou crie calças novas. + </text> + <text name="no modify instructions"> + Você não tem permissão para modificar esta vestimenta. + </text> + <text name="Item Action Label"> + Calças: + </text> + </panel> + <panel label="Sapatos" name="Shoes"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter novos olhos, arraste um tipo de olhos do inventário para o seu avatar. Ou crie olhos novos. + </text> + <button label="Criar novos sapatos" label_selected="Criar novos sapatos" name="Create New" width="166"/> + <text name="no modify instructions"> + Você não tem permissão para modificar esta vestimenta. + </text> + <text name="Item Action Label"> + Sapatos: + </text> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Meias" name="Socks"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido. + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter meias novas, arraste um par do inventário para o seu avatar. Ou crie meias novas. + </text> + <button label="Criar novas meias" label_selected="Criar novas meias" name="Create New"/> + <text name="no modify instructions"> + Você não tem permissão para modificar essa vestimenta. + </text> + <text name="Item Action Label"> + Meias: + </text> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Jaqueta" name="Jacket"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: Não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para por uma jaqueta nova, arraste uma do inventário para o seu avatar. Ou crie uma jaqueta nova. + </text> + <button label="Criar nova jaqueta" label_selected="Criar nova jaqueta" name="Create New"/> + <text name="no modify instructions"> + Você não tem permissão para modificar esta vestimenta. + </text> + <text name="Item Action Label"> + Jaqueta: + </text> + <texture_picker label="Tecido superior" name="Upper Fabric" tool_tip="Clique para escolher uma imagem." width="84"/> + <texture_picker label="Tecido Inferior" name="Lower Fabric" tool_tip="Clique para escolher uma imagem." width="84"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Luvas" name="Gloves"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando.... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter luvas novas, arraste um par do inventário para o seu avatar. Ou crie luvas novas. + </text> + <button label="Criar novas luvas" label_selected="Criar novas luvas" name="Create New"/> + <text name="no modify instructions"> + Você não tem permissão para modificar essa vestimenta. + </text> + <text name="Item Action Label"> + Luvas: + </text> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Camiseta" name="Undershirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter uma camiseta nova, arraste uma do inventário para o seu avatar. Ou crie uma camiseta nova. + </text> + <button label="Criar nova camiseta" label_selected="Criar nova camiseta" name="Create New"/> + <text name="no modify instructions"> + Você não ter permissão para modificar essa vestimenta. + </text> + <text name="Item Action Label"> + Camiseta: + </text> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Roupas de Baixo" name="Underpants"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter roupa de baixo nova, arraste um modelo do inventário para o seu avatar. Ou crie uma roupa de baixo nova. + </text> + <button label="Criar novas" label_selected="Criar novas" name="Create New" width="180"/> + <text name="no modify instructions"> + Você não tem permissão para modificar essa vestimenta. + </text> + <text name="Item Action Label"> + Roupas de baixo: + </text> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Saia" name="Skirt"> + <text name="title"> + [DESC] + </text> + <text name="title_no_modify"> + [DESC]: não foi possível modificar + </text> + <text name="title_loading"> + [DESC]: carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localizado em [PATH] + </text> + <text name="not worn instructions"> + Para obter um saia nova, arraste uma saia do inventário para o seu avatar. Ou crie uma saia nova. + </text> + <button label="Criar nova saia" label_selected="Criar nova saia" name="Create New"/> + <text name="no modify instructions"> + Você não tem permissão para modificar esta vestimenta. + </text> + <text name="Item Action Label"> + Saia: + </text> + <texture_picker label="Tecido" name="Fabric" tool_tip="Clique para escolher uma imagem"/> + <color_swatch label="Cor/Tint" name="Color/Tint" tool_tip="Selecionar a cor"/> + <button label="Remover" label_selected="Remover" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Tatuagem" name="Tattoo"> + <text name="title"> + [DESC]: + </text> + <text name="title_no_modify"> + [DESC]: não pode ser modificado + </text> + <text name="title_loading"> + [DESC]: Carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localização: [PATH] + </text> + <text name="not worn instructions"> + Para por uma tatuagem nova, arraste uma tatuagem do inventário para o seu avatar. Ou crie uma tatuagem nova. + </text> + <button label="Criar tatuagem" label_selected="Criar tatuagem" name="Create New"/> + <text name="no modify instructions"> + Você não está autorizado a modificar este acessório. + </text> + <text name="Item Action Label"> + Tatuagem: + </text> + <texture_picker label="Tatuagem na cabeça" name="Head Tattoo" tool_tip="Selecionar imagem"/> + <texture_picker label="Tatuagem parte de cima" name="Upper Tattoo" tool_tip="Selecionar imagem"/> + <texture_picker label="Tatuagem de baixo" name="Lower Tattoo" tool_tip="Selecionar imagem"/> + <button label="Tirar" label_selected="Tirar" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + <panel label="Alpha" name="Alpha"> + <text name="title"> + [DESC]: + </text> + <text name="title_no_modify"> + [DESC]: não pode ser modificado + </text> + <text name="title_loading"> + [DESC]: Carregando... + </text> + <text name="title_not_worn"> + [DESC]: não vestido + </text> + <text name="path"> + Localização: [PATH] + </text> + <text name="not worn instructions"> + Para por uma máscara alpha nova, arraste a máscara do inventário para o seu avatar. Ou crie uma máscara nova. + </text> + <button label="Criar Alpha novo" label_selected="Criar Alpha novo" name="Create New"/> + <text name="no modify instructions"> + Você não está autorizado a modificar este acessório. + </text> + <text name="Item Action Label"> + Alpha: + </text> + <texture_picker label="Alpha inferior" name="Lower Alpha" tool_tip="Selecionar imagem"/> + <texture_picker label="Alpha de cima" name="Upper Alpha" tool_tip="Selecionar imagem"/> + <texture_picker label="Cabeça Alpha" name="Head Alpha" tool_tip="Selecionar imagem"/> + <texture_picker label="Olhos Alpha" name="Eye Alpha" tool_tip="Selecionar imagem"/> + <texture_picker label="Cabelo alpha" name="Hair Alpha" tool_tip="Selecionar imagem"/> + <button label="Tirar" label_selected="Tirar" name="Take Off"/> + <button label="Salvar" label_selected="Salvar" name="Save"/> + <button label="Salvar como..." label_selected="Salvar como..." name="Save As"/> + <button label="Reverter" label_selected="Reverter" name="Revert"/> + </panel> + </tab_container> + <scroll_container left="249" name="panel_container"/> + <button label="Dados do script" label_selected="Dados do script" name="script_info" tool_tip="Mostrar scripts anexados ao seu avatar"/> + <button label="Criar look" label_selected="Criar look" name="make_outfit_btn"/> + <button label="Cancelar" label_selected="Cancelar" name="Cancel"/> + <button label="OK" label_selected="OK" name="Ok"/> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_device_settings.xml b/indra/newview/skins/default/xui/pt/floater_device_settings.xml new file mode 100644 index 0000000000..48a4a6ef6f --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_device_settings.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_device_settings" title="CONFIGURAÇÃO DE DISPOSITIVO DE VOZ"/> diff --git a/indra/newview/skins/default/xui/pt/floater_event.xml b/indra/newview/skins/default/xui/pt/floater_event.xml index 1cd4dcbda4..df4fe9a6a8 100644 --- a/indra/newview/skins/default/xui/pt/floater_event.xml +++ b/indra/newview/skins/default/xui/pt/floater_event.xml @@ -1,72 +1,40 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater label="Evento" name="Event" title="DETALHES DO EVENTO"> - <floater.string name="none"> - nenhum +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + follows="all" + height="400" + can_resize="true" + help_topic="event_details" + label="Event" + layout="topleft" + name="Event" + save_rect="true" + save_visibility="false" + title="EVENT DETAILS" + width="600"> + <floater.string + name="loading_text"> + Carregando... </floater.string> - <floater.string name="notify"> - Avisar - </floater.string> - <floater.string name="dont_notify"> - Não avisar - </floater.string> - <floater.string name="moderate"> - Moderado - </floater.string> - <floater.string name="adult"> - Adulto - </floater.string> - <floater.string name="general"> - Público geral - </floater.string> - <floater.string name="unknown"> - Desconhecido - </floater.string> - <layout_stack name="layout"> - <layout_panel name="profile_stack"> - <text name="event_name"> - Evento sem nome... Terror! Terror Aterrorizante. - </text> - <text name="event_category"> - (não categorizado) - </text> - <text name="event_runby_label"> - Organização: - </text> - <text initial_value="(pesquisando)" name="event_runby"/> - <text name="event_date_label"> - Data: - </text> - <text name="event_date"> - 10/10/2010 - </text> - <text name="event_duration_label"> - Duração: - </text> - <text name="event_duration"> - 1 hora - </text> - <text name="event_covercharge_label"> - Cover: - </text> - <text name="event_cover"> - Grátis - </text> - <text name="event_location_label"> - Localização: - </text> - <text name="event_location" value="LoteExemplo, Nome extenso (145, 228, 26)"/> - <text name="rating_label" value="Classificação:"/> - <text name="rating_value" value="(Desconhecido)"/> - <expandable_text name="event_desc"> - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. - </expandable_text> - </layout_panel> - <layout_panel name="button_panel"> - <button name="create_event_btn" tool_tip="Criar evento"/> - <button name="god_delete_event_btn" tool_tip="Excluir evento"/> - <button label="Avise-me" name="notify_btn"/> - <button label="Teletransportar" name="teleport_btn"/> - <button label="Mapa" name="map_btn"/> - </layout_panel> - </layout_stack> + <floater.string + name="done_text"> + Done + </floater.string> + <web_browser + trusted_content="true" + follows="left|right|top|bottom" + layout="topleft" + left="10" + name="browser" + height="365" + width="580" + top="0"/> + <text + follows="bottom|left" + height="16" + layout="topleft" + left_delta="0" + name="status_text" + top_pad="10" + width="150" /> </floater> + diff --git a/indra/newview/skins/default/xui/pt/floater_im.xml b/indra/newview/skins/default/xui/pt/floater_im.xml new file mode 100644 index 0000000000..c81d0dd7ef --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_im.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<multi_floater name="im_floater" title="Mensagem Instantânea"> + <string name="only_user_message"> + Você é o único residente nesta sessão + </string> + <string name="offline_message"> + [FIRST] [LAST] está offline. + </string> + <string name="invite_message"> + Clique no botão [BUTTON NAME] para aceitar/ conectar a este bate-papo em voz. + </string> + <string name="muted_message"> + Você bloqueou este residente. Se quiser retirar o bloqueio, basta enviar uma mensagem. + </string> + <string name="generic_request_error"> + Erro na requisição, por favor, tente novamente. + </string> + <string name="insufficient_perms_error"> + Você não tem permissões suficientes. + </string> + <string name="session_does_not_exist_error"> + A sessão deixou de existir + </string> + <string name="no_ability_error"> + Você não possui esta habilidade. + </string> + <string name="not_a_mod_error"> + Você não é um moderador de sessão. + </string> + <string name="muted_error"> + Um moderador do grupo desabilitou seu bate-papo em texto. + </string> + <string name="add_session_event"> + Não foi possível adicionar residentes ao bate-papo com [RECIPIENT]. + </string> + <string name="message_session_event"> + Não foi possível enviar sua mensagem na sessão de bate- papo com [RECIPIENT]. + </string> + <string name="removed_from_group"> + Você foi removido do grupo. + </string> + <string name="close_on_no_ability"> + Você não possui mais a habilidade de estar na sessão de bate-papo. + </string> +</multi_floater> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_classified.xml b/indra/newview/skins/default/xui/pt/floater_preview_classified.xml new file mode 100644 index 0000000000..bb626430ed --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_preview_classified.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="classified_preview" title="INFORMAÇÕES CLASSIFICADAS"> + <floater.string name="Title"> + Classificados: [NAME] + </floater.string> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_event.xml b/indra/newview/skins/default/xui/pt/floater_preview_event.xml new file mode 100644 index 0000000000..b422580f3b --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_preview_event.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="event_preview" title="DADOS DO EVENTO"> + <floater.string name="Title"> + Evento: [NAME] + </floater.string> +</floater> diff --git a/indra/newview/skins/default/xui/pt/floater_statistics.xml b/indra/newview/skins/default/xui/pt/floater_statistics.xml new file mode 100644 index 0000000000..ecbf638157 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_statistics.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="stats floater" title="ESTATÍSTICAS"/> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index ec0ea9efff..9a7c9579e2 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -2169,8 +2169,7 @@ Selecione o residente da lista e clique em 'MI' na parte de baixo do p [NAME] [DATE] <form name="form"> - <button name="Teleport" text="Teletransporte"/> - <button name="Description" text="Descrição"/> + <button name="Details" text="Descrição"/> <button name="Cancel" text="Cancelar"/> </form> </notification> diff --git a/indra/newview/skins/default/xui/pt/panel_friends.xml b/indra/newview/skins/default/xui/pt/panel_friends.xml new file mode 100644 index 0000000000..34073f9ce1 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_friends.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="friends"> + <string name="Multiple"> + Diversos amigos + </string> + <scroll_list name="friend_list" tool_tip="Aperte shift ou control enquanto clica para selecionar múltiplos amigos"> + <column name="icon_online_status" tool_tip="Status Online"/> + <column label="Nome" name="friend_name" tool_tip="Nome"/> + <column name="icon_visible_online" tool_tip="Amigo pode ver quando você está online"/> + <column name="icon_visible_map" tool_tip="Amigo pode localizá-lo no mapa"/> + <column name="icon_edit_mine" tool_tip="Amigo pode editar, apagar ou pegar seus objetos"/> + <column name="icon_edit_theirs" tool_tip="Você pode editar os objetos deste amigo"/> + </scroll_list> + <button label="MI/Chamar" name="im_btn" tool_tip="Abrir sessão de Mensagem Instantânea" width="86"/> + <button label="Perfil" name="profile_btn" tool_tip="Mostrar foto, grupos e outras informações" width="86"/> + <button label="Teletransportar" name="offer_teleport_btn" tool_tip="Oferecer a este amigo o teletransporte para sua localização atual" width="86"/> + <button label="Pagar" name="pay_btn" tool_tip="Dar Linden dólares (L$) a este amigo" width="86"/> + <button label="Tirar" name="remove_btn" tool_tip="Remover esta pessoa de sua lista de amigos" width="86"/> + <button label="Adicionar" name="add_btn" tool_tip="Oferecer amizade para um residente" width="86"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 5d87a855ef..800ad479fc 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -777,7 +777,7 @@ <string name="xml_file"> Arquivo XML </string> - <string name="dot_raw_file"> + <string name="raw_file"> Arquivo RAW </string> <string name="compressed_image_files"> @@ -1391,10 +1391,10 @@ Script não encontrado no servidor. </string> <string name="CompileQueueProblemDownloading"> - Problema no download + Problema no download </string> <string name="CompileQueueInsufficientPermDownload"> - Permissões insuficientes para fazer o download do script. + Permissões insuficientes para fazer o download do script. </string> <string name="CompileQueueInsufficientPermFor"> Permissões insuficientes para @@ -1699,7 +1699,7 @@ (vai atualizar depois de publicado) </string> <string name="NoPicksClassifiedsText"> - Você não criou nenhum Destaque ou Anúncio. Clique no botão "+" para criar um Destaque ou Anúncio. + Você não criou nenhum Destaque ou Anúncio. Clique no botão "+" para criar um Destaque ou Anúncio. </string> <string name="NoAvatarPicksClassifiedsText"> O usuário não tem nenhum destaque ou anúncio diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp index 99b346cff8..47353962e1 100644 --- a/indra/newview/tests/lldateutil_test.cpp +++ b/indra/newview/tests/lldateutil_test.cpp @@ -183,4 +183,14 @@ namespace tut LLDateUtil::ageFromDate("12/13/2009", now), "3 weeks old" ); } + + //template<> template<> + //void dateutil_object_t::test<6>() + //{ + // set_test_name("ISO dates"); + // LLDate now(std::string("2010-01-04T12:00:00Z")); + // ensure_equals("days", + // LLDateUtil::ageFromDateISO("2009-12-13", now), + // "3 weeks old" ); + //} } diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 949fa3cc1c..6861f02bfb 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -271,6 +271,12 @@ class WindowsManifest(ViewerManifest): self.disable_manifest_check() + # Get fmod dll, continue if missing + try: + self.path("fmod.dll") + except: + print "Skipping fmod.dll" + # For textures if self.args['configuration'].lower() == 'debug': self.path("openjpegd.dll") @@ -315,12 +321,6 @@ class WindowsManifest(ViewerManifest): # For use in crash reporting (generates minidumps) self.path("dbghelp.dll") - try: - # FMOD for sound - self.path("fmod.dll") - except: - print "Skipping FMOD - not found" - self.enable_no_crt_manifest_check() # Media plugins - QuickTime @@ -956,6 +956,13 @@ class Linux_i686Manifest(LinuxManifest): self.path("libvivoxplatform.so") self.end_prefix("lib") +class Linux_x86_64Manifest(LinuxManifest): + def construct(self): + super(Linux_x86_64Manifest, self).construct() + + # support file for valgrind debug tool + self.path("secondlife-i686.supp") + ################################################################ if __name__ == "__main__": diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp index 95d0421273..58bf371a04 100644 --- a/indra/viewer_components/login/tests/lllogin_test.cpp +++ b/indra/viewer_components/login/tests/lllogin_test.cpp @@ -6,7 +6,7 @@ * * $LicenseInfo:firstyear=2009&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2009-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 |