diff options
| author | Rye <rye@alchemyviewer.org> | 2025-08-20 18:04:55 -0400 |
|---|---|---|
| committer | Rye <rye@alchemyviewer.org> | 2025-08-20 18:04:55 -0400 |
| commit | ba30737d8f4add8ddd8c77d18df6497b46583fe9 (patch) | |
| tree | 81e5412a364ff80b5250fe6db9e653d35621c20e /indra | |
| parent | f0db568bf8d313a00e10c1c4ee4dd7f716a9d987 (diff) | |
| parent | d5f748c91c650a2ec534c497b9e098ccb317d70b (diff) | |
Merge branch 'develop' of github.com:secondlife/viewer into rye/infinitemac
Diffstat (limited to 'indra')
591 files changed, 47275 insertions, 19421 deletions
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 6c1b1f4d1d..4608f68f50 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -20,6 +20,7 @@ set(cmake_SOURCE_FILES Copy3rdPartyLibs.cmake DBusGlib.cmake DeploySharedLibs.cmake + Discord.cmake DragDrop.cmake EXPAT.cmake FindAutobuild.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 2ac82308cf..680f2f3ac2 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -6,6 +6,9 @@ include(CMakeCopyIfDifferent) include(Linking) +if (USE_DISCORD) + include(Discord) +endif () include(OPENAL) # When we copy our dependent libraries, we almost always want to copy them to @@ -70,6 +73,10 @@ if(WINDOWS) endif(ADDRESS_SIZE EQUAL 32) endif (USE_BUGSPLAT) + if (TARGET ll::discord_sdk) + list(APPEND release_files discord_partner_sdk.dll) + endif () + if (TARGET ll::openal) list(APPEND release_files openal32.dll alut.dll) endif () @@ -166,6 +173,10 @@ elseif(DARWIN) libndofdev.dylib ) + if (TARGET ll::discord_sdk) + list(APPEND release_files libdiscord_partner_sdk.dylib) + endif () + if (TARGET ll::openal) list(APPEND release_files libalut.dylib libopenal.dylib) endif () diff --git a/indra/cmake/Discord.cmake b/indra/cmake/Discord.cmake new file mode 100644 index 0000000000..95cfaacf5b --- /dev/null +++ b/indra/cmake/Discord.cmake @@ -0,0 +1,11 @@ +include(Prebuilt) + +include_guard() + +add_library(ll::discord_sdk INTERFACE IMPORTED) +target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1) + +use_prebuilt_binary(discord_sdk) + +target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk) +target_link_libraries(ll::discord_sdk INTERFACE discord_partner_sdk) diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index 3f4d0ed534..900a64e2dd 100644 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -73,7 +73,6 @@ else() find_library(COCOA_LIBRARY Cocoa) find_library(IOKIT_LIBRARY IOKit) - find_library(AGL_LIBRARY AGL) find_library(APPKIT_LIBRARY AppKit) find_library(COREAUDIO_LIBRARY CoreAudio) find_library(COREGRAPHICS_LIBRARY CoreGraphics) @@ -84,7 +83,6 @@ else() ${IOKIT_LIBRARY} ${COREFOUNDATION_LIBRARY} ${CARBON_LIBRARY} - ${AGL_LIBRARY} ${APPKIT_LIBRARY} ${COREAUDIO_LIBRARY} ${AUDIOTOOLBOX_LIBRARY} diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake index da5d2ef22c..7cce190f6a 100644 --- a/indra/cmake/Python.cmake +++ b/indra/cmake/Python.cmake @@ -13,7 +13,7 @@ elseif (WINDOWS) foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE) # prefer more recent Python versions to older ones, if multiple versions # are installed - foreach(pyver 3.12 3.11 3.10 3.9 3.8 3.7) + foreach(pyver 3.13 3.12 3.11 3.10 3.9 3.8 3.7) list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]") endforeach() endforeach() diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt deleted file mode 100644 index 8b13789179..0000000000 --- a/indra/edit-me-to-trigger-new-build.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt index c3be8bc78e..6744c8d8a4 100644 --- a/indra/llappearance/CMakeLists.txt +++ b/indra/llappearance/CMakeLists.txt @@ -14,6 +14,7 @@ set(llappearance_SOURCE_FILES llavatarjoint.cpp llavatarjointmesh.cpp lldriverparam.cpp + lljointdata.h lllocaltextureobject.cpp llpolyskeletaldistortion.cpp llpolymesh.cpp diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 3d66809ed6..dab18c240d 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -29,16 +29,17 @@ #include "llavatarappearance.h" #include "llavatarappearancedefines.h" #include "llavatarjointmesh.h" +#include "lljointdata.h" #include "llstl.h" #include "lldir.h" #include "llpolymorph.h" #include "llpolymesh.h" #include "llpolyskeletaldistortion.h" -#include "llstl.h" #include "lltexglobalcolor.h" #include "llwearabledata.h" #include "boost/bind.hpp" #include "boost/tokenizer.hpp" +#include "v4math.h" using namespace LLAvatarAppearanceDefines; @@ -71,11 +72,13 @@ public: mChildren.clear(); } bool parseXml(LLXmlTreeNode* node); + glm::mat4 getJointMatrix(); private: std::string mName; std::string mSupport; std::string mAliases; + std::string mGroup; bool mIsJoint; LLVector3 mPos; LLVector3 mEnd; @@ -106,10 +109,16 @@ public: S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; } private: + typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t; + static void getJointMatricesAndHierarhy( + LLAvatarBoneInfo* bone_info, + LLJointData& data, + const glm::mat4& parent_mat); + +private: S32 mNumBones; S32 mNumCollisionVolumes; LLAvatarAppearance::joint_alias_map_t mJointAliasMap; - typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t; bone_info_list_t mBoneInfoList; }; @@ -1598,6 +1607,15 @@ bool LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) mSupport = "base"; } + // Skeleton has 133 bones, but shader only allows 110 (LL_MAX_JOINTS_PER_MESH_OBJECT) + // Groups can be used by importer to cut out unused groups of joints + static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); + if (!node->getFastAttributeString(group_string, mGroup)) + { + LL_WARNS() << "Bone without group " << mName << LL_ENDL; + mGroup = "global"; + } + if (mIsJoint) { static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); @@ -1623,6 +1641,21 @@ bool LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node) return true; } + +glm::mat4 LLAvatarBoneInfo::getJointMatrix() +{ + glm::mat4 mat(1.0f); + // 1. Scaling + mat = glm::scale(mat, glm::vec3(mScale[0], mScale[1], mScale[2])); + // 2. Rotation (Euler angles rad) + mat = glm::rotate(mat, mRot[0], glm::vec3(1, 0, 0)); + mat = glm::rotate(mat, mRot[1], glm::vec3(0, 1, 0)); + mat = glm::rotate(mat, mRot[2], glm::vec3(0, 0, 1)); + // 3. Position + mat = glm::translate(mat, glm::vec3(mPos[0], mPos[1], mPos[2])); + return mat; +} + //----------------------------------------------------------------------------- // LLAvatarSkeletonInfo::parseXml() //----------------------------------------------------------------------------- @@ -1653,6 +1686,25 @@ bool LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) return true; } +void LLAvatarSkeletonInfo::getJointMatricesAndHierarhy( + LLAvatarBoneInfo* bone_info, + LLJointData& data, + const glm::mat4& parent_mat) +{ + data.mName = bone_info->mName; + data.mJointMatrix = bone_info->getJointMatrix(); + data.mScale = glm::vec3(bone_info->mScale[0], bone_info->mScale[1], bone_info->mScale[2]); + data.mRotation = bone_info->mRot; + data.mRestMatrix = parent_mat * data.mJointMatrix; + data.mIsJoint = bone_info->mIsJoint; + data.mGroup = bone_info->mGroup; + for (LLAvatarBoneInfo* child_info : bone_info->mChildren) + { + LLJointData& child_data = data.mChildren.emplace_back(); + getJointMatricesAndHierarhy(child_info, child_data, data.mRestMatrix); + } +} + //Make aliases for joint and push to map. void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info) { @@ -1714,6 +1766,16 @@ const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases return mJointAliasMap; } +void LLAvatarAppearance::getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const +{ + glm::mat4 identity(1.f); + for (LLAvatarBoneInfo* bone_info : sAvatarSkeletonInfo->mBoneInfoList) + { + LLJointData& child_data = data.emplace_back(); + LLAvatarSkeletonInfo::getJointMatricesAndHierarhy(bone_info, child_data, identity); + } +} + //----------------------------------------------------------------------------- // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h index 13e504e639..84cb42056a 100644 --- a/indra/llappearance/llavatarappearance.h +++ b/indra/llappearance/llavatarappearance.h @@ -34,6 +34,7 @@ #include "lltexlayer.h" #include "llviewervisualparam.h" #include "llxmltree.h" +#include "v4math.h" class LLTexLayerSet; class LLTexGlobalColor; @@ -41,6 +42,7 @@ class LLTexGlobalColorInfo; class LLWearableData; class LLAvatarBoneInfo; class LLAvatarSkeletonInfo; +class LLJointData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLAvatarAppearance @@ -138,7 +140,7 @@ public: LLVector3 mHeadOffset{}; // current head position LLAvatarJoint* mRoot{ nullptr }; - typedef std::map<std::string, LLJoint*> joint_map_t; + typedef std::map<std::string, LLJoint*, std::less<>> joint_map_t; joint_map_t mJointMap; typedef std::map<std::string, LLVector3> joint_state_map_t; @@ -151,9 +153,11 @@ public: public: typedef std::vector<LLAvatarJoint*> avatar_joint_list_t; const avatar_joint_list_t& getSkeleton() { return mSkeleton; } - typedef std::map<std::string, std::string> joint_alias_map_t; + typedef std::map<std::string, std::string, std::less<>> joint_alias_map_t; const joint_alias_map_t& getJointAliases(); - + typedef std::map<std::string, std::string> joint_parent_map_t; // matrix plus parent + typedef std::map<std::string, glm::mat4> joint_rest_map_t; + void getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const; protected: static bool parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree); diff --git a/indra/llappearance/lljointdata.h b/indra/llappearance/lljointdata.h new file mode 100644 index 0000000000..2fc26198ee --- /dev/null +++ b/indra/llappearance/lljointdata.h @@ -0,0 +1,66 @@ +/** + * @file lljointdata.h + * @brief LLJointData class for holding individual joint data and skeleton + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLJOINTDATA_H +#define LL_LLJOINTDATA_H + +#include "v4math.h" + +// may be just move LLAvatarBoneInfo +class LLJointData +{ +public: + std::string mName; + std::string mGroup; + glm::mat4 mJointMatrix; + glm::mat4 mRestMatrix; + glm::vec3 mScale; + LLVector3 mRotation; + + typedef std::vector<LLJointData> bones_t; + bones_t mChildren; + + bool mIsJoint; // if not, collision_volume + enum SupportCategory + { + SUPPORT_BASE, + SUPPORT_EXTENDED + }; + SupportCategory mSupport; + void setSupport(const std::string& support) + { + if (support == "extended") + { + mSupport = SUPPORT_EXTENDED; + } + else + { + mSupport = SUPPORT_BASE; + } + } +}; + +#endif //LL_LLJOINTDATA_H diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 8df8a9726f..5ee6649164 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -550,12 +550,12 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) mLastSex = avatar_sex; - // Check for NaN condition (NaN is detected if a variable doesn't equal itself. - if (mCurWeight != mCurWeight) + // Check for NaN condition + if (llisnan(mCurWeight)) { - mCurWeight = 0.0; + mCurWeight = 0.f; } - if (mLastWeight != mLastWeight) + if (llisnan(mLastWeight)) { mLastWeight = mCurWeight+.001f; } diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index aa48a2d621..b3800e6981 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1293,7 +1293,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC { if (!force_render && !hasMorph()) { - LL_DEBUGS() << "skipping renderMorphMasks for " << getUUID() << LL_ENDL; + LL_DEBUGS("Morph") << "skipping renderMorphMasks for " << getUUID() << LL_ENDL; return; } LL_PROFILE_ZONE_SCOPED; @@ -1325,7 +1325,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC success &= param->render( x, y, width, height ); if (!success && !force_render) { - LL_DEBUGS() << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL; + LL_DEBUGS("Morph") << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL; return; } } @@ -1365,7 +1365,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } else { - LL_WARNS() << "Skipping rendering of " << getInfo()->mStaticImageFileName + LL_WARNS("Morph") << "Skipping rendering of " << getInfo()->mStaticImageFileName << "; expected 1 or 4 components." << LL_ENDL; } } @@ -1404,8 +1404,8 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // We can get bad morph masks during login, on minimize, and occasional gl errors. // We should only be doing this when we believe something has changed with respect to the user's appearance. { - LL_DEBUGS("Avatar") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL; - // clear out a slot if we have filled our cache + LL_DEBUGS("Morph") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL; + // clear out a slot if we have filled our cache S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1; while ((S32)mAlphaCache.size() >= max_cache_entries) { @@ -1444,13 +1444,20 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC } glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp); - - U8* alpha_cursor = alpha_data; - U8* pixel = temp; - for (int i = 0; i < pixels; i++) + GLenum error = glGetError(); + if (error != GL_NO_ERROR) + { + LL_INFOS("Morph") << "GL Error while reading back morph texture. Error code: " << error << LL_ENDL; + } + else { - *alpha_cursor++ = pixel[3]; - pixel += 4; + U8* alpha_cursor = alpha_data; + U8* pixel = temp; + for (int i = 0; i < pixels; i++) + { + *alpha_cursor++ = pixel[3]; + pixel += 4; + } } gGL.getTexUnit(0)->disable(); diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 9dace08e6f..581e9f62d5 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -131,7 +131,7 @@ LLQuaternion::Order bvhStringToOrder( char *str ) // LLBVHLoader() //----------------------------------------------------------------------------- -LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ) +LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map ) { reset(); errorLine = 0; @@ -156,9 +156,9 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error } // Recognize all names we've been told are legal. - for (std::map<std::string, std::string>::value_type& alias_pair : joint_alias_map) + for (const auto& [alias, joint] : joint_alias_map) { - makeTranslation( alias_pair.first , alias_pair.second ); + makeTranslation(alias, joint); } char error_text[128]; /* Flawfinder: ignore */ diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index de31f76dd3..ae2e347ba1 100644 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -227,7 +227,7 @@ class LLBVHLoader friend class LLKeyframeMotion; public: // Constructor - LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map ); + LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map ); ~LLBVHLoader(); /* diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp index ecbcdb3bf5..8efcd9dd29 100644 --- a/indra/llcharacter/llcharacter.cpp +++ b/indra/llcharacter/llcharacter.cpp @@ -77,12 +77,11 @@ LLCharacter::~LLCharacter() //----------------------------------------------------------------------------- // getJoint() //----------------------------------------------------------------------------- -LLJoint *LLCharacter::getJoint( const std::string &name ) +LLJoint* LLCharacter::getJoint(std::string_view name) { - LLJoint* joint = NULL; + LLJoint* joint = nullptr; - LLJoint *root = getRootJoint(); - if (root) + if (LLJoint* root = getRootJoint()) { joint = root->findJoint(name); } diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h index 6143ec8cd1..079bcd132a 100644 --- a/indra/llcharacter/llcharacter.h +++ b/indra/llcharacter/llcharacter.h @@ -76,7 +76,7 @@ public: // get the specified joint // default implementation does recursive search, // subclasses may optimize/cache results. - virtual LLJoint *getJoint( const std::string &name ); + virtual LLJoint* getJoint(std::string_view name); // get the position of the character virtual LLVector3 getCharacterPosition() = 0; @@ -119,6 +119,8 @@ public: virtual void addDebugText( const std::string& text ) = 0; + virtual std::string getDebugName() const { return getID().asString(); } + virtual const LLUUID& getID() const = 0; //------------------------------------------------------------------------- // End Interface diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp index f31aa5d4c9..405e62a38b 100644 --- a/indra/llcharacter/lljoint.cpp +++ b/indra/llcharacter/lljoint.cpp @@ -242,21 +242,20 @@ LLJoint *LLJoint::getRoot() //----------------------------------------------------------------------------- // findJoint() //----------------------------------------------------------------------------- -LLJoint *LLJoint::findJoint( const std::string &name ) +LLJoint* LLJoint::findJoint(std::string_view name) { if (name == getName()) return this; for (LLJoint* joint : mChildren) { - LLJoint *found = joint->findJoint(name); - if (found) + if (LLJoint* found = joint->findJoint(name)) { return found; } } - return NULL; + return nullptr; } diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h index 763c1e3865..b58dc797f8 100644 --- a/indra/llcharacter/lljoint.h +++ b/indra/llcharacter/lljoint.h @@ -222,7 +222,7 @@ public: LLJoint *getRoot(); // search for child joints by name - LLJoint *findJoint( const std::string &name ); + LLJoint* findJoint(std::string_view name); // add/remove children void addChild( LLJoint *joint ); diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index c6bdab007f..a0394da281 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -31,15 +31,15 @@ class LLUUID; -static const F32 REGION_WIDTH_METERS = 256.f; -static const S32 REGION_WIDTH_UNITS = 256; -static const U32 REGION_WIDTH_U32 = 256; +static constexpr F32 REGION_WIDTH_METERS = 256.f; +static constexpr S32 REGION_WIDTH_UNITS = 256; +static constexpr U32 REGION_WIDTH_U32 = 256; -const F32 REGION_HEIGHT_METERS = 4096.f; +constexpr F32 REGION_HEIGHT_METERS = 4096.f; -const F32 DEFAULT_AGENT_DEPTH = 0.45f; -const F32 DEFAULT_AGENT_WIDTH = 0.60f; -const F32 DEFAULT_AGENT_HEIGHT = 1.9f; +constexpr F32 DEFAULT_AGENT_DEPTH = 0.45f; +constexpr F32 DEFAULT_AGENT_WIDTH = 0.60f; +constexpr F32 DEFAULT_AGENT_HEIGHT = 1.9f; enum ETerrainBrushType { @@ -67,112 +67,112 @@ enum EMouseClickType{ // keys // Bit masks for various keyboard modifier keys. -const MASK MASK_NONE = 0x0000; -const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs -const MASK MASK_ALT = 0x0002; -const MASK MASK_SHIFT = 0x0004; -const MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys -const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows -const MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL; +constexpr MASK MASK_NONE = 0x0000; +constexpr MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs +constexpr MASK MASK_ALT = 0x0002; +constexpr MASK MASK_SHIFT = 0x0004; +constexpr MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys +constexpr MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows +constexpr MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL; // Special keys go into >128 -const KEY KEY_SPECIAL = 0x80; // special keys start here -const KEY KEY_RETURN = 0x81; -const KEY KEY_LEFT = 0x82; -const KEY KEY_RIGHT = 0x83; -const KEY KEY_UP = 0x84; -const KEY KEY_DOWN = 0x85; -const KEY KEY_ESCAPE = 0x86; -const KEY KEY_BACKSPACE =0x87; -const KEY KEY_DELETE = 0x88; -const KEY KEY_SHIFT = 0x89; -const KEY KEY_CONTROL = 0x8A; -const KEY KEY_ALT = 0x8B; -const KEY KEY_HOME = 0x8C; -const KEY KEY_END = 0x8D; -const KEY KEY_PAGE_UP = 0x8E; -const KEY KEY_PAGE_DOWN = 0x8F; -const KEY KEY_HYPHEN = 0x90; -const KEY KEY_EQUALS = 0x91; -const KEY KEY_INSERT = 0x92; -const KEY KEY_CAPSLOCK = 0x93; -const KEY KEY_TAB = 0x94; -const KEY KEY_ADD = 0x95; -const KEY KEY_SUBTRACT =0x96; -const KEY KEY_MULTIPLY =0x97; -const KEY KEY_DIVIDE = 0x98; -const KEY KEY_F1 = 0xA1; -const KEY KEY_F2 = 0xA2; -const KEY KEY_F3 = 0xA3; -const KEY KEY_F4 = 0xA4; -const KEY KEY_F5 = 0xA5; -const KEY KEY_F6 = 0xA6; -const KEY KEY_F7 = 0xA7; -const KEY KEY_F8 = 0xA8; -const KEY KEY_F9 = 0xA9; -const KEY KEY_F10 = 0xAA; -const KEY KEY_F11 = 0xAB; -const KEY KEY_F12 = 0xAC; - -const KEY KEY_PAD_UP = 0xC0; -const KEY KEY_PAD_DOWN = 0xC1; -const KEY KEY_PAD_LEFT = 0xC2; -const KEY KEY_PAD_RIGHT = 0xC3; -const KEY KEY_PAD_HOME = 0xC4; -const KEY KEY_PAD_END = 0xC5; -const KEY KEY_PAD_PGUP = 0xC6; -const KEY KEY_PAD_PGDN = 0xC7; -const KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle -const KEY KEY_PAD_INS = 0xC9; -const KEY KEY_PAD_DEL = 0xCA; -const KEY KEY_PAD_RETURN = 0xCB; -const KEY KEY_PAD_ADD = 0xCC; // not used -const KEY KEY_PAD_SUBTRACT = 0xCD; // not used -const KEY KEY_PAD_MULTIPLY = 0xCE; // not used -const KEY KEY_PAD_DIVIDE = 0xCF; // not used - -const KEY KEY_BUTTON0 = 0xD0; -const KEY KEY_BUTTON1 = 0xD1; -const KEY KEY_BUTTON2 = 0xD2; -const KEY KEY_BUTTON3 = 0xD3; -const KEY KEY_BUTTON4 = 0xD4; -const KEY KEY_BUTTON5 = 0xD5; -const KEY KEY_BUTTON6 = 0xD6; -const KEY KEY_BUTTON7 = 0xD7; -const KEY KEY_BUTTON8 = 0xD8; -const KEY KEY_BUTTON9 = 0xD9; -const KEY KEY_BUTTON10 = 0xDA; -const KEY KEY_BUTTON11 = 0xDB; -const KEY KEY_BUTTON12 = 0xDC; -const KEY KEY_BUTTON13 = 0xDD; -const KEY KEY_BUTTON14 = 0xDE; -const KEY KEY_BUTTON15 = 0xDF; - -const KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only. - -const S32 KEY_COUNT = 256; - - -const F32 DEFAULT_WATER_HEIGHT = 20.0f; +constexpr KEY KEY_SPECIAL = 0x80; // special keys start here +constexpr KEY KEY_RETURN = 0x81; +constexpr KEY KEY_LEFT = 0x82; +constexpr KEY KEY_RIGHT = 0x83; +constexpr KEY KEY_UP = 0x84; +constexpr KEY KEY_DOWN = 0x85; +constexpr KEY KEY_ESCAPE = 0x86; +constexpr KEY KEY_BACKSPACE =0x87; +constexpr KEY KEY_DELETE = 0x88; +constexpr KEY KEY_SHIFT = 0x89; +constexpr KEY KEY_CONTROL = 0x8A; +constexpr KEY KEY_ALT = 0x8B; +constexpr KEY KEY_HOME = 0x8C; +constexpr KEY KEY_END = 0x8D; +constexpr KEY KEY_PAGE_UP = 0x8E; +constexpr KEY KEY_PAGE_DOWN = 0x8F; +constexpr KEY KEY_HYPHEN = 0x90; +constexpr KEY KEY_EQUALS = 0x91; +constexpr KEY KEY_INSERT = 0x92; +constexpr KEY KEY_CAPSLOCK = 0x93; +constexpr KEY KEY_TAB = 0x94; +constexpr KEY KEY_ADD = 0x95; +constexpr KEY KEY_SUBTRACT =0x96; +constexpr KEY KEY_MULTIPLY =0x97; +constexpr KEY KEY_DIVIDE = 0x98; +constexpr KEY KEY_F1 = 0xA1; +constexpr KEY KEY_F2 = 0xA2; +constexpr KEY KEY_F3 = 0xA3; +constexpr KEY KEY_F4 = 0xA4; +constexpr KEY KEY_F5 = 0xA5; +constexpr KEY KEY_F6 = 0xA6; +constexpr KEY KEY_F7 = 0xA7; +constexpr KEY KEY_F8 = 0xA8; +constexpr KEY KEY_F9 = 0xA9; +constexpr KEY KEY_F10 = 0xAA; +constexpr KEY KEY_F11 = 0xAB; +constexpr KEY KEY_F12 = 0xAC; + +constexpr KEY KEY_PAD_UP = 0xC0; +constexpr KEY KEY_PAD_DOWN = 0xC1; +constexpr KEY KEY_PAD_LEFT = 0xC2; +constexpr KEY KEY_PAD_RIGHT = 0xC3; +constexpr KEY KEY_PAD_HOME = 0xC4; +constexpr KEY KEY_PAD_END = 0xC5; +constexpr KEY KEY_PAD_PGUP = 0xC6; +constexpr KEY KEY_PAD_PGDN = 0xC7; +constexpr KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle +constexpr KEY KEY_PAD_INS = 0xC9; +constexpr KEY KEY_PAD_DEL = 0xCA; +constexpr KEY KEY_PAD_RETURN = 0xCB; +constexpr KEY KEY_PAD_ADD = 0xCC; // not used +constexpr KEY KEY_PAD_SUBTRACT = 0xCD; // not used +constexpr KEY KEY_PAD_MULTIPLY = 0xCE; // not used +constexpr KEY KEY_PAD_DIVIDE = 0xCF; // not used + +constexpr KEY KEY_BUTTON0 = 0xD0; +constexpr KEY KEY_BUTTON1 = 0xD1; +constexpr KEY KEY_BUTTON2 = 0xD2; +constexpr KEY KEY_BUTTON3 = 0xD3; +constexpr KEY KEY_BUTTON4 = 0xD4; +constexpr KEY KEY_BUTTON5 = 0xD5; +constexpr KEY KEY_BUTTON6 = 0xD6; +constexpr KEY KEY_BUTTON7 = 0xD7; +constexpr KEY KEY_BUTTON8 = 0xD8; +constexpr KEY KEY_BUTTON9 = 0xD9; +constexpr KEY KEY_BUTTON10 = 0xDA; +constexpr KEY KEY_BUTTON11 = 0xDB; +constexpr KEY KEY_BUTTON12 = 0xDC; +constexpr KEY KEY_BUTTON13 = 0xDD; +constexpr KEY KEY_BUTTON14 = 0xDE; +constexpr KEY KEY_BUTTON15 = 0xDF; + +constexpr KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only. + +constexpr S32 KEY_COUNT = 256; + + +constexpr F32 DEFAULT_WATER_HEIGHT = 20.0f; // Maturity ratings for simulators -const U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG -const U8 SIM_ACCESS_PG = 13; -const U8 SIM_ACCESS_MATURE = 21; -const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only -const U8 SIM_ACCESS_DOWN = 254; -const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT; +constexpr U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG +constexpr U8 SIM_ACCESS_PG = 13; +constexpr U8 SIM_ACCESS_MATURE = 21; +constexpr U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only +constexpr U8 SIM_ACCESS_DOWN = 254; +constexpr U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT; // attachment constants -const U8 ATTACHMENT_ADD = 0x80; +constexpr U8 ATTACHMENT_ADD = 0x80; // god levels -const U8 GOD_MAINTENANCE = 250; -const U8 GOD_FULL = 200; -const U8 GOD_LIAISON = 150; -const U8 GOD_CUSTOMER_SERVICE = 100; -const U8 GOD_LIKE = 1; -const U8 GOD_NOT = 0; +constexpr U8 GOD_MAINTENANCE = 250; +constexpr U8 GOD_FULL = 200; +constexpr U8 GOD_LIAISON = 150; +constexpr U8 GOD_CUSTOMER_SERVICE = 100; +constexpr U8 GOD_LIKE = 1; +constexpr U8 GOD_NOT = 0; // "agent id" for things that should be done to ALL agents LL_COMMON_API extern const LLUUID LL_UUID_ALL_AGENTS; @@ -239,120 +239,120 @@ LL_COMMON_API extern const LLUUID BLANK_OBJECT_NORMAL; LL_COMMON_API extern const LLUUID BLANK_MATERIAL_ASSET_ID; // radius within which a chat message is fully audible -const F32 CHAT_NORMAL_RADIUS = 20.f; +constexpr F32 CHAT_NORMAL_RADIUS = 20.f; // media commands -const U32 PARCEL_MEDIA_COMMAND_STOP = 0; -const U32 PARCEL_MEDIA_COMMAND_PAUSE = 1; -const U32 PARCEL_MEDIA_COMMAND_PLAY = 2; -const U32 PARCEL_MEDIA_COMMAND_LOOP = 3; -const U32 PARCEL_MEDIA_COMMAND_TEXTURE = 4; -const U32 PARCEL_MEDIA_COMMAND_URL = 5; -const U32 PARCEL_MEDIA_COMMAND_TIME = 6; -const U32 PARCEL_MEDIA_COMMAND_AGENT = 7; -const U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8; -const U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; -const U32 PARCEL_MEDIA_COMMAND_TYPE = 10; -const U32 PARCEL_MEDIA_COMMAND_SIZE = 11; -const U32 PARCEL_MEDIA_COMMAND_DESC = 12; -const U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13; +constexpr U32 PARCEL_MEDIA_COMMAND_STOP = 0; +constexpr U32 PARCEL_MEDIA_COMMAND_PAUSE = 1; +constexpr U32 PARCEL_MEDIA_COMMAND_PLAY = 2; +constexpr U32 PARCEL_MEDIA_COMMAND_LOOP = 3; +constexpr U32 PARCEL_MEDIA_COMMAND_TEXTURE = 4; +constexpr U32 PARCEL_MEDIA_COMMAND_URL = 5; +constexpr U32 PARCEL_MEDIA_COMMAND_TIME = 6; +constexpr U32 PARCEL_MEDIA_COMMAND_AGENT = 7; +constexpr U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8; +constexpr U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; +constexpr U32 PARCEL_MEDIA_COMMAND_TYPE = 10; +constexpr U32 PARCEL_MEDIA_COMMAND_SIZE = 11; +constexpr U32 PARCEL_MEDIA_COMMAND_DESC = 12; +constexpr U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13; const S32 CHAT_CHANNEL_DEBUG = S32_MAX; // agent constants -const U32 CONTROL_AT_POS_INDEX = 0; -const U32 CONTROL_AT_NEG_INDEX = 1; -const U32 CONTROL_LEFT_POS_INDEX = 2; -const U32 CONTROL_LEFT_NEG_INDEX = 3; -const U32 CONTROL_UP_POS_INDEX = 4; -const U32 CONTROL_UP_NEG_INDEX = 5; -const U32 CONTROL_PITCH_POS_INDEX = 6; -const U32 CONTROL_PITCH_NEG_INDEX = 7; -const U32 CONTROL_YAW_POS_INDEX = 8; -const U32 CONTROL_YAW_NEG_INDEX = 9; -const U32 CONTROL_FAST_AT_INDEX = 10; -const U32 CONTROL_FAST_LEFT_INDEX = 11; -const U32 CONTROL_FAST_UP_INDEX = 12; -const U32 CONTROL_FLY_INDEX = 13; -const U32 CONTROL_STOP_INDEX = 14; -const U32 CONTROL_FINISH_ANIM_INDEX = 15; -const U32 CONTROL_STAND_UP_INDEX = 16; -const U32 CONTROL_SIT_ON_GROUND_INDEX = 17; -const U32 CONTROL_MOUSELOOK_INDEX = 18; -const U32 CONTROL_NUDGE_AT_POS_INDEX = 19; -const U32 CONTROL_NUDGE_AT_NEG_INDEX = 20; -const U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21; -const U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22; -const U32 CONTROL_NUDGE_UP_POS_INDEX = 23; -const U32 CONTROL_NUDGE_UP_NEG_INDEX = 24; -const U32 CONTROL_TURN_LEFT_INDEX = 25; -const U32 CONTROL_TURN_RIGHT_INDEX = 26; -const U32 CONTROL_AWAY_INDEX = 27; -const U32 CONTROL_LBUTTON_DOWN_INDEX = 28; -const U32 CONTROL_LBUTTON_UP_INDEX = 29; -const U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30; -const U32 CONTROL_ML_LBUTTON_UP_INDEX = 31; -const U32 TOTAL_CONTROLS = 32; - -const U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001 -const U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002 -const U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004 -const U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008 -const U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010 -const U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020 -const U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040 -const U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080 -const U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100 -const U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200 - -const U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400 -const U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800 -const U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000 - -const U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000 -const U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000 -const U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000 -const U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000 -const U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000 -const U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000 - -const U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000 -const U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000 -const U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000 -const U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000 -const U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000 -const U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000 -const U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000 -const U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000 - -const U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000 - -const U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000 -const U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000 -const U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000 -const U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000 +constexpr U32 CONTROL_AT_POS_INDEX = 0; +constexpr U32 CONTROL_AT_NEG_INDEX = 1; +constexpr U32 CONTROL_LEFT_POS_INDEX = 2; +constexpr U32 CONTROL_LEFT_NEG_INDEX = 3; +constexpr U32 CONTROL_UP_POS_INDEX = 4; +constexpr U32 CONTROL_UP_NEG_INDEX = 5; +constexpr U32 CONTROL_PITCH_POS_INDEX = 6; +constexpr U32 CONTROL_PITCH_NEG_INDEX = 7; +constexpr U32 CONTROL_YAW_POS_INDEX = 8; +constexpr U32 CONTROL_YAW_NEG_INDEX = 9; +constexpr U32 CONTROL_FAST_AT_INDEX = 10; +constexpr U32 CONTROL_FAST_LEFT_INDEX = 11; +constexpr U32 CONTROL_FAST_UP_INDEX = 12; +constexpr U32 CONTROL_FLY_INDEX = 13; +constexpr U32 CONTROL_STOP_INDEX = 14; +constexpr U32 CONTROL_FINISH_ANIM_INDEX = 15; +constexpr U32 CONTROL_STAND_UP_INDEX = 16; +constexpr U32 CONTROL_SIT_ON_GROUND_INDEX = 17; +constexpr U32 CONTROL_MOUSELOOK_INDEX = 18; +constexpr U32 CONTROL_NUDGE_AT_POS_INDEX = 19; +constexpr U32 CONTROL_NUDGE_AT_NEG_INDEX = 20; +constexpr U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21; +constexpr U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22; +constexpr U32 CONTROL_NUDGE_UP_POS_INDEX = 23; +constexpr U32 CONTROL_NUDGE_UP_NEG_INDEX = 24; +constexpr U32 CONTROL_TURN_LEFT_INDEX = 25; +constexpr U32 CONTROL_TURN_RIGHT_INDEX = 26; +constexpr U32 CONTROL_AWAY_INDEX = 27; +constexpr U32 CONTROL_LBUTTON_DOWN_INDEX = 28; +constexpr U32 CONTROL_LBUTTON_UP_INDEX = 29; +constexpr U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30; +constexpr U32 CONTROL_ML_LBUTTON_UP_INDEX = 31; +constexpr U32 TOTAL_CONTROLS = 32; + +constexpr U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001 +constexpr U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002 +constexpr U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004 +constexpr U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008 +constexpr U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010 +constexpr U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020 +constexpr U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040 +constexpr U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080 +constexpr U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100 +constexpr U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200 + +constexpr U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400 +constexpr U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800 +constexpr U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000 + +constexpr U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000 +constexpr U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000 +constexpr U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000 +constexpr U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000 +constexpr U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000 +constexpr U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000 + +constexpr U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000 +constexpr U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000 +constexpr U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000 +constexpr U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000 +constexpr U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000 +constexpr U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000 +constexpr U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000 +constexpr U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000 + +constexpr U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000 + +constexpr U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000 +constexpr U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000 +constexpr U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000 +constexpr U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000 // move these up so that we can hide them in "State" for object updates // (for now) -const U32 AGENT_ATTACH_OFFSET = 4; -const U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET; +constexpr U32 AGENT_ATTACH_OFFSET = 4; +constexpr U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET; // RN: this method swaps the upper and lower nibbles to maintain backward // compatibility with old objects that only used the upper nibble #define ATTACHMENT_ID_FROM_STATE(state) ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4))) // DO NOT CHANGE THE SEQUENCE OF THIS LIST!! -const U8 CLICK_ACTION_NONE = 0; -const U8 CLICK_ACTION_TOUCH = 0; -const U8 CLICK_ACTION_SIT = 1; -const U8 CLICK_ACTION_BUY = 2; -const U8 CLICK_ACTION_PAY = 3; -const U8 CLICK_ACTION_OPEN = 4; -const U8 CLICK_ACTION_PLAY = 5; -const U8 CLICK_ACTION_OPEN_MEDIA = 6; -const U8 CLICK_ACTION_ZOOM = 7; -const U8 CLICK_ACTION_DISABLED = 8; -const U8 CLICK_ACTION_IGNORE = 9; +constexpr U8 CLICK_ACTION_NONE = 0; +constexpr U8 CLICK_ACTION_TOUCH = 0; +constexpr U8 CLICK_ACTION_SIT = 1; +constexpr U8 CLICK_ACTION_BUY = 2; +constexpr U8 CLICK_ACTION_PAY = 3; +constexpr U8 CLICK_ACTION_OPEN = 4; +constexpr U8 CLICK_ACTION_PLAY = 5; +constexpr U8 CLICK_ACTION_OPEN_MEDIA = 6; +constexpr U8 CLICK_ACTION_ZOOM = 7; +constexpr U8 CLICK_ACTION_DISABLED = 8; +constexpr U8 CLICK_ACTION_IGNORE = 9; // DO NOT CHANGE THE SEQUENCE OF THIS LIST!! constexpr U32 BEACON_SHOW_MAP = 0x0001; diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index c09cf7abd2..9672a3262b 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -29,6 +29,7 @@ #include "llassettype.h" #include "lldictionary.h" #include "llmemory.h" +#include "llsd.h" #include "llsingleton.h" ///---------------------------------------------------------------------------- @@ -246,3 +247,19 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type) } return false; } + +LLSD LLAssetType::getTypeNames() +{ + LLSD type_names; + const LLAssetDictionary *dict = LLAssetDictionary::getInstance(); + for (S32 type = AT_TEXTURE; type < AT_COUNT; ++type) + { + const AssetEntry *entry = dict->lookup((LLAssetType::EType) type); + // skip llassettype_bad_lookup + if (entry) + { + type_names.append(entry->mTypeName); + } + } + return type_names; +} diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 547c3f4329..17177d81c3 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -165,6 +165,8 @@ public: static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer + static LLSD getTypeNames(); + static const std::string BADLOOKUP; protected: diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index 2fbb26dc1a..232987da14 100644 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -171,13 +171,13 @@ constexpr U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 + // recursion tail template <typename T> -inline auto llmax(T data) +constexpr auto llmax(T data) { return data; } template <typename T0, typename T1, typename... Ts> -inline auto llmax(T0 d0, T1 d1, Ts... rest) +constexpr auto llmax(T0 d0, T1 d1, Ts... rest) { auto maxrest = llmax(d1, rest...); return (d0 > maxrest)? d0 : maxrest; @@ -185,20 +185,20 @@ inline auto llmax(T0 d0, T1 d1, Ts... rest) // recursion tail template <typename T> -inline auto llmin(T data) +constexpr auto llmin(T data) { return data; } template <typename T0, typename T1, typename... Ts> -inline auto llmin(T0 d0, T1 d1, Ts... rest) +constexpr auto llmin(T0 d0, T1 d1, Ts... rest) { auto minrest = llmin(d1, rest...); return (d0 < minrest) ? d0 : minrest; } template <typename A, typename MIN, typename MAX> -inline A llclamp(A a, MIN minval, MAX maxval) +constexpr A llclamp(A a, MIN minval, MAX maxval) { A aminval{ static_cast<A>(minval) }, amaxval{ static_cast<A>(maxval) }; if ( a < aminval ) @@ -213,13 +213,13 @@ inline A llclamp(A a, MIN minval, MAX maxval) } template <class LLDATATYPE> -inline LLDATATYPE llclampf(LLDATATYPE a) +constexpr LLDATATYPE llclampf(LLDATATYPE a) { return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(1)); } template <class LLDATATYPE> -inline LLDATATYPE llclampb(LLDATATYPE a) +constexpr LLDATATYPE llclampb(LLDATATYPE a) { return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(255)); } diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index c31030c5ea..497c0ad3eb 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -554,6 +554,45 @@ LLSD shallow(LLSD value, LLSD filter=LLSD()) { return llsd_shallow(value, filter } // namespace llsd /***************************************************************************** +* LLSDParam<std::vector<T>> +*****************************************************************************/ +// Given an LLSD array, return a const std::vector<T>&, where T is a type +// supported by LLSDParam. Bonus: if the LLSD value is actually a scalar, +// return a single-element vector containing the converted value. +template <typename T> +class LLSDParam<std::vector<T>>: public LLSDParamBase +{ +public: + LLSDParam(const LLSD& array) + { + // treat undefined "array" as empty vector + if (array.isDefined()) + { + // what if it's a scalar? + if (! array.isArray()) + { + v.push_back(LLSDParam<T>(array)); + } + else // really is an array + { + // reserve space for the array entries + v.reserve(array.size()); + for (const auto& item : llsd::inArray(array)) + { + v.push_back(LLSDParam<T>(item)); + } + } + } + } + + operator const std::vector<T>&() const { return v; } + +private: + std::vector<T> v; +}; + + +/***************************************************************************** * toArray(), toMap() *****************************************************************************/ namespace llsd diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index e5d25b52f0..692941a892 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -28,6 +28,7 @@ #include "apr_portable.h" +#include "llapp.h" #include "llthread.h" #include "llmutex.h" @@ -35,6 +36,7 @@ #include "lltrace.h" #include "lltracethreadrecorder.h" #include "llexception.h" +#include "workqueue.h" #if LL_LINUX #include <sched.h> @@ -106,6 +108,27 @@ namespace return s_thread_id; } +#if LL_WINDOWS + + static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific + + U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop) + { + if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop)) + { + // Handled + return EXCEPTION_CONTINUE_SEARCH; + } + else if (code == STATUS_MSC_EXCEPTION) + { + // C++ exception, go on + return EXCEPTION_CONTINUE_SEARCH; + } + + // handle it, convert to std::exception + return EXCEPTION_EXECUTE_HANDLER; + } +#endif // LL_WINDOWS } // anonymous namespace LL_COMMON_API bool on_main_thread() @@ -157,20 +180,11 @@ void LLThread::threadRun() // Run the user supplied function do { - try - { - run(); - } - catch (const LLContinueError &e) - { - LL_WARNS("THREAD") << "ContinueException on thread '" << mName << - "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL; - //output possible call stacks to log file. - LLError::LLCallStacks::print(); - - LOG_UNHANDLED_EXCEPTION("LLThread"); - continue; - } +#ifdef LL_WINDOWS + sehHandle(); // Structured Exception Handling +#else + tryRun(); +#endif break; } while (true); @@ -188,6 +202,69 @@ void LLThread::threadRun() mStatus = STOPPED; } +void LLThread::tryRun() +{ + try + { + run(); + } + catch (const LLContinueError& e) + { + LL_WARNS("THREAD") << "ContinueException on thread '" << mName << + "'. Error what is: '" << e.what() << "'" << LL_ENDL; + LLError::LLCallStacks::print(); + + LOG_UNHANDLED_EXCEPTION("LLThread"); + } + catch (std::bad_alloc&) + { + // Todo: improve this, this is going to have a different callstack + // instead of showing where it crashed + LL_WARNS("THREAD") << "Out of memory in a thread: " << mName << LL_ENDL; + + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + main_queue->post( + // Bind the current exception, rethrow it in main loop. + []() { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("THREAD") << "Out of memory in a thread" << LL_ENDL; + }); + } +#ifndef LL_WINDOWS + catch (...) + { + // Stash any other kind of uncaught exception to be rethrown by main thread. + LL_WARNS("THREAD") << "Capturing and rethrowing uncaught exception in LLThread " + << mName << LL_ENDL; + + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + main_queue->post( + // Bind the current exception, rethrow it in main loop. + [exc = std::current_exception()]() { std::rethrow_exception(exc); }); + } +#endif // else LL_WINDOWS +} + +#ifdef LL_WINDOWS +void LLThread::sehHandle() +{ + __try + { + // handle stop and continue exceptions first + tryRun(); + } + __except (exception_filter(GetExceptionCode(), GetExceptionInformation())) + { + // convert to C++ styled exception + // Note: it might be better to use _se_set_translator + // if you want exception to inherit full callstack + char integer_string[512]; + sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode()); + throw std::exception(integer_string); + } +} +#endif + LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mPaused(false), mName(name), diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 4194e0014d..8794ac93aa 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -68,7 +68,7 @@ public: // Called from MAIN THREAD. void pause(); void unpause(); - bool isPaused() { return isStopped() || mPaused; } + bool isPaused() const { return isStopped() || mPaused; } // Cause the thread to wake up and check its condition void wake(); @@ -97,6 +97,11 @@ private: // static function passed to APR thread creation routine void threadRun(); + void tryRun(); + +#ifdef LL_WINDOWS + void sehHandle(); +#endif protected: std::string mName; diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index 28e50b3d21..f1e4c2bc78 100644 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h @@ -164,14 +164,14 @@ private: FROM mValue; public: - narrow(FROM value): mValue(value) {} + constexpr narrow(FROM value): mValue(value) {} /*---------------------- Narrowing unsigned to signed ----------------------*/ template <typename TO, typename std::enable_if<std::is_unsigned<FROM>::value && std::is_signed<TO>::value, bool>::type = true> - inline + constexpr operator TO() const { // The reason we skip the @@ -189,7 +189,7 @@ public: typename std::enable_if<! (std::is_unsigned<FROM>::value && std::is_signed<TO>::value), bool>::type = true> - inline + constexpr operator TO() const { // two different assert()s so we can tell which condition failed diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index 0eb1891754..ac4f415f3e 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -55,7 +55,7 @@ namespace LL * ThreadPool listens for application shutdown messages on the "LLApp" * LLEventPump. Call close() to shut down this ThreadPool early. */ - virtual void close(); + void close(); std::string getName() const { return mName; } size_t getWidth() const { return mThreads.size(); } @@ -122,7 +122,7 @@ namespace LL size_t threads=1, size_t capacity=1024*1024, bool auto_shutdown = true): - ThreadPoolBase(name, threads, new queue_t(name, capacity), auto_shutdown) + ThreadPoolBase(name, threads, new queue_t(name, capacity, false), auto_shutdown) {} ~ThreadPoolUsing() override {} diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp index c8ece616b2..7efaebd569 100644 --- a/indra/llcommon/workqueue.cpp +++ b/indra/llcommon/workqueue.cpp @@ -21,6 +21,7 @@ #include "llcoros.h" #include LLCOROS_MUTEX_HEADER #include "llerror.h" +#include "llevents.h" #include "llexception.h" #include "stringize.h" @@ -30,11 +31,38 @@ using Lock = LLCoros::LockType; /***************************************************************************** * WorkQueueBase *****************************************************************************/ -LL::WorkQueueBase::WorkQueueBase(const std::string& name): - super(makeName(name)) +LL::WorkQueueBase::WorkQueueBase(const std::string& name, bool auto_shutdown) + : super(makeName(name)) { - // TODO: register for "LLApp" events so we can implicitly close() on - // viewer shutdown. + if (auto_shutdown) + { + // Register for "LLApp" events so we can implicitly close() on viewer shutdown + std::string listener_name = "WorkQueue:" + getKey(); + LLEventPumps::instance().obtain("LLApp").listen( + listener_name, + [this](const LLSD& stat) + { + std::string status(stat["status"]); + if (status != "running") + { + // Viewer is shutting down, close this queue + LL_DEBUGS("WorkQueue") << getKey() << " closing on app shutdown" << LL_ENDL; + close(); + } + return false; + }); + + // Store the listener name so we can unregister in the destructor + mListenerName = listener_name; + } +} + +LL::WorkQueueBase::~WorkQueueBase() +{ + if (!mListenerName.empty() && !LLEventPumps::wasDeleted()) + { + LLEventPumps::instance().obtain("LLApp").stopListening(mListenerName); + } } void LL::WorkQueueBase::runUntilClose() @@ -182,14 +210,22 @@ void LL::WorkQueueBase::callWork(const Work& work) } catch (...) { - // Stash any other kind of uncaught exception to be rethrown by main thread. - LL_WARNS("LLCoros") << "Capturing and rethrowing uncaught exception in WorkQueueBase " - << getKey() << LL_ENDL; - - LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); - main_queue->post( - // Bind the current exception, rethrow it in main loop. - [exc = std::current_exception()]() { std::rethrow_exception(exc); }); + if (getKey() != "mainloop") + { + // Stash any other kind of uncaught exception to be rethrown by main thread. + LL_WARNS("LLCoros") << "Capturing and rethrowing uncaught exception in WorkQueueBase " + << getKey() << LL_ENDL; + + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + main_queue->post( + // Bind the current exception, rethrow it in main loop. + [exc = std::current_exception()]() { std::rethrow_exception(exc); }); + } + else + { + // let main loop crash + throw; + } } #endif // else LL_WINDOWS } @@ -212,8 +248,8 @@ void LL::WorkQueueBase::checkCoroutine(const std::string& method) /***************************************************************************** * WorkQueue *****************************************************************************/ -LL::WorkQueue::WorkQueue(const std::string& name, size_t capacity): - super(name), +LL::WorkQueue::WorkQueue(const std::string& name, size_t capacity, bool auto_shutdown): + super(name, auto_shutdown), mQueue(capacity) { } @@ -261,8 +297,8 @@ bool LL::WorkQueue::tryPop_(Work& work) /***************************************************************************** * WorkSchedule *****************************************************************************/ -LL::WorkSchedule::WorkSchedule(const std::string& name, size_t capacity): - super(name), +LL::WorkSchedule::WorkSchedule(const std::string& name, size_t capacity, bool auto_shutdown): + super(name, auto_shutdown), mQueue(capacity) { } diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 9d7bbfbf7a..735ad38a26 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -51,7 +51,9 @@ namespace LL * You may omit the WorkQueueBase name, in which case a unique name is * synthesized; for practical purposes that makes it anonymous. */ - WorkQueueBase(const std::string& name); + WorkQueueBase(const std::string& name, bool auto_shutdown); + + virtual ~WorkQueueBase(); /** * Since the point of WorkQueue is to pass work to some other worker @@ -197,6 +199,9 @@ namespace LL private: virtual Work pop_() = 0; virtual bool tryPop_(Work&) = 0; + + // Name used for the LLApp event listener (empty if not registered) + std::string mListenerName; }; /***************************************************************************** @@ -212,7 +217,7 @@ namespace LL * You may omit the WorkQueue name, in which case a unique name is * synthesized; for practical purposes that makes it anonymous. */ - WorkQueue(const std::string& name = std::string(), size_t capacity=1024); + WorkQueue(const std::string& name = std::string(), size_t capacity=1024, bool auto_shutdown = true); /** * Since the point of WorkQueue is to pass work to some other worker @@ -282,7 +287,7 @@ namespace LL * You may omit the WorkSchedule name, in which case a unique name is * synthesized; for practical purposes that makes it anonymous. */ - WorkSchedule(const std::string& name = std::string(), size_t capacity=1024); + WorkSchedule(const std::string& name = std::string(), size_t capacity=1024, bool auto_shutdown = true); /** * Since the point of WorkSchedule is to pass work to some other worker diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 6186e7a308..081a4d9bac 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -538,6 +538,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) long sslHostV(0L); long dnsCacheTimeout(-1L); long nobody(0L); + curl_off_t lastModified(0L); if (mReqOptions) { @@ -546,6 +547,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) sslHostV = mReqOptions->getSSLVerifyHost() ? 2L : 0L; dnsCacheTimeout = mReqOptions->getDNSCacheTimeout(); nobody = mReqOptions->getHeadersOnly() ? 1L : 0L; + lastModified = (curl_off_t)mReqOptions->getLastModified(); } check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect); @@ -554,6 +556,17 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) check_curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody); + if (lastModified) + { + check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE); +#if (LIBCURL_VERSION_NUM >= 0x073B00) + // requires curl 7.59.0 + check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE_LARGE, lastModified); +#else + check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE, (long)lastModified); +#endif + } + // The Linksys WRT54G V5 router has an issue with frequent // DNS lookups from LAN machines. If they happen too often, // like for every HTTP request, the router gets annoyed after diff --git a/indra/llcorehttp/httpoptions.cpp b/indra/llcorehttp/httpoptions.cpp index d85f6039b1..5abd28e211 100644 --- a/indra/llcorehttp/httpoptions.cpp +++ b/indra/llcorehttp/httpoptions.cpp @@ -47,6 +47,7 @@ HttpOptions::HttpOptions() : mVerifyPeer(sDefaultVerifyPeer), mVerifyHost(false), mDNSCacheTimeout(-1L), + mLastModified(0), mNoBody(false) {} @@ -129,6 +130,11 @@ void HttpOptions::setHeadersOnly(bool nobody) } } +void HttpOptions::setLastModified(time_t lastModified) +{ + mLastModified = lastModified; +} + void HttpOptions::setDefaultSSLVerifyPeer(bool verify) { sDefaultVerifyPeer = verify; diff --git a/indra/llcorehttp/httpoptions.h b/indra/llcorehttp/httpoptions.h index 56a28013cb..fdb277c66e 100644 --- a/indra/llcorehttp/httpoptions.h +++ b/indra/llcorehttp/httpoptions.h @@ -178,6 +178,13 @@ public: return mNoBody; } + // Default: 0 + void setLastModified(time_t lastModified); + time_t getLastModified() const + { + return mLastModified; + } + /// Sets default behavior for verifying that the name in the /// security certificate matches the name of the host contacted. /// Defaults false if not set, but should be set according to @@ -199,6 +206,7 @@ protected: bool mVerifyHost; int mDNSCacheTimeout; bool mNoBody; + time_t mLastModified; static bool sDefaultVerifyPeer; }; // end class HttpOptions diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp index 9c61c25ada..ea33a3bb90 100644 --- a/indra/llfilesystem/lldir.cpp +++ b/indra/llfilesystem/lldir.cpp @@ -110,9 +110,10 @@ std::vector<std::string> LLDir::getFilesInDir(const std::string &dirname) std::vector<std::string> v; - if (exists(p)) + boost::system::error_code ec; + if (exists(p, ec) && !ec.failed()) { - if (is_directory(p)) + if (is_directory(p, ec) && !ec.failed()) { boost::filesystem::directory_iterator end_iter; for (boost::filesystem::directory_iterator dir_itr(p); diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index 2a328675c2..c8f99380ea 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -558,6 +558,12 @@ bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time) LL_INFOS() << "Dropping alpha information during BMP encoding" << LL_ENDL; } + if (raw_image->isBufferInvalid()) + { + setLastError("Invalid input, no buffer"); + return false; + } + setSize(raw_image->getWidth(), raw_image->getHeight(), dst_components); U8 magic[14]; diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp index d4efbcfad2..c896d60c85 100644 --- a/indra/llimage/llimagedimensionsinfo.cpp +++ b/indra/llimage/llimagedimensionsinfo.cpp @@ -75,7 +75,7 @@ bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec) bool LLImageDimensionsInfo::getImageDimensionsBmp() { // Make sure the file is long enough. - const S32 DATA_LEN = 26; // BMP header (14) + DIB header size (4) + width (4) + height (4) + constexpr S32 DATA_LEN = 26; // BMP header (14) + DIB header size (4) + width (4) + height (4) if (!checkFileLength(DATA_LEN)) { LL_WARNS() << "Premature end of file" << LL_ENDL; @@ -105,7 +105,7 @@ bool LLImageDimensionsInfo::getImageDimensionsBmp() bool LLImageDimensionsInfo::getImageDimensionsTga() { - const S32 TGA_FILE_HEADER_SIZE = 12; + constexpr S32 TGA_FILE_HEADER_SIZE = 12; // Make sure the file is long enough. if (!checkFileLength(TGA_FILE_HEADER_SIZE + 1 /* width */ + 1 /* height */)) @@ -124,7 +124,7 @@ bool LLImageDimensionsInfo::getImageDimensionsTga() bool LLImageDimensionsInfo::getImageDimensionsPng() { - const S32 PNG_MAGIC_SIZE = 8; + constexpr S32 PNG_MAGIC_SIZE = 8; // Make sure the file is long enough. if (!checkFileLength(PNG_MAGIC_SIZE + 8 + sizeof(S32) * 2 /* width, height */)) @@ -134,7 +134,7 @@ bool LLImageDimensionsInfo::getImageDimensionsPng() } // Read PNG signature. - const U8 png_magic[PNG_MAGIC_SIZE] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; + constexpr U8 png_magic[PNG_MAGIC_SIZE] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; U8 signature[PNG_MAGIC_SIZE]; mInfile.read((void*)signature, PNG_MAGIC_SIZE); @@ -166,34 +166,36 @@ bool LLImageDimensionsInfo::getImageDimensionsJpeg() { sJpegErrorEncountered = false; clean(); - FILE *fp = LLFile::fopen(mSrcFilename, "rb"); - if (fp == NULL) + FILE* fp = LLFile::fopen(mSrcFilename, "rb"); + if (!fp) { setLastError("Unable to open file for reading", mSrcFilename); return false; } /* Make sure this is a JPEG file. */ - const size_t JPEG_MAGIC_SIZE = 2; - const U8 jpeg_magic[JPEG_MAGIC_SIZE] = {0xFF, 0xD8}; + constexpr size_t JPEG_MAGIC_SIZE = 2; + constexpr U8 jpeg_magic[JPEG_MAGIC_SIZE] = {0xFF, 0xD8}; U8 signature[JPEG_MAGIC_SIZE]; if (fread(signature, sizeof(signature), 1, fp) != 1) { LL_WARNS() << "Premature end of file" << LL_ENDL; + fclose(fp); return false; } if (memcmp(signature, jpeg_magic, JPEG_MAGIC_SIZE) != 0) { LL_WARNS() << "Not a JPEG" << LL_ENDL; mWarning = "texture_load_format_error"; + fclose(fp); return false; } fseek(fp, 0, SEEK_SET); // go back to start of the file /* Init jpeg */ jpeg_error_mgr jerr; - jpeg_decompress_struct cinfo; + jpeg_decompress_struct cinfo{}; cinfo.err = jpeg_std_error(&jerr); // Call our function instead of exit() if Libjpeg encounters an error. // This is done to avoid crash in this case (STORM-472). diff --git a/indra/llimage/llimagedimensionsinfo.h b/indra/llimage/llimagedimensionsinfo.h index 681d66ae4e..4870f2e815 100644 --- a/indra/llimage/llimagedimensionsinfo.h +++ b/indra/llimage/llimagedimensionsinfo.h @@ -38,7 +38,7 @@ class LLImageDimensionsInfo { public: LLImageDimensionsInfo(): - mData(NULL) + mData(nullptr) ,mHeight(0) ,mWidth(0) {} @@ -67,7 +67,7 @@ protected: { mInfile.close(); delete[] mData; - mData = NULL; + mData = nullptr; mWidth = 0; mHeight = 0; } diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 6b960f9077..c3fd0c5aa8 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -329,6 +329,12 @@ bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_ { llassert_always(raw_image); + if (raw_image->isBufferInvalid()) + { + setLastError("Invalid input, no buffer"); + return false; + } + S32 ncomponents = raw_image->getComponents(); EFileFormat format; switch (ncomponents) diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index aa161709a1..5a941dc958 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -281,10 +281,11 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r S32 height = (h > 0) ? h : 2048; S32 max_dimension = llmax(width, height); // Find largest dimension S32 block_area = MAX_BLOCK_SIZE * MAX_BLOCK_SIZE; // Calculated initial block area from established max block size (currently 64) - block_area *= llmax((max_dimension / MAX_BLOCK_SIZE / max_components), 1); // Adjust initial block area by ratio of largest dimension to block size per component - S32 totalbytes = (S32) (block_area * max_components * precision); // First block layer computed before loop without compression rate - S32 block_layers = 1; // Start at layer 1 since first block layer is computed outside loop - while (block_layers < 6) // Walk five layers for the five discards in JPEG2000 + S32 max_layers = (S32)llmax(llround(log2f((float)max_dimension) - log2f((float)MAX_BLOCK_SIZE)), 4); // Find number of powers of two between extents and block size to a minimum of 4 + block_area *= llmax(max_layers, 1); // Adjust initial block area by max number of layers + S32 totalbytes = (S32) (MIN_LAYER_SIZE * max_components * precision); // Start estimation with a minimum reasonable size + S32 block_layers = 0; + while (block_layers <= max_layers) // Walk the layers { if (block_layers <= (5 - discard_level)) // Walk backwards from discard 5 to required discard layer. totalbytes += (S32) (block_area * max_components * precision * rate); // Add each block layer reduced by assumed compression rate diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index 50536a2798..ab6c593fc2 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -499,6 +499,12 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) resetLastError(); + if (raw_image->isBufferInvalid()) + { + setLastError("Invalid input, no buffer"); + return false; + } + LLImageDataSharedLock lockIn(raw_image); LLImageDataLock lockOut(this); diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index a5943fc0ef..5fa53657a0 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -30,8 +30,6 @@ // this is defined so that we get static linking. #include "openjpeg.h" -#define MAX_ENCODED_DISCARD_LEVELS 5 - // Factory function: see declaration in llimagej2c.cpp LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl() { @@ -112,73 +110,96 @@ public: static OPJ_SIZE_T opj_read(void * buffer, OPJ_SIZE_T bytes, void* user_data) { - llassert(user_data); + llassert(user_data && buffer); + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); - OPJ_SIZE_T remainder = (jpeg_codec->size - jpeg_codec->offset); - if (remainder <= 0) + + if (jpeg_codec->offset < 0 || static_cast<OPJ_SIZE_T>(jpeg_codec->offset) >= jpeg_codec->size) { jpeg_codec->offset = jpeg_codec->size; - // Indicate end of stream (hacky?) - return (OPJ_OFF_T)-1; + return static_cast<OPJ_SIZE_T>(-1); // Indicate EOF } - OPJ_SIZE_T to_read = llclamp(U32(bytes), U32(0), U32(remainder)); + + OPJ_SIZE_T remainder = jpeg_codec->size - static_cast<OPJ_SIZE_T>(jpeg_codec->offset); + OPJ_SIZE_T to_read = (bytes < remainder) ? bytes : remainder; + memcpy(buffer, jpeg_codec->buffer + jpeg_codec->offset, to_read); jpeg_codec->offset += to_read; + return to_read; } static OPJ_SIZE_T opj_write(void * buffer, OPJ_SIZE_T bytes, void* user_data) { - llassert(user_data); + llassert(user_data && buffer); + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); - OPJ_SIZE_T remainder = jpeg_codec->size - jpeg_codec->offset; - if (remainder < bytes) + OPJ_OFF_T required_offset = jpeg_codec->offset + static_cast<OPJ_OFF_T>(bytes); + + // Overflow check + if (required_offset < jpeg_codec->offset) + return 0; // Overflow detected + + // Resize if needed (exponential growth) + if (required_offset > static_cast<OPJ_OFF_T>(jpeg_codec->size)) { - OPJ_SIZE_T new_size = jpeg_codec->size + (bytes - remainder); + OPJ_SIZE_T new_size = jpeg_codec->size ? jpeg_codec->size : 1024; + while (required_offset > static_cast<OPJ_OFF_T>(new_size)) + new_size *= 2; + + const OPJ_SIZE_T MAX_BUFFER_SIZE = 512 * 1024 * 1024; // 512 MB, increase if needed + if (new_size > MAX_BUFFER_SIZE) return 0; + U8* new_buffer = (U8*)ll_aligned_malloc_16(new_size); - memcpy(new_buffer, jpeg_codec->buffer, jpeg_codec->offset); - U8* old_buffer = jpeg_codec->buffer; + if (!new_buffer) return 0; // Allocation failed + + if (jpeg_codec->offset > 0) + memcpy(new_buffer, jpeg_codec->buffer, static_cast<size_t>(jpeg_codec->offset)); + + ll_aligned_free_16(jpeg_codec->buffer); jpeg_codec->buffer = new_buffer; - ll_aligned_free_16(old_buffer); jpeg_codec->size = new_size; } - memcpy(jpeg_codec->buffer + jpeg_codec->offset, buffer, bytes); - jpeg_codec->offset += bytes; + + memcpy(jpeg_codec->buffer + jpeg_codec->offset, buffer, static_cast<size_t>(bytes)); + jpeg_codec->offset = required_offset; return bytes; } static OPJ_OFF_T opj_skip(OPJ_OFF_T bytes, void* user_data) { + llassert(user_data); JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); - jpeg_codec->offset += bytes; - if (jpeg_codec->offset > (OPJ_OFF_T)jpeg_codec->size) - { - jpeg_codec->offset = jpeg_codec->size; - // Indicate end of stream - return (OPJ_OFF_T)-1; - } + OPJ_OFF_T new_offset = jpeg_codec->offset + bytes; - if (jpeg_codec->offset < 0) + if (new_offset < 0 || new_offset > static_cast<OPJ_OFF_T>(jpeg_codec->size)) { - // Shouldn't be possible? - jpeg_codec->offset = 0; + // Clamp and indicate EOF or error + jpeg_codec->offset = llclamp<OPJ_OFF_T>(new_offset, 0, static_cast<OPJ_OFF_T>(jpeg_codec->size)); return (OPJ_OFF_T)-1; } + jpeg_codec->offset = new_offset; return bytes; } -static OPJ_BOOL opj_seek(OPJ_OFF_T bytes, void * user_data) +static OPJ_BOOL opj_seek(OPJ_OFF_T offset, void * user_data) { + llassert(user_data); JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); - jpeg_codec->offset = bytes; - jpeg_codec->offset = llclamp(U32(jpeg_codec->offset), U32(0), U32(jpeg_codec->size)); + + if (offset < 0 || offset > static_cast<OPJ_OFF_T>(jpeg_codec->size)) + return OPJ_FALSE; + + jpeg_codec->offset = offset; return OPJ_TRUE; } static void opj_free_user_data(void * user_data) { + llassert(user_data); + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); // Don't free, data is managed externally jpeg_codec->buffer = nullptr; @@ -188,14 +209,54 @@ static void opj_free_user_data(void * user_data) static void opj_free_user_data_write(void * user_data) { + llassert(user_data); + JPEG2KBase* jpeg_codec = static_cast<JPEG2KBase*>(user_data); // Free, data was allocated here - ll_aligned_free_16(jpeg_codec->buffer); - jpeg_codec->buffer = nullptr; + if (jpeg_codec->buffer) + { + ll_aligned_free_16(jpeg_codec->buffer); + jpeg_codec->buffer = nullptr; + } jpeg_codec->size = 0; jpeg_codec->offset = 0; } +/** + * Estimates the number of layers necessary depending on the image surface (w x h) + */ +static U32 estimate_num_layers(U32 surface) +{ + if (surface <= 1024) return 2; // Tiny (≤32×32) + else if (surface <= 16384) return 3; // Small (≤128×128) + else if (surface <= 262144) return 4; // Medium (≤512×512) + else if (surface <= 1048576) return 5; // Up to ~1MP + else return 6; // Up to ~1.5–2MP +} + +/** + * Sets the parameters.tcp_rates according to the number of layers and a last tcp_rate value (which equals to the final compression ratio). + * + * Example for 6 layers: + * + * i = 5, parameters.tcp_rates[6 - 1 - 5] = 8.0f * (1 << (5 << 1)) = 8192 // Layer 5 (lowest quality) + * i = 4, parameters.tcp_rates[6 - 1 - 4] = 8.0f * (1 << (4 << 1)) = 2048 // Layer 4 + * i = 3, parameters.tcp_rates[6 - 1 - 3] = 8.0f * (1 << (3 << 1)) = 512 // Layer 3 + * i = 2, parameters.tcp_rates[6 - 1 - 2] = 8.0f * (1 << (2 << 1)) = 128 // Layer 2 + * i = 1, parameters.tcp_rates[6 - 1 - 1] = 8.0f * (1 << (1 << 1)) = 32 // Layer 1 + * i = 0, parameters.tcp_rates[6 - 1 - 0] = 8.0f * (1 << (0 << 1)) = 8 // Layer 0 (highest quality) + * + */ +static void set_tcp_rates(opj_cparameters_t* parameters, U32 num_layers = 1, F32 last_tcp_rate = LAST_TCP_RATE) +{ + parameters->tcp_numlayers = num_layers; + + for (int i = num_layers - 1; i >= 0; i--) + { + parameters->tcp_rates[num_layers - 1 - i] = last_tcp_rate * static_cast<F32>(1 << (i << 1)); + } +} + class JPEG2KDecode : public JPEG2KBase { public: @@ -406,15 +467,16 @@ public: opj_set_default_encoder_parameters(¶meters); parameters.cod_format = OPJ_CODEC_J2K; - parameters.cp_disto_alloc = 1; + parameters.prog_order = OPJ_RLCP; // should be the default, but, just in case + parameters.cp_disto_alloc = 1; // enable rate allocation by distortion + parameters.max_cs_size = 0; // do not cap max size because we're using tcp_rates and also irrelevant with lossless. if (reversible) { - parameters.max_cs_size = 0; // do not limit size for reversible compression parameters.irreversible = 0; // should be the default, but, just in case parameters.tcp_numlayers = 1; /* documentation seems to be wrong, should be 0.0f for lossless, not 1.0f - see https://github.com/uclouvain/openjpeg/blob/39e8c50a2f9bdcf36810ee3d41bcbf1cc78968ae/src/lib/openjp2/j2k.c#L7755 + see https://github.com/uclouvain/openjpeg/blob/e7453e398b110891778d8da19209792c69ca7169/src/lib/openjp2/j2k.c#L7817 */ parameters.tcp_rates[0] = 0.0f; } @@ -474,53 +536,22 @@ public: opj_set_warning_handler(encoder, warning_callback, nullptr); opj_set_info_handler(encoder, info_callback, nullptr); - parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0; - parameters.cod_format = OPJ_CODEC_J2K; - parameters.prog_order = OPJ_RLCP; - parameters.cp_disto_alloc = 1; + parameters.tcp_mct = (image->numcomps >= 3) ? 1 : 0; // no color transform for RGBA images + // if not lossless compression, computes tcp_numlayers and max_cs_size depending on the image dimensions - if( parameters.irreversible ) { + if( parameters.irreversible ) + { // computes a number of layers U32 surface = rawImageIn.getWidth() * rawImageIn.getHeight(); - U32 nb_layers = 1; - U32 s = 64*64; - while (surface > s) - { - nb_layers++; - s *= 4; - } - nb_layers = llclamp(nb_layers, 1, 6); - parameters.tcp_numlayers = nb_layers; - parameters.tcp_rates[nb_layers - 1] = (U32)(1.f / DEFAULT_COMPRESSION_RATE); // 1:8 by default + // gets the necessary number of layers + U32 nb_layers = estimate_num_layers(surface); - // for each subsequent layer, computes its rate and adds surface * numcomps * 1/rate to the max_cs_size - U32 max_cs_size = (U32)(surface * image->numcomps * DEFAULT_COMPRESSION_RATE); - U32 multiplier; - for (int i = nb_layers - 2; i >= 0; i--) - { - if( i == nb_layers - 2 ) - { - multiplier = 15; - } - else if( i == nb_layers - 3 ) - { - multiplier = 4; - } - else - { - multiplier = 2; - } - parameters.tcp_rates[i] = parameters.tcp_rates[i + 1] * multiplier; - max_cs_size += (U32)(surface * image->numcomps * (1 / parameters.tcp_rates[i])); - } + // fills parameters.tcp_rates and updates parameters.tcp_numlayers + set_tcp_rates(¶meters, nb_layers, LAST_TCP_RATE); - //ensure that we have at least a minimal size - max_cs_size = llmax(max_cs_size, (U32)FIRST_PACKET_SIZE); - - parameters.max_cs_size = max_cs_size; } if (!opj_setup_encoder(encoder, ¶meters, image)) @@ -528,7 +559,20 @@ public: return false; } - U32 tile_count = (rawImageIn.getWidth() >> 6) * (rawImageIn.getHeight() >> 6); + U32 width_tiles = (rawImageIn.getWidth() >> 6); + U32 height_tiles = (rawImageIn.getHeight() >> 6); + + // Allow images with a width or height that are MIN_IMAGE_SIZE <= x < 64 + if (width_tiles == 0 && (rawImageIn.getWidth() >= MIN_IMAGE_SIZE)) + { + width_tiles = 1; + } + if (height_tiles == 0 && (rawImageIn.getHeight() >= MIN_IMAGE_SIZE)) + { + height_tiles = 1; + } + + U32 tile_count = width_tiles * height_tiles; U32 data_size_guess = tile_count * TILE_SIZE; // will be freed in opj_free_user_data_write @@ -543,7 +587,7 @@ public: opj_stream_destroy(stream); } - stream = opj_stream_create(data_size_guess, false); + stream = opj_stream_create(data_size_guess, OPJ_FALSE); if (!stream) { return false; @@ -584,17 +628,15 @@ public: void setImage(const LLImageRaw& raw) { - opj_image_cmptparm_t cmptparm[MAX_ENCODED_DISCARD_LEVELS]; - memset(&cmptparm[0], 0, MAX_ENCODED_DISCARD_LEVELS * sizeof(opj_image_cmptparm_t)); - S32 numcomps = raw.getComponents(); - S32 width = raw.getWidth(); - S32 height = raw.getHeight(); + S32 width = raw.getWidth(); + S32 height = raw.getHeight(); + + std::vector<opj_image_cmptparm_t> cmptparm(numcomps); for (S32 c = 0; c < numcomps; c++) { - cmptparm[c].prec = 8; - cmptparm[c].bpp = 8; + cmptparm[c].prec = 8; // replaces .bpp cmptparm[c].sgnd = 0; cmptparm[c].dx = parameters.subsampling_dx; cmptparm[c].dy = parameters.subsampling_dy; @@ -602,7 +644,7 @@ public: cmptparm[c].h = height; } - image = opj_image_create(numcomps, &cmptparm[0], OPJ_CLRSPC_SRGB); + image = opj_image_create(numcomps, cmptparm.data(), OPJ_CLRSPC_SRGB); image->x1 = width; image->y1 = height; @@ -614,7 +656,7 @@ public: { for (S32 x = 0; x < width; x++) { - const U8 *pixel = src_datap + (y*width + x) * numcomps; + const U8 *pixel = src_datap + (y * width + x) * numcomps; for (S32 c = 0; c < numcomps; c++) { image->comps[c].data[i] = *pixel; @@ -831,14 +873,19 @@ bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible) { + if (raw_image.isBufferInvalid()) + { + base.setLastError("Invalid input, no buffer"); + return false; + } + JPEG2KEncode encode(comment_text, reversible); bool encoded = encode.encode(raw_image, base); - if (encoded) + if (!encoded) { - LL_WARNS() << "Openjpeg encoding implementation isn't complete, returning false" << LL_ENDL; + LL_WARNS() << "Openjpeg encoding was unsuccessful, returning false" << LL_ENDL; } return encoded; - //return false; } bool LLImageJ2COJ::getMetadata(LLImageJ2C &base) diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h index 498502451a..da49597302 100644 --- a/indra/llimagej2coj/llimagej2coj.h +++ b/indra/llimagej2coj/llimagej2coj.h @@ -29,6 +29,8 @@ #include "llimagej2c.h" +const F32 LAST_TCP_RATE = 1.f/DEFAULT_COMPRESSION_RATE; // should be 8, giving a 1:8 ratio + class LLImageJ2COJ : public LLImageJ2CImpl { public: diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index 7e1be17ecc..670405e9b5 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -29,6 +29,7 @@ #include "llfoldertype.h" #include "lldictionary.h" #include "llmemory.h" +#include "llsd.h" #include "llsingleton.h" ///---------------------------------------------------------------------------- @@ -220,3 +221,21 @@ const std::string &LLFolderType::badLookup() static const std::string sBadLookup = "llfoldertype_bad_lookup"; return sBadLookup; } + +LLSD LLFolderType::getTypeNames() +{ + LLSD type_names; + for (S32 type = FT_TEXTURE; type < FT_COUNT; ++type) + { + if (lookupIsEnsembleType((LLFolderType::EType)type)) + continue; + + const FolderEntry* entry = LLFolderDictionary::getInstance()->lookup((LLFolderType::EType)type); + // skip llfoldertype_bad_lookup + if (entry) + { + type_names.append(entry->mName); + } + } + return type_names; +} diff --git a/indra/llinventory/llfoldertype.h b/indra/llinventory/llfoldertype.h index 46a1b92a96..dd12693f66 100644 --- a/indra/llinventory/llfoldertype.h +++ b/indra/llinventory/llfoldertype.h @@ -115,6 +115,8 @@ public: static const std::string& badLookup(); // error string when a lookup fails + static LLSD getTypeNames(); + protected: LLFolderType() {} ~LLFolderType() {} diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 075abf9536..3defad8f3b 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -46,6 +46,7 @@ static const std::string INV_ITEM_ID_LABEL("item_id"); static const std::string INV_FOLDER_ID_LABEL("cat_id"); static const std::string INV_PARENT_ID_LABEL("parent_id"); static const std::string INV_THUMBNAIL_LABEL("thumbnail"); +static const std::string INV_FAVORITE_LABEL("favorite"); static const std::string INV_THUMBNAIL_ID_LABEL("thumbnail_id"); static const std::string INV_ASSET_TYPE_LABEL("type"); static const std::string INV_PREFERRED_TYPE_LABEL("preferred_type"); @@ -59,6 +60,7 @@ static const std::string INV_LINKED_ID_LABEL("linked_id"); static const std::string INV_SALE_INFO_LABEL("sale_info"); static const std::string INV_FLAGS_LABEL("flags"); static const std::string INV_CREATION_DATE_LABEL("created_at"); +static const std::string INV_TOGGLED_LABEL("toggled"); // key used by agent-inventory-service static const std::string INV_ASSET_TYPE_LABEL_WS("type_default"); @@ -82,14 +84,16 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid, mParentUUID(parent_uuid), mType(type), mName(name), - mCreationDate(0) + mCreationDate(0), + mFavorite(false) { correctInventoryName(mName); } LLInventoryObject::LLInventoryObject() : mType(LLAssetType::AT_NONE), - mCreationDate(0) + mCreationDate(0), + mFavorite(false) { } @@ -104,6 +108,7 @@ void LLInventoryObject::copyObject(const LLInventoryObject* other) mType = other->mType; mName = other->mName; mThumbnailUUID = other->mThumbnailUUID; + mFavorite = other->mFavorite; } const LLUUID& LLInventoryObject::getUUID() const @@ -121,6 +126,11 @@ const LLUUID& LLInventoryObject::getThumbnailUUID() const return mThumbnailUUID; } +bool LLInventoryObject::getIsFavorite() const +{ + return mFavorite; +} + const std::string& LLInventoryObject::getName() const { return mName; @@ -175,6 +185,11 @@ void LLInventoryObject::setThumbnailUUID(const LLUUID& thumbnail_uuid) mThumbnailUUID = thumbnail_uuid; } +void LLInventoryObject::setFavorite(bool favorite) +{ + mFavorite = favorite; +} + void LLInventoryObject::setType(LLAssetType::EType type) { mType = type; @@ -247,6 +262,23 @@ bool LLInventoryObject::importLegacyStream(std::istream& input_stream) { setThumbnailUUID(LLUUID::null); } + + if (metadata.has("favorite")) + { + const LLSD& favorite = metadata["favorite"]; + if (favorite.has("toggled")) + { + setFavorite(favorite["toggled"].asBoolean()); + } + else + { + setFavorite(false); + } + } + else + { + setFavorite(false); + } } else if(0 == strcmp("name", keyword)) { @@ -735,6 +767,23 @@ bool LLInventoryItem::importLegacyStream(std::istream& input_stream) { setThumbnailUUID(LLUUID::null); } + + if (metadata.has("favorite")) + { + const LLSD& favorite = metadata["favorite"]; + if (favorite.has("toggled")) + { + setFavorite(favorite["toggled"].asBoolean()); + } + else + { + setFavorite(false); + } + } + else + { + setFavorite(false); + } } else if(0 == strcmp("inv_type", keyword)) { @@ -879,7 +928,7 @@ bool LLInventoryItem::exportLegacyStream(std::ostream& output_stream, bool inclu LLSD LLInventoryItem::asLLSD() const { - LLSD sd = LLSD(); + LLSD sd; asLLSD(sd); return sd; } @@ -888,13 +937,18 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const { sd[INV_ITEM_ID_LABEL] = mUUID; sd[INV_PARENT_ID_LABEL] = mParentUUID; - sd[INV_PERMISSIONS_LABEL] = ll_create_sd_from_permissions(mPermissions); + ll_fill_sd_from_permissions(sd[INV_PERMISSIONS_LABEL], mPermissions); if (mThumbnailUUID.notNull()) { sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); } + if (mFavorite) + { + sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); + } + U32 mask = mPermissions.getMaskBase(); if(((mask & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) || (mAssetUUID.isNull())) @@ -909,19 +963,22 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const cipher.encrypt(shadow_id.mData, UUID_BYTES); sd[INV_SHADOW_ID_LABEL] = shadow_id; } - sd[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); - sd[INV_INVENTORY_TYPE_LABEL] = mInventoryType; + sd[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType)); const std::string inv_type_str = LLInventoryType::lookup(mInventoryType); if(!inv_type_str.empty()) { sd[INV_INVENTORY_TYPE_LABEL] = inv_type_str; } + else + { + sd[INV_INVENTORY_TYPE_LABEL] = (LLSD::Integer)mInventoryType; + } //sd[INV_FLAGS_LABEL] = (S32)mFlags; sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags); - sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD(); + mSaleInfo.asLLSD(sd[INV_SALE_INFO_LABEL]); sd[INV_NAME_LABEL] = mName; sd[INV_DESC_LABEL] = mDescription; - sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate; + sd[INV_CREATION_DATE_LABEL] = (LLSD::Integer)mCreationDate; } bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) @@ -937,6 +994,8 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) // TODO - figure out if this should be moved into the noclobber fields above mThumbnailUUID.setNull(); + mFavorite = false; + mPermissions.init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null); // iterate as map to avoid making unnecessary temp copies of everything LLSD::map_const_iterator i, end; @@ -982,9 +1041,20 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new) continue; } + if (i->first == INV_FAVORITE_LABEL) + { + const LLSD& favorite_map = i->second; + const std::string w = INV_TOGGLED_LABEL; + if (favorite_map.has(w)) + { + mFavorite = favorite_map[w].asBoolean(); + } + continue; + } + if (i->first == INV_PERMISSIONS_LABEL) { - mPermissions = ll_permissions_from_sd(i->second); + mPermissions.importLLSD(i->second); continue; } @@ -1177,6 +1247,11 @@ LLSD LLInventoryCategory::asLLSD() const sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); } + if (mFavorite) + { + sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); + } + return sd; } @@ -1188,11 +1263,17 @@ LLSD LLInventoryCategory::asAISCreateCatLLSD() const S8 type = static_cast<S8>(mPreferredType); sd[INV_ASSET_TYPE_LABEL_WS] = type; sd[INV_NAME_LABEL] = mName; + if (mThumbnailUUID.notNull()) { sd[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); } + if (mFavorite) + { + sd[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); + } + return sd; } @@ -1240,6 +1321,17 @@ bool LLInventoryCategory::fromLLSD(const LLSD& sd) mThumbnailUUID = sd[w]; } } + mFavorite = false; + w = INV_FAVORITE_LABEL; + if (sd.has(w)) + { + const LLSD& favorite_map = sd[w]; + w = INV_TOGGLED_LABEL; + if (favorite_map.has(w)) + { + mFavorite = favorite_map[w].asBoolean(); + } + } w = INV_ASSET_TYPE_LABEL; if (sd.has(w)) { @@ -1362,6 +1454,23 @@ bool LLInventoryCategory::importLegacyStream(std::istream& input_stream) { setThumbnailUUID(LLUUID::null); } + + if (metadata.has("favorite")) + { + const LLSD& favorite = metadata["favorite"]; + if (favorite.has("toggled")) + { + setFavorite(favorite["toggled"].asBoolean()); + } + else + { + setFavorite(false); + } + } + else + { + setFavorite(false); + } } else { @@ -1396,12 +1505,11 @@ bool LLInventoryCategory::exportLegacyStream(std::ostream& output_stream, bool) return true; } -LLSD LLInventoryCategory::exportLLSD() const +void LLInventoryCategory::exportLLSD(LLSD& cat_data) const { - LLSD cat_data; cat_data[INV_FOLDER_ID_LABEL] = mUUID; cat_data[INV_PARENT_ID_LABEL] = mParentUUID; - cat_data[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(mType); + cat_data[INV_ASSET_TYPE_LABEL] = std::string(LLAssetType::lookup(mType)); cat_data[INV_PREFERRED_TYPE_LABEL] = LLFolderType::lookup(mPreferredType); cat_data[INV_NAME_LABEL] = mName; @@ -1409,49 +1517,76 @@ LLSD LLInventoryCategory::exportLLSD() const { cat_data[INV_THUMBNAIL_LABEL] = LLSD().with(INV_ASSET_ID_LABEL, mThumbnailUUID); } + if (mFavorite) + { + cat_data[INV_FAVORITE_LABEL] = LLSD().with(INV_TOGGLED_LABEL, mFavorite); + } +} - return cat_data; +bool LLInventoryCategory::importLLSDMap(const LLSD& cat_data) +{ + LLSD::map_const_iterator i, end; + end = cat_data.endMap(); + for ( i = cat_data.beginMap(); i != end; ++i) + { + importLLSD(i->first, i->second); + } + return true; } -bool LLInventoryCategory::importLLSD(const LLSD& cat_data) +bool LLInventoryCategory::importLLSD(const std::string& label, const LLSD& value) { - if (cat_data.has(INV_FOLDER_ID_LABEL)) + if (label == INV_FOLDER_ID_LABEL) { - setUUID(cat_data[INV_FOLDER_ID_LABEL].asUUID()); + setUUID(value.asUUID()); + return true; } - if (cat_data.has(INV_PARENT_ID_LABEL)) + else if (label == INV_PARENT_ID_LABEL) { - setParent(cat_data[INV_PARENT_ID_LABEL].asUUID()); + setParent(value.asUUID()); + return true; } - if (cat_data.has(INV_ASSET_TYPE_LABEL)) + else if (label == INV_ASSET_TYPE_LABEL) { - setType(LLAssetType::lookup(cat_data[INV_ASSET_TYPE_LABEL].asString())); + setType(LLAssetType::lookup(value.asString())); + return true; } - if (cat_data.has(INV_PREFERRED_TYPE_LABEL)) + else if (label == INV_PREFERRED_TYPE_LABEL) { - setPreferredType(LLFolderType::lookup(cat_data[INV_PREFERRED_TYPE_LABEL].asString())); + setPreferredType(LLFolderType::lookup(value.asString())); + return true; } - if (cat_data.has(INV_THUMBNAIL_LABEL)) + else if (label == INV_THUMBNAIL_LABEL) { LLUUID thumbnail_uuid; - const LLSD &thumbnail_data = cat_data[INV_THUMBNAIL_LABEL]; - if (thumbnail_data.has(INV_ASSET_ID_LABEL)) + if (value.has(INV_ASSET_ID_LABEL)) { - thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID(); + thumbnail_uuid = value[INV_ASSET_ID_LABEL].asUUID(); } setThumbnailUUID(thumbnail_uuid); + return true; + } + if (label == INV_FAVORITE_LABEL) + { + bool favorite = false; + if (value.has(INV_TOGGLED_LABEL)) + { + favorite = value[INV_TOGGLED_LABEL].asBoolean(); + } + setFavorite(favorite); } - if (cat_data.has(INV_NAME_LABEL)) + else if (label == INV_NAME_LABEL) { - mName = cat_data[INV_NAME_LABEL].asString(); + mName = value.asString(); LLStringUtil::replaceNonstandardASCII(mName, ' '); LLStringUtil::replaceChar(mName, '|', ' '); + return true; } - - return true; + return false; } + ///---------------------------------------------------------------------------- -/// Local function definitions +/// Local function definitions for testing purposes ///---------------------------------------------------------------------------- LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item) diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index e63f2deba7..181c46226c 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -71,6 +71,7 @@ public: virtual const LLUUID& getLinkedUUID() const; // inventoryID that this item points to, else this item's inventoryID const LLUUID& getParentUUID() const; virtual const LLUUID& getThumbnailUUID() const; + virtual bool getIsFavorite() const; virtual const std::string& getName() const; virtual LLAssetType::EType getType() const; LLAssetType::EType getActualType() const; // bypasses indirection for linked items @@ -86,6 +87,7 @@ public: virtual void rename(const std::string& new_name); void setParent(const LLUUID& new_parent); virtual void setThumbnailUUID(const LLUUID& thumbnail_uuid); + virtual void setFavorite(bool favorite); void setType(LLAssetType::EType type); virtual void setCreationDate(time_t creation_date_utc); // only stored for items @@ -111,6 +113,7 @@ protected: LLUUID mUUID; LLUUID mParentUUID; // Parent category. Root categories have LLUUID::NULL. LLUUID mThumbnailUUID; + bool mFavorite; LLAssetType::EType mType; std::string mName; time_t mCreationDate; // seconds from 1/1/1970, UTC @@ -270,8 +273,9 @@ public: virtual bool importLegacyStream(std::istream& input_stream); virtual bool exportLegacyStream(std::ostream& output_stream, bool include_asset_key = true) const; - LLSD exportLLSD() const; - bool importLLSD(const LLSD& cat_data); + virtual void exportLLSD(LLSD& sd) const; + bool importLLSDMap(const LLSD& cat_data); + virtual bool importLLSD(const std::string& label, const LLSD& value); //-------------------------------------------------------------------- // Member Variables //-------------------------------------------------------------------- @@ -285,6 +289,7 @@ protected: // // These functions convert between structured data and an inventory // item, appropriate for serialization. +// Not up to date (no favorites, nor thumbnails), for testing purposes //----------------------------------------------------------------------------- LLSD ll_create_sd_from_inventory_item(LLPointer<LLInventoryItem> item); LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat); diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 67d713db1f..ac50b428bf 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -37,98 +37,98 @@ #include "llsettingsdaycycle.h" // Grid out of which parcels taken is stepped every 4 meters. -const F32 PARCEL_GRID_STEP_METERS = 4.f; +constexpr F32 PARCEL_GRID_STEP_METERS = 4.f; // Area of one "square" of parcel -const S32 PARCEL_UNIT_AREA = 16; +constexpr S32 PARCEL_UNIT_AREA = 16; // Height _above_ground_ that parcel boundary ends -const F32 PARCEL_HEIGHT = 50.f; +constexpr F32 PARCEL_HEIGHT = 50.f; //Height above ground which parcel boundries exist for explicitly banned avatars -const F32 BAN_HEIGHT = 5000.f; +constexpr F32 BAN_HEIGHT = 5000.f; // Maximum number of entries in an access list -const S32 PARCEL_MAX_ACCESS_LIST = 300; +constexpr S32 PARCEL_MAX_ACCESS_LIST = 300; //Maximum number of entires in an update packet //for access/ban lists. -const F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f; +constexpr F32 PARCEL_MAX_ENTRIES_PER_PACKET = 48.f; // Maximum number of experiences -const S32 PARCEL_MAX_EXPERIENCE_LIST = 24; +constexpr S32 PARCEL_MAX_EXPERIENCE_LIST = 24; // Weekly charge for listing a parcel in the directory -const S32 PARCEL_DIRECTORY_FEE = 30; +constexpr S32 PARCEL_DIRECTORY_FEE = 30; -const S32 PARCEL_PASS_PRICE_DEFAULT = 10; -const F32 PARCEL_PASS_HOURS_DEFAULT = 1.f; +constexpr S32 PARCEL_PASS_PRICE_DEFAULT = 10; +constexpr F32 PARCEL_PASS_HOURS_DEFAULT = 1.f; // Number of "chunks" in which parcel overlay data is sent // Chunk 0 = southern rows, entire width -const S32 PARCEL_OVERLAY_CHUNKS = 4; +constexpr S32 PARCEL_OVERLAY_CHUNKS = 4; // Bottom three bits are a color index for the land overlay -const U8 PARCEL_COLOR_MASK = 0x07; -const U8 PARCEL_PUBLIC = 0x00; -const U8 PARCEL_OWNED = 0x01; -const U8 PARCEL_GROUP = 0x02; -const U8 PARCEL_SELF = 0x03; -const U8 PARCEL_FOR_SALE = 0x04; -const U8 PARCEL_AUCTION = 0x05; +constexpr U8 PARCEL_COLOR_MASK = 0x07; +constexpr U8 PARCEL_PUBLIC = 0x00; +constexpr U8 PARCEL_OWNED = 0x01; +constexpr U8 PARCEL_GROUP = 0x02; +constexpr U8 PARCEL_SELF = 0x03; +constexpr U8 PARCEL_FOR_SALE = 0x04; +constexpr U8 PARCEL_AUCTION = 0x05; // unused 0x06 // unused 0x07 // flag, unused 0x08 -const U8 PARCEL_HIDDENAVS = 0x10; // avatars not visible outside of parcel. Used for 'see avs' feature, but must be off for compatibility -const U8 PARCEL_SOUND_LOCAL = 0x20; -const U8 PARCEL_WEST_LINE = 0x40; // flag, property line on west edge -const U8 PARCEL_SOUTH_LINE = 0x80; // flag, property line on south edge +constexpr U8 PARCEL_HIDDENAVS = 0x10; // avatars not visible outside of parcel. Used for 'see avs' feature, but must be off for compatibility +constexpr U8 PARCEL_SOUND_LOCAL = 0x20; +constexpr U8 PARCEL_WEST_LINE = 0x40; // flag, property line on west edge +constexpr U8 PARCEL_SOUTH_LINE = 0x80; // flag, property line on south edge // Transmission results for parcel properties -const S32 PARCEL_RESULT_NO_DATA = -1; -const S32 PARCEL_RESULT_SUCCESS = 0; // got exactly one parcel -const S32 PARCEL_RESULT_MULTIPLE = 1; // got multiple parcels - -const S32 SELECTED_PARCEL_SEQ_ID = -10000; -const S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID = -20000; -const S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000; -const S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID = -40000; -const S32 HOVERED_PARCEL_SEQ_ID = -50000; - -const U32 RT_NONE = 0x1 << 0; -const U32 RT_OWNER = 0x1 << 1; -const U32 RT_GROUP = 0x1 << 2; -const U32 RT_OTHER = 0x1 << 3; -const U32 RT_LIST = 0x1 << 4; -const U32 RT_SELL = 0x1 << 5; - -const S32 INVALID_PARCEL_ID = -1; - -const S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2; +constexpr S32 PARCEL_RESULT_NO_DATA = -1; +constexpr S32 PARCEL_RESULT_SUCCESS = 0; // got exactly one parcel +constexpr S32 PARCEL_RESULT_MULTIPLE = 1; // got multiple parcels + +constexpr S32 SELECTED_PARCEL_SEQ_ID = -10000; +constexpr S32 COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID = -20000; +constexpr S32 COLLISION_BANNED_PARCEL_SEQ_ID = -30000; +constexpr S32 COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID = -40000; +constexpr S32 HOVERED_PARCEL_SEQ_ID = -50000; + +constexpr U32 RT_NONE = 0x1 << 0; +constexpr U32 RT_OWNER = 0x1 << 1; +constexpr U32 RT_GROUP = 0x1 << 2; +constexpr U32 RT_OTHER = 0x1 << 3; +constexpr U32 RT_LIST = 0x1 << 4; +constexpr U32 RT_SELL = 0x1 << 5; + +constexpr S32 INVALID_PARCEL_ID = -1; + +constexpr S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2; // if Region settings are used, parcel env. version is -1 -const S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1; +constexpr S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1; // Timeouts for parcels // default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000 -const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); +constexpr U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); // ***** TESTING is 10 minutes //const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000); // group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000 -const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); +constexpr U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); // ***** TESTING is 10 minutes //const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000); // default sale timeout is 2 days -> 172800000000 -const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); +constexpr U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); // ***** TESTING is 10 minutes //const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000); // more grace period extensions. -const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); +constexpr U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); // if more than 100,000s before sale revert, and no extra extension // has been given, go ahead and extend it more. That's about 1.2 days. -const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; +constexpr S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; @@ -250,9 +250,9 @@ public: void setMediaURL(const std::string& url); void setMediaType(const std::string& type); void setMediaDesc(const std::string& desc); - void setMediaID(const LLUUID& id) { mMediaID = id; } - void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; } - void setMediaLoop (U8 loop) { mMediaLoop = loop; } + void setMediaID(const LLUUID& id) { mMediaID = id; } + void setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; } + void setMediaLoop(U8 loop) { mMediaLoop = loop; } void setMediaWidth(S32 width); void setMediaHeight(S32 height); void setMediaCurrentURL(const std::string& url); @@ -262,6 +262,8 @@ public: void setMediaURLResetTimer(F32 time); virtual void setLocalID(S32 local_id); + void setRegionID(const LLUUID& id) { mRegionID = id; } + const LLUUID& getRegionID() const { return mRegionID; } // blow away all the extra stuff lurking in parcels, including urls, access lists, etc void clearParcel(); @@ -651,6 +653,7 @@ public: S32 mLocalID; LLUUID mBanListTransactionID; LLUUID mAccessListTransactionID; + LLUUID mRegionID; std::map<LLUUID,LLAccessEntry> mAccessList; std::map<LLUUID,LLAccessEntry> mBanList; std::map<LLUUID,LLAccessEntry> mTempBanList; diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp index c8963881df..ebf7445c65 100644 --- a/indra/llinventory/llpermissions.cpp +++ b/indra/llinventory/llpermissions.cpp @@ -704,6 +704,79 @@ bool LLPermissions::exportLegacyStream(std::ostream& output_stream) const return true; } +static const std::string PERM_CREATOR_ID_LABEL("creator_id"); +static const std::string PERM_OWNER_ID_LABEL("owner_id"); +static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id"); +static const std::string PERM_GROUP_ID_LABEL("group_id"); +static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group"); +static const std::string PERM_BASE_MASK_LABEL("base_mask"); +static const std::string PERM_OWNER_MASK_LABEL("owner_mask"); +static const std::string PERM_GROUP_MASK_LABEL("group_mask"); +static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask"); +static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask"); + +void LLPermissions::importLLSD(const LLSD& sd_perm) +{ + LLSD::map_const_iterator i, end; + end = sd_perm.endMap(); + for (i = sd_perm.beginMap(); i != end; ++i) + { + const std::string& label = i->first; + if (label == PERM_CREATOR_ID_LABEL) + { + mCreator = i->second.asUUID(); + continue; + } + if (label == PERM_OWNER_ID_LABEL) + { + mOwner = i->second.asUUID(); + continue; + } + if (label == PERM_LAST_OWNER_ID_LABEL) + { + mLastOwner = i->second.asUUID(); + continue; + } + if (label == PERM_GROUP_ID_LABEL) + { + mGroup = i->second.asUUID(); + continue; + } + if (label == PERM_BASE_MASK_LABEL) + { + PermissionMask mask = i->second.asInteger(); + mMaskBase = mask; + continue; + } + if (label == PERM_OWNER_MASK_LABEL) + { + PermissionMask mask = i->second.asInteger(); + mMaskOwner = mask; + continue; + } + if (label == PERM_EVERYONE_MASK_LABEL) + { + PermissionMask mask = i->second.asInteger(); + mMaskEveryone = mask; + continue; + } + if (label == PERM_GROUP_MASK_LABEL) + { + PermissionMask mask = i->second.asInteger(); + mMaskGroup = mask; + continue; + } + if (label == PERM_NEXT_OWNER_MASK_LABEL) + { + PermissionMask mask = i->second.asInteger(); + mMaskNextOwner = mask; + continue; + } + } + + fix(); +} + bool LLPermissions::operator==(const LLPermissions &rhs) const { return @@ -998,55 +1071,30 @@ std::string mask_to_string(U32 mask) ///---------------------------------------------------------------------------- /// exported functions ///---------------------------------------------------------------------------- -static const std::string PERM_CREATOR_ID_LABEL("creator_id"); -static const std::string PERM_OWNER_ID_LABEL("owner_id"); -static const std::string PERM_LAST_OWNER_ID_LABEL("last_owner_id"); -static const std::string PERM_GROUP_ID_LABEL("group_id"); -static const std::string PERM_IS_OWNER_GROUP_LABEL("is_owner_group"); -static const std::string PERM_BASE_MASK_LABEL("base_mask"); -static const std::string PERM_OWNER_MASK_LABEL("owner_mask"); -static const std::string PERM_GROUP_MASK_LABEL("group_mask"); -static const std::string PERM_EVERYONE_MASK_LABEL("everyone_mask"); -static const std::string PERM_NEXT_OWNER_MASK_LABEL("next_owner_mask"); LLSD ll_create_sd_from_permissions(const LLPermissions& perm) { LLSD rv; + ll_fill_sd_from_permissions(rv, perm); + return rv; +} +void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm) +{ rv[PERM_CREATOR_ID_LABEL] = perm.getCreator(); rv[PERM_OWNER_ID_LABEL] = perm.getOwner(); rv[PERM_LAST_OWNER_ID_LABEL] = perm.getLastOwner(); rv[PERM_GROUP_ID_LABEL] = perm.getGroup(); rv[PERM_IS_OWNER_GROUP_LABEL] = perm.isGroupOwned(); - rv[PERM_BASE_MASK_LABEL] = (S32)perm.getMaskBase(); - rv[PERM_OWNER_MASK_LABEL] = (S32)perm.getMaskOwner(); - rv[PERM_GROUP_MASK_LABEL] = (S32)perm.getMaskGroup(); - rv[PERM_EVERYONE_MASK_LABEL] = (S32)perm.getMaskEveryone(); - rv[PERM_NEXT_OWNER_MASK_LABEL] = (S32)perm.getMaskNextOwner(); - return rv; + rv[PERM_BASE_MASK_LABEL] = (LLSD::Integer)perm.getMaskBase(); + rv[PERM_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskOwner(); + rv[PERM_GROUP_MASK_LABEL] = (LLSD::Integer)perm.getMaskGroup(); + rv[PERM_EVERYONE_MASK_LABEL] = (LLSD::Integer)perm.getMaskEveryone(); + rv[PERM_NEXT_OWNER_MASK_LABEL] = (LLSD::Integer)perm.getMaskNextOwner(); } LLPermissions ll_permissions_from_sd(const LLSD& sd_perm) { LLPermissions rv; - rv.init( - sd_perm[PERM_CREATOR_ID_LABEL].asUUID(), - sd_perm[PERM_OWNER_ID_LABEL].asUUID(), - sd_perm[PERM_LAST_OWNER_ID_LABEL].asUUID(), - sd_perm[PERM_GROUP_ID_LABEL].asUUID()); - - // We do a cast to U32 here since LLSD does not attempt to - // represent unsigned ints. - PermissionMask mask; - mask = (U32)(sd_perm[PERM_BASE_MASK_LABEL].asInteger()); - rv.setMaskBase(mask); - mask = (U32)(sd_perm[PERM_OWNER_MASK_LABEL].asInteger()); - rv.setMaskOwner(mask); - mask = (U32)(sd_perm[PERM_EVERYONE_MASK_LABEL].asInteger()); - rv.setMaskEveryone(mask); - mask = (U32)(sd_perm[PERM_GROUP_MASK_LABEL].asInteger()); - rv.setMaskGroup(mask); - mask = (U32)(sd_perm[PERM_NEXT_OWNER_MASK_LABEL].asInteger()); - rv.setMaskNext(mask); - rv.fix(); + rv.importLLSD(sd_perm); return rv; } diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h index a68abcfa34..82cdc03727 100644 --- a/indra/llinventory/llpermissions.h +++ b/indra/llinventory/llpermissions.h @@ -299,6 +299,8 @@ public: bool importLegacyStream(std::istream& input_stream); bool exportLegacyStream(std::ostream& output_stream) const; + void importLLSD(const LLSD& sd_perm); + bool operator==(const LLPermissions &rhs) const; bool operator!=(const LLPermissions &rhs) const; @@ -435,6 +437,7 @@ protected: // like 'creator_id', 'owner_id', etc, with the value copied from the // permission object. LLSD ll_create_sd_from_permissions(const LLPermissions& perm); +void ll_fill_sd_from_permissions(LLSD& rv, const LLPermissions& perm); LLPermissions ll_permissions_from_sd(const LLSD& sd_perm); #endif diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp index 35bbc1dbb1..b4d64bb4fb 100644 --- a/indra/llinventory/llsaleinfo.cpp +++ b/indra/llinventory/llsaleinfo.cpp @@ -90,15 +90,20 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const LLSD LLSaleInfo::asLLSD() const { LLSD sd; + asLLSD(sd); + return sd; +} + +void LLSaleInfo::asLLSD(LLSD& sd) const +{ const char* type = lookup(mSaleType); if (!type) { LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL; type = lookup(LLSaleInfo::FS_NOT); } - sd["sale_type"] = type; + sd["sale_type"] = std::string(type); sd["sale_price"] = mSalePrice; - return sd; } bool LLSaleInfo::fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask) diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h index 44eb841641..7186e8ab49 100644 --- a/indra/llinventory/llsaleinfo.h +++ b/indra/llinventory/llsaleinfo.h @@ -86,6 +86,7 @@ public: bool exportLegacyStream(std::ostream& output_stream) const; LLSD asLLSD() const; + void asLLSD(LLSD &sd) const; operator LLSD() const { return asLLSD(); } bool fromLLSD(const LLSD& sd, bool& has_perm_mask, U32& perm_mask); bool importLegacyStream(std::istream& input_stream, bool& has_perm_mask, U32& perm_mask); diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index d483b33288..d7a94d61a5 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -361,14 +361,12 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD new_array = q.getValue(); } else - { // TODO: We could expand this to inspect the type and do a deep lerp based on type. - // for now assume a heterogeneous array of reals. + { size_t len = std::max(value.size(), other_value.size()); for (size_t i = 0; i < len; ++i) { - - new_array[i] = lerp((F32)value[i].asReal(), (F32)other_value[i].asReal(), (F32)mix); + new_array[i] = interpolateSDValue(key_name, value[i], other_value[i], defaults, mix, skip, slerps); } } diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 7de71588ef..bea6fdec97 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -398,7 +398,7 @@ protected: private: bool mLLSDDirty; - bool mDirty; + bool mDirty; // gates updateSettings bool mReplaced; // super dirty! static LLSD combineSDMaps(const LLSD &first, const LLSD &other); diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index ff28c30563..4957cf3c02 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -657,15 +657,16 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) mHasLegacyHaze |= lerp_legacy_float(mHazeDensity, mLegacyHazeDensity, other->mHazeDensity, other->mLegacyHazeDensity, 0.7f, (F32)blendf); mHasLegacyHaze |= lerp_legacy_float(mDistanceMultiplier, mLegacyDistanceMultiplier, other->mDistanceMultiplier, other->mLegacyDistanceMultiplier, 0.8f, (F32)blendf); mHasLegacyHaze |= lerp_legacy_float(mDensityMultiplier, mLegacyDensityMultiplier, other->mDensityMultiplier, other->mLegacyDensityMultiplier, 0.0001f, (F32)blendf); + mHasLegacyHaze |= lerp_legacy_color(mAmbientColor, mLegacyAmbientColor, other->mAmbientColor, other->mLegacyAmbientColor, LLColor3(0.25f, 0.25f, 0.25f), (F32)blendf); mHasLegacyHaze |= lerp_legacy_color(mBlueHorizon, mLegacyBlueHorizon, other->mBlueHorizon, other->mLegacyBlueHorizon, LLColor3(0.4954f, 0.4954f, 0.6399f), (F32)blendf); mHasLegacyHaze |= lerp_legacy_color(mBlueDensity, mLegacyBlueDensity, other->mBlueDensity, other->mLegacyBlueDensity, LLColor3(0.2447f, 0.4487f, 0.7599f), (F32)blendf); parammapping_t defaults = other->getParameterMap(); stringset_t skip = getSkipInterpolateKeys(); stringset_t slerps = getSlerpKeys(); - mAbsorptionConfigs = interpolateSDMap(mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps); - mMieConfigs = interpolateSDMap(mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps); - mRayleighConfigs = interpolateSDMap(mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps); + mAbsorptionConfigs = interpolateSDValue("absorption_config", mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps); + mMieConfigs = interpolateSDValue("mie_config", mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps); + mRayleighConfigs = interpolateSDValue("rayleigh_config", mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps); setDirtyFlag(true); setReplaced(); @@ -1932,6 +1933,7 @@ LLUUID LLSettingsSky::getCloudNoiseTextureId() const void LLSettingsSky::setCloudNoiseTextureId(const LLUUID &id) { mCloudTextureId = id; + setDirtyFlag(true); setLLSDDirty(); } @@ -1976,6 +1978,7 @@ LLVector2 LLSettingsSky::getCloudScrollRate() const void LLSettingsSky::setCloudScrollRate(const LLVector2 &val) { mScrollRate = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -2134,6 +2137,7 @@ LLUUID LLSettingsSky::getMoonTextureId() const void LLSettingsSky::setMoonTextureId(LLUUID id) { mMoonTextureId = id; + setDirtyFlag(true); setLLSDDirty(); } @@ -2218,6 +2222,7 @@ LLUUID LLSettingsSky::getSunTextureId() const void LLSettingsSky::setSunTextureId(LLUUID id) { mSunTextureId = id; + setDirtyFlag(true); setLLSDDirty(); } diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp index 9779cb8fbc..f11a4c3bf7 100644 --- a/indra/llinventory/tests/inventorymisc_test.cpp +++ b/indra/llinventory/tests/inventorymisc_test.cpp @@ -39,6 +39,34 @@ #pragma warning(disable: 4702) #endif +void set_random_inventory_metadata(LLInventoryObject* obj) +{ + S32 extra = rand() % 4; + switch (extra) + { + case 0: + { + LLUUID thumbnail_id; + thumbnail_id.generate(); + obj->setThumbnailUUID(thumbnail_id); + break; + } + case 1: + obj->setFavorite(true); + break; + case 2: + { + LLUUID thumbnail_id; + thumbnail_id.generate(); + obj->setThumbnailUUID(thumbnail_id); + obj->setFavorite(true); + break; + } + default: + break; + } +} + LLPointer<LLInventoryItem> create_random_inventory_item() { LLUUID item_id; @@ -75,6 +103,7 @@ LLPointer<LLInventoryItem> create_random_inventory_item() sale_info, flags, creation); + set_random_inventory_metadata(item); return item; } @@ -90,6 +119,7 @@ LLPointer<LLInventoryCategory> create_random_inventory_cat() parent_id, LLFolderType::FT_NONE, std::string("Sample category")); + set_random_inventory_metadata(cat); return cat; } @@ -290,6 +320,7 @@ namespace tut src->setCreationDate(new_creation); // test a save/load cycle to LLSD and back again + // Note: ll_create_sd_from_inventory_item does not support metadata LLSD sd = ll_create_sd_from_inventory_item(src); LLPointer<LLInventoryItem> dst = new LLInventoryItem; bool successful_parse = dst->fromLLSD(sd); @@ -329,7 +360,9 @@ namespace tut } LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); - fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->asLLSD()) << std::endl; + LLSD sd; + src1->asLLSD(sd); + fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl; fileXML.close(); @@ -364,13 +397,13 @@ namespace tut ensure_equals("8.name::getName() failed", src1->getName(), src2->getName()); ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription()); ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); - + ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); + ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite()); } template<> template<> void inventory_object::test<8>() { - LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); std::ostringstream ostream; @@ -390,8 +423,8 @@ namespace tut ensure_equals("8.name::getName() failed", src1->getName(), src2->getName()); ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription()); ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); - - + ensure_equals("11.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); + ensure_equals("12.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // not supposed to carry over } template<> template<> @@ -421,6 +454,8 @@ namespace tut ensure_equals("10.name::getName() failed", src1->getName(), src2->getName()); ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription()); ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); + ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); + ensure_equals("14.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite()); } //******class LLInventoryCategory*******// @@ -458,7 +493,9 @@ namespace tut } LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat(); - fileXML << LLSDOStreamer<LLSDNotationFormatter>(src1->exportLLSD()) << std::endl; + LLSD sd; + src1->exportLLSD(sd); + fileXML << LLSDOStreamer<LLSDNotationFormatter>(sd) << std::endl; fileXML.close(); llifstream file(filename.c_str()); @@ -481,13 +518,15 @@ namespace tut file.close(); LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory(); - src2->importLLSD(s_item); + src2->importLLSDMap(s_item); ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); ensure_equals("3.type::getType() failed", src1->getType(), src2->getType()); ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType()); ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); + ensure_equals("6.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); + ensure_equals("7.favorites::getIsFavorite() failed", src1->getIsFavorite(), src2->getIsFavorite()); } template<> template<> @@ -507,6 +546,7 @@ namespace tut ensure_equals("3.type::getType() failed", src1->getType(), src2->getType()); ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType()); ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); - + ensure_equals("13.thumbnails::getThumbnailUUID() failed", src1->getThumbnailUUID(), src2->getThumbnailUUID()); + ensure_equals("14.favorites::getIsFavorite() failed", false, src2->getIsFavorite()); // currently not supposed to carry over } } diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 8e2bd5b2d9..598455a31a 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -280,103 +280,118 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod { LLImageDataLock lock(&base); - S32 data_size = base.getDataSize(); - S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); + try + { - // - // Initialization - // - mCodeStreamp.reset(); + S32 data_size = base.getDataSize(); + S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); - // It's not clear to nat under what circumstances we would reuse a - // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of - // two U32s and a pointer, so it's not as if it would be a huge overhead - // to allocate a new one every time. - // Also -- why is base.getData() tested specifically here? If that returns - // nullptr, shouldn't we bail out of the whole method? - if (!mInputp && base.getData()) - { - // The compressed data has been loaded - // Setup the source for the codestream - mInputp = std::make_unique<LLKDUMemSource>(base.getData(), data_size); - } + // + // Initialization + // + mCodeStreamp.reset(); - if (mInputp) - { - // This is LLKDUMemSource::reset(), not std::unique_ptr::reset(). - mInputp->reset(); - } + // It's not clear to nat under what circumstances we would reuse a + // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of + // two U32s and a pointer, so it's not as if it would be a huge overhead + // to allocate a new one every time. + // Also -- why is base.getData() tested specifically here? If that returns + // nullptr, shouldn't we bail out of the whole method? + if (!mInputp && base.getData()) + { + // The compressed data has been loaded + // Setup the source for the codestream + mInputp = std::make_unique<LLKDUMemSource>(base.getData(), data_size); + } - mCodeStreamp->create(mInputp.get()); + if (mInputp) + { + // This is LLKDUMemSource::reset(), not std::unique_ptr::reset(). + mInputp->reset(); + } - // Set the maximum number of bytes to use from the codestream - // *TODO: This seems to be wrong. The base class should have no idea of - // how j2c compression works so no good way of computing what's the byte - // range to be used. + mCodeStreamp->create(mInputp.get()); + + // Set the maximum number of bytes to use from the codestream + // *TODO: This seems to be wrong. The base class should have no idea of + // how j2c compression works so no good way of computing what's the byte + // range to be used. mCodeStreamp->set_max_bytes(max_bytes); - // If you want to flip or rotate the image for some reason, change - // the resolution, or identify a restricted region of interest, this is - // the place to do it. You may use "kdu_codestream::change_appearance" - // and "kdu_codestream::apply_input_restrictions" for this purpose. - // If you wish to truncate the code-stream prior to decompression, you - // may use "kdu_codestream::set_max_bytes". - // If you wish to retain all compressed data so that the material - // can be decompressed multiple times, possibly with different appearance - // parameters, you should call "kdu_codestream::set_persistent" here. - // There are a variety of other features which must be enabled at - // this point if you want to take advantage of them. See the - // descriptions appearing with the "kdu_codestream" interface functions - // in "kdu_compressed.h" for an itemized account of these capabilities. - - switch (mode) - { - case MODE_FAST: - mCodeStreamp->set_fast(); - break; - case MODE_RESILIENT: - mCodeStreamp->set_resilient(); - break; - case MODE_FUSSY: - mCodeStreamp->set_fussy(); - break; - default: - llassert(0); - mCodeStreamp->set_fast(); - } + // If you want to flip or rotate the image for some reason, change + // the resolution, or identify a restricted region of interest, this is + // the place to do it. You may use "kdu_codestream::change_appearance" + // and "kdu_codestream::apply_input_restrictions" for this purpose. + // If you wish to truncate the code-stream prior to decompression, you + // may use "kdu_codestream::set_max_bytes". + // If you wish to retain all compressed data so that the material + // can be decompressed multiple times, possibly with different appearance + // parameters, you should call "kdu_codestream::set_persistent" here. + // There are a variety of other features which must be enabled at + // this point if you want to take advantage of them. See the + // descriptions appearing with the "kdu_codestream" interface functions + // in "kdu_compressed.h" for an itemized account of these capabilities. + + switch (mode) + { + case MODE_FAST: + mCodeStreamp->set_fast(); + break; + case MODE_RESILIENT: + mCodeStreamp->set_resilient(); + break; + case MODE_FUSSY: + mCodeStreamp->set_fussy(); + break; + default: + llassert(0); + mCodeStreamp->set_fast(); + } - kdu_dims dims; - mCodeStreamp->get_dims(0,dims); + kdu_dims dims; + mCodeStreamp->get_dims(0, dims); - S32 components = mCodeStreamp->get_num_components(); + S32 components = mCodeStreamp->get_num_components(); - // Check that components have consistent dimensions (for PPM file) - for (int idx = 1; idx < components; ++idx) - { - kdu_dims other_dims; - mCodeStreamp->get_dims(idx, other_dims); - if (other_dims != dims) + // Check that components have consistent dimensions (for PPM file) + for (int idx = 1; idx < components; ++idx) { - // This method is only called from methods that catch KDUError. - // We want to fail the image load, not crash the viewer. - LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " - << stringize(other_dims) - << " do not match component 0 dimensions " - << stringize(dims) << "!"))); + kdu_dims other_dims; + mCodeStreamp->get_dims(idx, other_dims); + if (other_dims != dims) + { + // This method is only called from methods that catch KDUError. + // We want to fail the image load, not crash the viewer. + LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " + << stringize(other_dims) + << " do not match component 0 dimensions " + << stringize(dims) << "!"))); + } } - } - // Get the number of resolution levels in that image - mLevels = mCodeStreamp->get_min_dwt_levels(); + // Get the number of resolution levels in that image + mLevels = mCodeStreamp->get_min_dwt_levels(); - // Set the base dimensions - base.setSize(dims.size.x, dims.size.y, components); - base.setLevels(mLevels); + // Set the base dimensions + base.setSize(dims.size.x, dims.size.y, components); + base.setLevels(mLevels); - if (!keep_codestream) + if (!keep_codestream) + { + mCodeStreamp.reset(); + mInputp.reset(); + } + } + catch (std::bad_alloc&) { - mCodeStreamp.reset(); - mInputp.reset(); + // we are in a thread, can't show an 'out of memory' here, + // main thread will keep going + throw; + } + catch (...) + { + LLTHROW(KDUError(STRINGIZE("Unknown J2C error : " + + boost::current_exception_diagnostic_information() << "!"))); } } @@ -647,6 +662,12 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co bool vflip = true; bool hflip = false; + if (raw_image.isBufferInvalid()) + { + base.setLastError("Invalid input, no buffer"); + return false; + } + try { // Set up input image files diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index b6e0e4a2be..6201761c46 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -33,23 +33,23 @@ #include "llplane.h" #include "llvector4a.h" -const F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD; -const F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f; -const F32 DEFAULT_NEAR_PLANE = 0.25f; -const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions +constexpr F32 DEFAULT_FIELD_OF_VIEW = 60.f * DEG_TO_RAD; +constexpr F32 DEFAULT_ASPECT_RATIO = 640.f / 480.f; +constexpr F32 DEFAULT_NEAR_PLANE = 0.25f; +constexpr F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions -const F32 MAX_ASPECT_RATIO = 50.0f; -const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends -const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. -const F32 MAX_FAR_CLIP = 512.0f; +constexpr F32 MAX_ASPECT_RATIO = 50.0f; +constexpr F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends +constexpr F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. +constexpr F32 MAX_FAR_CLIP = 512.0f; -const F32 MIN_ASPECT_RATIO = 0.02f; -const F32 MIN_NEAR_PLANE = 0.1f; -const F32 MIN_FAR_PLANE = 0.2f; +constexpr F32 MIN_ASPECT_RATIO = 0.02f; +constexpr F32 MIN_NEAR_PLANE = 0.1f; +constexpr F32 MIN_FAR_PLANE = 0.2f; // Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio. -static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD; -static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; +constexpr F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD; +constexpr F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; // An LLCamera is an LLCoorFrame with a view frustum. // This means that it has several methods for moving it around diff --git a/indra/llmath/llcoordframe.cpp b/indra/llmath/llcoordframe.cpp index 15c9f6ff3f..b42541c7c0 100644 --- a/indra/llmath/llcoordframe.cpp +++ b/indra/llmath/llcoordframe.cpp @@ -328,28 +328,30 @@ void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix) } +// Rotate 2 normalized orthogonal vectors in direction from `source` to `target` +static void rotate2(LLVector3& source, LLVector3& target, F32 angle) +{ + F32 sx = source[VX], sy = source[VY], sz = source[VZ]; + F32 tx = target[VX], ty = target[VY], tz = target[VZ]; + F32 c = cosf(angle), s = sinf(angle); + + source.set(sx * c + tx * s, sy * c + ty * s, sz * c + tz * s); + target.set(tx * c - sx * s, ty * c - sy * s, tz * c - sz * s); +} + void LLCoordFrame::roll(F32 angle) { - LLQuaternion q(angle, mXAxis); - LLMatrix3 rotation_matrix(q); - rotate(rotation_matrix); - CHECK_FINITE_OBJ(); + rotate2(mYAxis, mZAxis, angle); } void LLCoordFrame::pitch(F32 angle) { - LLQuaternion q(angle, mYAxis); - LLMatrix3 rotation_matrix(q); - rotate(rotation_matrix); - CHECK_FINITE_OBJ(); + rotate2(mZAxis, mXAxis, angle); } void LLCoordFrame::yaw(F32 angle) { - LLQuaternion q(angle, mZAxis); - LLMatrix3 rotation_matrix(q); - rotate(rotation_matrix); - CHECK_FINITE_OBJ(); + rotate2(mXAxis, mYAxis, angle); } // get*() routines diff --git a/indra/llmath/llcoordframe.h b/indra/llmath/llcoordframe.h index aaa701f792..458f6132c9 100644 --- a/indra/llmath/llcoordframe.h +++ b/indra/llmath/llcoordframe.h @@ -61,7 +61,7 @@ public: //LLCoordFrame(const F32 *origin, const F32 *rotation); // Assumes "origin" is 1x3 and "rotation" is 1x9 array //LLCoordFrame(const F32 *origin_and_rotation); // Assumes "origin_and_rotation" is 1x12 array - bool isFinite() { return mOrigin.isFinite() && mXAxis.isFinite() && mYAxis.isFinite() && mZAxis.isFinite(); } + bool isFinite() const { return mOrigin.isFinite() && mXAxis.isFinite() && mYAxis.isFinite() && mZAxis.isFinite(); } void reset(); void resetAxes(); diff --git a/indra/llmath/llline.h b/indra/llmath/llline.h index 2c66f2267d..fa151f8b20 100644 --- a/indra/llmath/llline.h +++ b/indra/llmath/llline.h @@ -33,7 +33,7 @@ #include "stdtypes.h" #include "v3math.h" -const F32 DEFAULT_INTERSECTION_ERROR = 0.000001f; +constexpr F32 DEFAULT_INTERSECTION_ERROR = 0.000001f; class LLLine { diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index fa315291a3..891f0ffc4c 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -39,18 +39,8 @@ // llcommon depend on llmath. #include "is_approx_equal_fraction.h" -// work around for Windows & older gcc non-standard function names. -#if LL_WINDOWS -#include <float.h> -#define llisnan(val) _isnan(val) -#define llfinite(val) _finite(val) -#elif (LL_LINUX && __GNUC__ <= 2) -#define llisnan(val) isnan(val) -#define llfinite(val) isfinite(val) -#else -#define llisnan(val) std::isnan(val) -#define llfinite(val) std::isfinite(val) -#endif +#define llisnan(val) std::isnan(val) +#define llfinite(val) std::isfinite(val) // Single Precision Floating Point Routines // (There used to be more defined here, but they appeared to be redundant and @@ -75,7 +65,7 @@ constexpr F32 DEG_TO_RAD = 0.017453292519943295769236907684886f; constexpr F32 RAD_TO_DEG = 57.295779513082320876798154814105f; constexpr F32 F_APPROXIMATELY_ZERO = 0.00001f; constexpr F32 F_LN10 = 2.3025850929940456840179914546844f; -constexpr F32 OO_LN10 = 0.43429448190325182765112891891661; +constexpr F32 OO_LN10 = 0.43429448190325182765112891891661f; constexpr F32 F_LN2 = 0.69314718056f; constexpr F32 OO_LN2 = 1.4426950408889634073599246810019f; @@ -89,7 +79,7 @@ constexpr F32 GIMBAL_THRESHOLD = 0.000436f; // sets the gimballock threshold 0 constexpr F32 FP_MAG_THRESHOLD = 0.0000001f; // TODO: Replace with logic like is_approx_equal -inline bool is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); } +constexpr bool is_approx_zero(F32 f) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); } // These functions work by interpreting sign+exp+mantissa as an unsigned // integer. @@ -148,33 +138,17 @@ inline F64 llabs(const F64 a) return F64(std::fabs(a)); } -inline S32 lltrunc( F32 f ) +constexpr S32 lltrunc(F32 f) { -#if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32) - // Avoids changing the floating point control word. - // Add or subtract 0.5 - epsilon and then round - const static U32 zpfp[] = { 0xBEFFFFFF, 0x3EFFFFFF }; - S32 result; - __asm { - fld f - mov eax, f - shr eax, 29 - and eax, 4 - fadd dword ptr [zpfp + eax] - fistp result - } - return result; -#else - return (S32)f; -#endif + return narrow(f); } -inline S32 lltrunc( F64 f ) +constexpr S32 lltrunc(F64 f) { - return (S32)f; + return narrow(f); } -inline S32 llfloor( F32 f ) +inline S32 llfloor(F32 f) { #if LL_WINDOWS && !defined( __INTEL_COMPILER ) && (ADDRESS_SIZE == 32) // Avoids changing the floating point control word. @@ -284,7 +258,7 @@ constexpr F32 FAST_MAG_BETA = 0.397824734759f; //constexpr F32 FAST_MAG_ALPHA = 0.948059448969f; //constexpr F32 FAST_MAG_BETA = 0.392699081699f; -inline F32 fastMagnitude(F32 a, F32 b) +constexpr F32 fastMagnitude(F32 a, F32 b) { a = (a > 0) ? a : -a; b = (b > 0) ? b : -b; @@ -342,7 +316,7 @@ inline F32 llfastpow(const F32 x, const F32 y) } -inline F32 snap_to_sig_figs(F32 foo, S32 sig_figs) +constexpr F32 snap_to_sig_figs(F32 foo, S32 sig_figs) { // compute the power of ten F32 bar = 1.f; @@ -358,12 +332,9 @@ inline F32 snap_to_sig_figs(F32 foo, S32 sig_figs) return new_foo; } -inline F32 lerp(F32 a, F32 b, F32 u) -{ - return a + ((b - a) * u); -} +using std::lerp; -inline F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v) +constexpr F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v) { F32 a = x00 + (x01-x00)*u; F32 b = x10 + (x11-x10)*u; @@ -371,17 +342,17 @@ inline F32 lerp2d(F32 x00, F32 x01, F32 x10, F32 x11, F32 u, F32 v) return r; } -inline F32 ramp(F32 x, F32 a, F32 b) +constexpr F32 ramp(F32 x, F32 a, F32 b) { return (a == b) ? 0.0f : ((a - x) / (a - b)); } -inline F32 rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2) +constexpr F32 rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2) { return lerp(y1, y2, ramp(x, x1, x2)); } -inline F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2) +constexpr F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2) { if (y1 < y2) { @@ -394,7 +365,7 @@ inline F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2) } -inline F32 cubic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 ) +constexpr F32 cubic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 ) { if (x <= x0) return s0; @@ -407,14 +378,14 @@ inline F32 cubic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 ) return s0 + (s1 - s0) * (f * f) * (3.0f - 2.0f * f); } -inline F32 cubic_step( F32 x ) +constexpr F32 cubic_step( F32 x ) { x = llclampf(x); return (x * x) * (3.0f - 2.0f * x); } -inline F32 quadratic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 ) +constexpr F32 quadratic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 ) { if (x <= x0) return s0; @@ -428,7 +399,7 @@ inline F32 quadratic_step( F32 x, F32 x0, F32 x1, F32 s0, F32 s1 ) return (s0 * (1.f - f_squared)) + ((s1 - s0) * f_squared); } -inline F32 llsimple_angle(F32 angle) +constexpr F32 llsimple_angle(F32 angle) { while(angle <= -F_PI) angle += F_TWO_PI; @@ -438,7 +409,7 @@ inline F32 llsimple_angle(F32 angle) } //SDK - Renamed this to get_lower_power_two, since this is what this actually does. -inline U32 get_lower_power_two(U32 val, U32 max_power_two) +constexpr U32 get_lower_power_two(U32 val, U32 max_power_two) { if(!max_power_two) { @@ -460,7 +431,7 @@ inline U32 get_lower_power_two(U32 val, U32 max_power_two) // number of digits, then add one. We subtract 1 initially to handle // the case where the number passed in is actually a power of two. // WARNING: this only works with 32 bit ints. -inline U32 get_next_power_two(U32 val, U32 max_power_two) +constexpr U32 get_next_power_two(U32 val, U32 max_power_two) { if(!max_power_two) { @@ -486,7 +457,7 @@ inline U32 get_next_power_two(U32 val, U32 max_power_two) //get the gaussian value given the linear distance from axis x and guassian value o inline F32 llgaussian(F32 x, F32 o) { - return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o)); + return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2.f*o*o)); } //helper function for removing outliers @@ -539,7 +510,8 @@ inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k) // Note: in our code, values labeled as sRGB are ALWAYS gamma corrected linear values, NOT linear values with monitor gamma applied // Note: stored color values should always be gamma corrected linear (i.e. the values returned from an on-screen color swatch) // Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses -inline float linearTosRGB(const float val) { +inline float linearTosRGB(const float val) +{ if (val < 0.0031308f) { return val * 12.92f; } @@ -554,7 +526,8 @@ inline float linearTosRGB(const float val) { // Note: Stored color values should generally be gamma corrected sRGB. // If you're serializing the return value of this function, you're probably doing it wrong. // Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses. -inline float sRGBtoLinear(const float val) { +inline float sRGBtoLinear(const float val) +{ if (val < 0.04045f) { return val / 12.92f; } diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp index aefb82b2f0..3a6748bdb3 100644 --- a/indra/llmath/llquaternion.cpp +++ b/indra/llmath/llquaternion.cpp @@ -30,7 +30,6 @@ #include "llquaternion.h" -//#include "vmath.h" #include "v3math.h" #include "v3dmath.h" #include "v4math.h" @@ -58,7 +57,7 @@ LLQuaternion::LLQuaternion(const LLMatrix3 &mat) LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec) { - F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + F32 mag = vec.length(); if (mag > FP_MAG_THRESHOLD) { angle *= 0.5; @@ -77,7 +76,7 @@ LLQuaternion::LLQuaternion(F32 angle, const LLVector4 &vec) LLQuaternion::LLQuaternion(F32 angle, const LLVector3 &vec) { - F32 mag = sqrtf(vec.mV[VX] * vec.mV[VX] + vec.mV[VY] * vec.mV[VY] + vec.mV[VZ] * vec.mV[VZ]); + F32 mag = vec.length(); if (mag > FP_MAG_THRESHOLD) { angle *= 0.5; diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 76e5e3aae9..7c60253618 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1294,10 +1294,11 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en c = cos(ang)*lerp(radius_start, radius_end, t); - pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) + pt->mPos.set(0 + lerp(0.f, params.getShear().mV[VX], s) + lerp(-skew ,skew, t) * 0.5f, - c + lerp(0,params.getShear().mV[1],s), + c + lerp(0.f, params.getShear().mV[VY], s), s); + pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), hole_y * lerp(taper_y_begin, taper_y_end, t), 0,1); @@ -1327,9 +1328,9 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en c = cos(ang)*lerp(radius_start, radius_end, t); s = sin(ang)*lerp(radius_start, radius_end, t); - pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) + pt->mPos.set(0 + lerp(0.f, params.getShear().mV[VX], s) + lerp(-skew ,skew, t) * 0.5f, - c + lerp(0,params.getShear().mV[1],s), + c + lerp(0.f, params.getShear().mV[VY], s), s); pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), @@ -1354,9 +1355,9 @@ void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 en c = cos(ang)*lerp(radius_start, radius_end, t); s = sin(ang)*lerp(radius_start, radius_end, t); - pt->mPos.set(0 + lerp(0,params.getShear().mV[0],s) + pt->mPos.set(0 + lerp(0.f, params.getShear().mV[VX], s) + lerp(-skew ,skew, t) * 0.5f, - c + lerp(0,params.getShear().mV[1],s), + c + lerp(0.f, params.getShear().mV[VY], s), s); pt->mScale.set(hole_x * lerp(taper_x_begin, taper_x_end, t), hole_y * lerp(taper_y_begin, taper_y_end, t), @@ -1494,8 +1495,8 @@ bool LLPath::generate(const LLPathParams& params, F32 detail, S32 split, for (S32 i=0;i<np;i++) { F32 t = lerp(params.getBegin(),params.getEnd(),(F32)i * mStep); - mPath[i].mPos.set(lerp(0,params.getShear().mV[0],t), - lerp(0,params.getShear().mV[1],t), + mPath[i].mPos.set(lerp(0.f, params.getShear().mV[VX], t), + lerp(0.f ,params.getShear().mV[VY], t), t - 0.5f); LLQuaternion quat; quat.setQuat(lerp(F_PI * params.getTwistBegin(),F_PI * params.getTwist(),t),0,0,1); @@ -1559,10 +1560,10 @@ bool LLPath::generate(const LLPathParams& params, F32 detail, S32 split, { F32 t = (F32)i * mStep; mPath[i].mPos.set(0, - lerp(0, -sin(F_PI*params.getTwist()*t)*0.5f,t), - lerp(-0.5f, cos(F_PI*params.getTwist()*t)*0.5f,t)); - mPath[i].mScale.set(lerp(1,params.getScale().mV[0],t), - lerp(1,params.getScale().mV[1],t), 0,1); + lerp(0.f, -sin(F_PI*params.getTwist() * t) * 0.5f, t), + lerp(-0.5f, cos(F_PI*params.getTwist() * t) * 0.5f, t)); + mPath[i].mScale.set(lerp(1.f, params.getScale().mV[VX], t), + lerp(1.f, params.getScale().mV[VY], t), 0.f, 1.f); mPath[i].mTexT = t; LLQuaternion quat; quat.setQuat(F_PI * params.getTwist() * t,1,0,0); @@ -5710,7 +5711,15 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) S32 vert_count = 0; if (!data.p.empty()) { - vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count)); + try + { + vert_count = static_cast<S32>(meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count)); + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Failed to allocate memory for VertexRemap: " << (S32)data.p.size() << LL_ENDL; + } } if (vert_count < 65535 && vert_count != 0) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 27c5fc5a49..3496928f7b 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -45,7 +45,6 @@ class LLVolumeOctree; #include "lluuid.h" #include "v4color.h" -//#include "vmath.h" #include "v2math.h" #include "v3math.h" #include "v3dmath.h" diff --git a/indra/llmath/m3math.cpp b/indra/llmath/m3math.cpp index 472d340af5..3c2097f947 100644 --- a/indra/llmath/m3math.cpp +++ b/indra/llmath/m3math.cpp @@ -26,7 +26,6 @@ #include "linden_common.h" -//#include "vmath.h" #include "v3math.h" #include "v3dmath.h" #include "v4math.h" diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 2a6e52798b..1724a50601 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -26,7 +26,6 @@ #include "linden_common.h" -//#include "vmath.h" #include "v3math.h" #include "v4math.h" #include "m4math.h" diff --git a/indra/llmath/raytrace.cpp b/indra/llmath/raytrace.cpp index 893bf1fc70..c0b5f48f2d 100644 --- a/indra/llmath/raytrace.cpp +++ b/indra/llmath/raytrace.cpp @@ -27,7 +27,6 @@ #include "linden_common.h" #include "math.h" -//#include "vmath.h" #include "v3math.h" #include "llquaternion.h" #include "m3math.h" diff --git a/indra/llmath/v2math.cpp b/indra/llmath/v2math.cpp index 4649e13376..175f08df88 100644 --- a/indra/llmath/v2math.cpp +++ b/indra/llmath/v2math.cpp @@ -26,7 +26,6 @@ #include "linden_common.h" -//#include "vmath.h" #include "v2math.h" #include "v3math.h" #include "v4math.h" @@ -47,8 +46,8 @@ bool LLVector2::abs() { bool ret{ false }; - if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = true; } - if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = true; } + if (mV[VX] < 0.f) { mV[VX] = -mV[VX]; ret = true; } + if (mV[VY] < 0.f) { mV[VY] = -mV[VY]; ret = true; } return ret; } @@ -67,14 +66,21 @@ F32 angle_between(const LLVector2& a, const LLVector2& b) return angle; } -bool are_parallel(const LLVector2 &a, const LLVector2 &b, float epsilon) +F32 signed_angle_between(const LLVector2& a, const LLVector2& b) +{ + F32 angle = angle_between(a, b); + F32 rhombus_square = a[VX] * b[VY] - b[VX] * a[VY]; + return rhombus_square < 0 ? -angle : angle; +} + +bool are_parallel(const LLVector2& a, const LLVector2& b, F32 epsilon) { LLVector2 an = a; LLVector2 bn = b; an.normVec(); bn.normVec(); F32 dot = an * bn; - if ( (1.0f - fabs(dot)) < epsilon) + if ((1.0f - fabs(dot)) < epsilon) { return true; } @@ -82,28 +88,28 @@ bool are_parallel(const LLVector2 &a, const LLVector2 &b, float epsilon) } -F32 dist_vec(const LLVector2 &a, const LLVector2 &b) +F32 dist_vec(const LLVector2& a, const LLVector2& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; + F32 x = a.mV[VX] - b.mV[VX]; + F32 y = a.mV[VY] - b.mV[VY]; return (F32) sqrt( x*x + y*y ); } -F32 dist_vec_squared(const LLVector2 &a, const LLVector2 &b) +F32 dist_vec_squared(const LLVector2& a, const LLVector2& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; + F32 x = a.mV[VX] - b.mV[VX]; + F32 y = a.mV[VY] - b.mV[VY]; return x*x + y*y; } -F32 dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b) +F32 dist_vec_squared2D(const LLVector2& a, const LLVector2& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; + F32 x = a.mV[VX] - b.mV[VX]; + F32 y = a.mV[VY] - b.mV[VY]; return x*x + y*y; } -LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u) +LLVector2 lerp(const LLVector2& a, const LLVector2& b, F32 u) { return LLVector2( a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, @@ -113,14 +119,14 @@ LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u) LLSD LLVector2::getValue() const { LLSD ret; - ret[0] = mV[0]; - ret[1] = mV[1]; + ret[VX] = mV[VX]; + ret[VY] = mV[VY]; return ret; } void LLVector2::setValue(const LLSD& sd) { - mV[0] = (F32) sd[0].asReal(); - mV[1] = (F32) sd[1].asReal(); + mV[VX] = (F32) sd[0].asReal(); + mV[VY] = (F32) sd[1].asReal(); } diff --git a/indra/llmath/v2math.h b/indra/llmath/v2math.h index c84c441492..b31e4056a3 100644 --- a/indra/llmath/v2math.h +++ b/indra/llmath/v2math.h @@ -36,7 +36,7 @@ class LLQuaternion; // Llvector2 = |x y z w| -static const U32 LENGTHOFVECTOR2 = 2; +static constexpr U32 LENGTHOFVECTOR2 = 2; class LLVector2 { @@ -82,7 +82,7 @@ class LLVector2 const LLVector2& scaleVec(const LLVector2& vec); // scales per component by vec - bool isNull(); // Returns true if vector has a _very_small_ length + bool isNull() const; // Returns true if vector has a _very_small_ length bool isExactlyZero() const { return !mV[VX] && !mV[VY]; } F32 operator[](int idx) const { return mV[idx]; } @@ -107,7 +107,7 @@ class LLVector2 friend LLVector2 operator-(const LLVector2 &a); // Return vector -a - friend std::ostream& operator<<(std::ostream& s, const LLVector2 &a); // Stream a + friend std::ostream& operator<<(std::ostream& s, const LLVector2 &a); // Stream a }; static_assert(std::is_trivially_copyable<LLVector2>::value, "LLVector2 must be trivial copy"); @@ -116,37 +116,34 @@ static_assert(std::is_standard_layout<LLVector2>::value, "LLVector2 must be a st // Non-member functions -F32 angle_between(const LLVector2 &a, const LLVector2 &b); // Returns angle (radians) between a and b -bool are_parallel(const LLVector2 &a, const LLVector2 &b, F32 epsilon=F_APPROXIMATELY_ZERO); // Returns true if a and b are very close to parallel -F32 dist_vec(const LLVector2 &a, const LLVector2 &b); // Returns distance between a and b -F32 dist_vec_squared(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b -F32 dist_vec_squared2D(const LLVector2 &a, const LLVector2 &b);// Returns distance squared between a and b ignoring Z component -LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u); // Returns a vector that is a linear interpolation between a and b +F32 angle_between(const LLVector2& a, const LLVector2& b); // Returns angle (radians) between a and b +F32 signed_angle_between(const LLVector2& a, const LLVector2& b); // Returns signed angle (radians) between a and b +bool are_parallel(const LLVector2& a, const LLVector2& b, F32 epsilon = F_APPROXIMATELY_ZERO); // Returns true if a and b are very close to parallel +F32 dist_vec(const LLVector2& a, const LLVector2& b); // Returns distance between a and b +F32 dist_vec_squared(const LLVector2& a, const LLVector2& b);// Returns distance squared between a and b +F32 dist_vec_squared2D(const LLVector2& a, const LLVector2& b);// Returns distance squared between a and b ignoring Z component +LLVector2 lerp(const LLVector2& a, const LLVector2& b, F32 u); // Returns a vector that is a linear interpolation between a and b // Constructors -inline LLVector2::LLVector2(void) +inline LLVector2::LLVector2() { - mV[VX] = 0.f; - mV[VY] = 0.f; + clear(); } inline LLVector2::LLVector2(F32 x, F32 y) { - mV[VX] = x; - mV[VY] = y; + set(x, y); } inline LLVector2::LLVector2(const F32 *vec) { - mV[VX] = vec[VX]; - mV[VY] = vec[VY]; + set(vec); } inline LLVector2::LLVector2(const LLVector3 &vec) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; + set(vec.mV); } inline LLVector2::LLVector2(const LLSD &sd) @@ -156,30 +153,26 @@ inline LLVector2::LLVector2(const LLSD &sd) // Clear and Assignment Functions -inline void LLVector2::clear(void) +inline void LLVector2::clear() { - mV[VX] = 0.f; - mV[VY] = 0.f; + mV[VX] = mV[VY] = 0.f; } -inline void LLVector2::setZero(void) +inline void LLVector2::setZero() { - mV[VX] = 0.f; - mV[VY] = 0.f; + clear(); } // deprecated -inline void LLVector2::clearVec(void) +inline void LLVector2::clearVec() { - mV[VX] = 0.f; - mV[VY] = 0.f; + clear(); } // deprecated -inline void LLVector2::zeroVec(void) +inline void LLVector2::zeroVec() { - mV[VX] = 0.f; - mV[VY] = 0.f; + clear(); } inline void LLVector2::set(F32 x, F32 y) @@ -190,108 +183,84 @@ inline void LLVector2::set(F32 x, F32 y) inline void LLVector2::set(const LLVector2 &vec) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; + set(vec.mV); } inline void LLVector2::set(const F32 *vec) { - mV[VX] = vec[VX]; - mV[VY] = vec[VY]; + set(vec[VX], vec[VY]); } // deprecated inline void LLVector2::setVec(F32 x, F32 y) { - mV[VX] = x; - mV[VY] = y; + set(x, y); } // deprecated inline void LLVector2::setVec(const LLVector2 &vec) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; + set(vec); } // deprecated inline void LLVector2::setVec(const F32 *vec) { - mV[VX] = vec[VX]; - mV[VY] = vec[VY]; + set(vec); } // LLVector2 Magnitude and Normalization Functions -inline F32 LLVector2::length(void) const +inline F32 LLVector2::length() const { - return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); + return sqrt(lengthSquared()); } -inline F32 LLVector2::lengthSquared(void) const +inline F32 LLVector2::lengthSquared() const { - return mV[0]*mV[0] + mV[1]*mV[1]; + return mV[VX]*mV[VX] + mV[VY]*mV[VY]; } -inline F32 LLVector2::normalize(void) +inline F32 LLVector2::normalize() { - F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); - F32 oomag; + F32 mag = length(); if (mag > FP_MAG_THRESHOLD) { - oomag = 1.f/mag; - mV[0] *= oomag; - mV[1] *= oomag; + *this /= mag; } else { - mV[0] = 0.f; - mV[1] = 0.f; + clear(); mag = 0; } - return (mag); + return mag; } // checker inline bool LLVector2::isFinite() const { - return (llfinite(mV[VX]) && llfinite(mV[VY])); + return llfinite(mV[VX]) && llfinite(mV[VY]); } // deprecated -inline F32 LLVector2::magVec(void) const +inline F32 LLVector2::magVec() const { - return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); + return length(); } // deprecated -inline F32 LLVector2::magVecSquared(void) const +inline F32 LLVector2::magVecSquared() const { - return mV[0]*mV[0] + mV[1]*mV[1]; + return lengthSquared(); } // deprecated -inline F32 LLVector2::normVec(void) +inline F32 LLVector2::normVec() { - F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1]); - F32 oomag; - - if (mag > FP_MAG_THRESHOLD) - { - oomag = 1.f/mag; - mV[0] *= oomag; - mV[1] *= oomag; - } - else - { - mV[0] = 0.f; - mV[1] = 0.f; - mag = 0; - } - return (mag); + return normalize(); } inline const LLVector2& LLVector2::scaleVec(const LLVector2& vec) @@ -302,22 +271,18 @@ inline const LLVector2& LLVector2::scaleVec(const LLVector2& vec) return *this; } -inline bool LLVector2::isNull() +inline bool LLVector2::isNull() const { - if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] ) - { - return true; - } - return false; + return F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY]; } // LLVector2 Operators // For sorting. By convention, x is "more significant" than y. -inline bool operator<(const LLVector2 &a, const LLVector2 &b) +inline bool operator<(const LLVector2& a, const LLVector2& b) { - if( a.mV[VX] == b.mV[VX] ) + if (a.mV[VX] == b.mV[VX]) { return a.mV[VY] < b.mV[VY]; } @@ -328,95 +293,92 @@ inline bool operator<(const LLVector2 &a, const LLVector2 &b) } -inline LLVector2 operator+(const LLVector2 &a, const LLVector2 &b) +inline LLVector2 operator+(const LLVector2& a, const LLVector2& b) { LLVector2 c(a); return c += b; } -inline LLVector2 operator-(const LLVector2 &a, const LLVector2 &b) +inline LLVector2 operator-(const LLVector2& a, const LLVector2& b) { LLVector2 c(a); return c -= b; } -inline F32 operator*(const LLVector2 &a, const LLVector2 &b) +inline F32 operator*(const LLVector2& a, const LLVector2& b) { - return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1]); + return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY]); } -inline LLVector2 operator%(const LLVector2 &a, const LLVector2 &b) +inline LLVector2 operator%(const LLVector2& a, const LLVector2& b) { - return LLVector2(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]); + return LLVector2(a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY], a.mV[VY]*b.mV[VX] - b.mV[VY]*a.mV[VX]); } -inline LLVector2 operator/(const LLVector2 &a, F32 k) +inline LLVector2 operator/(const LLVector2& a, F32 k) { F32 t = 1.f / k; - return LLVector2( a.mV[0] * t, a.mV[1] * t ); + return LLVector2( a.mV[VX] * t, a.mV[VY] * t ); } -inline LLVector2 operator*(const LLVector2 &a, F32 k) +inline LLVector2 operator*(const LLVector2& a, F32 k) { - return LLVector2( a.mV[0] * k, a.mV[1] * k ); + return LLVector2( a.mV[VX] * k, a.mV[VY] * k ); } -inline LLVector2 operator*(F32 k, const LLVector2 &a) +inline LLVector2 operator*(F32 k, const LLVector2& a) { - return LLVector2( a.mV[0] * k, a.mV[1] * k ); + return LLVector2( a.mV[VX] * k, a.mV[VY] * k ); } -inline bool operator==(const LLVector2 &a, const LLVector2 &b) +inline bool operator==(const LLVector2& a, const LLVector2& b) { - return ( (a.mV[0] == b.mV[0]) - &&(a.mV[1] == b.mV[1])); + return ( (a.mV[VX] == b.mV[VX]) + &&(a.mV[VY] == b.mV[VY])); } -inline bool operator!=(const LLVector2 &a, const LLVector2 &b) +inline bool operator!=(const LLVector2& a, const LLVector2& b) { - return ( (a.mV[0] != b.mV[0]) - ||(a.mV[1] != b.mV[1])); + return ( (a.mV[VX] != b.mV[VX]) + ||(a.mV[VY] != b.mV[VY])); } -inline const LLVector2& operator+=(LLVector2 &a, const LLVector2 &b) +inline const LLVector2& operator+=(LLVector2& a, const LLVector2& b) { - a.mV[0] += b.mV[0]; - a.mV[1] += b.mV[1]; + a.mV[VX] += b.mV[VX]; + a.mV[VY] += b.mV[VY]; return a; } -inline const LLVector2& operator-=(LLVector2 &a, const LLVector2 &b) +inline const LLVector2& operator-=(LLVector2& a, const LLVector2& b) { - a.mV[0] -= b.mV[0]; - a.mV[1] -= b.mV[1]; + a.mV[VX] -= b.mV[VX]; + a.mV[VY] -= b.mV[VY]; return a; } -inline const LLVector2& operator%=(LLVector2 &a, const LLVector2 &b) +inline const LLVector2& operator%=(LLVector2& a, const LLVector2& b) { - LLVector2 ret(a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1], a.mV[1]*b.mV[0] - b.mV[1]*a.mV[0]); + LLVector2 ret(a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY], a.mV[VY]*b.mV[VX] - b.mV[VY]*a.mV[VX]); a = ret; return a; } -inline const LLVector2& operator*=(LLVector2 &a, F32 k) +inline const LLVector2& operator*=(LLVector2& a, F32 k) { - a.mV[0] *= k; - a.mV[1] *= k; + a.mV[VX] *= k; + a.mV[VY] *= k; return a; } -inline const LLVector2& operator/=(LLVector2 &a, F32 k) +inline const LLVector2& operator/=(LLVector2& a, F32 k) { - F32 t = 1.f / k; - a.mV[0] *= t; - a.mV[1] *= t; - return a; + return a *= 1.f / k; } -inline LLVector2 operator-(const LLVector2 &a) +inline LLVector2 operator-(const LLVector2& a) { - return LLVector2( -a.mV[0], -a.mV[1] ); + return LLVector2( -a.mV[VX], -a.mV[VY] ); } inline void update_min_max(LLVector2& min, LLVector2& max, const LLVector2& pos) @@ -434,7 +396,7 @@ inline void update_min_max(LLVector2& min, LLVector2& max, const LLVector2& pos) } } -inline std::ostream& operator<<(std::ostream& s, const LLVector2 &a) +inline std::ostream& operator<<(std::ostream& s, const LLVector2& a) { s << "{ " << a.mV[VX] << ", " << a.mV[VY] << " }"; return s; diff --git a/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp index 4367b993f8..08b3795020 100644 --- a/indra/llmath/v3color.cpp +++ b/indra/llmath/v3color.cpp @@ -32,74 +32,79 @@ LLColor3 LLColor3::white(1.0f, 1.0f, 1.0f); LLColor3 LLColor3::black(0.0f, 0.0f, 0.0f); -LLColor3 LLColor3::grey (0.5f, 0.5f, 0.5f); +LLColor3 LLColor3::grey(0.5f, 0.5f, 0.5f); -LLColor3::LLColor3(const LLColor4 &a) +LLColor3::LLColor3(const LLColor4& a) { - mV[0] = a.mV[0]; - mV[1] = a.mV[1]; - mV[2] = a.mV[2]; + mV[VRED] = a.mV[VRED]; + mV[VGREEN] = a.mV[VGREEN]; + mV[VBLUE] = a.mV[VBLUE]; } -LLColor3::LLColor3(const LLVector4 &a) +LLColor3::LLColor3(const LLVector4& a) { - mV[0] = a.mV[0]; - mV[1] = a.mV[1]; - mV[2] = a.mV[2]; + mV[VRED] = a.mV[VRED]; + mV[VGREEN] = a.mV[VGREEN]; + mV[VBLUE] = a.mV[VBLUE]; } -LLColor3::LLColor3(const LLSD &sd) +LLColor3::LLColor3(const LLSD& sd) { setValue(sd); } -const LLColor3& LLColor3::operator=(const LLColor4 &a) +const LLColor3& LLColor3::operator=(const LLColor4& a) { - mV[0] = a.mV[0]; - mV[1] = a.mV[1]; - mV[2] = a.mV[2]; + mV[VRED] = a.mV[VRED]; + mV[VGREEN] = a.mV[VGREEN]; + mV[VBLUE] = a.mV[VBLUE]; return (*this); } -std::ostream& operator<<(std::ostream& s, const LLColor3 &a) +std::ostream& operator<<(std::ostream& s, const LLColor3& a) { s << "{ " << a.mV[VRED] << ", " << a.mV[VGREEN] << ", " << a.mV[VBLUE] << " }"; return s; } -static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) +static F32 hueToRgb(F32 val1In, F32 val2In, F32 valHUeIn) { - if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; - if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; - if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn ); - if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In ); - if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f ); - return ( val1In ); + if (valHUeIn < 0.0f) + valHUeIn += 1.0f; + if (valHUeIn > 1.0f) + valHUeIn -= 1.0f; + if ((6.0f * valHUeIn) < 1.0f) + return (val1In + (val2In - val1In) * 6.0f * valHUeIn); + if ((2.0f * valHUeIn) < 1.0f) + return (val2In); + if ((3.0f * valHUeIn) < 2.0f) + return (val1In + (val2In - val1In) * ((2.0f / 3.0f) - valHUeIn) * 6.0f); + return (val1In); } -void LLColor3::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn) +void LLColor3::setHSL(F32 hValIn, F32 sValIn, F32 lValIn) { - if ( sValIn < 0.00001f ) + if (sValIn < 0.00001f) { - mV[VRED] = lValIn; + mV[VRED] = lValIn; mV[VGREEN] = lValIn; - mV[VBLUE] = lValIn; + mV[VBLUE] = lValIn; } else { F32 interVal1; F32 interVal2; - if ( lValIn < 0.5f ) - interVal2 = lValIn * ( 1.0f + sValIn ); + if (lValIn < 0.5f) + interVal2 = lValIn * (1.0f + sValIn); else - interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn ); + interVal2 = (lValIn + sValIn) - (sValIn * lValIn); interVal1 = 2.0f * lValIn - interVal2; - mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) ); - mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn ); - mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) ); + mV[VRED] = hueToRgb(interVal1, interVal2, hValIn + (1.f / 3.f)); + mV[VGREEN] = hueToRgb(interVal1, interVal2, hValIn); + mV[VBLUE] = hueToRgb(interVal1, interVal2, hValIn - (1.f / 3.f)); } } @@ -109,45 +114,48 @@ void LLColor3::calcHSL(F32* hue, F32* saturation, F32* luminance) const F32 var_G = mV[VGREEN]; F32 var_B = mV[VBLUE]; - F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) ); - F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) ); + F32 var_Min = (var_R < (var_G < var_B ? var_G : var_B) ? var_R : (var_G < var_B ? var_G : var_B)); + F32 var_Max = (var_R > (var_G > var_B ? var_G : var_B) ? var_R : (var_G > var_B ? var_G : var_B)); F32 del_Max = var_Max - var_Min; - F32 L = ( var_Max + var_Min ) / 2.0f; + F32 L = (var_Max + var_Min) / 2.0f; F32 H = 0.0f; F32 S = 0.0f; - if ( del_Max == 0.0f ) + if (del_Max == 0.0f) { - H = 0.0f; - S = 0.0f; + H = 0.0f; + S = 0.0f; } else { - if ( L < 0.5 ) - S = del_Max / ( var_Max + var_Min ); + if (L < 0.5) + S = del_Max / (var_Max + var_Min); else - S = del_Max / ( 2.0f - var_Max - var_Min ); + S = del_Max / (2.0f - var_Max - var_Min); - F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; - F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; - F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; + F32 del_R = (((var_Max - var_R) / 6.0f) + (del_Max / 2.0f)) / del_Max; + F32 del_G = (((var_Max - var_G) / 6.0f) + (del_Max / 2.0f)) / del_Max; + F32 del_B = (((var_Max - var_B) / 6.0f) + (del_Max / 2.0f)) / del_Max; - if ( var_R >= var_Max ) + if (var_R >= var_Max) H = del_B - del_G; - else - if ( var_G >= var_Max ) - H = ( 1.0f / 3.0f ) + del_R - del_B; - else - if ( var_B >= var_Max ) - H = ( 2.0f / 3.0f ) + del_G - del_R; - - if ( H < 0.0f ) H += 1.0f; - if ( H > 1.0f ) H -= 1.0f; + else if (var_G >= var_Max) + H = (1.0f / 3.0f) + del_R - del_B; + else if (var_B >= var_Max) + H = (2.0f / 3.0f) + del_G - del_R; + + if (H < 0.0f) + H += 1.0f; + if (H > 1.0f) + H -= 1.0f; } - if (hue) *hue = H; - if (saturation) *saturation = S; - if (luminance) *luminance = L; + if (hue) + *hue = H; + if (saturation) + *saturation = S; + if (luminance) + *luminance = L; } diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 139db9539f..7357d93599 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -33,12 +33,12 @@ class LLVector4; #include "llerror.h" #include "llmath.h" #include "llsd.h" -#include "v3math.h" // needed for linearColor3v implemtation below +#include "v3math.h" // needed for linearColor3v implemtation below #include <string.h> // LLColor3 = |r g b| -static const U32 LENGTHOFCOLOR3 = 3; +static constexpr U32 LENGTHOFCOLOR3 = 3; class LLColor3 { @@ -50,44 +50,43 @@ public: static LLColor3 grey; public: - LLColor3(); // Initializes LLColor3 to (0, 0, 0) - LLColor3(F32 r, F32 g, F32 b); // Initializes LLColor3 to (r, g, b) - LLColor3(const F32 *vec); // Initializes LLColor3 to (vec[0]. vec[1], vec[2]) - LLColor3(const char *color_string); // html format color ie "#FFDDEE" - explicit LLColor3(const LLColor4& color4); // "explicit" to avoid automatic conversion - explicit LLColor3(const LLVector4& vector4); // "explicit" to avoid automatic conversion + LLColor3(); // Initializes LLColor3 to (0, 0, 0) + LLColor3(F32 r, F32 g, F32 b); // Initializes LLColor3 to (r, g, b) + LLColor3(const F32* vec); // Initializes LLColor3 to (vec[0]. vec[1], vec[2]) + LLColor3(const char* color_string); // html format color ie "#FFDDEE" + explicit LLColor3(const LLColor4& color4); // "explicit" to avoid automatic conversion + explicit LLColor3(const LLVector4& vector4); // "explicit" to avoid automatic conversion LLColor3(const LLSD& sd); - LLSD getValue() const { LLSD ret; - ret[0] = mV[0]; - ret[1] = mV[1]; - ret[2] = mV[2]; + ret[VRED] = mV[VRED]; + ret[VGREEN] = mV[VGREEN]; + ret[VBLUE] = mV[VBLUE]; return ret; } void setValue(const LLSD& sd) { - mV[0] = (F32) sd[0].asReal();; - mV[1] = (F32) sd[1].asReal();; - mV[2] = (F32) sd[2].asReal();; + mV[VRED] = (F32)sd[VRED].asReal(); + mV[VGREEN] = (F32)sd[VGREEN].asReal(); + mV[VBLUE] = (F32)sd[VBLUE].asReal(); } void setHSL(F32 hue, F32 saturation, F32 luminance); void calcHSL(F32* hue, F32* saturation, F32* luminance) const; - const LLColor3& setToBlack(); // Clears LLColor3 to (0, 0, 0) - const LLColor3& setToWhite(); // Zero LLColor3 to (0, 0, 0) + const LLColor3& setToBlack(); // Clears LLColor3 to (0, 0, 0) + const LLColor3& setToWhite(); // Zero LLColor3 to (0, 0, 0) - const LLColor3& setVec(F32 x, F32 y, F32 z); // deprecated - const LLColor3& setVec(const LLColor3 &vec); // deprecated - const LLColor3& setVec(const F32 *vec); // deprecated + const LLColor3& setVec(F32 x, F32 y, F32 z); // deprecated + const LLColor3& setVec(const LLColor3& vec); // deprecated + const LLColor3& setVec(const F32* vec); // deprecated - const LLColor3& set(F32 x, F32 y, F32 z); // Sets LLColor3 to (x, y, z) - const LLColor3& set(const LLColor3 &vec); // Sets LLColor3 to vec - const LLColor3& set(const F32 *vec); // Sets LLColor3 to vec + const LLColor3& set(F32 x, F32 y, F32 z); // Sets LLColor3 to (x, y, z) + const LLColor3& set(const LLColor3& vec); // Sets LLColor3 to vec + const LLColor3& set(const F32* vec); // Sets LLColor3 to vec // set from a vector of unknown type and size // may leave some data unmodified @@ -99,56 +98,50 @@ public: template<typename T> void write(std::vector<T>& v) const; - F32 magVec() const; // deprecated - F32 magVecSquared() const; // deprecated - F32 normVec(); // deprecated + F32 magVec() const; // deprecated + F32 magVecSquared() const; // deprecated + F32 normVec(); // deprecated - F32 length() const; // Returns magnitude of LLColor3 - F32 lengthSquared() const; // Returns magnitude squared of LLColor3 - F32 normalize(); // Normalizes and returns the magnitude of LLColor3 + F32 length() const; // Returns magnitude of LLColor3 + F32 lengthSquared() const; // Returns magnitude squared of LLColor3 + F32 normalize(); // Normalizes and returns the magnitude of LLColor3 - F32 brightness() const; // Returns brightness of LLColor3 + F32 brightness() const; // Returns brightness of LLColor3 - const LLColor3& operator=(const LLColor4 &a); + const LLColor3& operator=(const LLColor4& a); - LL_FORCE_INLINE LLColor3 divide(const LLColor3 &col2) + LL_FORCE_INLINE LLColor3 divide(const LLColor3& col2) const { - return LLColor3( - mV[0] / col2.mV[0], - mV[1] / col2.mV[1], - mV[2] / col2.mV[2] ); + return LLColor3(mV[VRED] / col2.mV[VRED], mV[VGREEN] / col2.mV[VGREEN], mV[VBLUE] / col2.mV[VBLUE]); } - LL_FORCE_INLINE LLColor3 color_norm() + LL_FORCE_INLINE LLColor3 color_norm() const { F32 l = length(); - return LLColor3( - mV[0] / l, - mV[1] / l, - mV[2] / l ); + return LLColor3(mV[VRED] / l, mV[VGREEN] / l, mV[VBLUE] / l); } - friend std::ostream& operator<<(std::ostream& s, const LLColor3 &a); // Print a - friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b); // Return vector a + b - friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b); // Return vector a minus b + friend std::ostream& operator<<(std::ostream& s, const LLColor3& a); // Print a + friend LLColor3 operator+(const LLColor3& a, const LLColor3& b); // Return vector a + b + friend LLColor3 operator-(const LLColor3& a, const LLColor3& b); // Return vector a minus b - friend const LLColor3& operator+=(LLColor3 &a, const LLColor3 &b); // Return vector a + b - friend const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b); // Return vector a minus b - friend const LLColor3& operator*=(LLColor3 &a, const LLColor3 &b); + friend const LLColor3& operator+=(LLColor3& a, const LLColor3& b); // Return vector a + b + friend const LLColor3& operator-=(LLColor3& a, const LLColor3& b); // Return vector a minus b + friend const LLColor3& operator*=(LLColor3& a, const LLColor3& b); - friend LLColor3 operator*(const LLColor3 &a, const LLColor3 &b); // Return component wise a * b - friend LLColor3 operator*(const LLColor3 &a, F32 k); // Return a times scaler k - friend LLColor3 operator*(F32 k, const LLColor3 &a); // Return a times scaler k + friend LLColor3 operator*(const LLColor3& a, const LLColor3& b); // Return component wise a * b + friend LLColor3 operator*(const LLColor3& a, F32 k); // Return a times scaler k + friend LLColor3 operator*(F32 k, const LLColor3& a); // Return a times scaler k - friend bool operator==(const LLColor3 &a, const LLColor3 &b); // Return a == b - friend bool operator!=(const LLColor3 &a, const LLColor3 &b); // Return a != b + friend bool operator==(const LLColor3& a, const LLColor3& b); // Return a == b + friend bool operator!=(const LLColor3& a, const LLColor3& b); // Return a != b - friend const LLColor3& operator*=(LLColor3 &a, F32 k); // Return a times scaler k + friend const LLColor3& operator*=(LLColor3& a, F32 k); // Return a times scaler k - friend LLColor3 operator-(const LLColor3 &a); // Return vector 1-rgb (inverse) + friend LLColor3 operator-(const LLColor3& a); // Return vector 1-rgb (inverse) inline void clamp(); - inline void exp(); // Do an exponential on the color + inline void exp(); // Do an exponential on the color }; static_assert(std::is_trivially_copyable<LLColor3>::value, "LLColor3 must be trivial copy"); @@ -156,360 +149,342 @@ static_assert(std::is_trivially_move_assignable<LLColor3>::value, "LLColor3 must static_assert(std::is_standard_layout<LLColor3>::value, "LLColor3 must be a standard layout type"); LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u); - void LLColor3::clamp() { // Clamp the color... - if (mV[0] < 0.f) + if (mV[VRED] < 0.f) { - mV[0] = 0.f; + mV[VRED] = 0.f; } - else if (mV[0] > 1.f) + else if (mV[VRED] > 1.f) { - mV[0] = 1.f; + mV[VRED] = 1.f; } - if (mV[1] < 0.f) + if (mV[VGREEN] < 0.f) { - mV[1] = 0.f; + mV[VGREEN] = 0.f; } - else if (mV[1] > 1.f) + else if (mV[VGREEN] > 1.f) { - mV[1] = 1.f; + mV[VGREEN] = 1.f; } - if (mV[2] < 0.f) + if (mV[VBLUE] < 0.f) { - mV[2] = 0.f; + mV[VBLUE] = 0.f; } - else if (mV[2] > 1.f) + else if (mV[VBLUE] > 1.f) { - mV[2] = 1.f; + mV[VBLUE] = 1.f; } } // Non-member functions -F32 distVec(const LLColor3 &a, const LLColor3 &b); // Returns distance between a and b -F32 distVec_squared(const LLColor3 &a, const LLColor3 &b);// Returns distance squared between a and b +F32 distVec(const LLColor3& a, const LLColor3& b); // Returns distance between a and b +F32 distVec_squared(const LLColor3& a, const LLColor3& b); // Returns distance squared between a and b -inline LLColor3::LLColor3(void) +inline LLColor3::LLColor3() { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + mV[VRED] = 0.f; + mV[VGREEN] = 0.f; + mV[VBLUE] = 0.f; } inline LLColor3::LLColor3(F32 r, F32 g, F32 b) { - mV[VRED] = r; + mV[VRED] = r; mV[VGREEN] = g; - mV[VBLUE] = b; + mV[VBLUE] = b; } - -inline LLColor3::LLColor3(const F32 *vec) +inline LLColor3::LLColor3(const F32* vec) { - mV[VRED] = vec[VRED]; + mV[VRED] = vec[VRED]; mV[VGREEN] = vec[VGREEN]; - mV[VBLUE] = vec[VBLUE]; + mV[VBLUE] = vec[VBLUE]; } inline LLColor3::LLColor3(const char* color_string) // takes a string of format "RRGGBB" where RR is hex 00..FF { - if (strlen(color_string) < 6) /* Flawfinder: ignore */ + if (strlen(color_string) < 6) /* Flawfinder: ignore */ { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + mV[VRED] = 0.f; + mV[VGREEN] = 0.f; + mV[VBLUE] = 0.f; return; } char tempstr[7]; - strncpy(tempstr,color_string,6); /* Flawfinder: ignore */ + strncpy(tempstr, color_string, 6); /* Flawfinder: ignore */ tempstr[6] = '\0'; - mV[VBLUE] = (F32)strtol(&tempstr[4],NULL,16)/255.f; + mV[VBLUE] = (F32)strtol(&tempstr[4], nullptr, 16) / 255.f; tempstr[4] = '\0'; - mV[VGREEN] = (F32)strtol(&tempstr[2],NULL,16)/255.f; + mV[VGREEN] = (F32)strtol(&tempstr[2], nullptr, 16) / 255.f; tempstr[2] = '\0'; - mV[VRED] = (F32)strtol(&tempstr[0],NULL,16)/255.f; + mV[VRED] = (F32)strtol(&tempstr[0], nullptr, 16) / 255.f; } -inline const LLColor3& LLColor3::setToBlack(void) +inline const LLColor3& LLColor3::setToBlack() { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + mV[VRED] = 0.f; + mV[VGREEN] = 0.f; + mV[VBLUE] = 0.f; return (*this); } -inline const LLColor3& LLColor3::setToWhite(void) +inline const LLColor3& LLColor3::setToWhite() { - mV[0] = 1.f; - mV[1] = 1.f; - mV[2] = 1.f; + mV[VRED] = 1.f; + mV[VGREEN] = 1.f; + mV[VBLUE] = 1.f; return (*this); } -inline const LLColor3& LLColor3::set(F32 r, F32 g, F32 b) +inline const LLColor3& LLColor3::set(F32 r, F32 g, F32 b) { - mV[0] = r; - mV[1] = g; - mV[2] = b; + mV[VRED] = r; + mV[VGREEN] = g; + mV[VBLUE] = b; return (*this); } -inline const LLColor3& LLColor3::set(const LLColor3 &vec) +inline const LLColor3& LLColor3::set(const LLColor3& vec) { - mV[0] = vec.mV[0]; - mV[1] = vec.mV[1]; - mV[2] = vec.mV[2]; + mV[VRED] = vec.mV[VRED]; + mV[VGREEN] = vec.mV[VGREEN]; + mV[VBLUE] = vec.mV[VBLUE]; return (*this); } -inline const LLColor3& LLColor3::set(const F32 *vec) +inline const LLColor3& LLColor3::set(const F32* vec) { - mV[0] = vec[0]; - mV[1] = vec[1]; - mV[2] = vec[2]; + mV[VRED] = vec[VRED]; + mV[VGREEN] = vec[VGREEN]; + mV[VBLUE] = vec[VBLUE]; return (*this); } // deprecated -inline const LLColor3& LLColor3::setVec(F32 r, F32 g, F32 b) +inline const LLColor3& LLColor3::setVec(F32 r, F32 g, F32 b) { - mV[0] = r; - mV[1] = g; - mV[2] = b; + mV[VRED] = r; + mV[VGREEN] = g; + mV[VBLUE] = b; return (*this); } // deprecated -inline const LLColor3& LLColor3::setVec(const LLColor3 &vec) +inline const LLColor3& LLColor3::setVec(const LLColor3& vec) { - mV[0] = vec.mV[0]; - mV[1] = vec.mV[1]; - mV[2] = vec.mV[2]; + mV[VRED] = vec.mV[VRED]; + mV[VGREEN] = vec.mV[VGREEN]; + mV[VBLUE] = vec.mV[VBLUE]; return (*this); } // deprecated -inline const LLColor3& LLColor3::setVec(const F32 *vec) +inline const LLColor3& LLColor3::setVec(const F32* vec) { - mV[0] = vec[0]; - mV[1] = vec[1]; - mV[2] = vec[2]; + mV[VRED] = vec[VRED]; + mV[VGREEN] = vec[VGREEN]; + mV[VBLUE] = vec[VBLUE]; return (*this); } -inline F32 LLColor3::brightness(void) const +inline F32 LLColor3::brightness() const { - return (mV[0] + mV[1] + mV[2]) / 3.0f; + return (mV[VRED] + mV[VGREEN] + mV[VBLUE]) / 3.0f; } -inline F32 LLColor3::length(void) const +inline F32 LLColor3::length() const { - return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); + return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); } -inline F32 LLColor3::lengthSquared(void) const +inline F32 LLColor3::lengthSquared() const { - return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; + return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]; } -inline F32 LLColor3::normalize(void) +inline F32 LLColor3::normalize() { - F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); + F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); F32 oomag; if (mag) { - oomag = 1.f/mag; - mV[0] *= oomag; - mV[1] *= oomag; - mV[2] *= oomag; + oomag = 1.f / mag; + mV[VRED] *= oomag; + mV[VGREEN] *= oomag; + mV[VBLUE] *= oomag; } - return (mag); + return mag; } // deprecated -inline F32 LLColor3::magVec(void) const +inline F32 LLColor3::magVec() const { - return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); + return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); } // deprecated -inline F32 LLColor3::magVecSquared(void) const +inline F32 LLColor3::magVecSquared() const { - return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; + return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]; } // deprecated -inline F32 LLColor3::normVec(void) +inline F32 LLColor3::normVec() { - F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); + F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); F32 oomag; if (mag) { - oomag = 1.f/mag; - mV[0] *= oomag; - mV[1] *= oomag; - mV[2] *= oomag; + oomag = 1.f / mag; + mV[VRED] *= oomag; + mV[VGREEN] *= oomag; + mV[VBLUE] *= oomag; } - return (mag); + return mag; } inline void LLColor3::exp() { #if 0 - mV[0] = ::exp(mV[0]); - mV[1] = ::exp(mV[1]); - mV[2] = ::exp(mV[2]); + mV[VRED] = ::exp(mV[VRED]); + mV[VGREEN] = ::exp(mV[VGREEN]); + mV[VBLUE] = ::exp(mV[VBLUE]); #else - mV[0] = (F32)LL_FAST_EXP(mV[0]); - mV[1] = (F32)LL_FAST_EXP(mV[1]); - mV[2] = (F32)LL_FAST_EXP(mV[2]); + mV[VRED] = (F32)LL_FAST_EXP(mV[VRED]); + mV[VGREEN] = (F32)LL_FAST_EXP(mV[VGREEN]); + mV[VBLUE] = (F32)LL_FAST_EXP(mV[VBLUE]); #endif } - -inline LLColor3 operator+(const LLColor3 &a, const LLColor3 &b) +inline LLColor3 operator+(const LLColor3& a, const LLColor3& b) { - return LLColor3( - a.mV[0] + b.mV[0], - a.mV[1] + b.mV[1], - a.mV[2] + b.mV[2]); + return LLColor3(a.mV[VRED] + b.mV[VRED], a.mV[VGREEN] + b.mV[VGREEN], a.mV[VBLUE] + b.mV[VBLUE]); } -inline LLColor3 operator-(const LLColor3 &a, const LLColor3 &b) +inline LLColor3 operator-(const LLColor3& a, const LLColor3& b) { - return LLColor3( - a.mV[0] - b.mV[0], - a.mV[1] - b.mV[1], - a.mV[2] - b.mV[2]); + return LLColor3(a.mV[VRED] - b.mV[VRED], a.mV[VGREEN] - b.mV[VGREEN], a.mV[VBLUE] - b.mV[VBLUE]); } -inline LLColor3 operator*(const LLColor3 &a, const LLColor3 &b) +inline LLColor3 operator*(const LLColor3& a, const LLColor3& b) { - return LLColor3( - a.mV[0] * b.mV[0], - a.mV[1] * b.mV[1], - a.mV[2] * b.mV[2]); + return LLColor3(a.mV[VRED] * b.mV[VRED], a.mV[VGREEN] * b.mV[VGREEN], a.mV[VBLUE] * b.mV[VBLUE]); } -inline LLColor3 operator*(const LLColor3 &a, F32 k) +inline LLColor3 operator*(const LLColor3& a, F32 k) { - return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); + return LLColor3(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k); } -inline LLColor3 operator*(F32 k, const LLColor3 &a) +inline LLColor3 operator*(F32 k, const LLColor3& a) { - return LLColor3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); + return LLColor3(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k); } -inline bool operator==(const LLColor3 &a, const LLColor3 &b) +inline bool operator==(const LLColor3& a, const LLColor3& b) { - return ( (a.mV[0] == b.mV[0]) - &&(a.mV[1] == b.mV[1]) - &&(a.mV[2] == b.mV[2])); + return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE])); } -inline bool operator!=(const LLColor3 &a, const LLColor3 &b) +inline bool operator!=(const LLColor3& a, const LLColor3& b) { - return ( (a.mV[0] != b.mV[0]) - ||(a.mV[1] != b.mV[1]) - ||(a.mV[2] != b.mV[2])); + return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE])); } -inline const LLColor3 &operator*=(LLColor3 &a, const LLColor3 &b) +inline const LLColor3& operator*=(LLColor3& a, const LLColor3& b) { - a.mV[0] *= b.mV[0]; - a.mV[1] *= b.mV[1]; - a.mV[2] *= b.mV[2]; + a.mV[VRED] *= b.mV[VRED]; + a.mV[VGREEN] *= b.mV[VGREEN]; + a.mV[VBLUE] *= b.mV[VBLUE]; return a; } -inline const LLColor3& operator+=(LLColor3 &a, const LLColor3 &b) +inline const LLColor3& operator+=(LLColor3& a, const LLColor3& b) { - a.mV[0] += b.mV[0]; - a.mV[1] += b.mV[1]; - a.mV[2] += b.mV[2]; + a.mV[VRED] += b.mV[VRED]; + a.mV[VGREEN] += b.mV[VGREEN]; + a.mV[VBLUE] += b.mV[VBLUE]; return a; } -inline const LLColor3& operator-=(LLColor3 &a, const LLColor3 &b) +inline const LLColor3& operator-=(LLColor3& a, const LLColor3& b) { - a.mV[0] -= b.mV[0]; - a.mV[1] -= b.mV[1]; - a.mV[2] -= b.mV[2]; + a.mV[VRED] -= b.mV[VRED]; + a.mV[VGREEN] -= b.mV[VGREEN]; + a.mV[VBLUE] -= b.mV[VBLUE]; return a; } -inline const LLColor3& operator*=(LLColor3 &a, F32 k) +inline const LLColor3& operator*=(LLColor3& a, F32 k) { - a.mV[0] *= k; - a.mV[1] *= k; - a.mV[2] *= k; + a.mV[VRED] *= k; + a.mV[VGREEN] *= k; + a.mV[VBLUE] *= k; return a; } -inline LLColor3 operator-(const LLColor3 &a) +inline LLColor3 operator-(const LLColor3& a) { - return LLColor3( - 1.f - a.mV[0], - 1.f - a.mV[1], - 1.f - a.mV[2] ); + return LLColor3(1.f - a.mV[VRED], 1.f - a.mV[VGREEN], 1.f - a.mV[VBLUE]); } // Non-member functions -inline F32 distVec(const LLColor3 &a, const LLColor3 &b) +inline F32 distVec(const LLColor3& a, const LLColor3& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; - F32 z = a.mV[2] - b.mV[2]; - return (F32) sqrt( x*x + y*y + z*z ); + F32 x = a.mV[VRED] - b.mV[VRED]; + F32 y = a.mV[VGREEN] - b.mV[VGREEN]; + F32 z = a.mV[VBLUE] - b.mV[VBLUE]; + return sqrt(x * x + y * y + z * z); } -inline F32 distVec_squared(const LLColor3 &a, const LLColor3 &b) +inline F32 distVec_squared(const LLColor3& a, const LLColor3& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; - F32 z = a.mV[2] - b.mV[2]; - return x*x + y*y + z*z; + F32 x = a.mV[VRED] - b.mV[VRED]; + F32 y = a.mV[VGREEN] - b.mV[VGREEN]; + F32 z = a.mV[VBLUE] - b.mV[VBLUE]; + return x * x + y * y + z * z; } -inline LLColor3 lerp(const LLColor3 &a, const LLColor3 &b, F32 u) +inline LLColor3 lerp(const LLColor3& a, const LLColor3& b, F32 u) { - return LLColor3( - a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, - a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, - a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u); + return LLColor3(a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u, a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u); } -inline const LLColor3 srgbColor3(const LLColor3 &a) { +inline const LLColor3 srgbColor3(const LLColor3& a) +{ LLColor3 srgbColor; - srgbColor.mV[0] = linearTosRGB(a.mV[0]); - srgbColor.mV[1] = linearTosRGB(a.mV[1]); - srgbColor.mV[2] = linearTosRGB(a.mV[2]); + srgbColor.mV[VRED] = linearTosRGB(a.mV[VRED]); + srgbColor.mV[VGREEN] = linearTosRGB(a.mV[VGREEN]); + srgbColor.mV[VBLUE] = linearTosRGB(a.mV[VBLUE]); return srgbColor; } -inline const LLColor3 linearColor3p(const F32* v) { +inline const LLColor3 linearColor3p(const F32* v) +{ LLColor3 linearColor; - linearColor.mV[0] = sRGBtoLinear(v[0]); - linearColor.mV[1] = sRGBtoLinear(v[1]); - linearColor.mV[2] = sRGBtoLinear(v[2]); + linearColor.mV[VRED] = sRGBtoLinear(v[VRED]); + linearColor.mV[VGREEN] = sRGBtoLinear(v[VGREEN]); + linearColor.mV[VBLUE] = sRGBtoLinear(v[VBLUE]); return linearColor; } template<class T> -inline const LLColor3 linearColor3(const T& a) { +inline const LLColor3 linearColor3(const T& a) +{ return linearColor3p(a.mV); } template<class T> -inline const LLVector3 linearColor3v(const T& a) { +inline const LLVector3 linearColor3v(const T& a) +{ return LLVector3(linearColor3p(a.mV).mV); } diff --git a/indra/llmath/v3colorutil.h b/indra/llmath/v3colorutil.h index af8799e42a..4dc3100443 100644 --- a/indra/llmath/v3colorutil.h +++ b/indra/llmath/v3colorutil.h @@ -30,59 +30,46 @@ #include "v3color.h" #include "v4color.h" -inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right) +inline LLColor3 componentDiv(const LLColor3& left, const LLColor3& right) { - return LLColor3(left.mV[0] / right.mV[0], - left.mV[1] / right.mV[1], - left.mV[2] / right.mV[2]); + return LLColor3(left.mV[VRED] / right.mV[VRED], left.mV[VGREEN] / right.mV[VGREEN], left.mV[VBLUE] / right.mV[VBLUE]); } - -inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right) +inline LLColor3 componentMult(const LLColor3& left, const LLColor3& right) { - return LLColor3(left.mV[0] * right.mV[0], - left.mV[1] * right.mV[1], - left.mV[2] * right.mV[2]); + return LLColor3(left.mV[VRED] * right.mV[VRED], left.mV[VGREEN] * right.mV[VGREEN], left.mV[VBLUE] * right.mV[VBLUE]); } - -inline LLColor3 componentExp(LLColor3 const &v) +inline LLColor3 componentExp(const LLColor3& v) { - return LLColor3(exp(v.mV[0]), - exp(v.mV[1]), - exp(v.mV[2])); + return LLColor3(exp(v.mV[VRED]), exp(v.mV[VGREEN]), exp(v.mV[VBLUE])); } -inline LLColor3 componentPow(LLColor3 const &v, F32 exponent) +inline LLColor3 componentPow(const LLColor3& v, F32 exponent) { - return LLColor3(pow(v.mV[0], exponent), - pow(v.mV[1], exponent), - pow(v.mV[2], exponent)); + return LLColor3(pow(v.mV[VRED], exponent), pow(v.mV[VGREEN], exponent), pow(v.mV[VBLUE], exponent)); } -inline LLColor3 componentSaturate(LLColor3 const &v) +inline LLColor3 componentSaturate(const LLColor3& v) { - return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f), - std::max(std::min(v.mV[1], 1.f), 0.f), - std::max(std::min(v.mV[2], 1.f), 0.f)); + return LLColor3(std::max(std::min(v.mV[VRED], 1.f), 0.f), + std::max(std::min(v.mV[VGREEN], 1.f), 0.f), + std::max(std::min(v.mV[VBLUE], 1.f), 0.f)); } - -inline LLColor3 componentSqrt(LLColor3 const &v) +inline LLColor3 componentSqrt(const LLColor3& v) { - return LLColor3(sqrt(v.mV[0]), - sqrt(v.mV[1]), - sqrt(v.mV[2])); + return LLColor3(sqrt(v.mV[VRED]), sqrt(v.mV[VGREEN]), sqrt(v.mV[VBLUE])); } -inline void componentMultBy(LLColor3 & left, LLColor3 const & right) +inline void componentMultBy(LLColor3& left, const LLColor3& right) { - left.mV[0] *= right.mV[0]; - left.mV[1] *= right.mV[1]; - left.mV[2] *= right.mV[2]; + left.mV[VRED] *= right.mV[VRED]; + left.mV[VGREEN] *= right.mV[VGREEN]; + left.mV[VBLUE] *= right.mV[VBLUE]; } -inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount) +inline LLColor3 colorMix(const LLColor3& left, const LLColor3& right, F32 amount) { return (left + ((right - left) * amount)); } @@ -92,25 +79,24 @@ inline LLColor3 smear(F32 val) return LLColor3(val, val, val); } -inline F32 color_intens(const LLColor3 &col) +inline F32 color_intens(const LLColor3& col) { - return col.mV[0] + col.mV[1] + col.mV[2]; + return col.mV[VRED] + col.mV[VGREEN] + col.mV[VBLUE]; } -inline F32 color_max(const LLColor3 &col) +inline F32 color_max(const LLColor3& col) { - return llmax(col.mV[0], col.mV[1], col.mV[2]); + return llmax(col.mV[VRED], col.mV[VGREEN], col.mV[VBLUE]); } -inline F32 color_max(const LLColor4 &col) +inline F32 color_max(const LLColor4& col) { - return llmax(col.mV[0], col.mV[1], col.mV[2]); + return llmax(col.mV[VRED], col.mV[VGREEN], col.mV[VBLUE]); } - -inline F32 color_min(const LLColor3 &col) +inline F32 color_min(const LLColor3& col) { - return llmin(col.mV[0], col.mV[1], col.mV[2]); + return llmin(col.mV[VRED], col.mV[VGREEN], col.mV[VBLUE]); } #endif diff --git a/indra/llmath/v3dmath.cpp b/indra/llmath/v3dmath.cpp index bb55c812b5..b051303686 100644 --- a/indra/llmath/v3dmath.cpp +++ b/indra/llmath/v3dmath.cpp @@ -30,7 +30,6 @@ #include "v3dmath.h" -//#include "vmath.h" #include "v4math.h" #include "m4math.h" #include "m3math.h" @@ -57,13 +56,13 @@ bool LLVector3d::clamp(F64 min, F64 max) { bool ret{ false }; - if (mdV[0] < min) { mdV[0] = min; ret = true; } - if (mdV[1] < min) { mdV[1] = min; ret = true; } - if (mdV[2] < min) { mdV[2] = min; ret = true; } + if (mdV[VX] < min) { mdV[VX] = min; ret = true; } + if (mdV[VY] < min) { mdV[VY] = min; ret = true; } + if (mdV[VZ] < min) { mdV[VZ] = min; ret = true; } - if (mdV[0] > max) { mdV[0] = max; ret = true; } - if (mdV[1] > max) { mdV[1] = max; ret = true; } - if (mdV[2] > max) { mdV[2] = max; ret = true; } + if (mdV[VX] > max) { mdV[VX] = max; ret = true; } + if (mdV[VY] > max) { mdV[VY] = max; ret = true; } + if (mdV[VZ] > max) { mdV[VZ] = max; ret = true; } return ret; } @@ -74,9 +73,9 @@ bool LLVector3d::abs() { bool ret{ false }; - if (mdV[0] < 0.0) { mdV[0] = -mdV[0]; ret = true; } - if (mdV[1] < 0.0) { mdV[1] = -mdV[1]; ret = true; } - if (mdV[2] < 0.0) { mdV[2] = -mdV[2]; ret = true; } + if (mdV[VX] < 0.0) { mdV[VX] = -mdV[VX]; ret = true; } + if (mdV[VY] < 0.0) { mdV[VY] = -mdV[VY]; ret = true; } + if (mdV[VZ] < 0.0) { mdV[VZ] = -mdV[VZ]; ret = true; } return ret; } @@ -89,37 +88,37 @@ std::ostream& operator<<(std::ostream& s, const LLVector3d &a) const LLVector3d& LLVector3d::operator=(const LLVector4 &a) { - mdV[0] = a.mV[0]; - mdV[1] = a.mV[1]; - mdV[2] = a.mV[2]; + mdV[VX] = a.mV[VX]; + mdV[VY] = a.mV[VY]; + mdV[VZ] = a.mV[VZ]; return *this; } -const LLVector3d& LLVector3d::rotVec(const LLMatrix3 &mat) +const LLVector3d& LLVector3d::rotVec(const LLMatrix3& mat) { *this = *this * mat; return *this; } -const LLVector3d& LLVector3d::rotVec(const LLQuaternion &q) +const LLVector3d& LLVector3d::rotVec(const LLQuaternion& q) { *this = *this * q; return *this; } -const LLVector3d& LLVector3d::rotVec(F64 angle, const LLVector3d &vec) +const LLVector3d& LLVector3d::rotVec(F64 angle, const LLVector3d& vec) { - if ( !vec.isExactlyZero() && angle ) + if (!vec.isExactlyZero() && angle) { *this = *this * LLMatrix3((F32)angle, vec); } return *this; } -const LLVector3d& LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z) +const LLVector3d& LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z) { LLVector3d vec(x, y, z); - if ( !vec.isExactlyZero() && angle ) + if (!vec.isExactlyZero() && angle) { *this = *this * LLMatrix3((F32)angle, vec); } @@ -129,16 +128,16 @@ const LLVector3d& LLVector3d::rotVec(F64 angle, F64 x, F64 y, F64 z) bool LLVector3d::parseVector3d(const std::string& buf, LLVector3d* value) { - if( buf.empty() || value == nullptr) + if (buf.empty() || value == nullptr) { return false; } LLVector3d v; - S32 count = sscanf( buf.c_str(), "%lf %lf %lf", v.mdV + 0, v.mdV + 1, v.mdV + 2 ); - if( 3 == count ) + S32 count = sscanf(buf.c_str(), "%lf %lf %lf", v.mdV + VX, v.mdV + VY, v.mdV + VZ); + if (3 == count) { - value->setVec( v ); + value->setVec(v); return true; } diff --git a/indra/llmath/v3dmath.h b/indra/llmath/v3dmath.h index d261e9de88..7c56cf138d 100644 --- a/indra/llmath/v3dmath.h +++ b/indra/llmath/v3dmath.h @@ -32,102 +32,101 @@ class LLVector3d { - public: - F64 mdV[3]; - - const static LLVector3d zero; - const static LLVector3d x_axis; - const static LLVector3d y_axis; - const static LLVector3d z_axis; - const static LLVector3d x_axis_neg; - const static LLVector3d y_axis_neg; - const static LLVector3d z_axis_neg; - - inline LLVector3d(); // Initializes LLVector3d to (0, 0, 0) - inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z) - inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2]) - inline explicit LLVector3d(const LLVector3 &vec); - explicit LLVector3d(const LLSD& sd) - { - setValue(sd); - } - - void setValue(const LLSD& sd) - { - mdV[0] = sd[0].asReal(); - mdV[1] = sd[1].asReal(); - mdV[2] = sd[2].asReal(); - } - - LLSD getValue() const - { - LLSD ret; - ret[0] = mdV[0]; - ret[1] = mdV[1]; - ret[2] = mdV[2]; - return ret; - } - - inline bool isFinite() const; // checks to see if all values of LLVector3d are finite - bool clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns true if data changed - bool abs(); // sets all values to absolute value of original value (first octant), returns true if changed - - inline const LLVector3d& clear(); // Clears LLVector3d to (0, 0, 0, 1) - inline const LLVector3d& clearVec(); // deprecated - inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0) - inline const LLVector3d& zeroVec(); // deprecated - inline const LLVector3d& set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1) - inline const LLVector3d& set(const LLVector3d &vec); // Sets LLVector3d to vec - inline const LLVector3d& set(const F64 *vec); // Sets LLVector3d to vec - inline const LLVector3d& set(const LLVector3 &vec); - inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // deprecated - inline const LLVector3d& setVec(const LLVector3d &vec); // deprecated - inline const LLVector3d& setVec(const F64 *vec); // deprecated - inline const LLVector3d& setVec(const LLVector3 &vec); // deprecated - - F64 magVec() const; // deprecated - F64 magVecSquared() const; // deprecated - inline F64 normVec(); // deprecated - - F64 length() const; // Returns magnitude of LLVector3d - F64 lengthSquared() const; // Returns magnitude squared of LLVector3d - inline F64 normalize(); // Normalizes and returns the magnitude of LLVector3d - - const LLVector3d& rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians - const LLVector3d& rotVec(const F64 angle, const F64 x, const F64 y, const F64 z); // Rotates about x,y,z by angle radians - const LLVector3d& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat - const LLVector3d& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q - - bool isNull() const; // Returns true if vector has a _very_small_ length - bool isExactlyZero() const { return !mdV[VX] && !mdV[VY] && !mdV[VZ]; } - - const LLVector3d& operator=(const LLVector4 &a); - - F64 operator[](int idx) const { return mdV[idx]; } - F64 &operator[](int idx) { return mdV[idx]; } - - friend LLVector3d operator+(const LLVector3d& a, const LLVector3d& b); // Return vector a + b - friend LLVector3d operator-(const LLVector3d& a, const LLVector3d& b); // Return vector a minus b - friend F64 operator*(const LLVector3d& a, const LLVector3d& b); // Return a dot b - friend LLVector3d operator%(const LLVector3d& a, const LLVector3d& b); // Return a cross b - friend LLVector3d operator*(const LLVector3d& a, const F64 k); // Return a times scaler k - friend LLVector3d operator/(const LLVector3d& a, const F64 k); // Return a divided by scaler k - friend LLVector3d operator*(const F64 k, const LLVector3d& a); // Return a times scaler k - friend bool operator==(const LLVector3d& a, const LLVector3d& b); // Return a == b - friend bool operator!=(const LLVector3d& a, const LLVector3d& b); // Return a != b - - friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b); // Return vector a + b - friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b); // Return vector a minus b - friend const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b); // Return a cross b - friend const LLVector3d& operator*=(LLVector3d& a, const F64 k); // Return a times scaler k - friend const LLVector3d& operator/=(LLVector3d& a, const F64 k); // Return a divided by scaler k - - friend LLVector3d operator-(const LLVector3d& a); // Return vector -a - - friend std::ostream& operator<<(std::ostream& s, const LLVector3d& a); // Stream a - - static bool parseVector3d(const std::string& buf, LLVector3d* value); +public: + F64 mdV[3]; + + const static LLVector3d zero; + const static LLVector3d x_axis; + const static LLVector3d y_axis; + const static LLVector3d z_axis; + const static LLVector3d x_axis_neg; + const static LLVector3d y_axis_neg; + const static LLVector3d z_axis_neg; + + inline LLVector3d(); // Initializes LLVector3d to (0, 0, 0) + inline LLVector3d(const F64 x, const F64 y, const F64 z); // Initializes LLVector3d to (x. y, z) + inline explicit LLVector3d(const F64 *vec); // Initializes LLVector3d to (vec[0]. vec[1], vec[2]) + inline explicit LLVector3d(const LLVector3 &vec); + explicit LLVector3d(const LLSD& sd) + { + setValue(sd); + } + + void setValue(const LLSD& sd) + { + mdV[VX] = sd[0].asReal(); + mdV[VY] = sd[1].asReal(); + mdV[VZ] = sd[2].asReal(); + } + LLSD getValue() const + { + LLSD ret; + ret[0] = mdV[VX]; + ret[1] = mdV[VY]; + ret[2] = mdV[VZ]; + return ret; + } + + inline bool isFinite() const; // checks to see if all values of LLVector3d are finite + bool clamp(const F64 min, const F64 max); // Clamps all values to (min,max), returns true if data changed + bool abs(); // sets all values to absolute value of original value (first octant), returns true if changed + + inline const LLVector3d& clear(); // Clears LLVector3d to (0, 0, 0, 1) + inline const LLVector3d& clearVec(); // deprecated + inline const LLVector3d& setZero(); // Zero LLVector3d to (0, 0, 0, 0) + inline const LLVector3d& zeroVec(); // deprecated + inline const LLVector3d& set(const F64 x, const F64 y, const F64 z); // Sets LLVector3d to (x, y, z, 1) + inline const LLVector3d& set(const LLVector3d &vec); // Sets LLVector3d to vec + inline const LLVector3d& set(const F64 *vec); // Sets LLVector3d to vec + inline const LLVector3d& set(const LLVector3 &vec); + inline const LLVector3d& setVec(const F64 x, const F64 y, const F64 z); // deprecated + inline const LLVector3d& setVec(const LLVector3d &vec); // deprecated + inline const LLVector3d& setVec(const F64 *vec); // deprecated + inline const LLVector3d& setVec(const LLVector3 &vec); // deprecated + + F64 magVec() const; // deprecated + F64 magVecSquared() const; // deprecated + inline F64 normVec(); // deprecated + + F64 length() const; // Returns magnitude of LLVector3d + F64 lengthSquared() const; // Returns magnitude squared of LLVector3d + inline F64 normalize(); // Normalizes and returns the magnitude of LLVector3d + + const LLVector3d& rotVec(const F64 angle, const LLVector3d &vec); // Rotates about vec by angle radians + const LLVector3d& rotVec(const F64 angle, const F64 x, const F64 y, const F64 z); // Rotates about x,y,z by angle radians + const LLVector3d& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat + const LLVector3d& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q + + bool isNull() const; // Returns true if vector has a _very_small_ length + bool isExactlyZero() const { return !mdV[VX] && !mdV[VY] && !mdV[VZ]; } + + const LLVector3d& operator=(const LLVector4 &a); + + F64 operator[](int idx) const { return mdV[idx]; } + F64 &operator[](int idx) { return mdV[idx]; } + + friend LLVector3d operator+(const LLVector3d& a, const LLVector3d& b); // Return vector a + b + friend LLVector3d operator-(const LLVector3d& a, const LLVector3d& b); // Return vector a minus b + friend F64 operator*(const LLVector3d& a, const LLVector3d& b); // Return a dot b + friend LLVector3d operator%(const LLVector3d& a, const LLVector3d& b); // Return a cross b + friend LLVector3d operator*(const LLVector3d& a, const F64 k); // Return a times scaler k + friend LLVector3d operator/(const LLVector3d& a, const F64 k); // Return a divided by scaler k + friend LLVector3d operator*(const F64 k, const LLVector3d& a); // Return a times scaler k + friend bool operator==(const LLVector3d& a, const LLVector3d& b); // Return a == b + friend bool operator!=(const LLVector3d& a, const LLVector3d& b); // Return a != b + + friend const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b); // Return vector a + b + friend const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b); // Return vector a minus b + friend const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b); // Return a cross b + friend const LLVector3d& operator*=(LLVector3d& a, const F64 k); // Return a times scaler k + friend const LLVector3d& operator/=(LLVector3d& a, const F64 k); // Return a divided by scaler k + + friend LLVector3d operator-(const LLVector3d& a); // Return vector -a + + friend std::ostream& operator<<(std::ostream& s, const LLVector3d& a); // Stream a + + static bool parseVector3d(const std::string& buf, LLVector3d* value); }; static_assert(std::is_trivially_copyable<LLVector3d>::value, "LLVector3d must be trivial copy"); @@ -138,26 +137,26 @@ typedef LLVector3d LLGlobalVec; inline const LLVector3d &LLVector3d::set(const LLVector3 &vec) { - mdV[0] = vec.mV[0]; - mdV[1] = vec.mV[1]; - mdV[2] = vec.mV[2]; + mdV[VX] = vec.mV[VX]; + mdV[VY] = vec.mV[VY]; + mdV[VZ] = vec.mV[VZ]; return *this; } inline const LLVector3d &LLVector3d::setVec(const LLVector3 &vec) { - mdV[0] = vec.mV[0]; - mdV[1] = vec.mV[1]; - mdV[2] = vec.mV[2]; + mdV[VX] = vec.mV[VX]; + mdV[VY] = vec.mV[VY]; + mdV[VZ] = vec.mV[VZ]; return *this; } inline LLVector3d::LLVector3d(void) { - mdV[0] = 0.f; - mdV[1] = 0.f; - mdV[2] = 0.f; + mdV[VX] = 0.f; + mdV[VY] = 0.f; + mdV[VZ] = 0.f; } inline LLVector3d::LLVector3d(const F64 x, const F64 y, const F64 z) @@ -203,33 +202,33 @@ inline bool LLVector3d::isFinite() const inline const LLVector3d& LLVector3d::clear(void) { - mdV[0] = 0.f; - mdV[1] = 0.f; - mdV[2]= 0.f; + mdV[VX] = 0.f; + mdV[VY] = 0.f; + mdV[VZ] = 0.f; return (*this); } inline const LLVector3d& LLVector3d::clearVec(void) { - mdV[0] = 0.f; - mdV[1] = 0.f; - mdV[2]= 0.f; + mdV[VX] = 0.f; + mdV[VY] = 0.f; + mdV[VZ] = 0.f; return (*this); } inline const LLVector3d& LLVector3d::setZero(void) { - mdV[0] = 0.f; - mdV[1] = 0.f; - mdV[2] = 0.f; + mdV[VX] = 0.f; + mdV[VY] = 0.f; + mdV[VZ] = 0.f; return (*this); } inline const LLVector3d& LLVector3d::zeroVec(void) { - mdV[0] = 0.f; - mdV[1] = 0.f; - mdV[2] = 0.f; + mdV[VX] = 0.f; + mdV[VY] = 0.f; + mdV[VZ] = 0.f; return (*this); } @@ -243,17 +242,17 @@ inline const LLVector3d& LLVector3d::set(const F64 x, const F64 y, const F64 inline const LLVector3d& LLVector3d::set(const LLVector3d &vec) { - mdV[0] = vec.mdV[0]; - mdV[1] = vec.mdV[1]; - mdV[2] = vec.mdV[2]; + mdV[VX] = vec.mdV[VX]; + mdV[VY] = vec.mdV[VY]; + mdV[VZ] = vec.mdV[VZ]; return (*this); } inline const LLVector3d& LLVector3d::set(const F64 *vec) { - mdV[0] = vec[0]; - mdV[1] = vec[1]; - mdV[2] = vec[2]; + mdV[VX] = vec[0]; + mdV[VY] = vec[1]; + mdV[VZ] = vec[2]; return (*this); } @@ -265,61 +264,62 @@ inline const LLVector3d& LLVector3d::setVec(const F64 x, const F64 y, const F return (*this); } -inline const LLVector3d& LLVector3d::setVec(const LLVector3d &vec) +inline const LLVector3d& LLVector3d::setVec(const LLVector3d& vec) { - mdV[0] = vec.mdV[0]; - mdV[1] = vec.mdV[1]; - mdV[2] = vec.mdV[2]; + mdV[VX] = vec.mdV[VX]; + mdV[VY] = vec.mdV[VY]; + mdV[VZ] = vec.mdV[VZ]; return (*this); } -inline const LLVector3d& LLVector3d::setVec(const F64 *vec) +inline const LLVector3d& LLVector3d::setVec(const F64* vec) { - mdV[0] = vec[0]; - mdV[1] = vec[1]; - mdV[2] = vec[2]; + mdV[VX] = vec[VX]; + mdV[VY] = vec[VY]; + mdV[VZ] = vec[VZ]; return (*this); } -inline F64 LLVector3d::normVec(void) +inline F64 LLVector3d::normVec() { - F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); + F64 mag = (F32)sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]); // This explicit cast to F32 limits the precision for numerical stability. + // Without it, Unit test "v3dmath_h" fails at "1:angle_between" on macos. F64 oomag; if (mag > FP_MAG_THRESHOLD) { - oomag = 1.f/mag; - mdV[0] *= oomag; - mdV[1] *= oomag; - mdV[2] *= oomag; + oomag = 1.0/mag; + mdV[VX] *= oomag; + mdV[VY] *= oomag; + mdV[VZ] *= oomag; } else { - mdV[0] = 0.f; - mdV[1] = 0.f; - mdV[2] = 0.f; + mdV[VX] = 0.0; + mdV[VY] = 0.0; + mdV[VZ] = 0.0; mag = 0; } return (mag); } -inline F64 LLVector3d::normalize(void) +inline F64 LLVector3d::normalize() { - F64 mag = (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); + F64 mag = (F32)sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]); // Same as in normVec() above. F64 oomag; if (mag > FP_MAG_THRESHOLD) { - oomag = 1.f/mag; - mdV[0] *= oomag; - mdV[1] *= oomag; - mdV[2] *= oomag; + oomag = 1.0/mag; + mdV[VX] *= oomag; + mdV[VY] *= oomag; + mdV[VZ] *= oomag; } else { - mdV[0] = 0.f; - mdV[1] = 0.f; - mdV[2] = 0.f; + mdV[VX] = 0.0; + mdV[VY] = 0.0; + mdV[VZ] = 0.0; mag = 0; } return (mag); @@ -327,24 +327,24 @@ inline F64 LLVector3d::normalize(void) // LLVector3d Magnitude and Normalization Functions -inline F64 LLVector3d::magVec(void) const +inline F64 LLVector3d::magVec() const { - return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); + return sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]); } -inline F64 LLVector3d::magVecSquared(void) const +inline F64 LLVector3d::magVecSquared() const { - return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]; + return mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]; } -inline F64 LLVector3d::length(void) const +inline F64 LLVector3d::length() const { - return (F32) sqrt(mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]); + return sqrt(mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]); } -inline F64 LLVector3d::lengthSquared(void) const +inline F64 LLVector3d::lengthSquared() const { - return mdV[0]*mdV[0] + mdV[1]*mdV[1] + mdV[2]*mdV[2]; + return mdV[VX]*mdV[VX] + mdV[VY]*mdV[VY] + mdV[VZ]*mdV[VZ]; } inline LLVector3d operator+(const LLVector3d& a, const LLVector3d& b) @@ -361,109 +361,109 @@ inline LLVector3d operator-(const LLVector3d& a, const LLVector3d& b) inline F64 operator*(const LLVector3d& a, const LLVector3d& b) { - return (a.mdV[0]*b.mdV[0] + a.mdV[1]*b.mdV[1] + a.mdV[2]*b.mdV[2]); + return (a.mdV[VX]*b.mdV[VX] + a.mdV[VY]*b.mdV[VY] + a.mdV[VZ]*b.mdV[VZ]); } inline LLVector3d operator%(const LLVector3d& a, const LLVector3d& b) { - return LLVector3d( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1] ); + return LLVector3d( a.mdV[VY]*b.mdV[VZ] - b.mdV[VY]*a.mdV[VZ], a.mdV[VZ]*b.mdV[VX] - b.mdV[VZ]*a.mdV[VX], a.mdV[VX]*b.mdV[VY] - b.mdV[VX]*a.mdV[VY] ); } inline LLVector3d operator/(const LLVector3d& a, const F64 k) { F64 t = 1.f / k; - return LLVector3d( a.mdV[0] * t, a.mdV[1] * t, a.mdV[2] * t ); + return LLVector3d( a.mdV[VX] * t, a.mdV[VY] * t, a.mdV[VZ] * t ); } inline LLVector3d operator*(const LLVector3d& a, const F64 k) { - return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k ); + return LLVector3d( a.mdV[VX] * k, a.mdV[VY] * k, a.mdV[VZ] * k ); } inline LLVector3d operator*(F64 k, const LLVector3d& a) { - return LLVector3d( a.mdV[0] * k, a.mdV[1] * k, a.mdV[2] * k ); + return LLVector3d( a.mdV[VX] * k, a.mdV[VY] * k, a.mdV[VZ] * k ); } inline bool operator==(const LLVector3d& a, const LLVector3d& b) { - return ( (a.mdV[0] == b.mdV[0]) - &&(a.mdV[1] == b.mdV[1]) - &&(a.mdV[2] == b.mdV[2])); + return ( (a.mdV[VX] == b.mdV[VX]) + &&(a.mdV[VY] == b.mdV[VY]) + &&(a.mdV[VZ] == b.mdV[VZ])); } inline bool operator!=(const LLVector3d& a, const LLVector3d& b) { - return ( (a.mdV[0] != b.mdV[0]) - ||(a.mdV[1] != b.mdV[1]) - ||(a.mdV[2] != b.mdV[2])); + return ( (a.mdV[VX] != b.mdV[VX]) + ||(a.mdV[VY] != b.mdV[VY]) + ||(a.mdV[VZ] != b.mdV[VZ])); } inline const LLVector3d& operator+=(LLVector3d& a, const LLVector3d& b) { - a.mdV[0] += b.mdV[0]; - a.mdV[1] += b.mdV[1]; - a.mdV[2] += b.mdV[2]; + a.mdV[VX] += b.mdV[VX]; + a.mdV[VY] += b.mdV[VY]; + a.mdV[VZ] += b.mdV[VZ]; return a; } inline const LLVector3d& operator-=(LLVector3d& a, const LLVector3d& b) { - a.mdV[0] -= b.mdV[0]; - a.mdV[1] -= b.mdV[1]; - a.mdV[2] -= b.mdV[2]; + a.mdV[VX] -= b.mdV[VX]; + a.mdV[VY] -= b.mdV[VY]; + a.mdV[VZ] -= b.mdV[VZ]; return a; } inline const LLVector3d& operator%=(LLVector3d& a, const LLVector3d& b) { - LLVector3d ret( a.mdV[1]*b.mdV[2] - b.mdV[1]*a.mdV[2], a.mdV[2]*b.mdV[0] - b.mdV[2]*a.mdV[0], a.mdV[0]*b.mdV[1] - b.mdV[0]*a.mdV[1]); + LLVector3d ret( a.mdV[VY]*b.mdV[VZ] - b.mdV[VY]*a.mdV[VZ], a.mdV[VZ]*b.mdV[VX] - b.mdV[VZ]*a.mdV[VX], a.mdV[VX]*b.mdV[VY] - b.mdV[VX]*a.mdV[VY]); a = ret; return a; } inline const LLVector3d& operator*=(LLVector3d& a, const F64 k) { - a.mdV[0] *= k; - a.mdV[1] *= k; - a.mdV[2] *= k; + a.mdV[VX] *= k; + a.mdV[VY] *= k; + a.mdV[VZ] *= k; return a; } inline const LLVector3d& operator/=(LLVector3d& a, const F64 k) { F64 t = 1.f / k; - a.mdV[0] *= t; - a.mdV[1] *= t; - a.mdV[2] *= t; + a.mdV[VX] *= t; + a.mdV[VY] *= t; + a.mdV[VZ] *= t; return a; } inline LLVector3d operator-(const LLVector3d& a) { - return LLVector3d( -a.mdV[0], -a.mdV[1], -a.mdV[2] ); + return LLVector3d( -a.mdV[VX], -a.mdV[VY], -a.mdV[VZ] ); } inline F64 dist_vec(const LLVector3d& a, const LLVector3d& b) { - F64 x = a.mdV[0] - b.mdV[0]; - F64 y = a.mdV[1] - b.mdV[1]; - F64 z = a.mdV[2] - b.mdV[2]; + F64 x = a.mdV[VX] - b.mdV[VX]; + F64 y = a.mdV[VY] - b.mdV[VY]; + F64 z = a.mdV[VZ] - b.mdV[VZ]; return (F32) sqrt( x*x + y*y + z*z ); } inline F64 dist_vec_squared(const LLVector3d& a, const LLVector3d& b) { - F64 x = a.mdV[0] - b.mdV[0]; - F64 y = a.mdV[1] - b.mdV[1]; - F64 z = a.mdV[2] - b.mdV[2]; + F64 x = a.mdV[VX] - b.mdV[VX]; + F64 y = a.mdV[VY] - b.mdV[VY]; + F64 z = a.mdV[VZ] - b.mdV[VZ]; return x*x + y*y + z*z; } inline F64 dist_vec_squared2D(const LLVector3d& a, const LLVector3d& b) { - F64 x = a.mdV[0] - b.mdV[0]; - F64 y = a.mdV[1] - b.mdV[1]; + F64 x = a.mdV[VX] - b.mdV[VX]; + F64 y = a.mdV[VY] - b.mdV[VY]; return x*x + y*y; } diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index 73ad2a4ed6..eac95ed023 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -28,7 +28,6 @@ #include "v3math.h" -//#include "vmath.h" #include "v2math.h" #include "v4math.h" #include "m4math.h" @@ -58,13 +57,13 @@ bool LLVector3::clamp(F32 min, F32 max) { bool ret{ false }; - if (mV[0] < min) { mV[0] = min; ret = true; } - if (mV[1] < min) { mV[1] = min; ret = true; } - if (mV[2] < min) { mV[2] = min; ret = true; } + if (mV[VX] < min) { mV[VX] = min; ret = true; } + if (mV[VY] < min) { mV[VY] = min; ret = true; } + if (mV[VZ] < min) { mV[VZ] = min; ret = true; } - if (mV[0] > max) { mV[0] = max; ret = true; } - if (mV[1] > max) { mV[1] = max; ret = true; } - if (mV[2] > max) { mV[2] = max; ret = true; } + if (mV[VX] > max) { mV[VX] = max; ret = true; } + if (mV[VY] > max) { mV[VY] = max; ret = true; } + if (mV[VZ] > max) { mV[VZ] = max; ret = true; } return ret; } @@ -85,9 +84,9 @@ bool LLVector3::clampLength( F32 length_limit ) { length_limit = 0.f; } - mV[0] *= length_limit; - mV[1] *= length_limit; - mV[2] *= length_limit; + mV[VX] *= length_limit; + mV[VY] *= length_limit; + mV[VZ] *= length_limit; changed = true; } } @@ -116,35 +115,35 @@ bool LLVector3::clampLength( F32 length_limit ) { // yes it can be salvaged --> // bring the components down before we normalize - mV[0] /= max_abs_component; - mV[1] /= max_abs_component; - mV[2] /= max_abs_component; + mV[VX] /= max_abs_component; + mV[VY] /= max_abs_component; + mV[VZ] /= max_abs_component; normalize(); if (length_limit < 0.f) { length_limit = 0.f; } - mV[0] *= length_limit; - mV[1] *= length_limit; - mV[2] *= length_limit; + mV[VX] *= length_limit; + mV[VY] *= length_limit; + mV[VZ] *= length_limit; } } return changed; } -bool LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec) +bool LLVector3::clamp(const LLVector3& min_vec, const LLVector3& max_vec) { bool ret{ false }; - if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = true; } - if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = true; } - if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = true; } + if (mV[VX] < min_vec[0]) { mV[VX] = min_vec[0]; ret = true; } + if (mV[VY] < min_vec[1]) { mV[VY] = min_vec[1]; ret = true; } + if (mV[VZ] < min_vec[2]) { mV[VZ] = min_vec[2]; ret = true; } - if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = true; } - if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = true; } - if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = true; } + if (mV[VX] > max_vec[0]) { mV[VX] = max_vec[0]; ret = true; } + if (mV[VY] > max_vec[1]) { mV[VY] = max_vec[1]; ret = true; } + if (mV[VZ] > max_vec[2]) { mV[VZ] = max_vec[2]; ret = true; } return ret; } @@ -156,15 +155,15 @@ bool LLVector3::abs() { bool ret{ false }; - if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = true; } - if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = true; } - if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = true; } + if (mV[VX] < 0.f) { mV[VX] = -mV[VX]; ret = true; } + if (mV[VY] < 0.f) { mV[VY] = -mV[VY]; ret = true; } + if (mV[VZ] < 0.f) { mV[VZ] = -mV[VZ]; ret = true; } return ret; } // Quatizations -void LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) +void LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) { F32 x = mV[VX]; F32 y = mV[VY]; @@ -179,7 +178,7 @@ void LLVector3::quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) mV[VZ] = z; } -void LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) +void LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) { mV[VX] = U8_to_F32(F32_to_U8(mV[VX], lowerxy, upperxy), lowerxy, upperxy);; mV[VY] = U8_to_F32(F32_to_U8(mV[VY], lowerxy, upperxy), lowerxy, upperxy); @@ -187,20 +186,20 @@ void LLVector3::quantize8(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz) } -void LLVector3::snap(S32 sig_digits) +void LLVector3::snap(S32 sig_digits) { mV[VX] = snap_to_sig_figs(mV[VX], sig_digits); mV[VY] = snap_to_sig_figs(mV[VY], sig_digits); mV[VZ] = snap_to_sig_figs(mV[VZ], sig_digits); } -const LLVector3& LLVector3::rotVec(const LLMatrix3 &mat) +const LLVector3& LLVector3::rotVec(const LLMatrix3& mat) { *this = *this * mat; return *this; } -const LLVector3& LLVector3::rotVec(const LLQuaternion &q) +const LLVector3& LLVector3::rotVec(const LLQuaternion& q) { *this = *this * q; return *this; @@ -228,26 +227,26 @@ const LLVector3& LLVector3::transVec(const LLMatrix4& mat) } -const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3 &vec) +const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3& vec) { - if ( !vec.isExactlyZero() && angle ) + if (!vec.isExactlyZero() && angle) { *this = *this * LLQuaternion(angle, vec); } return *this; } -const LLVector3& LLVector3::rotVec(F32 angle, F32 x, F32 y, F32 z) +const LLVector3& LLVector3::rotVec(F32 angle, F32 x, F32 y, F32 z) { LLVector3 vec(x, y, z); - if ( !vec.isExactlyZero() && angle ) + if (!vec.isExactlyZero() && angle) { *this = *this * LLQuaternion(angle, vec); } return *this; } -const LLVector3& LLVector3::scaleVec(const LLVector3& vec) +const LLVector3& LLVector3::scaleVec(const LLVector3& vec) { mV[VX] *= vec.mV[VX]; mV[VY] *= vec.mV[VY]; @@ -256,42 +255,42 @@ const LLVector3& LLVector3::scaleVec(const LLVector3& vec) return *this; } -LLVector3 LLVector3::scaledVec(const LLVector3& vec) const +LLVector3 LLVector3::scaledVec(const LLVector3& vec) const { LLVector3 ret = LLVector3(*this); ret.scaleVec(vec); return ret; } -const LLVector3& LLVector3::set(const LLVector3d &vec) +const LLVector3& LLVector3::set(const LLVector3d& vec) { - mV[0] = (F32)vec.mdV[0]; - mV[1] = (F32)vec.mdV[1]; - mV[2] = (F32)vec.mdV[2]; + mV[VX] = (F32)vec.mdV[VX]; + mV[VY] = (F32)vec.mdV[VY]; + mV[VZ] = (F32)vec.mdV[VZ]; return (*this); } -const LLVector3& LLVector3::set(const LLVector4 &vec) +const LLVector3& LLVector3::set(const LLVector4& vec) { - mV[0] = vec.mV[0]; - mV[1] = vec.mV[1]; - mV[2] = vec.mV[2]; + mV[VX] = vec.mV[VX]; + mV[VY] = vec.mV[VY]; + mV[VZ] = vec.mV[VZ]; return (*this); } -const LLVector3& LLVector3::setVec(const LLVector3d &vec) +const LLVector3& LLVector3::setVec(const LLVector3d& vec) { - mV[0] = (F32)vec.mdV[0]; - mV[1] = (F32)vec.mdV[1]; - mV[2] = (F32)vec.mdV[2]; + mV[VX] = (F32)vec.mdV[0]; + mV[VY] = (F32)vec.mdV[1]; + mV[VZ] = (F32)vec.mdV[2]; return (*this); } -const LLVector3& LLVector3::setVec(const LLVector4 &vec) +const LLVector3& LLVector3::setVec(const LLVector4& vec) { - mV[0] = vec.mV[0]; - mV[1] = vec.mV[1]; - mV[2] = vec.mV[2]; + mV[VX] = vec.mV[VX]; + mV[VY] = vec.mV[VY]; + mV[VZ] = vec.mV[VZ]; return (*this); } @@ -299,17 +298,17 @@ LLVector3::LLVector3(const LLVector2 &vec) { mV[VX] = (F32)vec.mV[VX]; mV[VY] = (F32)vec.mV[VY]; - mV[VZ] = 0; + mV[VZ] = 0.f; } -LLVector3::LLVector3(const LLVector3d &vec) +LLVector3::LLVector3(const LLVector3d& vec) { mV[VX] = (F32)vec.mdV[VX]; mV[VY] = (F32)vec.mdV[VY]; mV[VZ] = (F32)vec.mdV[VZ]; } -LLVector3::LLVector3(const LLVector4 &vec) +LLVector3::LLVector3(const LLVector4& vec) { mV[VX] = (F32)vec.mV[VX]; mV[VY] = (F32)vec.mV[VY]; @@ -319,7 +318,6 @@ LLVector3::LLVector3(const LLVector4 &vec) LLVector3::LLVector3(const LLVector4a& vec) : LLVector3(vec.getF32ptr()) { - } LLVector3::LLVector3(const LLSD& sd) @@ -330,20 +328,20 @@ LLVector3::LLVector3(const LLSD& sd) LLSD LLVector3::getValue() const { LLSD ret; - ret[0] = mV[0]; - ret[1] = mV[1]; - ret[2] = mV[2]; + ret[VX] = mV[VX]; + ret[VY] = mV[VY]; + ret[VZ] = mV[VZ]; return ret; } void LLVector3::setValue(const LLSD& sd) { - mV[0] = (F32) sd[0].asReal(); - mV[1] = (F32) sd[1].asReal(); - mV[2] = (F32) sd[2].asReal(); + mV[VX] = (F32) sd[VX].asReal(); + mV[VY] = (F32) sd[VY].asReal(); + mV[VZ] = (F32) sd[VZ].asReal(); } -const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot) +const LLVector3& operator*=(LLVector3& a, const LLQuaternion& rot) { const F32 rw = - rot.mQ[VX] * a.mV[VX] - rot.mQ[VY] * a.mV[VY] - rot.mQ[VZ] * a.mV[VZ]; const F32 rx = rot.mQ[VW] * a.mV[VX] + rot.mQ[VY] * a.mV[VZ] - rot.mQ[VZ] * a.mV[VY]; @@ -360,16 +358,16 @@ const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &rot) // static bool LLVector3::parseVector3(const std::string& buf, LLVector3* value) { - if( buf.empty() || value == nullptr) + if (buf.empty() || value == nullptr) { return false; } LLVector3 v; - S32 count = sscanf( buf.c_str(), "%f %f %f", v.mV + 0, v.mV + 1, v.mV + 2 ); - if( 3 == count ) + S32 count = sscanf(buf.c_str(), "%f %f %f", v.mV + VX, v.mV + VY, v.mV + VZ); + if (3 == count) { - value->setVec( v ); + value->setVec(v); return true; } @@ -381,7 +379,7 @@ bool LLVector3::parseVector3(const std::string& buf, LLVector3* value) LLVector3 point_to_box_offset(LLVector3& pos, const LLVector3* box) { LLVector3 offset; - for (S32 k=0; k<3; k++) + for (S32 k = 0; k < 3; k++) { offset[k] = 0; if (pos[k] < box[0][k]) @@ -410,4 +408,3 @@ bool box_valid_and_non_zero(const LLVector3* box) } return false; } - diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 8f0d00270d..196ecdcf7d 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -46,7 +46,7 @@ class LLQuaternion; // LLvector3 = |x y z w| -static const U32 LENGTHOFVECTOR3 = 3; +static constexpr U32 LENGTHOFVECTOR3 = 3; class LLVector3 { @@ -112,24 +112,24 @@ class LLVector3 const LLVector3& setVec(const LLVector4 &vec); // deprecated const LLVector3& setVec(const LLVector3d &vec); // deprecated - F32 length() const; // Returns magnitude of LLVector3 - F32 lengthSquared() const; // Returns magnitude squared of LLVector3 - F32 magVec() const; // deprecated - F32 magVecSquared() const; // deprecated + F32 length() const; // Returns magnitude of LLVector3 + F32 lengthSquared() const; // Returns magnitude squared of LLVector3 + F32 magVec() const; // deprecated + F32 magVecSquared() const; // deprecated - inline F32 normalize(); // Normalizes and returns the magnitude of LLVector3 - inline F32 normVec(); // deprecated + inline F32 normalize(); // Normalizes and returns the magnitude of LLVector3 + inline F32 normVec(); // deprecated - inline bool inRange( F32 min, F32 max ) const; // Returns true if all values of the vector are between min and max + inline bool inRange(F32 min, F32 max) const; // Returns true if all values of the vector are between min and max - const LLVector3& rotVec(F32 angle, const LLVector3 &vec); // Rotates about vec by angle radians - const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians - const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat - const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q - const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v) + const LLVector3& rotVec(F32 angle, const LLVector3 &vec); // Rotates about vec by angle radians + const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians + const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat + const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q + const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v) - const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec - LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec + const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec + LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec bool isNull() const; // Returns true if vector has a _very_small_ length bool isExactlyZero() const { return !mV[VX] && !mV[VY] && !mV[VZ]; } @@ -185,25 +185,19 @@ LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vect LLVector3 point_to_box_offset(LLVector3& pos, const LLVector3* box); // Displacement from query point to nearest point on bounding box. bool box_valid_and_non_zero(const LLVector3* box); -inline LLVector3::LLVector3(void) +inline LLVector3::LLVector3() { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + clear(); } inline LLVector3::LLVector3(const F32 x, const F32 y, const F32 z) { - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; + set(x, y, z); } inline LLVector3::LLVector3(const F32 *vec) { - mV[VX] = vec[VX]; - mV[VY] = vec[VY]; - mV[VZ] = vec[VZ]; + set(vec); } inline LLVector3::LLVector3(const glm::vec3& vec) @@ -234,38 +228,30 @@ inline LLVector3::LLVector3(const LLVector3 ©) // checker inline bool LLVector3::isFinite() const { - return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ])); + return llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]); } // Clear and Assignment Functions -inline void LLVector3::clear(void) +inline void LLVector3::clear() { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + set(0.f, 0.f, 0.f); } -inline void LLVector3::setZero(void) +inline void LLVector3::setZero() { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + clear(); } -inline void LLVector3::clearVec(void) +inline void LLVector3::clearVec() { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + clear(); } -inline void LLVector3::zeroVec(void) +inline void LLVector3::zeroVec() { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + clear(); } inline void LLVector3::set(F32 x, F32 y, F32 z) @@ -275,18 +261,14 @@ inline void LLVector3::set(F32 x, F32 y, F32 z) mV[VZ] = z; } -inline void LLVector3::set(const LLVector3 &vec) +inline void LLVector3::set(const LLVector3& vec) { - mV[0] = vec.mV[0]; - mV[1] = vec.mV[1]; - mV[2] = vec.mV[2]; + set(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); } -inline void LLVector3::set(const F32 *vec) +inline void LLVector3::set(const F32* vec) { - mV[0] = vec[0]; - mV[1] = vec[1]; - mV[2] = vec[2]; + set(vec[VX], vec[VY], vec[VZ]); } inline void LLVector3::set(const glm::vec4& vec) @@ -306,213 +288,181 @@ inline void LLVector3::set(const glm::vec3& vec) // deprecated inline void LLVector3::setVec(F32 x, F32 y, F32 z) { - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; + set(x, y, z); } // deprecated -inline void LLVector3::setVec(const LLVector3 &vec) +inline void LLVector3::setVec(const LLVector3& vec) { - mV[0] = vec.mV[0]; - mV[1] = vec.mV[1]; - mV[2] = vec.mV[2]; + set(vec); } // deprecated -inline void LLVector3::setVec(const F32 *vec) +inline void LLVector3::setVec(const F32* vec) { - mV[0] = vec[0]; - mV[1] = vec[1]; - mV[2] = vec[2]; + set(vec); } -inline F32 LLVector3::normalize(void) +inline F32 LLVector3::normalize() { - F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); - F32 oomag; + F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); if (mag > FP_MAG_THRESHOLD) { - oomag = 1.f/mag; - mV[0] *= oomag; - mV[1] *= oomag; - mV[2] *= oomag; + *this /= mag; } else { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; + clear(); mag = 0; } - return (mag); + return mag; } // deprecated -inline F32 LLVector3::normVec(void) +inline F32 LLVector3::normVec() { - F32 mag = (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); - F32 oomag; - - if (mag > FP_MAG_THRESHOLD) - { - oomag = 1.f/mag; - mV[0] *= oomag; - mV[1] *= oomag; - mV[2] *= oomag; - } - else - { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; - mag = 0; - } - return (mag); + return normalize(); } // LLVector3 Magnitude and Normalization Functions -inline F32 LLVector3::length(void) const +inline F32 LLVector3::length() const { - return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); + return sqrt(lengthSquared()); } -inline F32 LLVector3::lengthSquared(void) const +inline F32 LLVector3::lengthSquared() const { - return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; + return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; } -inline F32 LLVector3::magVec(void) const +inline F32 LLVector3::magVec() const { - return (F32) sqrt(mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]); + return length(); } -inline F32 LLVector3::magVecSquared(void) const +inline F32 LLVector3::magVecSquared() const { - return mV[0]*mV[0] + mV[1]*mV[1] + mV[2]*mV[2]; + return lengthSquared(); } -inline bool LLVector3::inRange( F32 min, F32 max ) const +inline bool LLVector3::inRange(F32 min, F32 max) const { - return mV[0] >= min && mV[0] <= max && - mV[1] >= min && mV[1] <= max && - mV[2] >= min && mV[2] <= max; + return mV[VX] >= min && mV[VX] <= max && + mV[VY] >= min && mV[VY] <= max && + mV[VZ] >= min && mV[VZ] <= max; } -inline LLVector3 operator+(const LLVector3 &a, const LLVector3 &b) +inline LLVector3 operator+(const LLVector3& a, const LLVector3& b) { LLVector3 c(a); return c += b; } -inline LLVector3 operator-(const LLVector3 &a, const LLVector3 &b) +inline LLVector3 operator-(const LLVector3& a, const LLVector3& b) { LLVector3 c(a); return c -= b; } -inline F32 operator*(const LLVector3 &a, const LLVector3 &b) +inline F32 operator*(const LLVector3& a, const LLVector3& b) { - return (a.mV[0]*b.mV[0] + a.mV[1]*b.mV[1] + a.mV[2]*b.mV[2]); + return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]); } -inline LLVector3 operator%(const LLVector3 &a, const LLVector3 &b) +inline LLVector3 operator%(const LLVector3& a, const LLVector3& b) { - return LLVector3( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1] ); + return LLVector3(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]); } -inline LLVector3 operator/(const LLVector3 &a, F32 k) +inline LLVector3 operator/(const LLVector3& a, F32 k) { F32 t = 1.f / k; - return LLVector3( a.mV[0] * t, a.mV[1] * t, a.mV[2] * t ); + return LLVector3( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t ); } -inline LLVector3 operator*(const LLVector3 &a, F32 k) +inline LLVector3 operator*(const LLVector3& a, F32 k) { - return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); + return LLVector3( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k ); } -inline LLVector3 operator*(F32 k, const LLVector3 &a) +inline LLVector3 operator*(F32 k, const LLVector3& a) { - return LLVector3( a.mV[0] * k, a.mV[1] * k, a.mV[2] * k ); + return LLVector3( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k ); } -inline bool operator==(const LLVector3 &a, const LLVector3 &b) +inline bool operator==(const LLVector3& a, const LLVector3& b) { - return ( (a.mV[0] == b.mV[0]) - &&(a.mV[1] == b.mV[1]) - &&(a.mV[2] == b.mV[2])); + return ( (a.mV[VX] == b.mV[VX]) + &&(a.mV[VY] == b.mV[VY]) + &&(a.mV[VZ] == b.mV[VZ])); } -inline bool operator!=(const LLVector3 &a, const LLVector3 &b) +inline bool operator!=(const LLVector3& a, const LLVector3& b) { - return ( (a.mV[0] != b.mV[0]) - ||(a.mV[1] != b.mV[1]) - ||(a.mV[2] != b.mV[2])); + return ( (a.mV[VX] != b.mV[VX]) + ||(a.mV[VY] != b.mV[VY]) + ||(a.mV[VZ] != b.mV[VZ])); } -inline bool operator<(const LLVector3 &a, const LLVector3 &b) +inline bool operator<(const LLVector3& a, const LLVector3& b) { - return (a.mV[0] < b.mV[0] - || (a.mV[0] == b.mV[0] - && (a.mV[1] < b.mV[1] - || ((a.mV[1] == b.mV[1]) - && a.mV[2] < b.mV[2])))); + return (a.mV[VX] < b.mV[VX] + || (a.mV[VX] == b.mV[VX] + && (a.mV[VY] < b.mV[VY] + || ((a.mV[VY] == b.mV[VY]) + && a.mV[VZ] < b.mV[VZ])))); } -inline const LLVector3& operator+=(LLVector3 &a, const LLVector3 &b) +inline const LLVector3& operator+=(LLVector3& a, const LLVector3& b) { - a.mV[0] += b.mV[0]; - a.mV[1] += b.mV[1]; - a.mV[2] += b.mV[2]; + a.mV[VX] += b.mV[VX]; + a.mV[VY] += b.mV[VY]; + a.mV[VZ] += b.mV[VZ]; return a; } -inline const LLVector3& operator-=(LLVector3 &a, const LLVector3 &b) +inline const LLVector3& operator-=(LLVector3& a, const LLVector3& b) { - a.mV[0] -= b.mV[0]; - a.mV[1] -= b.mV[1]; - a.mV[2] -= b.mV[2]; + a.mV[VX] -= b.mV[VX]; + a.mV[VY] -= b.mV[VY]; + a.mV[VZ] -= b.mV[VZ]; return a; } -inline const LLVector3& operator%=(LLVector3 &a, const LLVector3 &b) +inline const LLVector3& operator%=(LLVector3& a, const LLVector3& b) { - LLVector3 ret( a.mV[1]*b.mV[2] - b.mV[1]*a.mV[2], a.mV[2]*b.mV[0] - b.mV[2]*a.mV[0], a.mV[0]*b.mV[1] - b.mV[0]*a.mV[1]); + LLVector3 ret(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]); a = ret; return a; } -inline const LLVector3& operator*=(LLVector3 &a, F32 k) +inline const LLVector3& operator*=(LLVector3& a, F32 k) { - a.mV[0] *= k; - a.mV[1] *= k; - a.mV[2] *= k; + a.mV[VX] *= k; + a.mV[VY] *= k; + a.mV[VZ] *= k; return a; } -inline const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b) +inline const LLVector3& operator*=(LLVector3& a, const LLVector3& b) { - a.mV[0] *= b.mV[0]; - a.mV[1] *= b.mV[1]; - a.mV[2] *= b.mV[2]; + a.mV[VX] *= b.mV[VX]; + a.mV[VY] *= b.mV[VY]; + a.mV[VZ] *= b.mV[VZ]; return a; } -inline const LLVector3& operator/=(LLVector3 &a, F32 k) +inline const LLVector3& operator/=(LLVector3& a, F32 k) { - F32 t = 1.f / k; - a.mV[0] *= t; - a.mV[1] *= t; - a.mV[2] *= t; + a *= 1.f / k; return a; } -inline LLVector3 operator-(const LLVector3 &a) +inline LLVector3 operator-(const LLVector3& a) { - return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] ); + return LLVector3(-a.mV[VX], -a.mV[VY], -a.mV[VZ]); } inline LLVector3::operator glm::vec3() const @@ -526,40 +476,37 @@ inline LLVector3::operator glm::vec4() const return glm::vec4(mV[VX], mV[VY], mV[VZ], 1.f); } -inline F32 dist_vec(const LLVector3 &a, const LLVector3 &b) +inline F32 dist_vec(const LLVector3& a, const LLVector3& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; - F32 z = a.mV[2] - b.mV[2]; - return (F32) sqrt( x*x + y*y + z*z ); + F32 x = a.mV[VX] - b.mV[VX]; + F32 y = a.mV[VY] - b.mV[VY]; + F32 z = a.mV[VZ] - b.mV[VZ]; + return sqrt(x*x + y*y + z*z); } -inline F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b) +inline F32 dist_vec_squared(const LLVector3& a, const LLVector3& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; - F32 z = a.mV[2] - b.mV[2]; + F32 x = a.mV[VX] - b.mV[VX]; + F32 y = a.mV[VY] - b.mV[VY]; + F32 z = a.mV[VZ] - b.mV[VZ]; return x*x + y*y + z*z; } -inline F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b) +inline F32 dist_vec_squared2D(const LLVector3& a, const LLVector3& b) { - F32 x = a.mV[0] - b.mV[0]; - F32 y = a.mV[1] - b.mV[1]; + F32 x = a.mV[VX] - b.mV[VX]; + F32 y = a.mV[VY] - b.mV[VY]; return x*x + y*y; } -inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b) +inline LLVector3 projected_vec(const LLVector3& a, const LLVector3& b) { F32 bb = b * b; if (bb > FP_MAG_THRESHOLD * FP_MAG_THRESHOLD) { return ((a * b) / bb) * b; } - else - { - return b.zero; - } + return b.zero; } inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b) @@ -574,18 +521,18 @@ inline LLVector3 inverse_projected_vec(const LLVector3& a, const LLVector3& b) return normalized_a * (b_length / dot_product); } -inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b) +inline LLVector3 parallel_component(const LLVector3& a, const LLVector3& b) { return projected_vec(a, b); } -inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b) +inline LLVector3 orthogonal_component(const LLVector3& a, const LLVector3& b) { return a - projected_vec(a, b); } -inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u) +inline LLVector3 lerp(const LLVector3& a, const LLVector3& b, F32 u) { return LLVector3( a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, @@ -596,11 +543,7 @@ inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u) inline bool LLVector3::isNull() const { - if ( F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ] ) - { - return true; - } - return false; + return F_APPROXIMATELY_ZERO > mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; } inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos) @@ -641,17 +584,17 @@ inline F32 angle_between(const LLVector3& a, const LLVector3& b) ab = 0.0f; // get rid of negative zero } LLVector3 c = a % b; // crossproduct - return atan2f(sqrtf(c * c), ab); // return the angle + return atan2f(c.length(), ab); // return the angle } -inline bool are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon) +inline bool are_parallel(const LLVector3& a, const LLVector3& b, F32 epsilon) { LLVector3 an = a; LLVector3 bn = b; an.normalize(); bn.normalize(); F32 dot = an * bn; - if ( (1.0f - fabs(dot)) < epsilon) + if (1.0f - fabs(dot) < epsilon) { return true; } diff --git a/indra/llmath/v4color.cpp b/indra/llmath/v4color.cpp index ad13656bbd..1b687642ca 100644 --- a/indra/llmath/v4color.cpp +++ b/indra/llmath/v4color.cpp @@ -124,65 +124,64 @@ LLColor4 LLColor4::cyan6(0.2f, 0.6f, 0.6f, 1.0f); // conversion LLColor4::operator LLColor4U() const { - return LLColor4U( - (U8)llclampb(ll_round(mV[VRED]*255.f)), - (U8)llclampb(ll_round(mV[VGREEN]*255.f)), - (U8)llclampb(ll_round(mV[VBLUE]*255.f)), - (U8)llclampb(ll_round(mV[VALPHA]*255.f))); + return LLColor4U((U8)llclampb(ll_round(mV[VRED] * 255.f)), + (U8)llclampb(ll_round(mV[VGREEN] * 255.f)), + (U8)llclampb(ll_round(mV[VBLUE] * 255.f)), + (U8)llclampb(ll_round(mV[VALPHA] * 255.f))); } -LLColor4::LLColor4(const LLColor3 &vec, F32 a) +LLColor4::LLColor4(const LLColor3& vec, F32 a) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; mV[VALPHA] = a; } LLColor4::LLColor4(const LLColor4U& color4u) { - const F32 SCALE = 1.f/255.f; - mV[VRED] = color4u.mV[VRED] * SCALE; - mV[VGREEN] = color4u.mV[VGREEN] * SCALE; - mV[VBLUE] = color4u.mV[VBLUE] * SCALE; - mV[VALPHA] = color4u.mV[VALPHA] * SCALE; + constexpr F32 SCALE = 1.f / 255.f; + mV[VRED] = color4u.mV[VRED] * SCALE; + mV[VGREEN] = color4u.mV[VGREEN] * SCALE; + mV[VBLUE] = color4u.mV[VBLUE] * SCALE; + mV[VALPHA] = color4u.mV[VALPHA] * SCALE; } LLColor4::LLColor4(const LLVector4& vector4) { - mV[VRED] = vector4.mV[VRED]; + mV[VRED] = vector4.mV[VRED]; mV[VGREEN] = vector4.mV[VGREEN]; - mV[VBLUE] = vector4.mV[VBLUE]; + mV[VBLUE] = vector4.mV[VBLUE]; mV[VALPHA] = vector4.mV[VALPHA]; } const LLColor4& LLColor4::set(const LLColor4U& color4u) { - const F32 SCALE = 1.f/255.f; - mV[VRED] = color4u.mV[VRED] * SCALE; - mV[VGREEN] = color4u.mV[VGREEN] * SCALE; - mV[VBLUE] = color4u.mV[VBLUE] * SCALE; - mV[VALPHA] = color4u.mV[VALPHA] * SCALE; + constexpr F32 SCALE = 1.f / 255.f; + mV[VRED] = color4u.mV[VRED] * SCALE; + mV[VGREEN] = color4u.mV[VGREEN] * SCALE; + mV[VBLUE] = color4u.mV[VBLUE] * SCALE; + mV[VALPHA] = color4u.mV[VALPHA] * SCALE; return (*this); } -const LLColor4& LLColor4::set(const LLColor3 &vec) +const LLColor4& LLColor4::set(const LLColor3& vec) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; -// no change to alpha! -// mV[VALPHA] = 1.f; + // no change to alpha! + // mV[VALPHA] = 1.f; return (*this); } -const LLColor4& LLColor4::set(const LLColor3 &vec, F32 a) +const LLColor4& LLColor4::set(const LLColor3& vec, F32 a) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; mV[VALPHA] = a; return (*this); } @@ -190,33 +189,33 @@ const LLColor4& LLColor4::set(const LLColor3 &vec, F32 a) // deprecated -- use set() const LLColor4& LLColor4::setVec(const LLColor4U& color4u) { - const F32 SCALE = 1.f/255.f; - mV[VRED] = color4u.mV[VRED] * SCALE; - mV[VGREEN] = color4u.mV[VGREEN] * SCALE; - mV[VBLUE] = color4u.mV[VBLUE] * SCALE; - mV[VALPHA] = color4u.mV[VALPHA] * SCALE; + constexpr F32 SCALE = 1.f / 255.f; + mV[VRED] = color4u.mV[VRED] * SCALE; + mV[VGREEN] = color4u.mV[VGREEN] * SCALE; + mV[VBLUE] = color4u.mV[VBLUE] * SCALE; + mV[VALPHA] = color4u.mV[VALPHA] * SCALE; return (*this); } // deprecated -- use set() -const LLColor4& LLColor4::setVec(const LLColor3 &vec) +const LLColor4& LLColor4::setVec(const LLColor3& vec) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; -// no change to alpha! -// mV[VALPHA] = 1.f; + // no change to alpha! + // mV[VALPHA] = 1.f; return (*this); } // deprecated -- use set() -const LLColor4& LLColor4::setVec(const LLColor3 &vec, F32 a) +const LLColor4& LLColor4::setVec(const LLColor3& vec, F32 a) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; mV[VALPHA] = a; return (*this); } @@ -228,110 +227,110 @@ void LLColor4::setValue(const LLSD& sd) F32 val; bool out_of_range = false; val = sd[0].asReal(); - mV[0] = llclamp(val, 0.f, 1.f); - out_of_range = mV[0] != val; + mV[VRED] = llclamp(val, 0.f, 1.f); + out_of_range = mV[VRED] != val; val = sd[1].asReal(); - mV[1] = llclamp(val, 0.f, 1.f); - out_of_range |= mV[1] != val; + mV[VGREEN] = llclamp(val, 0.f, 1.f); + out_of_range |= mV[VGREEN] != val; val = sd[2].asReal(); - mV[2] = llclamp(val, 0.f, 1.f); - out_of_range |= mV[2] != val; + mV[VBLUE] = llclamp(val, 0.f, 1.f); + out_of_range |= mV[VBLUE] != val; val = sd[3].asReal(); - mV[3] = llclamp(val, 0.f, 1.f); - out_of_range |= mV[3] != val; + mV[VALPHA] = llclamp(val, 0.f, 1.f); + out_of_range |= mV[VALPHA] != val; if (out_of_range) { LL_WARNS() << "LLSD color value out of range!" << LL_ENDL; } #else - mV[0] = (F32) sd[0].asReal(); - mV[1] = (F32) sd[1].asReal(); - mV[2] = (F32) sd[2].asReal(); - mV[3] = (F32) sd[3].asReal(); + mV[VRED] = (F32)sd[VRED].asReal(); + mV[VGREEN] = (F32)sd[VGREEN].asReal(); + mV[VBLUE] = (F32)sd[VBLUE].asReal(); + mV[VALPHA] = (F32)sd[VALPHA].asReal(); #endif } -const LLColor4& LLColor4::operator=(const LLColor3 &a) +const LLColor4& LLColor4::operator=(const LLColor3& a) { - mV[VRED] = a.mV[VRED]; + mV[VRED] = a.mV[VRED]; mV[VGREEN] = a.mV[VGREEN]; - mV[VBLUE] = a.mV[VBLUE]; + mV[VBLUE] = a.mV[VBLUE]; -// converting from an rgb sets a=1 (opaque) + // converting from an rgb sets a=1 (opaque) mV[VALPHA] = 1.f; return (*this); } - -std::ostream& operator<<(std::ostream& s, const LLColor4 &a) +std::ostream& operator<<(std::ostream& s, const LLColor4& a) { s << "{ " << a.mV[VRED] << ", " << a.mV[VGREEN] << ", " << a.mV[VBLUE] << ", " << a.mV[VALPHA] << " }"; return s; } -bool operator==(const LLColor4 &a, const LLColor3 &b) +bool operator==(const LLColor4& a, const LLColor3& b) { - return ( (a.mV[VRED] == b.mV[VRED]) - &&(a.mV[VGREEN] == b.mV[VGREEN]) - &&(a.mV[VBLUE] == b.mV[VBLUE])); + return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE])); } -bool operator!=(const LLColor4 &a, const LLColor3 &b) +bool operator!=(const LLColor4& a, const LLColor3& b) { - return ( (a.mV[VRED] != b.mV[VRED]) - ||(a.mV[VGREEN] != b.mV[VGREEN]) - ||(a.mV[VBLUE] != b.mV[VBLUE])); + return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE])); } -LLColor3 vec4to3(const LLColor4 &vec) +LLColor3 vec4to3(const LLColor4& vec) { - LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]); + LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]); return temp; } -LLColor4 vec3to4(const LLColor3 &vec) +LLColor4 vec3to4(const LLColor3& vec) { - LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]); + LLColor3 temp(vec.mV[VRED], vec.mV[VGREEN], vec.mV[VBLUE]); return temp; } -static F32 hueToRgb ( F32 val1In, F32 val2In, F32 valHUeIn ) +static F32 hueToRgb(F32 val1In, F32 val2In, F32 valHUeIn) { - if ( valHUeIn < 0.0f ) valHUeIn += 1.0f; - if ( valHUeIn > 1.0f ) valHUeIn -= 1.0f; - if ( ( 6.0f * valHUeIn ) < 1.0f ) return ( val1In + ( val2In - val1In ) * 6.0f * valHUeIn ); - if ( ( 2.0f * valHUeIn ) < 1.0f ) return ( val2In ); - if ( ( 3.0f * valHUeIn ) < 2.0f ) return ( val1In + ( val2In - val1In ) * ( ( 2.0f / 3.0f ) - valHUeIn ) * 6.0f ); - return ( val1In ); + if (valHUeIn < 0.0f) + valHUeIn += 1.0f; + if (valHUeIn > 1.0f) + valHUeIn -= 1.0f; + if ((6.0f * valHUeIn) < 1.0f) + return (val1In + (val2In - val1In) * 6.0f * valHUeIn); + if ((2.0f * valHUeIn) < 1.0f) + return (val2In); + if ((3.0f * valHUeIn) < 2.0f) + return (val1In + (val2In - val1In) * ((2.0f / 3.0f) - valHUeIn) * 6.0f); + return (val1In); } -void LLColor4::setHSL ( F32 hValIn, F32 sValIn, F32 lValIn) +void LLColor4::setHSL(F32 hValIn, F32 sValIn, F32 lValIn) { - if ( sValIn < 0.00001f ) + if (sValIn < 0.00001f) { - mV[VRED] = lValIn; + mV[VRED] = lValIn; mV[VGREEN] = lValIn; - mV[VBLUE] = lValIn; + mV[VBLUE] = lValIn; } else { F32 interVal1; F32 interVal2; - if ( lValIn < 0.5f ) - interVal2 = lValIn * ( 1.0f + sValIn ); + if (lValIn < 0.5f) + interVal2 = lValIn * (1.0f + sValIn); else - interVal2 = ( lValIn + sValIn ) - ( sValIn * lValIn ); + interVal2 = (lValIn + sValIn) - (sValIn * lValIn); interVal1 = 2.0f * lValIn - interVal2; - mV[VRED] = hueToRgb ( interVal1, interVal2, hValIn + ( 1.f / 3.f ) ); - mV[VGREEN] = hueToRgb ( interVal1, interVal2, hValIn ); - mV[VBLUE] = hueToRgb ( interVal1, interVal2, hValIn - ( 1.f / 3.f ) ); + mV[VRED] = hueToRgb(interVal1, interVal2, hValIn + (1.f / 3.f)); + mV[VGREEN] = hueToRgb(interVal1, interVal2, hValIn); + mV[VBLUE] = hueToRgb(interVal1, interVal2, hValIn - (1.f / 3.f)); } } @@ -341,58 +340,61 @@ void LLColor4::calcHSL(F32* hue, F32* saturation, F32* luminance) const F32 var_G = mV[VGREEN]; F32 var_B = mV[VBLUE]; - F32 var_Min = ( var_R < ( var_G < var_B ? var_G : var_B ) ? var_R : ( var_G < var_B ? var_G : var_B ) ); - F32 var_Max = ( var_R > ( var_G > var_B ? var_G : var_B ) ? var_R : ( var_G > var_B ? var_G : var_B ) ); + F32 var_Min = (var_R < (var_G < var_B ? var_G : var_B) ? var_R : (var_G < var_B ? var_G : var_B)); + F32 var_Max = (var_R > (var_G > var_B ? var_G : var_B) ? var_R : (var_G > var_B ? var_G : var_B)); F32 del_Max = var_Max - var_Min; - F32 L = ( var_Max + var_Min ) / 2.0f; + F32 L = (var_Max + var_Min) / 2.0f; F32 H = 0.0f; F32 S = 0.0f; - if ( del_Max == 0.0f ) + if (del_Max == 0.0f) { - H = 0.0f; - S = 0.0f; + H = 0.0f; + S = 0.0f; } else { - if ( L < 0.5 ) - S = del_Max / ( var_Max + var_Min ); + if (L < 0.5f) + S = del_Max / (var_Max + var_Min); else - S = del_Max / ( 2.0f - var_Max - var_Min ); + S = del_Max / (2.0f - var_Max - var_Min); - F32 del_R = ( ( ( var_Max - var_R ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; - F32 del_G = ( ( ( var_Max - var_G ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; - F32 del_B = ( ( ( var_Max - var_B ) / 6.0f ) + ( del_Max / 2.0f ) ) / del_Max; + F32 del_R = (((var_Max - var_R) / 6.0f) + (del_Max / 2.0f)) / del_Max; + F32 del_G = (((var_Max - var_G) / 6.0f) + (del_Max / 2.0f)) / del_Max; + F32 del_B = (((var_Max - var_B) / 6.0f) + (del_Max / 2.0f)) / del_Max; - if ( var_R >= var_Max ) + if (var_R >= var_Max) H = del_B - del_G; - else - if ( var_G >= var_Max ) - H = ( 1.0f / 3.0f ) + del_R - del_B; - else - if ( var_B >= var_Max ) - H = ( 2.0f / 3.0f ) + del_G - del_R; - - if ( H < 0.0f ) H += 1.0f; - if ( H > 1.0f ) H -= 1.0f; + else if (var_G >= var_Max) + H = (1.0f / 3.0f) + del_R - del_B; + else if (var_B >= var_Max) + H = (2.0f / 3.0f) + del_G - del_R; + + if (H < 0.0f) + H += 1.0f; + if (H > 1.0f) + H -= 1.0f; } - if (hue) *hue = H; - if (saturation) *saturation = S; - if (luminance) *luminance = L; + if (hue) + *hue = H; + if (saturation) + *saturation = S; + if (luminance) + *luminance = L; } // static bool LLColor4::parseColor(const std::string& buf, LLColor4* color) { - if( buf.empty() || color == nullptr) + if (buf.empty() || color == nullptr) { return false; } - boost_tokenizer tokens(buf, boost::char_separator<char>(", ")); + boost_tokenizer tokens(buf, boost::char_separator<char>(", ")); boost_tokenizer::iterator token_iter = tokens.begin(); if (token_iter == tokens.end()) { @@ -401,16 +403,16 @@ bool LLColor4::parseColor(const std::string& buf, LLColor4* color) // Grab the first token into a string, since we don't know // if this is a float or a color name. - std::string color_name( (*token_iter) ); + std::string color_name((*token_iter)); ++token_iter; if (token_iter != tokens.end()) { // There are more tokens to read. This must be a vector. LLColor4 v; - LLStringUtil::convertToF32( color_name, v.mV[VRED] ); - LLStringUtil::convertToF32( *token_iter, v.mV[VGREEN] ); - v.mV[VBLUE] = 0.0f; + LLStringUtil::convertToF32(color_name, v.mV[VRED]); + LLStringUtil::convertToF32(*token_iter, v.mV[VGREEN]); + v.mV[VBLUE] = 0.0f; v.mV[VALPHA] = 1.0f; ++token_iter; @@ -422,283 +424,284 @@ bool LLColor4::parseColor(const std::string& buf, LLColor4* color) else { // There is a z-component. - LLStringUtil::convertToF32( *token_iter, v.mV[VBLUE] ); + LLStringUtil::convertToF32(*token_iter, v.mV[VBLUE]); ++token_iter; if (token_iter != tokens.end()) { // There is an alpha component. - LLStringUtil::convertToF32( *token_iter, v.mV[VALPHA] ); + LLStringUtil::convertToF32(*token_iter, v.mV[VALPHA]); } } // Make sure all values are between 0 and 1. if (v.mV[VRED] > 1.f || v.mV[VGREEN] > 1.f || v.mV[VBLUE] > 1.f || v.mV[VALPHA] > 1.f) { - v = v * (1.f / 255.f); + constexpr F32 SCALE{ 1.f / 255.f }; + v *= SCALE; } - color->set( v ); + color->set(v); } else // Single value. Read as a named color. { // We have a color name - if ( "red" == color_name ) + if ("red" == color_name) { color->set(LLColor4::red); } - else if ( "red1" == color_name ) + else if ("red1" == color_name) { color->set(LLColor4::red1); } - else if ( "red2" == color_name ) + else if ("red2" == color_name) { color->set(LLColor4::red2); } - else if ( "red3" == color_name ) + else if ("red3" == color_name) { color->set(LLColor4::red3); } - else if ( "red4" == color_name ) + else if ("red4" == color_name) { color->set(LLColor4::red4); } - else if ( "red5" == color_name ) + else if ("red5" == color_name) { color->set(LLColor4::red5); } - else if( "green" == color_name ) + else if ("green" == color_name) { color->set(LLColor4::green); } - else if( "green1" == color_name ) + else if ("green1" == color_name) { color->set(LLColor4::green1); } - else if( "green2" == color_name ) + else if ("green2" == color_name) { color->set(LLColor4::green2); } - else if( "green3" == color_name ) + else if ("green3" == color_name) { color->set(LLColor4::green3); } - else if( "green4" == color_name ) + else if ("green4" == color_name) { color->set(LLColor4::green4); } - else if( "green5" == color_name ) + else if ("green5" == color_name) { color->set(LLColor4::green5); } - else if( "green6" == color_name ) + else if ("green6" == color_name) { color->set(LLColor4::green6); } - else if( "blue" == color_name ) + else if ("blue" == color_name) { color->set(LLColor4::blue); } - else if( "blue1" == color_name ) + else if ("blue1" == color_name) { color->set(LLColor4::blue1); } - else if( "blue2" == color_name ) + else if ("blue2" == color_name) { color->set(LLColor4::blue2); } - else if( "blue3" == color_name ) + else if ("blue3" == color_name) { color->set(LLColor4::blue3); } - else if( "blue4" == color_name ) + else if ("blue4" == color_name) { color->set(LLColor4::blue4); } - else if( "blue5" == color_name ) + else if ("blue5" == color_name) { color->set(LLColor4::blue5); } - else if( "blue6" == color_name ) + else if ("blue6" == color_name) { color->set(LLColor4::blue6); } - else if( "black" == color_name ) + else if ("black" == color_name) { color->set(LLColor4::black); } - else if( "white" == color_name ) + else if ("white" == color_name) { color->set(LLColor4::white); } - else if( "yellow" == color_name ) + else if ("yellow" == color_name) { color->set(LLColor4::yellow); } - else if( "yellow1" == color_name ) + else if ("yellow1" == color_name) { color->set(LLColor4::yellow1); } - else if( "yellow2" == color_name ) + else if ("yellow2" == color_name) { color->set(LLColor4::yellow2); } - else if( "yellow3" == color_name ) + else if ("yellow3" == color_name) { color->set(LLColor4::yellow3); } - else if( "yellow4" == color_name ) + else if ("yellow4" == color_name) { color->set(LLColor4::yellow4); } - else if( "yellow5" == color_name ) + else if ("yellow5" == color_name) { color->set(LLColor4::yellow5); } - else if( "yellow6" == color_name ) + else if ("yellow6" == color_name) { color->set(LLColor4::yellow6); } - else if( "magenta" == color_name ) + else if ("magenta" == color_name) { color->set(LLColor4::magenta); } - else if( "magenta1" == color_name ) + else if ("magenta1" == color_name) { color->set(LLColor4::magenta1); } - else if( "magenta2" == color_name ) + else if ("magenta2" == color_name) { color->set(LLColor4::magenta2); } - else if( "magenta3" == color_name ) + else if ("magenta3" == color_name) { color->set(LLColor4::magenta3); } - else if( "magenta4" == color_name ) + else if ("magenta4" == color_name) { color->set(LLColor4::magenta4); } - else if( "purple" == color_name ) + else if ("purple" == color_name) { color->set(LLColor4::purple); } - else if( "purple1" == color_name ) + else if ("purple1" == color_name) { color->set(LLColor4::purple1); } - else if( "purple2" == color_name ) + else if ("purple2" == color_name) { color->set(LLColor4::purple2); } - else if( "purple3" == color_name ) + else if ("purple3" == color_name) { color->set(LLColor4::purple3); } - else if( "purple4" == color_name ) + else if ("purple4" == color_name) { color->set(LLColor4::purple4); } - else if( "purple5" == color_name ) + else if ("purple5" == color_name) { color->set(LLColor4::purple5); } - else if( "purple6" == color_name ) + else if ("purple6" == color_name) { color->set(LLColor4::purple6); } - else if( "pink" == color_name ) + else if ("pink" == color_name) { color->set(LLColor4::pink); } - else if( "pink1" == color_name ) + else if ("pink1" == color_name) { color->set(LLColor4::pink1); } - else if( "pink2" == color_name ) + else if ("pink2" == color_name) { color->set(LLColor4::pink2); } - else if( "cyan" == color_name ) + else if ("cyan" == color_name) { color->set(LLColor4::cyan); } - else if( "cyan1" == color_name ) + else if ("cyan1" == color_name) { color->set(LLColor4::cyan1); } - else if( "cyan2" == color_name ) + else if ("cyan2" == color_name) { color->set(LLColor4::cyan2); } - else if( "cyan3" == color_name ) + else if ("cyan3" == color_name) { color->set(LLColor4::cyan3); } - else if( "cyan4" == color_name ) + else if ("cyan4" == color_name) { color->set(LLColor4::cyan4); } - else if( "cyan5" == color_name ) + else if ("cyan5" == color_name) { color->set(LLColor4::cyan5); } - else if( "cyan6" == color_name ) + else if ("cyan6" == color_name) { color->set(LLColor4::cyan6); } - else if( "smoke" == color_name ) + else if ("smoke" == color_name) { color->set(LLColor4::smoke); } - else if( "grey" == color_name ) + else if ("grey" == color_name) { color->set(LLColor4::grey); } - else if( "grey1" == color_name ) + else if ("grey1" == color_name) { color->set(LLColor4::grey1); } - else if( "grey2" == color_name ) + else if ("grey2" == color_name) { color->set(LLColor4::grey2); } - else if( "grey3" == color_name ) + else if ("grey3" == color_name) { color->set(LLColor4::grey3); } - else if( "grey4" == color_name ) + else if ("grey4" == color_name) { color->set(LLColor4::grey4); } - else if( "orange" == color_name ) + else if ("orange" == color_name) { color->set(LLColor4::orange); } - else if( "orange1" == color_name ) + else if ("orange1" == color_name) { color->set(LLColor4::orange1); } - else if( "orange2" == color_name ) + else if ("orange2" == color_name) { color->set(LLColor4::orange2); } - else if( "orange3" == color_name ) + else if ("orange3" == color_name) { color->set(LLColor4::orange3); } - else if( "orange4" == color_name ) + else if ("orange4" == color_name) { color->set(LLColor4::orange4); } - else if( "orange5" == color_name ) + else if ("orange5" == color_name) { color->set(LLColor4::orange5); } - else if( "orange6" == color_name ) + else if ("orange6" == color_name) { color->set(LLColor4::orange6); } - else if ( "clear" == color_name ) + else if ("clear" == color_name) { color->set(0.f, 0.f, 0.f, 0.f); } @@ -714,21 +717,21 @@ bool LLColor4::parseColor(const std::string& buf, LLColor4* color) // static bool LLColor4::parseColor4(const std::string& buf, LLColor4* value) { - if( buf.empty() || value == nullptr) + if (buf.empty() || value == nullptr) { return false; } LLColor4 v; - S32 count = sscanf( buf.c_str(), "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); - if (1 == count ) + S32 count = sscanf(buf.c_str(), "%f, %f, %f, %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3); + if (1 == count) { // try this format - count = sscanf( buf.c_str(), "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3 ); + count = sscanf(buf.c_str(), "%f %f %f %f", v.mV + 0, v.mV + 1, v.mV + 2, v.mV + 3); } - if( 4 == count ) + if (4 == count) { - value->setVec( v ); + value->setVec(v); return true; } diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index 97ffead7a0..d48020c223 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -28,7 +28,6 @@ #define LL_V4COLOR_H #include "llerror.h" -//#include "vmath.h" #include "llmath.h" #include "llsd.h" @@ -38,198 +37,198 @@ class LLVector4; // LLColor4 = |x y z w| -static const U32 LENGTHOFCOLOR4 = 4; +static constexpr U32 LENGTHOFCOLOR4 = 4; -static const U32 MAX_LENGTH_OF_COLOR_NAME = 15; //Give plenty of room for additional colors... +static constexpr U32 MAX_LENGTH_OF_COLOR_NAME = 15; // Give plenty of room for additional colors... class LLColor4 { - public: - F32 mV[LENGTHOFCOLOR4]; - LLColor4(); // Initializes LLColor4 to (0, 0, 0, 1) - LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1) - LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a) - LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a) - explicit LLColor4(const LLSD& sd); - explicit LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1) - explicit LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc)) - explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion - explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion - - LLSD getValue() const - { - LLSD ret; - ret[0] = mV[0]; - ret[1] = mV[1]; - ret[2] = mV[2]; - ret[3] = mV[3]; - return ret; - } - - void setValue(const LLSD& sd); - - void setHSL(F32 hue, F32 saturation, F32 luminance); - void calcHSL(F32* hue, F32* saturation, F32* luminance) const; - - const LLColor4& setToBlack(); // zero LLColor4 to (0, 0, 0, 1) - const LLColor4& setToWhite(); // zero LLColor4 to (0, 0, 0, 1) - - const LLColor4& setVec(F32 r, F32 g, F32 b, F32 a); // deprecated -- use set() - const LLColor4& setVec(F32 r, F32 g, F32 b); // deprecated -- use set() - const LLColor4& setVec(const LLColor4 &vec); // deprecated -- use set() - const LLColor4& setVec(const LLColor3 &vec); // deprecated -- use set() - const LLColor4& setVec(const LLColor3 &vec, F32 a); // deprecated -- use set() - const LLColor4& setVec(const F32 *vec); // deprecated -- use set() - const LLColor4& setVec(const LLColor4U& color4u); // deprecated -- use set() - - const LLColor4& set(F32 r, F32 g, F32 b, F32 a); // Sets LLColor4 to (r, g, b, a) - const LLColor4& set(F32 r, F32 g, F32 b); // Sets LLColor4 to (r, g, b) (no change in a) - const LLColor4& set(const LLColor4 &vec); // Sets LLColor4 to vec - const LLColor4& set(const LLColor3 &vec); // Sets LLColor4 to LLColor3 vec (no change in alpha) - const LLColor4& set(const LLColor3 &vec, F32 a); // Sets LLColor4 to LLColor3 vec, with alpha specified - const LLColor4& set(const F32 *vec); // Sets LLColor4 to vec - const LLColor4& set(const F64 *vec); // Sets LLColor4 to (double)vec - const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. - - // set from a vector of unknown type and size - // may leave some data unmodified - template<typename T> - const LLColor4& set(const std::vector<T>& v); - - // write to a vector of unknown type and size - // maye leave some data unmodified - template<typename T> - void write(std::vector<T>& v) const; - - const LLColor4& setAlpha(F32 a); - - F32 magVec() const; // deprecated -- use length() - F32 magVecSquared() const; // deprecated -- use lengthSquared() - F32 normVec(); // deprecated -- use normalize() - - F32 length() const; // Returns magnitude of LLColor4 - F32 lengthSquared() const; // Returns magnitude squared of LLColor4 - F32 normalize(); // deprecated -- use normalize() - - bool isOpaque() { return mV[VALPHA] == 1.f; } - - F32 operator[](int idx) const { return mV[idx]; } - F32 &operator[](int idx) { return mV[idx]; } - - const LLColor4& operator=(const LLColor3 &a); // Assigns vec3 to vec4 and returns vec4 - - bool operator<(const LLColor4& rhs) const; - friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a - friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b - friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b - friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b - friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change) - friend LLColor4 operator/(const LLColor4 &a, F32 k); // Return rgb divided by scalar k (no alpha change) - friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change) - friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change) - friend LLColor4 operator%(F32 k, const LLColor4 &a); // Return alpha times scaler k (no rgb change) - - friend bool operator==(const LLColor4 &a, const LLColor4 &b); // Return a == b - friend bool operator!=(const LLColor4 &a, const LLColor4 &b); // Return a != b - - friend bool operator==(const LLColor4 &a, const LLColor3 &b); // Return a == b - friend bool operator!=(const LLColor4 &a, const LLColor3 &b); // Return a != b - - friend const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b); // Return vector a + b - friend const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b); // Return vector a minus b - friend const LLColor4& operator*=(LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change) - friend const LLColor4& operator%=(LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change) - - friend const LLColor4& operator*=(LLColor4 &a, const LLColor4 &b); // Doesn't multiply alpha! (for lighting) - - // conversion - operator LLColor4U() const; - - // Basic color values. - static LLColor4 red; - static LLColor4 green; - static LLColor4 blue; - static LLColor4 black; - static LLColor4 white; - static LLColor4 yellow; - static LLColor4 magenta; - static LLColor4 cyan; - static LLColor4 smoke; - static LLColor4 grey; - static LLColor4 orange; - static LLColor4 purple; - static LLColor4 pink; - static LLColor4 transparent; - - // Extra color values. - static LLColor4 grey1; - static LLColor4 grey2; - static LLColor4 grey3; - static LLColor4 grey4; - - static LLColor4 red1; - static LLColor4 red2; - static LLColor4 red3; - static LLColor4 red4; - static LLColor4 red5; - - static LLColor4 green1; - static LLColor4 green2; - static LLColor4 green3; - static LLColor4 green4; - static LLColor4 green5; - static LLColor4 green6; - - static LLColor4 blue1; - static LLColor4 blue2; - static LLColor4 blue3; - static LLColor4 blue4; - static LLColor4 blue5; - static LLColor4 blue6; - - static LLColor4 yellow1; - static LLColor4 yellow2; - static LLColor4 yellow3; - static LLColor4 yellow4; - static LLColor4 yellow5; - static LLColor4 yellow6; - static LLColor4 yellow7; - static LLColor4 yellow8; - static LLColor4 yellow9; - - static LLColor4 orange1; - static LLColor4 orange2; - static LLColor4 orange3; - static LLColor4 orange4; - static LLColor4 orange5; - static LLColor4 orange6; - - static LLColor4 magenta1; - static LLColor4 magenta2; - static LLColor4 magenta3; - static LLColor4 magenta4; - - static LLColor4 purple1; - static LLColor4 purple2; - static LLColor4 purple3; - static LLColor4 purple4; - static LLColor4 purple5; - static LLColor4 purple6; - - static LLColor4 pink1; - static LLColor4 pink2; - - static LLColor4 cyan1; - static LLColor4 cyan2; - static LLColor4 cyan3; - static LLColor4 cyan4; - static LLColor4 cyan5; - static LLColor4 cyan6; - - static bool parseColor(const std::string& buf, LLColor4* color); - static bool parseColor4(const std::string& buf, LLColor4* color); - - inline void clamp(); +public: + F32 mV[LENGTHOFCOLOR4]; + LLColor4(); // Initializes LLColor4 to (0, 0, 0, 1) + LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1) + LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a) + LLColor4(const LLColor3& vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a) + explicit LLColor4(const LLSD& sd); + explicit LLColor4(const F32* vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1) + explicit LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc)) + explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion + explicit LLColor4(const LLVector4& vector4); // "explicit" to avoid automatic conversion + + LLSD getValue() const + { + LLSD ret; + ret[VRED] = mV[VRED]; + ret[VGREEN] = mV[VGREEN]; + ret[VBLUE] = mV[VBLUE]; + ret[VALPHA] = mV[VALPHA]; + return ret; + } + + void setValue(const LLSD& sd); + + void setHSL(F32 hue, F32 saturation, F32 luminance); + void calcHSL(F32* hue, F32* saturation, F32* luminance) const; + + const LLColor4& setToBlack(); // zero LLColor4 to (0, 0, 0, 1) + const LLColor4& setToWhite(); // zero LLColor4 to (0, 0, 0, 1) + + const LLColor4& setVec(F32 r, F32 g, F32 b, F32 a); // deprecated -- use set() + const LLColor4& setVec(F32 r, F32 g, F32 b); // deprecated -- use set() + const LLColor4& setVec(const LLColor4& vec); // deprecated -- use set() + const LLColor4& setVec(const LLColor3& vec); // deprecated -- use set() + const LLColor4& setVec(const LLColor3& vec, F32 a); // deprecated -- use set() + const LLColor4& setVec(const F32* vec); // deprecated -- use set() + const LLColor4& setVec(const LLColor4U& color4u); // deprecated -- use set() + + const LLColor4& set(F32 r, F32 g, F32 b, F32 a); // Sets LLColor4 to (r, g, b, a) + const LLColor4& set(F32 r, F32 g, F32 b); // Sets LLColor4 to (r, g, b) (no change in a) + const LLColor4& set(const LLColor4& vec); // Sets LLColor4 to vec + const LLColor4& set(const LLColor3& vec); // Sets LLColor4 to LLColor3 vec (no change in alpha) + const LLColor4& set(const LLColor3& vec, F32 a); // Sets LLColor4 to LLColor3 vec, with alpha specified + const LLColor4& set(const F32* vec); // Sets LLColor4 to vec + const LLColor4& set(const F64* vec); // Sets LLColor4 to (double)vec + const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. + + // set from a vector of unknown type and size + // may leave some data unmodified + template<typename T> + const LLColor4& set(const std::vector<T>& v); + + // write to a vector of unknown type and size + // maye leave some data unmodified + template<typename T> + void write(std::vector<T>& v) const; + + const LLColor4& setAlpha(F32 a); + + F32 magVec() const; // deprecated -- use length() + F32 magVecSquared() const; // deprecated -- use lengthSquared() + F32 normVec(); // deprecated -- use normalize() + + F32 length() const; // Returns magnitude of LLColor4 + F32 lengthSquared() const; // Returns magnitude squared of LLColor4 + F32 normalize(); // deprecated -- use normalize() + + bool isOpaque() const { return mV[VALPHA] == 1.f; } + + F32 operator[](int idx) const { return mV[idx]; } + F32& operator[](int idx) { return mV[idx]; } + + const LLColor4& operator=(const LLColor3& a); // Assigns vec3 to vec4 and returns vec4 + + bool operator<(const LLColor4& rhs) const; + friend std::ostream& operator<<(std::ostream& s, const LLColor4& a); // Print a + friend LLColor4 operator+(const LLColor4& a, const LLColor4& b); // Return vector a + b + friend LLColor4 operator-(const LLColor4& a, const LLColor4& b); // Return vector a minus b + friend LLColor4 operator*(const LLColor4& a, const LLColor4& b); // Return component wise a * b + friend LLColor4 operator*(const LLColor4& a, F32 k); // Return rgb times scaler k (no alpha change) + friend LLColor4 operator/(const LLColor4& a, F32 k); // Return rgb divided by scalar k (no alpha change) + friend LLColor4 operator*(F32 k, const LLColor4& a); // Return rgb times scaler k (no alpha change) + friend LLColor4 operator%(const LLColor4& a, F32 k); // Return alpha times scaler k (no rgb change) + friend LLColor4 operator%(F32 k, const LLColor4& a); // Return alpha times scaler k (no rgb change) + + friend bool operator==(const LLColor4& a, const LLColor4& b); // Return a == b + friend bool operator!=(const LLColor4& a, const LLColor4& b); // Return a != b + + friend bool operator==(const LLColor4& a, const LLColor3& b); // Return a == b + friend bool operator!=(const LLColor4& a, const LLColor3& b); // Return a != b + + friend const LLColor4& operator+=(LLColor4& a, const LLColor4& b); // Return vector a + b + friend const LLColor4& operator-=(LLColor4& a, const LLColor4& b); // Return vector a minus b + friend const LLColor4& operator*=(LLColor4& a, F32 k); // Return rgb times scaler k (no alpha change) + friend const LLColor4& operator%=(LLColor4& a, F32 k); // Return alpha times scaler k (no rgb change) + + friend const LLColor4& operator*=(LLColor4& a, const LLColor4& b); // Doesn't multiply alpha! (for lighting) + + // conversion + operator LLColor4U() const; + + // Basic color values. + static LLColor4 red; + static LLColor4 green; + static LLColor4 blue; + static LLColor4 black; + static LLColor4 white; + static LLColor4 yellow; + static LLColor4 magenta; + static LLColor4 cyan; + static LLColor4 smoke; + static LLColor4 grey; + static LLColor4 orange; + static LLColor4 purple; + static LLColor4 pink; + static LLColor4 transparent; + + // Extra color values. + static LLColor4 grey1; + static LLColor4 grey2; + static LLColor4 grey3; + static LLColor4 grey4; + + static LLColor4 red1; + static LLColor4 red2; + static LLColor4 red3; + static LLColor4 red4; + static LLColor4 red5; + + static LLColor4 green1; + static LLColor4 green2; + static LLColor4 green3; + static LLColor4 green4; + static LLColor4 green5; + static LLColor4 green6; + + static LLColor4 blue1; + static LLColor4 blue2; + static LLColor4 blue3; + static LLColor4 blue4; + static LLColor4 blue5; + static LLColor4 blue6; + + static LLColor4 yellow1; + static LLColor4 yellow2; + static LLColor4 yellow3; + static LLColor4 yellow4; + static LLColor4 yellow5; + static LLColor4 yellow6; + static LLColor4 yellow7; + static LLColor4 yellow8; + static LLColor4 yellow9; + + static LLColor4 orange1; + static LLColor4 orange2; + static LLColor4 orange3; + static LLColor4 orange4; + static LLColor4 orange5; + static LLColor4 orange6; + + static LLColor4 magenta1; + static LLColor4 magenta2; + static LLColor4 magenta3; + static LLColor4 magenta4; + + static LLColor4 purple1; + static LLColor4 purple2; + static LLColor4 purple3; + static LLColor4 purple4; + static LLColor4 purple5; + static LLColor4 purple6; + + static LLColor4 pink1; + static LLColor4 pink2; + + static LLColor4 cyan1; + static LLColor4 cyan2; + static LLColor4 cyan3; + static LLColor4 cyan4; + static LLColor4 cyan5; + static LLColor4 cyan6; + + static bool parseColor(const std::string& buf, LLColor4* color); + static bool parseColor4(const std::string& buf, LLColor4* color); + + inline void clamp(); }; static_assert(std::is_trivially_copyable<LLColor4>::value, "LLColor4 must be trivial copy"); @@ -237,17 +236,17 @@ static_assert(std::is_trivially_move_assignable<LLColor4>::value, "LLColor4 must static_assert(std::is_standard_layout<LLColor4>::value, "LLColor4 must be a standard layout type"); // Non-member functions -F32 distVec(const LLColor4 &a, const LLColor4 &b); // Returns distance between a and b -F32 distVec_squared(const LLColor4 &a, const LLColor4 &b); // Returns distance squared between a and b -LLColor3 vec4to3(const LLColor4 &vec); -LLColor4 vec3to4(const LLColor3 &vec); -LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u); +F32 distVec(const LLColor4& a, const LLColor4& b); // Returns distance between a and b +F32 distVec_squared(const LLColor4& a, const LLColor4& b); // Returns distance squared between a and b +LLColor3 vec4to3(const LLColor4& vec); +LLColor4 vec3to4(const LLColor3& vec); +LLColor4 lerp(const LLColor4& a, const LLColor4& b, F32 u); -inline LLColor4::LLColor4(void) +inline LLColor4::LLColor4() { - mV[VRED] = 0.f; + mV[VRED] = 0.f; mV[VGREEN] = 0.f; - mV[VBLUE] = 0.f; + mV[VBLUE] = 0.f; mV[VALPHA] = 1.f; } @@ -258,149 +257,146 @@ inline LLColor4::LLColor4(const LLSD& sd) inline LLColor4::LLColor4(F32 r, F32 g, F32 b) { - mV[VRED] = r; + mV[VRED] = r; mV[VGREEN] = g; - mV[VBLUE] = b; + mV[VBLUE] = b; mV[VALPHA] = 1.f; } inline LLColor4::LLColor4(F32 r, F32 g, F32 b, F32 a) { - mV[VRED] = r; + mV[VRED] = r; mV[VGREEN] = g; - mV[VBLUE] = b; + mV[VBLUE] = b; mV[VALPHA] = a; } inline LLColor4::LLColor4(U32 clr) { - mV[VRED] = (clr&0xff) * (1.0f/255.0f); - mV[VGREEN] = ((clr>>8)&0xff) * (1.0f/255.0f); - mV[VBLUE] = ((clr>>16)&0xff) * (1.0f/255.0f); - mV[VALPHA] = (clr>>24) * (1.0f/255.0f); + mV[VRED] = (clr & 0xff) * (1.0f / 255.0f); + mV[VGREEN] = ((clr >> 8) & 0xff) * (1.0f / 255.0f); + mV[VBLUE] = ((clr >> 16) & 0xff) * (1.0f / 255.0f); + mV[VALPHA] = (clr >> 24) * (1.0f / 255.0f); } - -inline LLColor4::LLColor4(const F32 *vec) +inline LLColor4::LLColor4(const F32* vec) { - mV[VRED] = vec[VRED]; + mV[VRED] = vec[VRED]; mV[VGREEN] = vec[VGREEN]; - mV[VBLUE] = vec[VBLUE]; + mV[VBLUE] = vec[VBLUE]; mV[VALPHA] = vec[VALPHA]; } -inline const LLColor4& LLColor4::setToBlack(void) +inline const LLColor4& LLColor4::setToBlack(void) { - mV[VRED] = 0.f; + mV[VRED] = 0.f; mV[VGREEN] = 0.f; - mV[VBLUE] = 0.f; + mV[VBLUE] = 0.f; mV[VALPHA] = 1.f; return (*this); } -inline const LLColor4& LLColor4::setToWhite(void) +inline const LLColor4& LLColor4::setToWhite(void) { - mV[VRED] = 1.f; + mV[VRED] = 1.f; mV[VGREEN] = 1.f; - mV[VBLUE] = 1.f; + mV[VBLUE] = 1.f; mV[VALPHA] = 1.f; return (*this); } -inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z) +inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z) { - mV[VRED] = x; + mV[VRED] = x; mV[VGREEN] = y; - mV[VBLUE] = z; + mV[VBLUE] = z; -// no change to alpha! -// mV[VALPHA] = 1.f; + // no change to alpha! + // mV[VALPHA] = 1.f; return (*this); } -inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z, F32 a) +inline const LLColor4& LLColor4::set(F32 x, F32 y, F32 z, F32 a) { - mV[VRED] = x; + mV[VRED] = x; mV[VGREEN] = y; - mV[VBLUE] = z; + mV[VBLUE] = z; mV[VALPHA] = a; return (*this); } -inline const LLColor4& LLColor4::set(const LLColor4 &vec) +inline const LLColor4& LLColor4::set(const LLColor4& vec) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; mV[VALPHA] = vec.mV[VALPHA]; return (*this); } - -inline const LLColor4& LLColor4::set(const F32 *vec) +inline const LLColor4& LLColor4::set(const F32* vec) { - mV[VRED] = vec[VRED]; + mV[VRED] = vec[VRED]; mV[VGREEN] = vec[VGREEN]; - mV[VBLUE] = vec[VBLUE]; + mV[VBLUE] = vec[VBLUE]; mV[VALPHA] = vec[VALPHA]; return (*this); } -inline const LLColor4& LLColor4::set(const F64 *vec) +inline const LLColor4& LLColor4::set(const F64* vec) { - mV[VRED] = static_cast<F32>(vec[VRED]); + mV[VRED] = static_cast<F32>(vec[VRED]); mV[VGREEN] = static_cast<F32>(vec[VGREEN]); - mV[VBLUE] = static_cast<F32>(vec[VBLUE]); + mV[VBLUE] = static_cast<F32>(vec[VBLUE]); mV[VALPHA] = static_cast<F32>(vec[VALPHA]); return (*this); } // deprecated -inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z) +inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z) { - mV[VRED] = x; + mV[VRED] = x; mV[VGREEN] = y; - mV[VBLUE] = z; + mV[VBLUE] = z; -// no change to alpha! -// mV[VALPHA] = 1.f; + // no change to alpha! + // mV[VALPHA] = 1.f; return (*this); } // deprecated -inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z, F32 a) +inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z, F32 a) { - mV[VRED] = x; + mV[VRED] = x; mV[VGREEN] = y; - mV[VBLUE] = z; + mV[VBLUE] = z; mV[VALPHA] = a; return (*this); } // deprecated -inline const LLColor4& LLColor4::setVec(const LLColor4 &vec) +inline const LLColor4& LLColor4::setVec(const LLColor4& vec) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; mV[VALPHA] = vec.mV[VALPHA]; return (*this); } - // deprecated -inline const LLColor4& LLColor4::setVec(const F32 *vec) +inline const LLColor4& LLColor4::setVec(const F32* vec) { - mV[VRED] = vec[VRED]; + mV[VRED] = vec[VRED]; mV[VGREEN] = vec[VGREEN]; - mV[VBLUE] = vec[VBLUE]; + mV[VBLUE] = vec[VBLUE]; mV[VALPHA] = vec[VALPHA]; return (*this); } -inline const LLColor4& LLColor4::setAlpha(F32 a) +inline const LLColor4& LLColor4::setAlpha(F32 a) { mV[VALPHA] = a; return (*this); @@ -408,155 +404,116 @@ inline const LLColor4& LLColor4::setAlpha(F32 a) // LLColor4 Magnitude and Normalization Functions -inline F32 LLColor4::length(void) const +inline F32 LLColor4::length() const { - return (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]); + return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); } -inline F32 LLColor4::lengthSquared(void) const +inline F32 LLColor4::lengthSquared() const { - return mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]; + return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]; } -inline F32 LLColor4::normalize(void) +inline F32 LLColor4::normalize() { - F32 mag = (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]); + F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); F32 oomag; if (mag) { - oomag = 1.f/mag; + oomag = 1.f / mag; mV[VRED] *= oomag; mV[VGREEN] *= oomag; mV[VBLUE] *= oomag; } - return (mag); + return mag; } // deprecated -inline F32 LLColor4::magVec(void) const +inline F32 LLColor4::magVec() const { - return (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]); + return sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); } // deprecated -inline F32 LLColor4::magVecSquared(void) const +inline F32 LLColor4::magVecSquared() const { - return mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]; + return mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]; } // deprecated -inline F32 LLColor4::normVec(void) +inline F32 LLColor4::normVec() { - F32 mag = (F32) sqrt(mV[VRED]*mV[VRED] + mV[VGREEN]*mV[VGREEN] + mV[VBLUE]*mV[VBLUE]); + F32 mag = sqrt(mV[VRED] * mV[VRED] + mV[VGREEN] * mV[VGREEN] + mV[VBLUE] * mV[VBLUE]); F32 oomag; if (mag) { - oomag = 1.f/mag; + oomag = 1.f / mag; mV[VRED] *= oomag; mV[VGREEN] *= oomag; mV[VBLUE] *= oomag; } - return (mag); + return mag; } // LLColor4 Operators - -inline LLColor4 operator+(const LLColor4 &a, const LLColor4 &b) +inline LLColor4 operator+(const LLColor4& a, const LLColor4& b) { - return LLColor4( - a.mV[VRED] + b.mV[VRED], - a.mV[VGREEN] + b.mV[VGREEN], - a.mV[VBLUE] + b.mV[VBLUE], - a.mV[VALPHA] + b.mV[VALPHA]); + return LLColor4(a.mV[VRED] + b.mV[VRED], a.mV[VGREEN] + b.mV[VGREEN], a.mV[VBLUE] + b.mV[VBLUE], a.mV[VALPHA] + b.mV[VALPHA]); } -inline LLColor4 operator-(const LLColor4 &a, const LLColor4 &b) +inline LLColor4 operator-(const LLColor4& a, const LLColor4& b) { - return LLColor4( - a.mV[VRED] - b.mV[VRED], - a.mV[VGREEN] - b.mV[VGREEN], - a.mV[VBLUE] - b.mV[VBLUE], - a.mV[VALPHA] - b.mV[VALPHA]); + return LLColor4(a.mV[VRED] - b.mV[VRED], a.mV[VGREEN] - b.mV[VGREEN], a.mV[VBLUE] - b.mV[VBLUE], a.mV[VALPHA] - b.mV[VALPHA]); } -inline LLColor4 operator*(const LLColor4 &a, const LLColor4 &b) +inline LLColor4 operator*(const LLColor4& a, const LLColor4& b) { - return LLColor4( - a.mV[VRED] * b.mV[VRED], - a.mV[VGREEN] * b.mV[VGREEN], - a.mV[VBLUE] * b.mV[VBLUE], - a.mV[VALPHA] * b.mV[VALPHA]); + return LLColor4(a.mV[VRED] * b.mV[VRED], a.mV[VGREEN] * b.mV[VGREEN], a.mV[VBLUE] * b.mV[VBLUE], a.mV[VALPHA] * b.mV[VALPHA]); } -inline LLColor4 operator*(const LLColor4 &a, F32 k) +inline LLColor4 operator*(const LLColor4& a, F32 k) { // only affects rgb (not a!) - return LLColor4( - a.mV[VRED] * k, - a.mV[VGREEN] * k, - a.mV[VBLUE] * k, - a.mV[VALPHA]); + return LLColor4(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k, a.mV[VALPHA]); } -inline LLColor4 operator/(const LLColor4 &a, F32 k) +inline LLColor4 operator/(const LLColor4& a, F32 k) { - return LLColor4( - a.mV[VRED] / k, - a.mV[VGREEN] / k, - a.mV[VBLUE] / k, - a.mV[VALPHA]); + return LLColor4(a.mV[VRED] / k, a.mV[VGREEN] / k, a.mV[VBLUE] / k, a.mV[VALPHA]); } -inline LLColor4 operator*(F32 k, const LLColor4 &a) +inline LLColor4 operator*(F32 k, const LLColor4& a) { // only affects rgb (not a!) - return LLColor4( - a.mV[VRED] * k, - a.mV[VGREEN] * k, - a.mV[VBLUE] * k, - a.mV[VALPHA]); + return LLColor4(a.mV[VRED] * k, a.mV[VGREEN] * k, a.mV[VBLUE] * k, a.mV[VALPHA]); } -inline LLColor4 operator%(F32 k, const LLColor4 &a) +inline LLColor4 operator%(F32 k, const LLColor4& a) { // only affects alpha (not rgb!) - return LLColor4( - a.mV[VRED], - a.mV[VGREEN], - a.mV[VBLUE], - a.mV[VALPHA] * k); + return LLColor4(a.mV[VRED], a.mV[VGREEN], a.mV[VBLUE], a.mV[VALPHA] * k); } -inline LLColor4 operator%(const LLColor4 &a, F32 k) +inline LLColor4 operator%(const LLColor4& a, F32 k) { // only affects alpha (not rgb!) - return LLColor4( - a.mV[VRED], - a.mV[VGREEN], - a.mV[VBLUE], - a.mV[VALPHA] * k); + return LLColor4(a.mV[VRED], a.mV[VGREEN], a.mV[VBLUE], a.mV[VALPHA] * k); } -inline bool operator==(const LLColor4 &a, const LLColor4 &b) +inline bool operator==(const LLColor4& a, const LLColor4& b) { - return ( (a.mV[VRED] == b.mV[VRED]) - &&(a.mV[VGREEN] == b.mV[VGREEN]) - &&(a.mV[VBLUE] == b.mV[VBLUE]) - &&(a.mV[VALPHA] == b.mV[VALPHA])); + return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE]) && (a.mV[VALPHA] == b.mV[VALPHA])); } -inline bool operator!=(const LLColor4 &a, const LLColor4 &b) +inline bool operator!=(const LLColor4& a, const LLColor4& b) { - return ( (a.mV[VRED] != b.mV[VRED]) - ||(a.mV[VGREEN] != b.mV[VGREEN]) - ||(a.mV[VBLUE] != b.mV[VBLUE]) - ||(a.mV[VALPHA] != b.mV[VALPHA])); + return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE]) || (a.mV[VALPHA] != b.mV[VALPHA])); } -inline const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b) +inline const LLColor4& operator+=(LLColor4& a, const LLColor4& b) { a.mV[VRED] += b.mV[VRED]; a.mV[VGREEN] += b.mV[VGREEN]; @@ -565,7 +522,7 @@ inline const LLColor4& operator+=(LLColor4 &a, const LLColor4 &b) return a; } -inline const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b) +inline const LLColor4& operator-=(LLColor4& a, const LLColor4& b) { a.mV[VRED] -= b.mV[VRED]; a.mV[VGREEN] -= b.mV[VGREEN]; @@ -574,7 +531,7 @@ inline const LLColor4& operator-=(LLColor4 &a, const LLColor4 &b) return a; } -inline const LLColor4& operator*=(LLColor4 &a, F32 k) +inline const LLColor4& operator*=(LLColor4& a, F32 k) { // only affects rgb (not a!) a.mV[VRED] *= k; @@ -583,121 +540,120 @@ inline const LLColor4& operator*=(LLColor4 &a, F32 k) return a; } -inline const LLColor4& operator *=(LLColor4 &a, const LLColor4 &b) +inline const LLColor4& operator*=(LLColor4& a, const LLColor4& b) { a.mV[VRED] *= b.mV[VRED]; a.mV[VGREEN] *= b.mV[VGREEN]; a.mV[VBLUE] *= b.mV[VBLUE]; -// a.mV[VALPHA] *= b.mV[VALPHA]; + // a.mV[VALPHA] *= b.mV[VALPHA]; return a; } -inline const LLColor4& operator%=(LLColor4 &a, F32 k) +inline const LLColor4& operator%=(LLColor4& a, F32 k) { // only affects alpha (not rgb!) a.mV[VALPHA] *= k; return a; } - // Non-member functions -inline F32 distVec(const LLColor4 &a, const LLColor4 &b) +inline F32 distVec(const LLColor4& a, const LLColor4& b) { LLColor4 vec = a - b; - return (vec.length()); + return vec.length(); } -inline F32 distVec_squared(const LLColor4 &a, const LLColor4 &b) +inline F32 distVec_squared(const LLColor4& a, const LLColor4& b) { LLColor4 vec = a - b; - return (vec.lengthSquared()); + return vec.lengthSquared(); } -inline LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u) +inline LLColor4 lerp(const LLColor4& a, const LLColor4& b, F32 u) { - return LLColor4( - a.mV[VRED] + (b.mV[VRED] - a.mV[VRED]) * u, - a.mV[VGREEN] + (b.mV[VGREEN] - a.mV[VGREEN]) * u, - a.mV[VBLUE] + (b.mV[VBLUE] - a.mV[VBLUE]) * u, - a.mV[VALPHA] + (b.mV[VALPHA] - a.mV[VALPHA]) * u); + return LLColor4(a.mV[VRED] + (b.mV[VRED] - a.mV[VRED]) * u, + a.mV[VGREEN] + (b.mV[VGREEN] - a.mV[VGREEN]) * u, + a.mV[VBLUE] + (b.mV[VBLUE] - a.mV[VBLUE]) * u, + a.mV[VALPHA] + (b.mV[VALPHA] - a.mV[VALPHA]) * u); } inline bool LLColor4::operator<(const LLColor4& rhs) const { - if (mV[0] != rhs.mV[0]) + if (mV[VRED] != rhs.mV[VRED]) { - return mV[0] < rhs.mV[0]; + return mV[VRED] < rhs.mV[VRED]; } - if (mV[1] != rhs.mV[1]) + if (mV[VGREEN] != rhs.mV[VGREEN]) { - return mV[1] < rhs.mV[1]; + return mV[VGREEN] < rhs.mV[VGREEN]; } - if (mV[2] != rhs.mV[2]) + if (mV[VBLUE] != rhs.mV[VBLUE]) { - return mV[2] < rhs.mV[2]; + return mV[VBLUE] < rhs.mV[VBLUE]; } - return mV[3] < rhs.mV[3]; + return mV[VALPHA] < rhs.mV[VALPHA]; } void LLColor4::clamp() { // Clamp the color... - if (mV[0] < 0.f) + if (mV[VRED] < 0.f) { - mV[0] = 0.f; + mV[VRED] = 0.f; } - else if (mV[0] > 1.f) + else if (mV[VRED] > 1.f) { - mV[0] = 1.f; + mV[VRED] = 1.f; } - if (mV[1] < 0.f) + if (mV[VGREEN] < 0.f) { - mV[1] = 0.f; + mV[VGREEN] = 0.f; } - else if (mV[1] > 1.f) + else if (mV[VGREEN] > 1.f) { - mV[1] = 1.f; + mV[VGREEN] = 1.f; } - if (mV[2] < 0.f) + if (mV[VBLUE] < 0.f) { - mV[2] = 0.f; + mV[VBLUE] = 0.f; } - else if (mV[2] > 1.f) + else if (mV[VBLUE] > 1.f) { - mV[2] = 1.f; + mV[VBLUE] = 1.f; } - if (mV[3] < 0.f) + if (mV[VALPHA] < 0.f) { - mV[3] = 0.f; + mV[VALPHA] = 0.f; } - else if (mV[3] > 1.f) + else if (mV[VALPHA] > 1.f) { - mV[3] = 1.f; + mV[VALPHA] = 1.f; } } // Return the given linear space color value in gamma corrected (sRGB) space -inline const LLColor4 srgbColor4(const LLColor4 &a) { +inline const LLColor4 srgbColor4(const LLColor4& a) +{ LLColor4 srgbColor; - srgbColor.mV[0] = linearTosRGB(a.mV[0]); - srgbColor.mV[1] = linearTosRGB(a.mV[1]); - srgbColor.mV[2] = linearTosRGB(a.mV[2]); - srgbColor.mV[3] = a.mV[3]; + srgbColor.mV[VRED] = linearTosRGB(a.mV[VRED]); + srgbColor.mV[VGREEN] = linearTosRGB(a.mV[VGREEN]); + srgbColor.mV[VBLUE] = linearTosRGB(a.mV[VBLUE]); + srgbColor.mV[VALPHA] = a.mV[VALPHA]; return srgbColor; } // Return the given gamma corrected (sRGB) color in linear space -inline const LLColor4 linearColor4(const LLColor4 &a) +inline const LLColor4 linearColor4(const LLColor4& a) { LLColor4 linearColor; - linearColor.mV[0] = sRGBtoLinear(a.mV[0]); - linearColor.mV[1] = sRGBtoLinear(a.mV[1]); - linearColor.mV[2] = sRGBtoLinear(a.mV[2]); - linearColor.mV[3] = a.mV[3]; + linearColor.mV[VRED] = sRGBtoLinear(a.mV[VRED]); + linearColor.mV[VGREEN] = sRGBtoLinear(a.mV[VGREEN]); + linearColor.mV[VBLUE] = sRGBtoLinear(a.mV[VBLUE]); + linearColor.mV[VALPHA] = a.mV[VALPHA]; return linearColor; } @@ -723,4 +679,3 @@ void LLColor4::write(std::vector<T>& v) const } #endif - diff --git a/indra/llmath/v4coloru.cpp b/indra/llmath/v4coloru.cpp index acf349245a..c495ffdb4c 100644 --- a/indra/llmath/v4coloru.cpp +++ b/indra/llmath/v4coloru.cpp @@ -26,10 +26,7 @@ #include "linden_common.h" -//#include "v3coloru.h" #include "v4coloru.h" -#include "v4color.h" -//#include "vmath.h" #include "llmath.h" // LLColor4U @@ -39,49 +36,7 @@ LLColor4U LLColor4U::red (255, 0, 0, 255); LLColor4U LLColor4U::green( 0, 255, 0, 255); LLColor4U LLColor4U::blue ( 0, 0, 255, 255); -// conversion -/* inlined to fix gcc compile link error -LLColor4U::operator LLColor4() -{ - return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f)); -} -*/ - -// Constructors - - -/* -LLColor4U::LLColor4U(const LLColor3 &vec) -{ - mV[VRED] = vec.mV[VRED]; - mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; - mV[VALPHA] = 255; -} -*/ - - -// Clear and Assignment Functions - - - -// LLColor4U Operators - -/* -LLColor4U LLColor4U::operator=(const LLColor3 &a) -{ - mV[VRED] = a.mV[VRED]; - mV[VGREEN] = a.mV[VGREEN]; - mV[VBLUE] = a.mV[VBLUE]; - -// converting from an rgb sets a=1 (opaque) - mV[VALPHA] = 255; - return (*this); -} -*/ - - -std::ostream& operator<<(std::ostream& s, const LLColor4U &a) +std::ostream& operator<<(std::ostream& s, const LLColor4U& a) { s << "{ " << (S32)a.mV[VRED] << ", " << (S32)a.mV[VGREEN] << ", " << (S32)a.mV[VBLUE] << ", " << (S32)a.mV[VALPHA] << " }"; return s; @@ -90,31 +45,31 @@ std::ostream& operator<<(std::ostream& s, const LLColor4U &a) // static bool LLColor4U::parseColor4U(const std::string& buf, LLColor4U* value) { - if( buf.empty() || value == nullptr) + if (buf.empty() || value == nullptr) { return false; } - U32 v[4]; - S32 count = sscanf( buf.c_str(), "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3 ); - if (1 == count ) + U32 v[4]{}; + S32 count = sscanf(buf.c_str(), "%u, %u, %u, %u", v + 0, v + 1, v + 2, v + 3); + if (1 == count) { // try this format - count = sscanf( buf.c_str(), "%u %u %u %u", v + 0, v + 1, v + 2, v + 3 ); + count = sscanf(buf.c_str(), "%u %u %u %u", v + 0, v + 1, v + 2, v + 3); } - if( 4 != count ) + if (4 != count) { return false; } - for( S32 i = 0; i < 4; i++ ) + for (S32 i = 0; i < 4; i++) { - if( v[i] > U8_MAX ) + if (v[i] > U8_MAX) { return false; } } - value->set( U8(v[0]), U8(v[1]), U8(v[2]), U8(v[3]) ); + value->set(U8(v[VRED]), U8(v[VGREEN]), U8(v[VBLUE]), U8(v[VALPHA])); return true; } diff --git a/indra/llmath/v4coloru.h b/indra/llmath/v4coloru.h index e17db7704a..e495fd3eea 100644 --- a/indra/llmath/v4coloru.h +++ b/indra/llmath/v4coloru.h @@ -28,104 +28,93 @@ #define LL_V4COLORU_H #include "llerror.h" -//#include "vmath.h" #include "llmath.h" -//#include "v4color.h" #include "v3color.h" #include "v4color.h" -//class LLColor3U; class LLColor4; // LLColor4U = | red green blue alpha | -static const U32 LENGTHOFCOLOR4U = 4; - +static constexpr U32 LENGTHOFCOLOR4U = 4; class LLColor4U { public: - U8 mV[LENGTHOFCOLOR4U]; - LLColor4U(); // Initializes LLColor4U to (0, 0, 0, 1) - LLColor4U(U8 r, U8 g, U8 b); // Initializes LLColor4U to (r, g, b, 1) - LLColor4U(U8 r, U8 g, U8 b, U8 a); // Initializes LLColor4U to (r. g, b, a) - LLColor4U(const U8 *vec); // Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1) - explicit LLColor4U(const LLSD& sd) - { - setValue(sd); - } + LLColor4U(); // Initializes LLColor4U to (0, 0, 0, 1) + LLColor4U(U8 r, U8 g, U8 b); // Initializes LLColor4U to (r, g, b, 1) + LLColor4U(U8 r, U8 g, U8 b, U8 a); // Initializes LLColor4U to (r. g, b, a) + LLColor4U(const U8* vec); // Initializes LLColor4U to (vec[0]. vec[1], vec[2], 1) + explicit LLColor4U(const LLSD& sd) { setValue(sd); } void setValue(const LLSD& sd) { - mV[0] = sd[0].asInteger(); - mV[1] = sd[1].asInteger(); - mV[2] = sd[2].asInteger(); - mV[3] = sd[3].asInteger(); + mV[VRED] = sd[VRED].asInteger(); + mV[VGREEN] = sd[VGREEN].asInteger(); + mV[VBLUE] = sd[VBLUE].asInteger(); + mV[VALPHA] = sd[VALPHA].asInteger(); } LLSD getValue() const { LLSD ret; - ret[0] = mV[0]; - ret[1] = mV[1]; - ret[2] = mV[2]; - ret[3] = mV[3]; + ret[VRED] = mV[VRED]; + ret[VGREEN] = mV[VGREEN]; + ret[VBLUE] = mV[VBLUE]; + ret[VALPHA] = mV[VALPHA]; return ret; } - const LLColor4U& setToBlack(); // zero LLColor4U to (0, 0, 0, 1) - const LLColor4U& setToWhite(); // zero LLColor4U to (0, 0, 0, 1) + const LLColor4U& setToBlack(); // zero LLColor4U to (0, 0, 0, 1) + const LLColor4U& setToWhite(); // zero LLColor4U to (0, 0, 0, 1) - const LLColor4U& set(U8 r, U8 g, U8 b, U8 a);// Sets LLColor4U to (r, g, b, a) - const LLColor4U& set(U8 r, U8 g, U8 b); // Sets LLColor4U to (r, g, b) (no change in a) - const LLColor4U& set(const LLColor4U &vec); // Sets LLColor4U to vec - const LLColor4U& set(const U8 *vec); // Sets LLColor4U to vec + const LLColor4U& set(U8 r, U8 g, U8 b, U8 a); // Sets LLColor4U to (r, g, b, a) + const LLColor4U& set(U8 r, U8 g, U8 b); // Sets LLColor4U to (r, g, b) (no change in a) + const LLColor4U& set(const LLColor4U& vec); // Sets LLColor4U to vec + const LLColor4U& set(const U8* vec); // Sets LLColor4U to vec - const LLColor4U& setVec(U8 r, U8 g, U8 b, U8 a); // deprecated -- use set() - const LLColor4U& setVec(U8 r, U8 g, U8 b); // deprecated -- use set() - const LLColor4U& setVec(const LLColor4U &vec); // deprecated -- use set() - const LLColor4U& setVec(const U8 *vec); // deprecated -- use set() + const LLColor4U& setVec(U8 r, U8 g, U8 b, U8 a); // deprecated -- use set() + const LLColor4U& setVec(U8 r, U8 g, U8 b); // deprecated -- use set() + const LLColor4U& setVec(const LLColor4U& vec); // deprecated -- use set() + const LLColor4U& setVec(const U8* vec); // deprecated -- use set() - const LLColor4U& setAlpha(U8 a); + const LLColor4U& setAlpha(U8 a); - F32 magVec() const; // deprecated -- use length() - F32 magVecSquared() const; // deprecated -- use lengthSquared() + F32 magVec() const; // deprecated -- use length() + F32 magVecSquared() const; // deprecated -- use lengthSquared() - F32 length() const; // Returns magnitude squared of LLColor4U - F32 lengthSquared() const; // Returns magnitude squared of LLColor4U + F32 length() const; // Returns magnitude squared of LLColor4U + F32 lengthSquared() const; // Returns magnitude squared of LLColor4U - friend std::ostream& operator<<(std::ostream& s, const LLColor4U &a); // Print a - friend LLColor4U operator+(const LLColor4U &a, const LLColor4U &b); // Return vector a + b - friend LLColor4U operator-(const LLColor4U &a, const LLColor4U &b); // Return vector a minus b - friend LLColor4U operator*(const LLColor4U &a, const LLColor4U &b); // Return a * b - friend bool operator==(const LLColor4U &a, const LLColor4U &b); // Return a == b - friend bool operator!=(const LLColor4U &a, const LLColor4U &b); // Return a != b + friend std::ostream& operator<<(std::ostream& s, const LLColor4U& a); // Print a + friend LLColor4U operator+(const LLColor4U& a, const LLColor4U& b); // Return vector a + b + friend LLColor4U operator-(const LLColor4U& a, const LLColor4U& b); // Return vector a minus b + friend LLColor4U operator*(const LLColor4U& a, const LLColor4U& b); // Return a * b + friend bool operator==(const LLColor4U& a, const LLColor4U& b); // Return a == b + friend bool operator!=(const LLColor4U& a, const LLColor4U& b); // Return a != b - friend const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b); // Return vector a + b - friend const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b); // Return vector a minus b - friend const LLColor4U& operator*=(LLColor4U &a, U8 k); // Return rgb times scaler k (no alpha change) - friend const LLColor4U& operator%=(LLColor4U &a, U8 k); // Return alpha times scaler k (no rgb change) + friend const LLColor4U& operator+=(LLColor4U& a, const LLColor4U& b); // Return vector a + b + friend const LLColor4U& operator-=(LLColor4U& a, const LLColor4U& b); // Return vector a minus b + friend const LLColor4U& operator*=(LLColor4U& a, U8 k); // Return rgb times scaler k (no alpha change) + friend const LLColor4U& operator%=(LLColor4U& a, U8 k); // Return alpha times scaler k (no rgb change) - LLColor4U addClampMax(const LLColor4U &color); // Add and clamp the max + LLColor4U addClampMax(const LLColor4U& color); // Add and clamp the max - LLColor4U multAll(const F32 k); // Multiply ALL channels by scalar k + LLColor4U multAll(const F32 k); // Multiply ALL channels by scalar k - inline void setVecScaleClamp(const LLColor3 &color); - inline void setVecScaleClamp(const LLColor4 &color); + inline void setVecScaleClamp(const LLColor3& color); + inline void setVecScaleClamp(const LLColor4& color); static bool parseColor4U(const std::string& buf, LLColor4U* value); // conversion - operator LLColor4() const - { - return LLColor4(*this); - } + operator LLColor4() const { return LLColor4(*this); } - U32 asRGBA() const; - void fromRGBA( U32 aVal ); + U32 asRGBA() const; + void fromRGBA(U32 aVal); static LLColor4U white; static LLColor4U black; @@ -139,102 +128,94 @@ static_assert(std::is_trivially_move_assignable<LLColor4U>::value, "LLColor4U mu static_assert(std::is_standard_layout<LLColor4U>::value, "LLColor4U must be a standard layout type"); // Non-member functions -F32 distVec(const LLColor4U &a, const LLColor4U &b); // Returns distance between a and b -F32 distVec_squared(const LLColor4U &a, const LLColor4U &b); // Returns distance squared between a and b - +F32 distVec(const LLColor4U& a, const LLColor4U& b); // Returns distance between a and b +F32 distVec_squared(const LLColor4U& a, const LLColor4U& b); // Returns distance squared between a and b inline LLColor4U::LLColor4U() { - mV[VRED] = 0; + mV[VRED] = 0; mV[VGREEN] = 0; - mV[VBLUE] = 0; + mV[VBLUE] = 0; mV[VALPHA] = 255; } inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b) { - mV[VRED] = r; + mV[VRED] = r; mV[VGREEN] = g; - mV[VBLUE] = b; + mV[VBLUE] = b; mV[VALPHA] = 255; } inline LLColor4U::LLColor4U(U8 r, U8 g, U8 b, U8 a) { - mV[VRED] = r; + mV[VRED] = r; mV[VGREEN] = g; - mV[VBLUE] = b; + mV[VBLUE] = b; mV[VALPHA] = a; } -inline LLColor4U::LLColor4U(const U8 *vec) +inline LLColor4U::LLColor4U(const U8* vec) { - mV[VRED] = vec[VRED]; + mV[VRED] = vec[VRED]; mV[VGREEN] = vec[VGREEN]; - mV[VBLUE] = vec[VBLUE]; + mV[VBLUE] = vec[VBLUE]; mV[VALPHA] = vec[VALPHA]; } -/* -inline LLColor4U::operator LLColor4() -{ - return(LLColor4((F32)mV[VRED]/255.f,(F32)mV[VGREEN]/255.f,(F32)mV[VBLUE]/255.f,(F32)mV[VALPHA]/255.f)); -} -*/ - inline const LLColor4U& LLColor4U::setToBlack(void) { - mV[VRED] = 0; + mV[VRED] = 0; mV[VGREEN] = 0; - mV[VBLUE] = 0; + mV[VBLUE] = 0; mV[VALPHA] = 255; return (*this); } inline const LLColor4U& LLColor4U::setToWhite(void) { - mV[VRED] = 255; + mV[VRED] = 255; mV[VGREEN] = 255; - mV[VBLUE] = 255; + mV[VBLUE] = 255; mV[VALPHA] = 255; return (*this); } inline const LLColor4U& LLColor4U::set(const U8 x, const U8 y, const U8 z) { - mV[VRED] = x; + mV[VRED] = x; mV[VGREEN] = y; - mV[VBLUE] = z; + mV[VBLUE] = z; -// no change to alpha! -// mV[VALPHA] = 255; + // no change to alpha! + // mV[VALPHA] = 255; return (*this); } inline const LLColor4U& LLColor4U::set(const U8 r, const U8 g, const U8 b, U8 a) { - mV[0] = r; - mV[1] = g; - mV[2] = b; - mV[3] = a; + mV[VRED] = r; + mV[VGREEN] = g; + mV[VBLUE] = b; + mV[VALPHA] = a; return (*this); } -inline const LLColor4U& LLColor4U::set(const LLColor4U &vec) +inline const LLColor4U& LLColor4U::set(const LLColor4U& vec) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; mV[VALPHA] = vec.mV[VALPHA]; return (*this); } -inline const LLColor4U& LLColor4U::set(const U8 *vec) +inline const LLColor4U& LLColor4U::set(const U8* vec) { - mV[VRED] = vec[VRED]; + mV[VRED] = vec[VRED]; mV[VGREEN] = vec[VGREEN]; - mV[VBLUE] = vec[VBLUE]; + mV[VBLUE] = vec[VBLUE]; mV[VALPHA] = vec[VALPHA]; return (*this); } @@ -242,12 +223,12 @@ inline const LLColor4U& LLColor4U::set(const U8 *vec) // deprecated inline const LLColor4U& LLColor4U::setVec(const U8 x, const U8 y, const U8 z) { - mV[VRED] = x; + mV[VRED] = x; mV[VGREEN] = y; - mV[VBLUE] = z; + mV[VBLUE] = z; -// no change to alpha! -// mV[VALPHA] = 255; + // no change to alpha! + // mV[VALPHA] = 255; return (*this); } @@ -255,29 +236,29 @@ inline const LLColor4U& LLColor4U::setVec(const U8 x, const U8 y, const U8 z) // deprecated inline const LLColor4U& LLColor4U::setVec(const U8 r, const U8 g, const U8 b, U8 a) { - mV[0] = r; - mV[1] = g; - mV[2] = b; - mV[3] = a; + mV[VRED] = r; + mV[VGREEN] = g; + mV[VBLUE] = b; + mV[VALPHA] = a; return (*this); } // deprecated -inline const LLColor4U& LLColor4U::setVec(const LLColor4U &vec) +inline const LLColor4U& LLColor4U::setVec(const LLColor4U& vec) { - mV[VRED] = vec.mV[VRED]; + mV[VRED] = vec.mV[VRED]; mV[VGREEN] = vec.mV[VGREEN]; - mV[VBLUE] = vec.mV[VBLUE]; + mV[VBLUE] = vec.mV[VBLUE]; mV[VALPHA] = vec.mV[VALPHA]; return (*this); } // deprecated -inline const LLColor4U& LLColor4U::setVec(const U8 *vec) +inline const LLColor4U& LLColor4U::setVec(const U8* vec) { - mV[VRED] = vec[VRED]; + mV[VRED] = vec[VRED]; mV[VGREEN] = vec[VGREEN]; - mV[VBLUE] = vec[VBLUE]; + mV[VBLUE] = vec[VBLUE]; mV[VALPHA] = vec[VALPHA]; return (*this); } @@ -290,131 +271,68 @@ inline const LLColor4U& LLColor4U::setAlpha(U8 a) // LLColor4U Magnitude and Normalization Functions -inline F32 LLColor4U::length(void) const +inline F32 LLColor4U::length() const { - return (F32) sqrt( ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE] ); + return sqrt(((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE]); } -inline F32 LLColor4U::lengthSquared(void) const +inline F32 LLColor4U::lengthSquared() const { return ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE]; } // deprecated -inline F32 LLColor4U::magVec(void) const +inline F32 LLColor4U::magVec() const { - return (F32) sqrt( ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE] ); + return sqrt(((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE]); } // deprecated -inline F32 LLColor4U::magVecSquared(void) const +inline F32 LLColor4U::magVecSquared() const { return ((F32)mV[VRED]) * mV[VRED] + ((F32)mV[VGREEN]) * mV[VGREEN] + ((F32)mV[VBLUE]) * mV[VBLUE]; } -inline LLColor4U operator+(const LLColor4U &a, const LLColor4U &b) +inline LLColor4U operator+(const LLColor4U& a, const LLColor4U& b) { - return LLColor4U( - a.mV[VRED] + b.mV[VRED], - a.mV[VGREEN] + b.mV[VGREEN], - a.mV[VBLUE] + b.mV[VBLUE], - a.mV[VALPHA] + b.mV[VALPHA]); + return LLColor4U(a.mV[VRED] + b.mV[VRED], a.mV[VGREEN] + b.mV[VGREEN], a.mV[VBLUE] + b.mV[VBLUE], a.mV[VALPHA] + b.mV[VALPHA]); } -inline LLColor4U operator-(const LLColor4U &a, const LLColor4U &b) +inline LLColor4U operator-(const LLColor4U& a, const LLColor4U& b) { - return LLColor4U( - a.mV[VRED] - b.mV[VRED], - a.mV[VGREEN] - b.mV[VGREEN], - a.mV[VBLUE] - b.mV[VBLUE], - a.mV[VALPHA] - b.mV[VALPHA]); + return LLColor4U(a.mV[VRED] - b.mV[VRED], a.mV[VGREEN] - b.mV[VGREEN], a.mV[VBLUE] - b.mV[VBLUE], a.mV[VALPHA] - b.mV[VALPHA]); } -inline LLColor4U operator*(const LLColor4U &a, const LLColor4U &b) +inline LLColor4U operator*(const LLColor4U& a, const LLColor4U& b) { - return LLColor4U( - a.mV[VRED] * b.mV[VRED], - a.mV[VGREEN] * b.mV[VGREEN], - a.mV[VBLUE] * b.mV[VBLUE], - a.mV[VALPHA] * b.mV[VALPHA]); + return LLColor4U(a.mV[VRED] * b.mV[VRED], a.mV[VGREEN] * b.mV[VGREEN], a.mV[VBLUE] * b.mV[VBLUE], a.mV[VALPHA] * b.mV[VALPHA]); } -inline LLColor4U LLColor4U::addClampMax(const LLColor4U &color) +inline LLColor4U LLColor4U::addClampMax(const LLColor4U& color) { return LLColor4U(llmin((S32)mV[VRED] + color.mV[VRED], 255), - llmin((S32)mV[VGREEN] + color.mV[VGREEN], 255), - llmin((S32)mV[VBLUE] + color.mV[VBLUE], 255), - llmin((S32)mV[VALPHA] + color.mV[VALPHA], 255)); + llmin((S32)mV[VGREEN] + color.mV[VGREEN], 255), + llmin((S32)mV[VBLUE] + color.mV[VBLUE], 255), + llmin((S32)mV[VALPHA] + color.mV[VALPHA], 255)); } inline LLColor4U LLColor4U::multAll(const F32 k) { // Round to nearest - return LLColor4U( - (U8)ll_round(mV[VRED] * k), - (U8)ll_round(mV[VGREEN] * k), - (U8)ll_round(mV[VBLUE] * k), - (U8)ll_round(mV[VALPHA] * k)); -} -/* -inline LLColor4U operator*(const LLColor4U &a, U8 k) -{ - // only affects rgb (not a!) - return LLColor4U( - a.mV[VRED] * k, - a.mV[VGREEN] * k, - a.mV[VBLUE] * k, - a.mV[VALPHA]); -} - -inline LLColor4U operator*(U8 k, const LLColor4U &a) -{ - // only affects rgb (not a!) - return LLColor4U( - a.mV[VRED] * k, - a.mV[VGREEN] * k, - a.mV[VBLUE] * k, - a.mV[VALPHA]); -} - -inline LLColor4U operator%(U8 k, const LLColor4U &a) -{ - // only affects alpha (not rgb!) - return LLColor4U( - a.mV[VRED], - a.mV[VGREEN], - a.mV[VBLUE], - a.mV[VALPHA] * k ); + return LLColor4U((U8)ll_round(mV[VRED] * k), (U8)ll_round(mV[VGREEN] * k), (U8)ll_round(mV[VBLUE] * k), (U8)ll_round(mV[VALPHA] * k)); } -inline LLColor4U operator%(const LLColor4U &a, U8 k) +inline bool operator==(const LLColor4U& a, const LLColor4U& b) { - // only affects alpha (not rgb!) - return LLColor4U( - a.mV[VRED], - a.mV[VGREEN], - a.mV[VBLUE], - a.mV[VALPHA] * k ); -} -*/ - -inline bool operator==(const LLColor4U &a, const LLColor4U &b) -{ - return ( (a.mV[VRED] == b.mV[VRED]) - &&(a.mV[VGREEN] == b.mV[VGREEN]) - &&(a.mV[VBLUE] == b.mV[VBLUE]) - &&(a.mV[VALPHA] == b.mV[VALPHA])); + return ((a.mV[VRED] == b.mV[VRED]) && (a.mV[VGREEN] == b.mV[VGREEN]) && (a.mV[VBLUE] == b.mV[VBLUE]) && (a.mV[VALPHA] == b.mV[VALPHA])); } -inline bool operator!=(const LLColor4U &a, const LLColor4U &b) +inline bool operator!=(const LLColor4U& a, const LLColor4U& b) { - return ( (a.mV[VRED] != b.mV[VRED]) - ||(a.mV[VGREEN] != b.mV[VGREEN]) - ||(a.mV[VBLUE] != b.mV[VBLUE]) - ||(a.mV[VALPHA] != b.mV[VALPHA])); + return ((a.mV[VRED] != b.mV[VRED]) || (a.mV[VGREEN] != b.mV[VGREEN]) || (a.mV[VBLUE] != b.mV[VBLUE]) || (a.mV[VALPHA] != b.mV[VALPHA])); } -inline const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b) +inline const LLColor4U& operator+=(LLColor4U& a, const LLColor4U& b) { a.mV[VRED] += b.mV[VRED]; a.mV[VGREEN] += b.mV[VGREEN]; @@ -423,7 +341,7 @@ inline const LLColor4U& operator+=(LLColor4U &a, const LLColor4U &b) return a; } -inline const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b) +inline const LLColor4U& operator-=(LLColor4U& a, const LLColor4U& b) { a.mV[VRED] -= b.mV[VRED]; a.mV[VGREEN] -= b.mV[VGREEN]; @@ -432,7 +350,7 @@ inline const LLColor4U& operator-=(LLColor4U &a, const LLColor4U &b) return a; } -inline const LLColor4U& operator*=(LLColor4U &a, U8 k) +inline const LLColor4U& operator*=(LLColor4U& a, U8 k) { // only affects rgb (not a!) a.mV[VRED] *= k; @@ -441,20 +359,20 @@ inline const LLColor4U& operator*=(LLColor4U &a, U8 k) return a; } -inline const LLColor4U& operator%=(LLColor4U &a, U8 k) +inline const LLColor4U& operator%=(LLColor4U& a, U8 k) { // only affects alpha (not rgb!) a.mV[VALPHA] *= k; return a; } -inline F32 distVec(const LLColor4U &a, const LLColor4U &b) +inline F32 distVec(const LLColor4U& a, const LLColor4U& b) { LLColor4U vec = a - b; return (vec.length()); } -inline F32 distVec_squared(const LLColor4U &a, const LLColor4U &b) +inline F32 distVec_squared(const LLColor4U& a, const LLColor4U& b) { LLColor4U vec = a - b; return (vec.lengthSquared()); @@ -463,13 +381,13 @@ inline F32 distVec_squared(const LLColor4U &a, const LLColor4U &b) void LLColor4U::setVecScaleClamp(const LLColor4& color) { F32 color_scale_factor = 255.f; - F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); + F32 max_color = llmax(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); if (max_color > 1.f) { color_scale_factor /= max_color; } - const S32 MAX_COLOR = 255; - S32 r = ll_round(color.mV[0] * color_scale_factor); + constexpr S32 MAX_COLOR = 255; + S32 r = ll_round(color.mV[VRED] * color_scale_factor); if (r > MAX_COLOR) { r = MAX_COLOR; @@ -478,9 +396,9 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color) { r = 0; } - mV[0] = r; + mV[VRED] = r; - S32 g = ll_round(color.mV[1] * color_scale_factor); + S32 g = ll_round(color.mV[VGREEN] * color_scale_factor); if (g > MAX_COLOR) { g = MAX_COLOR; @@ -489,9 +407,9 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color) { g = 0; } - mV[1] = g; + mV[VGREEN] = g; - S32 b = ll_round(color.mV[2] * color_scale_factor); + S32 b = ll_round(color.mV[VBLUE] * color_scale_factor); if (b > MAX_COLOR) { b = MAX_COLOR; @@ -500,10 +418,10 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color) { b = 0; } - mV[2] = b; + mV[VBLUE] = b; // Alpha shouldn't be scaled, just clamped... - S32 a = ll_round(color.mV[3] * MAX_COLOR); + S32 a = ll_round(color.mV[VALPHA] * MAX_COLOR); if (a > MAX_COLOR) { a = MAX_COLOR; @@ -512,44 +430,42 @@ void LLColor4U::setVecScaleClamp(const LLColor4& color) { a = 0; } - mV[3] = a; + mV[VALPHA] = a; } void LLColor4U::setVecScaleClamp(const LLColor3& color) { F32 color_scale_factor = 255.f; - F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); + F32 max_color = llmax(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); if (max_color > 1.f) { color_scale_factor /= max_color; } const S32 MAX_COLOR = 255; - S32 r = ll_round(color.mV[0] * color_scale_factor); + S32 r = ll_round(color.mV[VRED] * color_scale_factor); if (r > MAX_COLOR) { r = MAX_COLOR; } - else - if (r < 0) + else if (r < 0) { r = 0; } - mV[0] = r; + mV[VRED] = r; - S32 g = ll_round(color.mV[1] * color_scale_factor); + S32 g = ll_round(color.mV[VGREEN] * color_scale_factor); if (g > MAX_COLOR) { g = MAX_COLOR; } - else - if (g < 0) + else if (g < 0) { g = 0; } - mV[1] = g; + mV[VGREEN] = g; - S32 b = ll_round(color.mV[2] * color_scale_factor); + S32 b = ll_round(color.mV[VBLUE] * color_scale_factor); if (b > MAX_COLOR) { b = MAX_COLOR; @@ -558,31 +474,29 @@ void LLColor4U::setVecScaleClamp(const LLColor3& color) { b = 0; } - mV[2] = b; + mV[VBLUE] = b; - mV[3] = 255; + mV[VALPHA] = 255; } inline U32 LLColor4U::asRGBA() const { // Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here - return (mV[3] << 24) | (mV[2] << 16) | (mV[1] << 8) | mV[0]; + return (mV[VALPHA] << 24) | (mV[VBLUE] << 16) | (mV[VGREEN] << 8) | mV[VRED]; } -inline void LLColor4U::fromRGBA( U32 aVal ) +inline void LLColor4U::fromRGBA(U32 aVal) { // Little endian: values are swapped in memory. The original code access the array like a U32, so we need to swap here - mV[ 0 ] = aVal & 0xFF; + mV[VRED] = aVal & 0xFF; aVal >>= 8; - mV[ 1 ] = aVal & 0xFF; + mV[VGREEN] = aVal & 0xFF; aVal >>= 8; - mV[ 2 ] = aVal & 0xFF; + mV[VBLUE] = aVal & 0xFF; aVal >>= 8; - mV[ 3 ] = aVal & 0xFF; + mV[VALPHA] = aVal & 0xFF; } - #endif - diff --git a/indra/llmath/v4math.cpp b/indra/llmath/v4math.cpp index 0aa6eb09c3..cd475380d6 100644 --- a/indra/llmath/v4math.cpp +++ b/indra/llmath/v4math.cpp @@ -26,7 +26,6 @@ #include "linden_common.h" -//#include "vmath.h" #include "v3math.h" #include "v4math.h" #include "m4math.h" @@ -36,13 +35,13 @@ // LLVector4 // Axis-Angle rotations -const LLVector4& LLVector4::rotVec(const LLMatrix4 &mat) +const LLVector4& LLVector4::rotVec(const LLMatrix4& mat) { *this = *this * mat; return *this; } -const LLVector4& LLVector4::rotVec(const LLQuaternion &q) +const LLVector4& LLVector4::rotVec(const LLQuaternion& q) { *this = *this * q; return *this; @@ -64,16 +63,16 @@ bool LLVector4::abs() { bool ret{ false }; - if (mV[0] < 0.f) { mV[0] = -mV[0]; ret = true; } - if (mV[1] < 0.f) { mV[1] = -mV[1]; ret = true; } - if (mV[2] < 0.f) { mV[2] = -mV[2]; ret = true; } - if (mV[3] < 0.f) { mV[3] = -mV[3]; ret = true; } + if (mV[VX] < 0.f) { mV[VX] = -mV[VX]; ret = true; } + if (mV[VY] < 0.f) { mV[VY] = -mV[VY]; ret = true; } + if (mV[VZ] < 0.f) { mV[VZ] = -mV[VZ]; ret = true; } + if (mV[VW] < 0.f) { mV[VW] = -mV[VW]; ret = true; } return ret; } -std::ostream& operator<<(std::ostream& s, const LLVector4 &a) +std::ostream& operator<<(std::ostream& s, const LLVector4& a) { s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << ", " << a.mV[VW] << " }"; return s; @@ -108,12 +107,12 @@ bool are_parallel(const LLVector4 &a, const LLVector4 &b, F32 epsilon) } -LLVector3 vec4to3(const LLVector4 &vec) +LLVector3 vec4to3(const LLVector4& vec) { return LLVector3( vec.mV[VX], vec.mV[VY], vec.mV[VZ] ); } -LLVector4 vec3to4(const LLVector3 &vec) +LLVector4 vec3to4(const LLVector3& vec) { return LLVector4(vec.mV[VX], vec.mV[VY], vec.mV[VZ]); } diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h index f5b79759b0..edfc2f8592 100644 --- a/indra/llmath/v4math.h +++ b/indra/llmath/v4math.h @@ -42,108 +42,108 @@ class LLQuaternion; // LLVector4 = |x y z w| -static const U32 LENGTHOFVECTOR4 = 4; +static constexpr U32 LENGTHOFVECTOR4 = 4; class LLVector4 { - public: - F32 mV[LENGTHOFVECTOR4]; - LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1) - explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3]) - explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]); - explicit LLVector4(const LLVector2 &vec); - explicit LLVector4(const LLVector2 &vec, F32 z, F32 w); - explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1) - explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w) - explicit LLVector4(const LLSD &sd); - LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1) - LLVector4(F32 x, F32 y, F32 z, F32 w); - - LLSD getValue() const - { - LLSD ret; - ret[0] = mV[0]; - ret[1] = mV[1]; - ret[2] = mV[2]; - ret[3] = mV[3]; - return ret; - } - - void setValue(const LLSD& sd) - { - mV[0] = (F32)sd[0].asReal(); - mV[1] = (F32)sd[1].asReal(); - mV[2] = (F32)sd[2].asReal(); - mV[3] = (F32)sd[3].asReal(); - } - - // GLM interop - explicit LLVector4(const glm::vec3& vec); // Initializes LLVector4 to (vec, 1) - explicit LLVector4(const glm::vec4& vec); // Initializes LLVector4 to vec - explicit operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2]) - explicit operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], vec[3]) - - inline bool isFinite() const; // checks to see if all values of LLVector3 are finite - - inline void clear(); // Clears LLVector4 to (0, 0, 0, 1) - inline void clearVec(); // deprecated - inline void zeroVec(); // deprecated - - inline void set(F32 x, F32 y, F32 z); // Sets LLVector4 to (x, y, z, 1) - inline void set(F32 x, F32 y, F32 z, F32 w); // Sets LLVector4 to (x, y, z, w) - inline void set(const LLVector4 &vec); // Sets LLVector4 to vec - inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec - inline void set(const F32 *vec); // Sets LLVector4 to vec - inline void set(const glm::vec4& vec); // Sets LLVector4 to vec - inline void set(const glm::vec3& vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec with w defaulted to 1 - - inline void setVec(F32 x, F32 y, F32 z); // deprecated - inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated - inline void setVec(const LLVector4 &vec); // deprecated - inline void setVec(const LLVector3 &vec, F32 w = 1.f); // deprecated - inline void setVec(const F32 *vec); // deprecated - - F32 length() const; // Returns magnitude of LLVector4 - F32 lengthSquared() const; // Returns magnitude squared of LLVector4 - F32 normalize(); // Normalizes and returns the magnitude of LLVector4 - - F32 magVec() const; // deprecated - F32 magVecSquared() const; // deprecated - F32 normVec(); // deprecated - - // Sets all values to absolute value of their original values - // Returns true if data changed - bool abs(); - - bool isExactlyClear() const { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; } - bool isExactlyZero() const { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; } - - const LLVector4& rotVec(const LLMatrix4 &mat); // Rotates by MAT4 mat - const LLVector4& rotVec(const LLQuaternion &q); // Rotates by QUAT q - - const LLVector4& scaleVec(const LLVector4& vec); // Scales component-wise by vec - - F32 operator[](int idx) const { return mV[idx]; } - F32 &operator[](int idx) { return mV[idx]; } - - friend std::ostream& operator<<(std::ostream& s, const LLVector4 &a); // Print a - friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b); // Return vector a + b - friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b); // Return vector a minus b - friend F32 operator*(const LLVector4 &a, const LLVector4 &b); // Return a dot b - friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b); // Return a cross b - friend LLVector4 operator/(const LLVector4 &a, F32 k); // Return a divided by scaler k - friend LLVector4 operator*(const LLVector4 &a, F32 k); // Return a times scaler k - friend LLVector4 operator*(F32 k, const LLVector4 &a); // Return a times scaler k - friend bool operator==(const LLVector4 &a, const LLVector4 &b); // Return a == b - friend bool operator!=(const LLVector4 &a, const LLVector4 &b); // Return a != b - - friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b); // Return vector a + b - friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b); // Return vector a minus b - friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b); // Return a cross b - friend const LLVector4& operator*=(LLVector4 &a, F32 k); // Return a times scaler k - friend const LLVector4& operator/=(LLVector4 &a, F32 k); // Return a divided by scaler k - - friend LLVector4 operator-(const LLVector4 &a); // Return vector -a +public: + F32 mV[LENGTHOFVECTOR4]; + LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1) + explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3]) + explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]); + explicit LLVector4(const LLVector2 &vec); + explicit LLVector4(const LLVector2 &vec, F32 z, F32 w); + explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1) + explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w) + explicit LLVector4(const LLSD &sd); + LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1) + LLVector4(F32 x, F32 y, F32 z, F32 w); + + LLSD getValue() const + { + LLSD ret; + ret[VX] = mV[VX]; + ret[VY] = mV[VY]; + ret[VZ] = mV[VZ]; + ret[VW] = mV[VW]; + return ret; + } + + void setValue(const LLSD& sd) + { + mV[VX] = (F32)sd[VX].asReal(); + mV[VY] = (F32)sd[VY].asReal(); + mV[VZ] = (F32)sd[VZ].asReal(); + mV[VW] = (F32)sd[VW].asReal(); + } + + // GLM interop + explicit LLVector4(const glm::vec3& vec); // Initializes LLVector4 to (vec, 1) + explicit LLVector4(const glm::vec4& vec); // Initializes LLVector4 to vec + explicit operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2]) + explicit operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], vec[3]) + + inline bool isFinite() const; // checks to see if all values of LLVector3 are finite + + inline void clear(); // Clears LLVector4 to (0, 0, 0, 1) + inline void clearVec(); // deprecated + inline void zeroVec(); // deprecated + + inline void set(F32 x, F32 y, F32 z); // Sets LLVector4 to (x, y, z, 1) + inline void set(F32 x, F32 y, F32 z, F32 w); // Sets LLVector4 to (x, y, z, w) + inline void set(const LLVector4 &vec); // Sets LLVector4 to vec + inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec + inline void set(const F32 *vec); // Sets LLVector4 to vec + inline void set(const glm::vec4& vec); // Sets LLVector4 to vec + inline void set(const glm::vec3& vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec with w defaulted to 1 + + inline void setVec(F32 x, F32 y, F32 z); // deprecated + inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated + inline void setVec(const LLVector4 &vec); // deprecated + inline void setVec(const LLVector3 &vec, F32 w = 1.f); // deprecated + inline void setVec(const F32 *vec); // deprecated + + F32 length() const; // Returns magnitude of LLVector4 + F32 lengthSquared() const; // Returns magnitude squared of LLVector4 + F32 normalize(); // Normalizes and returns the magnitude of LLVector4 + + F32 magVec() const; // deprecated + F32 magVecSquared() const; // deprecated + F32 normVec(); // deprecated + + // Sets all values to absolute value of their original values + // Returns true if data changed + bool abs(); + + bool isExactlyClear() const { return (mV[VW] == 1.0f) && !mV[VX] && !mV[VY] && !mV[VZ]; } + bool isExactlyZero() const { return !mV[VW] && !mV[VX] && !mV[VY] && !mV[VZ]; } + + const LLVector4& rotVec(const LLMatrix4 &mat); // Rotates by MAT4 mat + const LLVector4& rotVec(const LLQuaternion &q); // Rotates by QUAT q + + const LLVector4& scaleVec(const LLVector4& vec); // Scales component-wise by vec + + F32 operator[](int idx) const { return mV[idx]; } + F32 &operator[](int idx) { return mV[idx]; } + + friend std::ostream& operator<<(std::ostream& s, const LLVector4 &a); // Print a + friend LLVector4 operator+(const LLVector4 &a, const LLVector4 &b); // Return vector a + b + friend LLVector4 operator-(const LLVector4 &a, const LLVector4 &b); // Return vector a minus b + friend F32 operator*(const LLVector4 &a, const LLVector4 &b); // Return a dot b + friend LLVector4 operator%(const LLVector4 &a, const LLVector4 &b); // Return a cross b + friend LLVector4 operator/(const LLVector4 &a, F32 k); // Return a divided by scaler k + friend LLVector4 operator*(const LLVector4 &a, F32 k); // Return a times scaler k + friend LLVector4 operator*(F32 k, const LLVector4 &a); // Return a times scaler k + friend bool operator==(const LLVector4 &a, const LLVector4 &b); // Return a == b + friend bool operator!=(const LLVector4 &a, const LLVector4 &b); // Return a != b + + friend const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b); // Return vector a + b + friend const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b); // Return vector a minus b + friend const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b); // Return a cross b + friend const LLVector4& operator*=(LLVector4 &a, F32 k); // Return a times scaler k + friend const LLVector4& operator/=(LLVector4 &a, F32 k); // Return a divided by scaler k + + friend LLVector4 operator-(const LLVector4 &a); // Return vector -a }; static_assert(std::is_trivially_copyable<LLVector4>::value, "LLVector4 must be trivial copy"); @@ -163,34 +163,22 @@ LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u); // Returns a vect inline LLVector4::LLVector4(void) { - mV[VX] = 0.f; - mV[VY] = 0.f; - mV[VZ] = 0.f; - mV[VW] = 1.f; + clear(); } inline LLVector4::LLVector4(F32 x, F32 y, F32 z) { - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; - mV[VW] = 1.f; + set(x, y, z, 1.f); } inline LLVector4::LLVector4(F32 x, F32 y, F32 z, F32 w) { - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; - mV[VW] = w; + set(x, y, z, w); } inline LLVector4::LLVector4(const F32 *vec) { - mV[VX] = vec[VX]; - mV[VY] = vec[VY]; - mV[VZ] = vec[VZ]; - mV[VW] = vec[VW]; + set(vec); } inline LLVector4::LLVector4(const F64 *vec) @@ -219,18 +207,12 @@ inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w) inline LLVector4::LLVector4(const LLVector3 &vec) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; - mV[VZ] = vec.mV[VZ]; - mV[VW] = 1.f; + set(vec, 1.f); } inline LLVector4::LLVector4(const LLVector3 &vec, F32 w) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; - mV[VZ] = vec.mV[VZ]; - mV[VW] = w; + set(vec, w); } inline LLVector4::LLVector4(const LLSD &sd) @@ -256,43 +238,31 @@ inline LLVector4::LLVector4(const glm::vec4& vec) inline bool LLVector4::isFinite() const { - return (llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW])); + return llfinite(mV[VX]) && llfinite(mV[VY]) && llfinite(mV[VZ]) && llfinite(mV[VW]); } // Clear and Assignment Functions -inline void LLVector4::clear(void) +inline void LLVector4::clear() { - mV[VX] = 0.f; - mV[VY] = 0.f; - mV[VZ] = 0.f; - mV[VW] = 1.f; + set(0.f, 0.f, 0.f, 1.f); } // deprecated -inline void LLVector4::clearVec(void) +inline void LLVector4::clearVec() { - mV[VX] = 0.f; - mV[VY] = 0.f; - mV[VZ] = 0.f; - mV[VW] = 1.f; + clear(); } // deprecated -inline void LLVector4::zeroVec(void) +inline void LLVector4::zeroVec() { - mV[VX] = 0.f; - mV[VY] = 0.f; - mV[VZ] = 0.f; - mV[VW] = 0.f; + set(0.f, 0.f, 0.f, 0.f); } inline void LLVector4::set(F32 x, F32 y, F32 z) { - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; - mV[VW] = 1.f; + set(x, y, z, 1.f); } inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w) @@ -303,15 +273,12 @@ inline void LLVector4::set(F32 x, F32 y, F32 z, F32 w) mV[VW] = w; } -inline void LLVector4::set(const LLVector4 &vec) +inline void LLVector4::set(const LLVector4& vec) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; - mV[VZ] = vec.mV[VZ]; - mV[VW] = vec.mV[VW]; + set(vec.mV); } -inline void LLVector4::set(const LLVector3 &vec, F32 w) +inline void LLVector4::set(const LLVector3& vec, F32 w) { mV[VX] = vec.mV[VX]; mV[VY] = vec.mV[VY]; @@ -319,14 +286,13 @@ inline void LLVector4::set(const LLVector3 &vec, F32 w) mV[VW] = w; } -inline void LLVector4::set(const F32 *vec) +inline void LLVector4::set(const F32* vec) { mV[VX] = vec[VX]; mV[VY] = vec[VY]; mV[VZ] = vec[VZ]; mV[VW] = vec[VW]; } - inline void LLVector4::set(const glm::vec4& vec) { mV[VX] = vec.x; @@ -346,119 +312,104 @@ inline void LLVector4::set(const glm::vec3& vec, F32 w) // deprecated inline void LLVector4::setVec(F32 x, F32 y, F32 z) { - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; - mV[VW] = 1.f; + set(x, y, z); } // deprecated inline void LLVector4::setVec(F32 x, F32 y, F32 z, F32 w) { - mV[VX] = x; - mV[VY] = y; - mV[VZ] = z; - mV[VW] = w; + set(x, y, z, w); } // deprecated -inline void LLVector4::setVec(const LLVector4 &vec) +inline void LLVector4::setVec(const LLVector4& vec) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; - mV[VZ] = vec.mV[VZ]; - mV[VW] = vec.mV[VW]; + set(vec); } // deprecated -inline void LLVector4::setVec(const LLVector3 &vec, F32 w) +inline void LLVector4::setVec(const LLVector3& vec, F32 w) { - mV[VX] = vec.mV[VX]; - mV[VY] = vec.mV[VY]; - mV[VZ] = vec.mV[VZ]; - mV[VW] = w; + set(vec, w); } // deprecated -inline void LLVector4::setVec(const F32 *vec) +inline void LLVector4::setVec(const F32* vec) { - mV[VX] = vec[VX]; - mV[VY] = vec[VY]; - mV[VZ] = vec[VZ]; - mV[VW] = vec[VW]; + set(vec); } // LLVector4 Magnitude and Normalization Functions -inline F32 LLVector4::length(void) const +inline F32 LLVector4::length() const { - return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); + return sqrt(lengthSquared()); } -inline F32 LLVector4::lengthSquared(void) const +inline F32 LLVector4::lengthSquared() const { return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; } -inline F32 LLVector4::magVec(void) const +inline F32 LLVector4::magVec() const { - return (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); + return length(); } -inline F32 LLVector4::magVecSquared(void) const +inline F32 LLVector4::magVecSquared() const { - return mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]; + return lengthSquared(); } // LLVector4 Operators -inline LLVector4 operator+(const LLVector4 &a, const LLVector4 &b) +inline LLVector4 operator+(const LLVector4& a, const LLVector4& b) { LLVector4 c(a); return c += b; } -inline LLVector4 operator-(const LLVector4 &a, const LLVector4 &b) +inline LLVector4 operator-(const LLVector4& a, const LLVector4& b) { LLVector4 c(a); return c -= b; } -inline F32 operator*(const LLVector4 &a, const LLVector4 &b) +inline F32 operator*(const LLVector4& a, const LLVector4& b) { - return (a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]); + return a.mV[VX]*b.mV[VX] + a.mV[VY]*b.mV[VY] + a.mV[VZ]*b.mV[VZ]; } -inline LLVector4 operator%(const LLVector4 &a, const LLVector4 &b) +inline LLVector4 operator%(const LLVector4& a, const LLVector4& b) { return LLVector4(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]); } -inline LLVector4 operator/(const LLVector4 &a, F32 k) +inline LLVector4 operator/(const LLVector4& a, F32 k) { F32 t = 1.f / k; return LLVector4( a.mV[VX] * t, a.mV[VY] * t, a.mV[VZ] * t ); } -inline LLVector4 operator*(const LLVector4 &a, F32 k) +inline LLVector4 operator*(const LLVector4& a, F32 k) { return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k ); } -inline LLVector4 operator*(F32 k, const LLVector4 &a) +inline LLVector4 operator*(F32 k, const LLVector4& a) { return LLVector4( a.mV[VX] * k, a.mV[VY] * k, a.mV[VZ] * k ); } -inline bool operator==(const LLVector4 &a, const LLVector4 &b) +inline bool operator==(const LLVector4& a, const LLVector4& b) { return ( (a.mV[VX] == b.mV[VX]) &&(a.mV[VY] == b.mV[VY]) &&(a.mV[VZ] == b.mV[VZ])); } -inline bool operator!=(const LLVector4 &a, const LLVector4 &b) +inline bool operator!=(const LLVector4& a, const LLVector4& b) { return ( (a.mV[VX] != b.mV[VX]) ||(a.mV[VY] != b.mV[VY]) @@ -466,7 +417,7 @@ inline bool operator!=(const LLVector4 &a, const LLVector4 &b) ||(a.mV[VW] != b.mV[VW]) ); } -inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b) +inline const LLVector4& operator+=(LLVector4& a, const LLVector4& b) { a.mV[VX] += b.mV[VX]; a.mV[VY] += b.mV[VY]; @@ -474,7 +425,7 @@ inline const LLVector4& operator+=(LLVector4 &a, const LLVector4 &b) return a; } -inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b) +inline const LLVector4& operator-=(LLVector4& a, const LLVector4& b) { a.mV[VX] -= b.mV[VX]; a.mV[VY] -= b.mV[VY]; @@ -482,14 +433,14 @@ inline const LLVector4& operator-=(LLVector4 &a, const LLVector4 &b) return a; } -inline const LLVector4& operator%=(LLVector4 &a, const LLVector4 &b) +inline const LLVector4& operator%=(LLVector4& a, const LLVector4& b) { LLVector4 ret(a.mV[VY]*b.mV[VZ] - b.mV[VY]*a.mV[VZ], a.mV[VZ]*b.mV[VX] - b.mV[VZ]*a.mV[VX], a.mV[VX]*b.mV[VY] - b.mV[VX]*a.mV[VY]); a = ret; return a; } -inline const LLVector4& operator*=(LLVector4 &a, F32 k) +inline const LLVector4& operator*=(LLVector4& a, F32 k) { a.mV[VX] *= k; a.mV[VY] *= k; @@ -497,16 +448,12 @@ inline const LLVector4& operator*=(LLVector4 &a, F32 k) return a; } -inline const LLVector4& operator/=(LLVector4 &a, F32 k) +inline const LLVector4& operator/=(LLVector4& a, F32 k) { - F32 t = 1.f / k; - a.mV[VX] *= t; - a.mV[VY] *= t; - a.mV[VZ] *= t; - return a; + return a *= 1.f / k; } -inline LLVector4 operator-(const LLVector4 &a) +inline LLVector4 operator-(const LLVector4& a) { return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] ); } @@ -521,19 +468,19 @@ inline LLVector4::operator glm::vec4() const return glm::make_vec4(mV); } -inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b) +inline F32 dist_vec(const LLVector4& a, const LLVector4& b) { LLVector4 vec = a - b; - return (vec.length()); + return vec.length(); } -inline F32 dist_vec_squared(const LLVector4 &a, const LLVector4 &b) +inline F32 dist_vec_squared(const LLVector4& a, const LLVector4& b) { LLVector4 vec = a - b; - return (vec.lengthSquared()); + return vec.lengthSquared(); } -inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u) +inline LLVector4 lerp(const LLVector4& a, const LLVector4& b, F32 u) { return LLVector4( a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u, @@ -542,59 +489,39 @@ inline LLVector4 lerp(const LLVector4 &a, const LLVector4 &b, F32 u) a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u); } -inline F32 LLVector4::normalize(void) +inline F32 LLVector4::normalize() { - F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); - F32 oomag; + F32 mag = sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); if (mag > FP_MAG_THRESHOLD) { - oomag = 1.f/mag; - mV[VX] *= oomag; - mV[VY] *= oomag; - mV[VZ] *= oomag; + *this /= mag; } else { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; - mag = 0; + mV[VX] = 0.f; + mV[VY] = 0.f; + mV[VZ] = 0.f; + mag = 0.f; } - return (mag); + return mag; } // deprecated -inline F32 LLVector4::normVec(void) +inline F32 LLVector4::normVec() { - F32 mag = (F32) sqrt(mV[VX]*mV[VX] + mV[VY]*mV[VY] + mV[VZ]*mV[VZ]); - F32 oomag; - - if (mag > FP_MAG_THRESHOLD) - { - oomag = 1.f/mag; - mV[VX] *= oomag; - mV[VY] *= oomag; - mV[VZ] *= oomag; - } - else - { - mV[0] = 0.f; - mV[1] = 0.f; - mV[2] = 0.f; - mag = 0; - } - return (mag); + return normalize(); } // Because apparently some parts of the viewer use this for color info. -inline const LLVector4 srgbVector4(const LLVector4 &a) { +inline const LLVector4 srgbVector4(const LLVector4& a) +{ LLVector4 srgbColor; - srgbColor.mV[0] = linearTosRGB(a.mV[0]); - srgbColor.mV[1] = linearTosRGB(a.mV[1]); - srgbColor.mV[2] = linearTosRGB(a.mV[2]); - srgbColor.mV[3] = a.mV[3]; + srgbColor.mV[VX] = linearTosRGB(a.mV[VX]); + srgbColor.mV[VY] = linearTosRGB(a.mV[VY]); + srgbColor.mV[VZ] = linearTosRGB(a.mV[VZ]); + srgbColor.mV[VW] = a.mV[VW]; return srgbColor; } diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h index 7434301670..fa45fffeae 100644 --- a/indra/llmath/xform.h +++ b/indra/llmath/xform.h @@ -115,7 +115,7 @@ public: void clearChanged(U32 bits) { mChanged &= ~bits; } void setScaleChildOffset(bool scale) { mScaleChildOffset = scale; } - bool getScaleChildOffset() { return mScaleChildOffset; } + bool getScaleChildOffset() const { return mScaleChildOffset; } LLXform* getParent() const { return mParent; } LLXform* getRoot() const; diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 6a663a8e97..563dd9459c 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -50,7 +50,7 @@ static const U32 DEFAULT_POOL_SIZE = 5; // SL-14399: When we teleport to a brand-new simulator, the coprocedure queue // gets absolutely slammed with fetch requests. Make this queue effectively // unlimited. -const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*1024; +const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*512; //========================================================================= class LLCoprocedurePool: private boost::noncopyable @@ -58,7 +58,7 @@ class LLCoprocedurePool: private boost::noncopyable public: typedef LLCoprocedureManager::CoProcedure_t CoProcedure_t; - LLCoprocedurePool(const std::string &name, size_t size); + LLCoprocedurePool(const std::string &name, size_t size, size_t queue_size); ~LLCoprocedurePool(); /// Places the coprocedure on the queue for processing. @@ -118,7 +118,7 @@ private: typedef std::shared_ptr<CoprocQueue_t> CoprocQueuePtr; std::string mPoolName; - size_t mPoolSize, mActiveCoprocsCount, mPending; + size_t mPoolSize, mQueueSize, mActiveCoprocsCount, mPending; CoprocQueuePtr mPendingCoprocs; LLTempBoundListener mStatusListener; @@ -141,7 +141,7 @@ LLCoprocedureManager::~LLCoprocedureManager() close(); } -void LLCoprocedureManager::initializePool(const std::string &poolName) +void LLCoprocedureManager::initializePool(const std::string &poolName, size_t queue_size) { poolMap_t::iterator it = mPoolMap.find(poolName); @@ -180,7 +180,7 @@ void LLCoprocedureManager::initializePool(const std::string &poolName) LL_WARNS("CoProcMgr") << "LLCoprocedureManager: No setting for \"" << keyName << "\" setting pool size to default of " << size << LL_ENDL; } - poolPtr_t pool(new LLCoprocedurePool(poolName, size)); + poolPtr_t pool(new LLCoprocedurePool(poolName, size, queue_size)); LL_ERRS_IF(!pool, "CoprocedureManager") << "Unable to create pool named \"" << poolName << "\" FATAL!" << LL_ENDL; bool inserted = mPoolMap.emplace(poolName, pool).second; @@ -212,7 +212,8 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd mPropertyQueryFn = queryfn; mPropertyDefineFn = updatefn; - initializePool("Upload"); + constexpr size_t UPLOAD_QUEUE_SIZE = 2048; + initializePool("Upload", UPLOAD_QUEUE_SIZE); initializePool("AIS"); // it might be better to have some kind of on-demand initialization for AIS // "ExpCache" pool gets initialized in LLExperienceCache // asset storage pool gets initialized in LLViewerAssetStorage @@ -296,17 +297,19 @@ void LLCoprocedureManager::close(const std::string &pool) } //========================================================================= -LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): +LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size, size_t queue_size): mPoolName(poolName), mPoolSize(size), + mQueueSize(queue_size), mActiveCoprocsCount(0), mPending(0), mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID), mCoroMapping() { + llassert_always(mQueueSize > mPoolSize); // queue should be able to fit pool try { - mPendingCoprocs = std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE); + mPendingCoprocs = std::make_shared<CoprocQueue_t>(mQueueSize); // store in our LLTempBoundListener so that when the LLCoprocedurePool is // destroyed, we implicitly disconnect from this LLEventPump // Monitores application status @@ -357,7 +360,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter)); } - LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL; + LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << mQueueSize << LL_ENDL; } LLCoprocedurePool::~LLCoprocedurePool() @@ -376,7 +379,7 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced << "\" at " << mPending << LL_ENDL; - if (mPending >= (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1)) + if (mPending >= (mQueueSize - 1)) { // If it's all used up (not supposed to happen, // fetched should cap it), we are going to crash diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 6c6e506654..485333657c 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -79,7 +79,7 @@ public: void close(); void close(const std::string &pool); - void initializePool(const std::string &poolName); + void initializePool(const std::string &poolName, size_t queue_size = DEFAULT_QUEUE_SIZE); private: diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp index 83a070df32..78cca47456 100644 --- a/indra/llmessage/llexperiencecache.cpp +++ b/indra/llmessage/llexperiencecache.cpp @@ -110,7 +110,8 @@ void LLExperienceCache::initSingleton() cache_stream >> (*this); } - LLCoprocedureManager::instance().initializePool("ExpCache"); + constexpr size_t CORO_QUEUE_SIZE = 2048; + LLCoprocedureManager::instance().initializePool("ExpCache", CORO_QUEUE_SIZE); LLCoros::instance().launch("LLExperienceCache::idleCoro", boost::bind(&LLExperienceCache::idleCoro, this)); diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp index eb6650c6c5..b8284334ea 100644 --- a/indra/llmessage/llpacketring.cpp +++ b/indra/llmessage/llpacketring.cpp @@ -209,8 +209,14 @@ S32 LLPacketRing::receiveOrDropBufferedPacket(char *datap, bool drop) if (!drop) { - assert(packet_size > 0); - memcpy(datap, packet->getData(), packet_size); + if (packet_size > 0) + { + memcpy(datap, packet->getData(), packet_size); + } + else + { + assert(false); + } } else { diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index d04ca52ad6..d79d5c3a11 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -506,6 +506,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou rv = apr_socket_recv(apr_socket, datain, &maxinlen); if (rv != APR_SUCCESS) { + // if rv == 70060 it's WSAETIMEDOUT char buf[MAX_STRING]; LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; ll_apr_warn_status(rv); diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index c264a9f086..21dbf35783 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -1402,3 +1402,4 @@ char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->ge char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience"); char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID"); char const* const _PREHASH_LargeGenericMessage = LLMessageStringTable::getInstance()->getString("LargeGenericMessage"); +char const* const _PREHASH_MetaData = LLMessageStringTable::getInstance()->getString("MetaData"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 1d30b69b67..8a2ad1587c 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -1403,5 +1403,6 @@ extern char const* const _PREHASH_HoverHeight; extern char const* const _PREHASH_Experience; extern char const* const _PREHASH_ExperienceID; extern char const* const _PREHASH_LargeGenericMessage; +extern char const* const _PREHASH_MetaData; #endif diff --git a/indra/llmessage/patch_code.cpp b/indra/llmessage/patch_code.cpp index 489b6ce6a6..9f9f4c852a 100644 --- a/indra/llmessage/patch_code.cpp +++ b/indra/llmessage/patch_code.cpp @@ -27,7 +27,6 @@ #include "linden_common.h" #include "llmath.h" -//#include "vmath.h" #include "v3math.h" #include "patch_dct.h" #include "patch_code.h" diff --git a/indra/llmessage/patch_dct.cpp b/indra/llmessage/patch_dct.cpp index 728fe84537..e74e5fd459 100644 --- a/indra/llmessage/patch_dct.cpp +++ b/indra/llmessage/patch_dct.cpp @@ -27,7 +27,6 @@ #include "linden_common.h" #include "llmath.h" -//#include "vmath.h" #include "v3math.h" #include "patch_dct.h" diff --git a/indra/llmessage/patch_idct.cpp b/indra/llmessage/patch_idct.cpp index 5483cf98c0..4bcc439917 100644 --- a/indra/llmessage/patch_idct.cpp +++ b/indra/llmessage/patch_idct.cpp @@ -27,7 +27,6 @@ #include "linden_common.h" #include "llmath.h" -//#include "vmath.h" #include "v3math.h" #include "patch_dct.h" diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 19a0ce639a..afee099697 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -575,7 +575,7 @@ void LLPluginProcessParent::idle(void) params.args.add("-e"); params.args.add("tell application \"Terminal\""); params.args.add("-e"); - params.args.add(STRINGIZE("set win to do script \"lldb -pid " + params.args.add(STRINGIZE("set win to do script \"lldb -p " << mProcess->getProcessID() << "\"")); params.args.add("-e"); params.args.add("do script \"continue\" in win"); diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 3d8e02cb16..e13f0bbd96 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -12,7 +12,6 @@ include(TinyGLTF) set(llprimitive_SOURCE_FILES lldaeloader.cpp - llgltfloader.cpp llgltfmaterial.cpp llmaterialid.cpp llmaterial.cpp @@ -32,7 +31,6 @@ set(llprimitive_SOURCE_FILES set(llprimitive_HEADER_FILES CMakeLists.txt lldaeloader.h - llgltfloader.h llgltfmaterial.h llgltfmaterial_templates.h legacy_object_types.h diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 4c028e7128..81ebe631c5 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -204,12 +204,15 @@ LLModel::EModelStatus load_face_from_dom_triangles( if (idx_stride <= 0 || (pos_source && pos_offset >= idx_stride) + || (pos_source && pos_offset < 0) || (tc_source && tc_offset >= idx_stride) - || (norm_source && norm_offset >= idx_stride)) + || (tc_source && tc_offset < 0) + || (norm_source && norm_offset >= idx_stride) + || (norm_source && norm_offset < 0)) { // Looks like these offsets should fit inside idx_stride // Might be good idea to also check idx.getCount()%idx_stride != 0 - LL_WARNS() << "Invalid pos_offset " << pos_offset << ", tc_offset " << tc_offset << " or norm_offset " << norm_offset << LL_ENDL; + LL_WARNS() << "Invalid idx_stride " << idx_stride << ", pos_offset " << pos_offset << ", tc_offset " << tc_offset << " or norm_offset " << norm_offset << LL_ENDL; return LLModel::BAD_ELEMENT; } @@ -880,9 +883,10 @@ LLDAELoader::LLDAELoader( void* opaque_userdata, JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, - std::map<std::string, std::string>& jointAliasMap, + std::map<std::string, std::string, std::less<>>& jointAliasMap, U32 maxJointsPerMesh, U32 modelLimit, + U32 debugMode, bool preprocess) : LLModelLoader( filename, @@ -895,8 +899,9 @@ LLDAELoader::LLDAELoader( jointTransformMap, jointsFromNodes, jointAliasMap, - maxJointsPerMesh), - mGeneratedModelLimit(modelLimit), + maxJointsPerMesh, + modelLimit, + debugMode), mPreprocessDAE(preprocess) { } @@ -1680,6 +1685,7 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do { materials[model->mMaterialList[i]] = LLImportMaterial(); } + // todo: likely a bug here, shouldn't be using suffixed label, see how it gets used in other places. mScene[transformation].push_back(LLModelInstance(model, model->mLabel, transformation, materials)); stretch_extents(model, transformation); } @@ -2412,7 +2418,7 @@ std::string LLDAELoader::getElementLabel(daeElement *element) } // static -size_t LLDAELoader::getSuffixPosition(std::string label) +size_t LLDAELoader::getSuffixPosition(const std::string &label) { if ((label.find("_LOD") != -1) || (label.find("_PHYS") != -1)) { diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 4531e03474..0335011a56 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -47,19 +47,20 @@ public: dae_model_map mModelsMap; LLDAELoader( - std::string filename, - S32 lod, - LLModelLoader::load_callback_t load_cb, - LLModelLoader::joint_lookup_func_t joint_lookup_func, - LLModelLoader::texture_load_func_t texture_load_func, - LLModelLoader::state_callback_t state_cb, - void* opaque_userdata, - JointTransformMap& jointTransformMap, - JointNameSet& jointsFromNodes, - std::map<std::string, std::string>& jointAliasMap, - U32 maxJointsPerMesh, - U32 modelLimit, - bool preprocess); + std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void* opaque_userdata, + JointTransformMap& jointTransformMap, + JointNameSet& jointsFromNodes, + std::map<std::string, std::string, std::less<>>& jointAliasMap, + U32 maxJointsPerMesh, + U32 modelLimit, + U32 debugMode, + bool preprocess); virtual ~LLDAELoader() ; virtual bool OpenFile(const std::string& filename); @@ -97,13 +98,12 @@ protected: bool loadModelsFromDomMesh(domMesh* mesh, std::vector<LLModel*>& models_out, U32 submodel_limit); static std::string getElementLabel(daeElement *element); - static size_t getSuffixPosition(std::string label); + static size_t getSuffixPosition(const std::string& label); static std::string getLodlessLabel(daeElement *element); static std::string preprocessDAE(std::string filename); private: - U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels bool mPreprocessDAE; }; diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp deleted file mode 100644 index 480012699a..0000000000 --- a/indra/llprimitive/llgltfloader.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/** - * @file LLGLTFLoader.cpp - * @brief LLGLTFLoader class implementation - * - * $LicenseInfo:firstyear=2022&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2022, 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 "llgltfloader.h" - -// Import & define single-header gltf import/export lib -#define TINYGLTF_IMPLEMENTATION -#define TINYGLTF_USE_CPP14 // default is C++ 11 - -// tinygltf by default loads image files using STB -#define STB_IMAGE_IMPLEMENTATION -// to use our own image loading: -// 1. replace this definition with TINYGLTF_NO_STB_IMAGE -// 2. provide image loader callback with TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data) - -// tinygltf saves image files using STB -#define STB_IMAGE_WRITE_IMPLEMENTATION -// similarly, can override with TINYGLTF_NO_STB_IMAGE_WRITE and TinyGLTF::SetImageWriter(fxn, data) - -// Additionally, disable inclusion of STB header files entirely with -// TINYGLTF_NO_INCLUDE_STB_IMAGE -// TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE -#include "tinygltf/tiny_gltf.h" - - -// TODO: includes inherited from dae loader. Validate / prune - -#include "llsdserialize.h" -#include "lljoint.h" - -#include "llmatrix4a.h" - -#include <boost/regex.hpp> -#include <boost/algorithm/string/replace.hpp> - -static const std::string lod_suffix[LLModel::NUM_LODS] = -{ - "_LOD0", - "_LOD1", - "_LOD2", - "", - "_PHYS", -}; - - -LLGLTFLoader::LLGLTFLoader(std::string filename, - S32 lod, - LLModelLoader::load_callback_t load_cb, - LLModelLoader::joint_lookup_func_t joint_lookup_func, - LLModelLoader::texture_load_func_t texture_load_func, - LLModelLoader::state_callback_t state_cb, - void * opaque_userdata, - JointTransformMap & jointTransformMap, - JointNameSet & jointsFromNodes, - std::map<std::string, std::string> &jointAliasMap, - U32 maxJointsPerMesh, - U32 modelLimit) //, - //bool preprocess) - : LLModelLoader( filename, - lod, - load_cb, - joint_lookup_func, - texture_load_func, - state_cb, - opaque_userdata, - jointTransformMap, - jointsFromNodes, - jointAliasMap, - maxJointsPerMesh ), - //mPreprocessGLTF(preprocess), - mMeshesLoaded(false), - mMaterialsLoaded(false) -{ -} - -LLGLTFLoader::~LLGLTFLoader() {} - -bool LLGLTFLoader::OpenFile(const std::string &filename) -{ - tinygltf::TinyGLTF loader; - std::string error_msg; - std::string warn_msg; - std::string filename_lc(filename); - LLStringUtil::toLower(filename_lc); - - // Load a tinygltf model fom a file. Assumes that the input filename has already been - // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. - if (std::string::npos == filename_lc.rfind(".gltf")) - { // file is binary - mGltfLoaded = loader.LoadBinaryFromFile(&mGltfModel, &error_msg, &warn_msg, filename); - } - else - { // file is ascii - mGltfLoaded = loader.LoadASCIIFromFile(&mGltfModel, &error_msg, &warn_msg, filename); - } - - if (!mGltfLoaded) - { - if (!warn_msg.empty()) - LL_WARNS("GLTF_IMPORT") << "gltf load warning: " << warn_msg.c_str() << LL_ENDL; - if (!error_msg.empty()) - LL_WARNS("GLTF_IMPORT") << "gltf load error: " << error_msg.c_str() << LL_ENDL; - return false; - } - - mMeshesLoaded = parseMeshes(); - if (mMeshesLoaded) uploadMeshes(); - - mMaterialsLoaded = parseMaterials(); - if (mMaterialsLoaded) uploadMaterials(); - - return (mMeshesLoaded || mMaterialsLoaded); -} - -bool LLGLTFLoader::parseMeshes() -{ - if (!mGltfLoaded) return false; - - // 2022-04 DJH Volume params from dae example. TODO understand PCODE - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - - for (tinygltf::Mesh mesh : mGltfModel.meshes) - { - LLModel *pModel = new LLModel(volume_params, 0.f); - - if (populateModelFromMesh(pModel, mesh) && - (LLModel::NO_ERRORS == pModel->getStatus()) && - validate_model(pModel)) - { - mModelList.push_back(pModel); - } - else - { - setLoadState(ERROR_MODEL + pModel->getStatus()); - delete(pModel); - return false; - } - } - return true; -} - -bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh) -{ - pModel->mLabel = mesh.name; - int pos_idx; - tinygltf::Accessor indices_a, positions_a, normals_a, uv0_a, color0_a; - - auto prims = mesh.primitives; - for (auto prim : prims) - { - if (prim.indices >= 0) indices_a = mGltfModel.accessors[prim.indices]; - - pos_idx = (prim.attributes.count("POSITION") > 0) ? prim.attributes.at("POSITION") : -1; - if (pos_idx >= 0) - { - positions_a = mGltfModel.accessors[pos_idx]; - if (TINYGLTF_COMPONENT_TYPE_FLOAT != positions_a.componentType) - continue; - auto positions_bv = mGltfModel.bufferViews[positions_a.bufferView]; - auto positions_buf = mGltfModel.buffers[positions_bv.buffer]; - //auto type = positions_vb. - //if (positions_buf.name - } - -#if 0 - int norm_idx, tan_idx, uv0_idx, uv1_idx, color0_idx, color1_idx; - norm_idx = (prim.attributes.count("NORMAL") > 0) ? prim.attributes.at("NORMAL") : -1; - tan_idx = (prim.attributes.count("TANGENT") > 0) ? prim.attributes.at("TANGENT") : -1; - uv0_idx = (prim.attributes.count("TEXCOORDS_0") > 0) ? prim.attributes.at("TEXCOORDS_0") : -1; - uv1_idx = (prim.attributes.count("TEXCOORDS_1") > 0) ? prim.attributes.at("TEXCOORDS_1") : -1; - color0_idx = (prim.attributes.count("COLOR_0") > 0) ? prim.attributes.at("COLOR_0") : -1; - color1_idx = (prim.attributes.count("COLOR_1") > 0) ? prim.attributes.at("COLOR_1") : -1; -#endif - - if (prim.mode == TINYGLTF_MODE_TRIANGLES) - { - //auto pos = mesh. TODO resume here DJH 2022-04 - } - } - - //pModel->addFace() - return false; -} - -bool LLGLTFLoader::parseMaterials() -{ - if (!mGltfLoaded) return false; - - // fill local texture data structures - mSamplers.clear(); - for (auto in_sampler : mGltfModel.samplers) - { - gltf_sampler sampler; - sampler.magFilter = in_sampler.magFilter > 0 ? in_sampler.magFilter : GL_LINEAR; - sampler.minFilter = in_sampler.minFilter > 0 ? in_sampler.minFilter : GL_LINEAR;; - sampler.wrapS = in_sampler.wrapS; - sampler.wrapT = in_sampler.wrapT; - sampler.name = in_sampler.name; // unused - mSamplers.push_back(sampler); - } - - mImages.clear(); - for (auto in_image : mGltfModel.images) - { - gltf_image image; - image.numChannels = in_image.component; - image.bytesPerChannel = in_image.bits >> 3; // Convert bits to bytes - image.pixelType = in_image.pixel_type; // Maps exactly, i.e. TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE == GL_UNSIGNED_BYTE, etc - image.size = static_cast<U32>(in_image.image.size()); - image.height = in_image.height; - image.width = in_image.width; - image.data = in_image.image.data(); - - if (in_image.as_is) - { - LL_WARNS("GLTF_IMPORT") << "Unsupported image encoding" << LL_ENDL; - return false; - } - - if (image.size != image.height * image.width * image.numChannels * image.bytesPerChannel) - { - LL_WARNS("GLTF_IMPORT") << "Image size error" << LL_ENDL; - return false; - } - - mImages.push_back(image); - } - - mTextures.clear(); - for (auto in_tex : mGltfModel.textures) - { - gltf_texture tex; - tex.imageIdx = in_tex.source; - tex.samplerIdx = in_tex.sampler; - tex.imageUuid.setNull(); - - if (tex.imageIdx >= mImages.size() || tex.samplerIdx >= mSamplers.size()) - { - LL_WARNS("GLTF_IMPORT") << "Texture sampler/image index error" << LL_ENDL; - return false; - } - - mTextures.push_back(tex); - } - - // parse each material - for (tinygltf::Material gltf_material : mGltfModel.materials) - { - gltf_render_material mat; - mat.name = gltf_material.name; - - tinygltf::PbrMetallicRoughness& pbr = gltf_material.pbrMetallicRoughness; - mat.hasPBR = true; // Always true, for now - - mat.baseColor.set(pbr.baseColorFactor.data()); - mat.hasBaseTex = pbr.baseColorTexture.index >= 0; - mat.baseColorTexIdx = pbr.baseColorTexture.index; - mat.baseColorTexCoords = pbr.baseColorTexture.texCoord; - - mat.metalness = pbr.metallicFactor; - mat.roughness = pbr.roughnessFactor; - mat.hasMRTex = pbr.metallicRoughnessTexture.index >= 0; - mat.metalRoughTexIdx = pbr.metallicRoughnessTexture.index; - mat.metalRoughTexCoords = pbr.metallicRoughnessTexture.texCoord; - - mat.normalScale = gltf_material.normalTexture.scale; - mat.hasNormalTex = gltf_material.normalTexture.index >= 0; - mat.normalTexIdx = gltf_material.normalTexture.index; - mat.normalTexCoords = gltf_material.normalTexture.texCoord; - - mat.occlusionScale = gltf_material.occlusionTexture.strength; - mat.hasOcclusionTex = gltf_material.occlusionTexture.index >= 0; - mat.occlusionTexIdx = gltf_material.occlusionTexture.index; - mat.occlusionTexCoords = gltf_material.occlusionTexture.texCoord; - - mat.emissiveColor.set(gltf_material.emissiveFactor.data()); - mat.hasEmissiveTex = gltf_material.emissiveTexture.index >= 0; - mat.emissiveTexIdx = gltf_material.emissiveTexture.index; - mat.emissiveTexCoords = gltf_material.emissiveTexture.texCoord; - - mat.alphaMode = gltf_material.alphaMode; - mat.alphaMask = gltf_material.alphaCutoff; - - if ((mat.hasNormalTex && (mat.normalTexIdx >= mTextures.size())) || - (mat.hasOcclusionTex && (mat.occlusionTexIdx >= mTextures.size())) || - (mat.hasEmissiveTex && (mat.emissiveTexIdx >= mTextures.size())) || - (mat.hasBaseTex && (mat.baseColorTexIdx >= mTextures.size())) || - (mat.hasMRTex && (mat.metalRoughTexIdx >= mTextures.size()))) - { - LL_WARNS("GLTF_IMPORT") << "Texture resource index error" << LL_ENDL; - return false; - } - - if ((mat.hasNormalTex && (mat.normalTexCoords > 2)) || // mesh can have up to 3 sets of UV - (mat.hasOcclusionTex && (mat.occlusionTexCoords > 2)) || - (mat.hasEmissiveTex && (mat.emissiveTexCoords > 2)) || - (mat.hasBaseTex && (mat.baseColorTexCoords > 2)) || - (mat.hasMRTex && (mat.metalRoughTexCoords > 2))) - { - LL_WARNS("GLTF_IMPORT") << "Image texcoord index error" << LL_ENDL; - return false; - } - - mMaterials.push_back(mat); - } - - return true; -} - -// TODO: convert raw vertex buffers to UUIDs -void LLGLTFLoader::uploadMeshes() -{ - llassert(0); -} - -// convert raw image buffers to texture UUIDs & assemble into a render material -void LLGLTFLoader::uploadMaterials() -{ - for (gltf_render_material mat : mMaterials) // Initially 1 material per gltf file, but design for multiple - { - if (mat.hasBaseTex) - { - gltf_texture& gtex = mTextures[mat.baseColorTexIdx]; - if (gtex.imageUuid.isNull()) - { - gtex.imageUuid = imageBufferToTextureUUID(gtex); - } - } - - if (mat.hasMRTex) - { - gltf_texture& gtex = mTextures[mat.metalRoughTexIdx]; - if (gtex.imageUuid.isNull()) - { - gtex.imageUuid = imageBufferToTextureUUID(gtex); - } - } - - if (mat.hasNormalTex) - { - gltf_texture& gtex = mTextures[mat.normalTexIdx]; - if (gtex.imageUuid.isNull()) - { - gtex.imageUuid = imageBufferToTextureUUID(gtex); - } - } - - if (mat.hasOcclusionTex) - { - gltf_texture& gtex = mTextures[mat.occlusionTexIdx]; - if (gtex.imageUuid.isNull()) - { - gtex.imageUuid = imageBufferToTextureUUID(gtex); - } - } - - if (mat.hasEmissiveTex) - { - gltf_texture& gtex = mTextures[mat.emissiveTexIdx]; - if (gtex.imageUuid.isNull()) - { - gtex.imageUuid = imageBufferToTextureUUID(gtex); - } - } - } -} - -LLUUID LLGLTFLoader::imageBufferToTextureUUID(const gltf_texture& tex) -{ - //gltf_image& image = mImages[tex.imageIdx]; - //gltf_sampler& sampler = mSamplers[tex.samplerIdx]; - - // fill an LLSD container with image+sampler data - - // upload texture - - // retrieve UUID - - return LLUUID::null; -} diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h deleted file mode 100644 index 66671d1c5a..0000000000 --- a/indra/llprimitive/llgltfloader.h +++ /dev/null @@ -1,206 +0,0 @@ -/** - * @file LLGLTFLoader.h - * @brief LLGLTFLoader class definition - * - * $LicenseInfo:firstyear=2022&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2022, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLGLTFLoader_H -#define LL_LLGLTFLoader_H - -#include "tinygltf/tiny_gltf.h" - -#include "llglheaders.h" -#include "llmodelloader.h" - -// gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD - -class gltf_sampler -{ -public: - // Uses GL enums - S32 minFilter; // GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR - S32 magFilter; // GL_NEAREST or GL_LINEAR - S32 wrapS; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT - S32 wrapT; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT - //S32 wrapR; // Found in some sample files, but not part of glTF 2.0 spec. Ignored. - std::string name; // optional, currently unused - // extensions and extras are sampler optional fields that we don't support - at least initially -}; - -class gltf_image -{ -public:// Note that glTF images are defined with row 0 at the top (opposite of OpenGL) - U8* data; // ptr to decoded image data - U32 size; // in bytes, regardless of channel width - U32 width; - U32 height; - U32 numChannels; // range 1..4 - U32 bytesPerChannel; // converted from gltf "bits", expects only 8, 16 or 32 as input - U32 pixelType; // one of (TINYGLTF_COMPONENT_TYPE)_UNSIGNED_BYTE, _UNSIGNED_SHORT, _UNSIGNED_INT, or _FLOAT -}; - -class gltf_texture -{ -public: - U32 imageIdx; - U32 samplerIdx; - LLUUID imageUuid = LLUUID::null; -}; - -class gltf_render_material -{ -public: - std::string name; - - // scalar values - LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present. - double metalness; - double roughness; - double normalScale; // scale applies only to X,Y components of normal - double occlusionScale; // strength multiplier for occlusion - LLColor4 emissiveColor; // emissive mulitiplier, assumed linear encoding (spec 2.0 is silent) - std::string alphaMode; // "OPAQUE", "MASK" or "BLEND" - double alphaMask; // alpha cut-off - - // textures - U32 baseColorTexIdx; // always sRGB encoded - U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel - U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) - U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded - U32 emissiveTexIdx; // always stored as sRGB, in nits (candela / meter^2) - - // texture coordinates - U32 baseColorTexCoords; - U32 metalRoughTexCoords; - U32 normalTexCoords; - U32 occlusionTexCoords; - U32 emissiveTexCoords; - - // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry?? - - bool hasPBR; - bool hasBaseTex, hasMRTex, hasNormalTex, hasOcclusionTex, hasEmissiveTex; - - // This field is populated after upload - LLUUID material_uuid = LLUUID::null; - -}; - -class gltf_mesh -{ -public: - std::string name; - - // TODO add mesh import DJH 2022-04 - -}; - -class LLGLTFLoader : public LLModelLoader -{ - public: - typedef std::map<std::string, LLImportMaterial> material_map; - - LLGLTFLoader(std::string filename, - S32 lod, - LLModelLoader::load_callback_t load_cb, - LLModelLoader::joint_lookup_func_t joint_lookup_func, - LLModelLoader::texture_load_func_t texture_load_func, - LLModelLoader::state_callback_t state_cb, - void * opaque_userdata, - JointTransformMap & jointTransformMap, - JointNameSet & jointsFromNodes, - std::map<std::string, std::string> &jointAliasMap, - U32 maxJointsPerMesh, - U32 modelLimit); //, - //bool preprocess ); - virtual ~LLGLTFLoader(); - - virtual bool OpenFile(const std::string &filename); - -protected: - tinygltf::Model mGltfModel; - bool mGltfLoaded; - bool mMeshesLoaded; - bool mMaterialsLoaded; - - std::vector<gltf_mesh> mMeshes; - std::vector<gltf_render_material> mMaterials; - - std::vector<gltf_texture> mTextures; - std::vector<gltf_image> mImages; - std::vector<gltf_sampler> mSamplers; - -private: - bool parseMeshes(); - void uploadMeshes(); - bool parseMaterials(); - void uploadMaterials(); - bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); - LLUUID imageBufferToTextureUUID(const gltf_texture& tex); - - // bool mPreprocessGLTF; - - /* Below inherited from dae loader - unknown if/how useful here - - void processElement(gltfElement *element, bool &badElement, GLTF *gltf); - void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin); - - material_map getMaterials(LLModel *model, gltfInstance_geometry *instance_geo, GLTF *gltf); - LLImportMaterial profileToMaterial(gltfProfile_COMMON *material, GLTF *gltf); - LLColor4 getGltfColor(gltfElement *element); - - gltfElement *getChildFromElement(gltfElement *pElement, std::string const &name); - - bool isNodeAJoint(gltfNode *pNode); - void processJointNode(gltfNode *pNode, std::map<std::string, LLMatrix4> &jointTransforms); - void extractTranslation(gltfTranslate *pTranslate, LLMatrix4 &transform); - void extractTranslationViaElement(gltfElement *pTranslateElement, LLMatrix4 &transform); - void extractTranslationViaSID(gltfElement *pElement, LLMatrix4 &transform); - void buildJointToNodeMappingFromScene(gltfElement *pRoot); - void processJointToNodeMapping(gltfNode *pNode); - void processChildJoints(gltfNode *pParentNode); - - bool verifyCount(int expected, int result); - - // Verify that a controller matches vertex counts - bool verifyController(gltfController *pController); - - static bool addVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh, LLSD &log_msg); - static bool createVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh); - - static LLModel *loadModelFromGltfMesh(gltfMesh *mesh); - - // Loads a mesh breaking it into one or more models as necessary - // to get around volume face limitations while retaining >8 materials - // - bool loadModelsFromGltfMesh(gltfMesh *mesh, std::vector<LLModel *> &models_out, U32 submodel_limit); - - static std::string getElementLabel(gltfElement *element); - static size_t getSuffixPosition(std::string label); - static std::string getLodlessLabel(gltfElement *element); - - static std::string preprocessGLTF(std::string filename); - */ - -}; -#endif // LL_LLGLTFLLOADER_H diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 4e3e49ec9f..00ef79ce7f 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -66,7 +66,12 @@ LLModel::~LLModel() { if (mDecompID >= 0) { - LLConvexDecomposition::getInstance()->deleteDecomposition(mDecompID); + // can be null on shutdown + LLConvexDecomposition* decomp = LLConvexDecomposition::getInstance(); + if (decomp) + { + decomp->deleteDecomposition(mDecompID); + } } mPhysics.mMesh.clear(); } @@ -334,6 +339,162 @@ void LLModel::normalizeVolumeFaces() } } +void LLModel::normalizeVolumeFacesAndWeights() +{ + if (!mVolumeFaces.empty()) + { + LLVector4a min, max; + + // For all of the volume faces + // in the model, loop over + // them and see what the extents + // of the volume along each axis. + min = mVolumeFaces[0].mExtents[0]; + max = mVolumeFaces[0].mExtents[1]; + + for (U32 i = 1; i < mVolumeFaces.size(); ++i) + { + LLVolumeFace& face = mVolumeFaces[i]; + + update_min_max(min, max, face.mExtents[0]); + update_min_max(min, max, face.mExtents[1]); + + if (face.mTexCoords) + { + LLVector2& min_tc = face.mTexCoordExtents[0]; + LLVector2& max_tc = face.mTexCoordExtents[1]; + + min_tc = face.mTexCoords[0]; + max_tc = face.mTexCoords[0]; + + for (S32 j = 1; j < face.mNumVertices; ++j) + { + update_min_max(min_tc, max_tc, face.mTexCoords[j]); + } + } + else + { + face.mTexCoordExtents[0].set(0, 0); + face.mTexCoordExtents[1].set(1, 1); + } + } + + // Now that we have the extents of the model + // we can compute the offset needed to center + // the model at the origin. + + // Compute center of the model + // and make it negative to get translation + // needed to center at origin. + LLVector4a trans; + trans.setAdd(min, max); + trans.mul(-0.5f); + + // Compute the total size along all + // axes of the model. + LLVector4a size; + size.setSub(max, min); + + // Prevent division by zero. + F32 x = size[0]; + F32 y = size[1]; + F32 z = size[2]; + F32 w = size[3]; + if (fabs(x) < F_APPROXIMATELY_ZERO) + { + x = 1.0; + } + if (fabs(y) < F_APPROXIMATELY_ZERO) + { + y = 1.0; + } + if (fabs(z) < F_APPROXIMATELY_ZERO) + { + z = 1.0; + } + size.set(x, y, z, w); + + // Compute scale as reciprocal of size + LLVector4a scale; + scale.splat(1.f); + scale.div(size); + + LLVector4a inv_scale(1.f); + inv_scale.div(scale); + + for (U32 i = 0; i < mVolumeFaces.size(); ++i) + { + LLVolumeFace& face = mVolumeFaces[i]; + + // We shrink the extents so + // that they fall within + // the unit cube. + // VFExtents change + face.mExtents[0].add(trans); + face.mExtents[0].mul(scale); + + face.mExtents[1].add(trans); + face.mExtents[1].mul(scale); + + // For all the positions, we scale + // the positions to fit within the unit cube. + LLVector4a* pos = (LLVector4a*)face.mPositions; + LLVector4a* norm = (LLVector4a*)face.mNormals; + LLVector4a* t = (LLVector4a*)face.mTangents; + + for (S32 j = 0; j < face.mNumVertices; ++j) + { + pos[j].add(trans); + pos[j].mul(scale); + if (norm && !norm[j].equals3(LLVector4a::getZero())) + { + norm[j].mul(inv_scale); + norm[j].normalize3(); + } + + if (t) + { + F32 w = t[j].getF32ptr()[3]; + t[j].mul(inv_scale); + t[j].normalize3(); + t[j].getF32ptr()[3] = w; + } + } + } + + weight_map old_weights = mSkinWeights; + mSkinWeights.clear(); + mPosition.clear(); + + for (auto& weights : old_weights) + { + LLVector4a pos(weights.first.mV[VX], weights.first.mV[VY], weights.first.mV[VZ]); + pos.add(trans); + pos.mul(scale); + LLVector3 scaled_pos(pos.getF32ptr()); + mPosition.push_back(scaled_pos); + mSkinWeights[scaled_pos] = weights.second; + } + + // mNormalizedScale is the scale at which + // we would need to multiply the model + // by to get the original size of the + // model instead of the normalized size. + LLVector4a normalized_scale; + normalized_scale.splat(1.f); + normalized_scale.div(scale); + mNormalizedScale.set(normalized_scale.getF32ptr()); + mNormalizedTranslation.set(trans.getF32ptr()); + mNormalizedTranslation *= -1.f; + + // remember normalized scale so original dimensions can be recovered for mesh processing (i.e. tangent generation) + for (auto& face : mVolumeFaces) + { + face.mNormalizedScale = mNormalizedScale; + } + } +} + void LLModel::getNormalizedScaleTranslation(LLVector3& scale_out, LLVector3& translation_out) const { scale_out = mNormalizedScale; @@ -662,7 +823,7 @@ LLSD LLModel::writeModel( bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, - bool nowrite, + EWriteModelMode write_mode, bool as_slm, int submodel_id) { @@ -941,10 +1102,10 @@ LLSD LLModel::writeModel( } } - return writeModelToStream(ostr, mdl, nowrite, as_slm); + return writeModelToStream(ostr, mdl, write_mode, as_slm); } -LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, bool nowrite, bool as_slm) +LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, EWriteModelMode write_mode, bool as_slm) { std::string::size_type cur_offset = 0; @@ -1006,7 +1167,11 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, bool nowrite, bo } } - if (!nowrite) + if (write_mode == WRITE_HUMAN) + { + ostr << mdl; + } + else if (write_mode == WRITE_BINARY) { LLSDSerialize::toBinary(header, ostr); @@ -1561,11 +1726,21 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi { ret["joint_names"][i] = mJointNames[i]; + // For model to work at all there must be a matching bind matrix, + // so supply an indentity one if it isn't true + // Note: can build an actual bind matrix from joints + const LLMatrix4a& inv_bind = mInvBindMatrix.size() > i ? mInvBindMatrix[i] : LLMatrix4a::identity(); + if (i >= mInvBindMatrix.size()) + { + LL_WARNS("MESHSKININFO") << "Joint index " << i << " (" << mJointNames[i] << ") exceeds inverse bind matrix size " + << mInvBindMatrix.size() << LL_ENDL; + } + for (U32 j = 0; j < 4; j++) { for (U32 k = 0; k < 4; k++) { - ret["inverse_bind_matrix"][i][j*4+k] = mInvBindMatrix[i].mMatrix[j][k]; + ret["inverse_bind_matrix"][i][j * 4 + k] = inv_bind.mMatrix[j][k]; } } } @@ -1578,15 +1753,25 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi } } - if ( include_joints && mAlternateBindMatrix.size() > 0 ) + // optional 'joint overrides' + if (include_joints && mAlternateBindMatrix.size() > 0) { for (U32 i = 0; i < mJointNames.size(); ++i) { + // If there is not enough to match mJointNames, + // either supply no alternate matrixes at all or supply + // replacements + const LLMatrix4a& alt_bind = mAlternateBindMatrix.size() > i ? mAlternateBindMatrix[i] : LLMatrix4a::identity(); + if (i >= mAlternateBindMatrix.size()) + { + LL_WARNS("MESHSKININFO") << "Joint index " << i << " (" << mJointNames[i] << ") exceeds alternate bind matrix size " + << mAlternateBindMatrix.size() << LL_ENDL; + } for (U32 j = 0; j < 4; j++) { for (U32 k = 0; k < 4; k++) { - ret["alt_inverse_bind_matrix"][i][j*4+k] = mAlternateBindMatrix[i].mMatrix[j][k]; + ret["alt_inverse_bind_matrix"][i][j * 4 + k] = alt_bind.mMatrix[j][k]; } } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index fe28926720..6501b3dc50 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -160,6 +160,12 @@ public: bool loadSkinInfo(LLSD& header, std::istream& is); bool loadDecomposition(LLSD& header, std::istream& is); + enum EWriteModelMode + { + WRITE_NO = 0, + WRITE_BINARY, + WRITE_HUMAN, + }; static LLSD writeModel( std::ostream& ostr, LLModel* physics, @@ -171,14 +177,14 @@ public: bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, - bool nowrite = false, + EWriteModelMode write_mode = WRITE_BINARY, bool as_slm = false, int submodel_id = 0); static LLSD writeModelToStream( std::ostream& ostr, LLSD& mdl, - bool nowrite = false, bool as_slm = false); + EWriteModelMode write_mode = WRITE_BINARY, bool as_slm = false); void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); } @@ -202,6 +208,7 @@ public: void sortVolumeFacesByMaterialName(); void normalizeVolumeFaces(); + void normalizeVolumeFacesAndWeights(); void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); void remapVolumeFaces(); void optimizeVolumeFaces(); diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 7facd53a72..0383659f62 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -33,6 +33,7 @@ #include "llmatrix4a.h" #include <boost/bind.hpp> +#include <boost/exception/diagnostic_information.hpp> std::list<LLModelLoader*> LLModelLoader::sActiveLoaderList; @@ -113,7 +114,9 @@ LLModelLoader::LLModelLoader( JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, JointMap& legalJointNamesMap, - U32 maxJointsPerMesh) + U32 maxJointsPerMesh, + U32 modelLimit, + U32 debugMode) : mJointList( jointTransformMap ) , mJointsFromNode( jointsFromNodes ) , LLThread("Model Loader") @@ -121,7 +124,6 @@ LLModelLoader::LLModelLoader( , mLod(lod) , mTrySLM(false) , mFirstTransform(true) -, mNumOfFetchingTextures(0) , mLoadCallback(load_cb) , mJointLookupFunc(joint_lookup_func) , mTextureLoadFunc(texture_load_func) @@ -132,7 +134,10 @@ LLModelLoader::LLModelLoader( , mNoNormalize(false) , mNoOptimize(false) , mCacheOnlyHitIfRigged(false) +, mTexturesNeedScaling(false) , mMaxJointsPerMesh(maxJointsPerMesh) +, mGeneratedModelLimit(modelLimit) +, mDebugMode(debugMode) , mJointMap(legalJointNamesMap) { assert_main_thread(); @@ -149,7 +154,44 @@ LLModelLoader::~LLModelLoader() void LLModelLoader::run() { mWarningsArray.clear(); - doLoadModel(); + try + { + doLoadModel(); + } + // Model loader isn't mission critical, so we just log all exceptions + catch (const LLException& e) + { + LL_WARNS("THREAD") << "LLException in model loader: " << e.what() << "" << LL_ENDL; + LLSD args; + args["Message"] = "UnknownException"; + args["FILENAME"] = mFilename; + args["EXCEPTION"] = e.what(); + mWarningsArray.append(args); + setLoadState(ERROR_PARSING); + } + catch (const std::exception& e) + { + LL_WARNS() << "Exception in LLModelLoader::run: " << e.what() << LL_ENDL; + LLSD args; + args["Message"] = "UnknownException"; + args["FILENAME"] = mFilename; + args["EXCEPTION"] = e.what(); + mWarningsArray.append(args); + setLoadState(ERROR_PARSING); + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION("LLModelLoader"); + LLSD args; + args["Message"] = "UnknownException"; + args["FILENAME"] = mFilename; + args["EXCEPTION"] = boost::current_exception_diagnostic_information(); + mWarningsArray.append(args); + setLoadState(ERROR_PARSING); + } + + // todo: we are inside of a thread, push this into main thread worker, + // not into doOnIdleOneTime that laks tread safety doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } @@ -201,7 +243,9 @@ bool LLModelLoader::doLoadModel() } } - return OpenFile(mFilename); + bool res = OpenFile(mFilename); + dumpDebugData(); // conditional on mDebugMode + return res; } void LLModelLoader::setLoadState(U32 state) @@ -466,6 +510,148 @@ bool LLModelLoader::isRigSuitableForJointPositionUpload( const std::vector<std:: return true; } +void LLModelLoader::dumpDebugData() +{ + if (mDebugMode == 0) + { + return; + } + + std::string log_file = mFilename + "_importer.txt"; + LLStringUtil::toLower(log_file); + llofstream file; + file.open(log_file.c_str()); + if (!file) + { + LL_WARNS() << "dumpDebugData failed to open file " << log_file << LL_ENDL; + return; + } + file << "Importing: " << mFilename << "\n"; + + std::map<std::string, LLMatrix4a> inv_bind; + std::map<std::string, LLMatrix4a> alt_bind; + for (LLPointer<LLModel>& mdl : mModelList) + { + + file << "Model name: " << mdl->mLabel << "\n"; + const LLMeshSkinInfo& skin_info = mdl->mSkinInfo; + file << "Shape Bind matrix: " << skin_info.mBindShapeMatrix << "\n"; + file << "Skin Weights count: " << (S32)mdl->mSkinWeights.size() << "\n"; + + // some objects might have individual bind matrices, + // but for now it isn't accounted for + size_t joint_count = skin_info.mJointNames.size(); + for (size_t i = 0; i< joint_count;i++) + { + const std::string& joint = skin_info.mJointNames[i]; + if (skin_info.mInvBindMatrix.size() > i) + { + inv_bind[joint] = skin_info.mInvBindMatrix[i]; + } + if (skin_info.mAlternateBindMatrix.size() > i) + { + alt_bind[joint] = skin_info.mAlternateBindMatrix[i]; + } + } + } + + file << "\nInv Bind matrices.\n"; + for (auto& bind : inv_bind) + { + file << "Joint: " << bind.first << " Matrix: " << bind.second << "\n"; + } + + file << "\nAlt Bind matrices.\n"; + for (auto& bind : alt_bind) + { + file << "Joint: " << bind.first << " Matrix: " << bind.second << "\n"; + } + + if (mDebugMode == 2) + { + S32 model_count = 0; + for (LLPointer<LLModel>& mdl : mModelList) + { + const LLVolume::face_list_t &face_list = mdl->getVolumeFaces(); + for (S32 face = 0; face < face_list.size(); face++) + { + const LLVolumeFace& vf = face_list[face]; + file << "\nModel: " << mdl->mLabel + << " face " << face + << " has " << vf.mNumVertices + << " vertices and " << vf.mNumIndices + << " indices " << "\n"; + + file << "\nPositions for model: " << mdl->mLabel << " face " << face << "\n"; + + for (S32 pos = 0; pos < vf.mNumVertices; ++pos) + { + file << vf.mPositions[pos] << " "; + } + + file << "\n\nIndices for model: " << mdl->mLabel << " face " << face << "\n"; + + for (S32 ind = 0; ind < vf.mNumIndices; ++ind) + { + file << vf.mIndices[ind] << " "; + } + } + + file << "\n\nWeights for model: " << mdl->mLabel; + for (auto& weights : mdl->mSkinWeights) + { + file << "\nVertex: " << weights.first << " Weights: "; + for (auto& weight : weights.second) + { + file << weight.mJointIdx << ":" << weight.mWeight << " "; + } + } + + file << "\n"; + model_count++; + if (model_count == 5) + { + file << "Too many models, stopping at 5.\n"; + break; + } + } + } + else if (mDebugMode > 2) + { + file << "\nModel LLSDs\n"; + S32 model_count = 0; + // some files contain too many models, so stop at 5. + for (LLPointer<LLModel>& mdl : mModelList) + { + const LLMeshSkinInfo& skin_info = mdl->mSkinInfo; + size_t joint_count = skin_info.mJointNames.size(); + size_t alt_count = skin_info.mAlternateBindMatrix.size(); + + LLModel::writeModel( + file, + nullptr, + mdl, + nullptr, + nullptr, + nullptr, + mdl->mPhysics, + joint_count > 0, + alt_count > 0, + false, + LLModel::WRITE_HUMAN, + false, + mdl->mSubmodelID); + + file << "\n"; + model_count++; + if (model_count == 5) + { + file << "Too many models, stopping at 5.\n"; + break; + } + } + } +} //called in the main thread void LLModelLoader::loadTextures() @@ -484,7 +670,7 @@ void LLModelLoader::loadTextures() if(!material.mDiffuseMapFilename.empty()) { - mNumOfFetchingTextures += mTextureLoadFunc(material, mOpaqueData); + mTextureLoadFunc(material, mOpaqueData); } } } diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 530e61e2b8..335d809386 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -36,7 +36,7 @@ class LLJoint; typedef std::map<std::string, LLMatrix4> JointTransformMap; typedef std::map<std::string, LLMatrix4>::iterator JointTransformMapIt; -typedef std::map<std::string, std::string> JointMap; +typedef std::map<std::string, std::string, std::less<>> JointMap; typedef std::deque<std::string> JointNameSet; const S32 SLM_SUPPORTED_VERSION = 3; @@ -109,8 +109,10 @@ public: bool mTrySLM; bool mCacheOnlyHitIfRigged; // ignore cached SLM if it does not contain rig info (and we want rig info) + bool mTexturesNeedScaling; model_list mModelList; + // The scene is pretty much what ends up getting loaded for upload. Basically assign things to this guy if you want something uploaded. scene mScene; typedef std::queue<LLPointer<LLModel> > model_queue; @@ -119,10 +121,16 @@ public: model_queue mPhysicsQ; //map of avatar joints as named in COLLADA assets to internal joint names + // Do not use this for anything other than looking up the name of a joint. This is populated elsewhere. JointMap mJointMap; + + // The joint list is what you want to use to actually setup the specific joint transformations. JointTransformMap& mJointList; JointNameSet& mJointsFromNode; + + U32 mMaxJointsPerMesh; + U32 mDebugMode; // see dumDebugData() for details LLModelLoader( std::string filename, @@ -135,7 +143,9 @@ public: JointTransformMap& jointTransformMap, JointNameSet& jointsFromNodes, JointMap& legalJointNamesMap, - U32 maxJointsPerMesh); + U32 maxJointsPerMesh, + U32 modelLimit, + U32 debugMode); virtual ~LLModelLoader(); virtual void setNoNormalize() { mNoNormalize = true; } @@ -161,9 +171,6 @@ public: void stretch_extents(const LLModel* model, const LLMatrix4& mat); - S32 mNumOfFetchingTextures ; // updated in the main thread - bool areTexturesReady() { return !mNumOfFetchingTextures; } // called in the main thread. - bool verifyCount( int expected, int result ); //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) @@ -192,6 +199,7 @@ public: const LLSD logOut() const { return mWarningsArray; } void clearLog() { mWarningsArray.clear(); } + void dumpDebugData(); protected: @@ -203,6 +211,7 @@ protected: bool mRigValidJointUpload; U32 mLegacyRigFlags; + U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels bool mNoNormalize; bool mNoOptimize; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 97f01da084..d37b16ce0c 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -582,7 +582,14 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_glyph_type, bitmap_num); LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_glyph_type, bitmap_num); - image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); + if (image_gl && image_raw) + { + image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); + } + else + { + llassert(false); //images were just inserted by nextOpenPos, they shouldn't be missing + } return gi; } @@ -766,7 +773,12 @@ bool LLFontFreetype::setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U1 { LLImageRaw* image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Color, bitmap_num); llassert(!mIsFallback); - llassert(image_raw && (image_raw->getComponents() == 4)); + if (!image_raw) + { + llassert(false); + return false; + } + llassert(image_raw->getComponents() == 4); // NOTE: inspired by LLImageRaw::setSubImage() U32* image_data = (U32*)image_raw->getData(); @@ -794,10 +806,17 @@ bool LLFontFreetype::setSubImageBGRA(U32 x, U32 y, U32 bitmap_num, U16 width, U1 void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride) const { LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(EFontGlyphType::Grayscale, bitmap_num); - LLImageDataLock lock(image_raw); llassert(!mIsFallback); - llassert(image_raw && (image_raw->getComponents() == 2)); + if (!image_raw) + { + llassert(false); + return; + } + + LLImageDataLock lock(image_raw); + + llassert(image_raw->getComponents() == 2); U8 *target = image_raw->getData(); llassert(target); diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index b062eca132..9cd5dc8145 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1079,8 +1079,8 @@ void LLGLSLShader::bind() void LLGLSLShader::bind(U8 variant) { - llassert(mGLTFVariants.size() == LLGLSLShader::NUM_GLTF_VARIANTS); - llassert(variant < LLGLSLShader::NUM_GLTF_VARIANTS); + llassert_always(mGLTFVariants.size() == LLGLSLShader::NUM_GLTF_VARIANTS); + llassert_always(variant < LLGLSLShader::NUM_GLTF_VARIANTS); mGLTFVariants[variant].bind(); } @@ -1088,7 +1088,7 @@ void LLGLSLShader::bind(bool rigged) { if (rigged) { - llassert(mRiggedVariant); + llassert_always(mRiggedVariant); mRiggedVariant->bind(); } else diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 3f8903ca09..1db36d91f9 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1870,8 +1870,17 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint*)&glbytes); if(!imageraw->allocateDataSize(width, height, ncomponents, glbytes)) { - LL_WARNS() << "Memory allocation failed for reading back texture. Size is: " << glbytes << LL_ENDL ; - LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ; + constexpr S64 MAX_GL_BYTES = 2048 * 2048; + if (glbytes > 0 && glbytes <= MAX_GL_BYTES) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Memory allocation failed for reading back texture. Data size: " << glbytes << LL_ENDL; + } + else + { + LL_WARNS() << "Memory allocation failed for reading back texture. Data size is: " << glbytes << LL_ENDL; + LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL; + } return false ; } @@ -1882,8 +1891,18 @@ bool LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre { if(!imageraw->allocateDataSize(width, height, ncomponents)) { - LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL ; - LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL ; + constexpr F32 MAX_IMAGE_SIZE = 2048 * 2048; + F32 size = (F32)width * (F32)height * (F32)ncomponents; + if (size > 0 && size <= MAX_IMAGE_SIZE) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Memory allocation failed for reading back texture. Data size: " << size << LL_ENDL; + } + else + { + LL_WARNS() << "Memory allocation failed for reading back texture." << LL_ENDL; + LL_WARNS() << "width: " << width << "height: " << height << "components: " << ncomponents << LL_ENDL; + } return false ; } diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 38bc5ff331..0b0d69812f 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -492,22 +492,6 @@ U32 LLRenderTarget::getNumTextures() const void LLRenderTarget::bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options) { gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index), filter_options == LLTexUnit::TFO_TRILINEAR || filter_options == LLTexUnit::TFO_ANISOTROPIC); - - bool isSRGB = false; - llassert(mInternalFormat.size() > index); - switch (mInternalFormat[index]) - { - case GL_SRGB: - case GL_SRGB8: - case GL_SRGB_ALPHA: - case GL_SRGB8_ALPHA8: - isSRGB = true; - break; - - default: - break; - } - gGL.getTexUnit(channel)->setTextureFilteringOption(filter_options); } diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index a0314cb5f2..908e94b24c 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -18,6 +18,7 @@ set(llui_SOURCE_FILES llbadgeowner.cpp llbutton.cpp llchatentry.cpp + llchatmentionhelper.cpp llcheckboxctrl.cpp llclipboard.cpp llcombobox.cpp @@ -130,6 +131,7 @@ set(llui_HEADER_FILES llcallbackmap.h llchatentry.h llchat.h + llchatmentionhelper.h llcheckboxctrl.h llclipboard.h llcombobox.h diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index cf3569683e..bb0b8ce04f 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -126,7 +126,7 @@ public: void setSelected(bool is_selected); - bool getCollapsible() { return mCollapsible; }; + bool getCollapsible() const { return mCollapsible; }; void setCollapsible(bool collapsible) { mCollapsible = collapsible; }; void changeOpenClose(bool is_open); @@ -140,7 +140,7 @@ public: S32 notify(const LLSD& info); bool notifyChildren(const LLSD& info); - void draw(); + virtual void draw(); void storeOpenCloseState(); void restoreOpenCloseState(); @@ -181,7 +181,7 @@ public: void setHeaderVisible(bool value); - bool getHeaderVisible() { return mHeaderVisible;} + bool getHeaderVisible() const { return mHeaderVisible;} S32 mExpandedHeight; // Height of expanded ctrl. // Used to restore height after expand. diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp index da5afd0386..7506cd99c0 100644 --- a/indra/llui/llchatentry.cpp +++ b/indra/llui/llchatentry.cpp @@ -45,12 +45,14 @@ LLChatEntry::LLChatEntry(const Params& p) mExpandLinesCount(p.expand_lines_count), mPrevLinesCount(0), mSingleLineMode(false), - mPrevExpandedLineCount(S32_MAX) + mPrevExpandedLineCount(S32_MAX), + mCurrentInput("") { // Initialize current history line iterator mCurrentHistoryLine = mLineHistory.begin(); mAutoIndent = false; + mShowChatMentionPicker = true; keepSelectionOnReturn(true); } @@ -189,6 +191,7 @@ bool LLChatEntry::handleSpecialKey(const KEY key, const MASK mask) { needsReflow(); } + mCurrentInput = ""; break; case KEY_UP: @@ -196,6 +199,11 @@ bool LLChatEntry::handleSpecialKey(const KEY key, const MASK mask) { if (!mLineHistory.empty() && mCurrentHistoryLine > mLineHistory.begin()) { + if (mCurrentHistoryLine == mLineHistory.end()) + { + mCurrentInput = getText(); + } + setText(*(--mCurrentHistoryLine)); endOfDoc(); } @@ -210,16 +218,15 @@ bool LLChatEntry::handleSpecialKey(const KEY key, const MASK mask) case KEY_DOWN: if (mHasHistory && MASK_CONTROL == mask) { - if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1) ) + if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1)) { setText(*(++mCurrentHistoryLine)); endOfDoc(); } - else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1) ) + else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1)) { mCurrentHistoryLine++; - std::string empty(""); - setText(empty); + setText(mCurrentInput); needsReflow(); endOfDoc(); } diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h index 5621ede1e7..9a0e8ee91e 100644 --- a/indra/llui/llchatentry.h +++ b/indra/llui/llchatentry.h @@ -101,6 +101,8 @@ private: S32 mExpandLinesCount; S32 mPrevLinesCount; S32 mPrevExpandedLineCount; + + std::string mCurrentInput; }; #endif /* LLCHATENTRY_H_ */ diff --git a/indra/llui/llchatmentionhelper.cpp b/indra/llui/llchatmentionhelper.cpp new file mode 100644 index 0000000000..5745389a58 --- /dev/null +++ b/indra/llui/llchatmentionhelper.cpp @@ -0,0 +1,158 @@ +/** +* @file llchatmentionhelper.cpp +* +* $LicenseInfo:firstyear=2025&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2025, 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 "llchatmentionhelper.h" +#include "llfloater.h" +#include "llfloaterreg.h" +#include "lluictrl.h" + +constexpr char CHAT_MENTION_HELPER_FLOATER[] = "chat_mention_picker"; + +bool LLChatMentionHelper::isActive(const LLUICtrl* ctrl) const +{ + return mHostHandle.get() == ctrl; +} + +bool LLChatMentionHelper::isCursorInNameMention(const LLWString& wtext, S32 cursor_pos, S32* mention_start_pos) const +{ + if (cursor_pos <= 0 || cursor_pos > static_cast<S32>(wtext.size())) + return false; + + // Find the beginning of the current word + S32 start = cursor_pos - 1; + while (start > 0 && wtext[start - 1] != U32(' ') && wtext[start - 1] != U32('\n')) + { + --start; + } + + if (wtext[start] != U32('@')) + return false; + + if (mention_start_pos) + *mention_start_pos = start; + + S32 word_length = cursor_pos - start; + + if (word_length == 1) + { + return true; + } + + // Get the name after '@' + std::string name = wstring_to_utf8str(wtext.substr(start + 1, word_length - 1)); + LLStringUtil::toLower(name); + for (const auto& av_name : mAvatarNames) + { + if (av_name == name || av_name.find(name) == 0) + { + return true; + } + } + + return false; +} + +void LLChatMentionHelper::showHelper(LLUICtrl* host_ctrl, S32 local_x, S32 local_y, const std::string& av_name, std::function<void(std::string)> cb) +{ + if (mHelperHandle.isDead()) + { + LLFloater* av_picker_floater = LLFloaterReg::getInstance(CHAT_MENTION_HELPER_FLOATER); + mHelperHandle = av_picker_floater->getHandle(); + mHelperCommitConn = av_picker_floater->setCommitCallback([&](LLUICtrl* ctrl, const LLSD& param) { onCommitName(param.asString()); }); + } + setHostCtrl(host_ctrl); + mNameCommitCb = cb; + + S32 floater_x, floater_y; + if (!host_ctrl->localPointToOtherView(local_x, local_y, &floater_x, &floater_y, gFloaterView)) + { + LL_WARNS() << "Cannot show helper for non-floater controls." << LL_ENDL; + return; + } + + LLFloater* av_picker_floater = mHelperHandle.get(); + LLRect rect = av_picker_floater->getRect(); + rect.setLeftTopAndSize(floater_x, floater_y + rect.getHeight(), rect.getWidth(), rect.getHeight()); + av_picker_floater->setRect(rect); + if (av_picker_floater->isShown()) + { + av_picker_floater->onOpen(LLSD().with("av_name", av_name)); + } + else + { + av_picker_floater->openFloater(LLSD().with("av_name", av_name)); + } +} + +void LLChatMentionHelper::hideHelper(const LLUICtrl* ctrl) +{ + if ((ctrl && !isActive(ctrl))) + { + return; + } + setHostCtrl(nullptr); +} + +bool LLChatMentionHelper::handleKey(const LLUICtrl* ctrl, KEY key, MASK mask) +{ + if (mHelperHandle.isDead() || !isActive(ctrl)) + { + return false; + } + + return mHelperHandle.get()->handleKey(key, mask, true); +} + +void LLChatMentionHelper::onCommitName(std::string name_url) +{ + if (!mHostHandle.isDead() && mNameCommitCb) + { + mNameCommitCb(name_url); + } +} + +void LLChatMentionHelper::setHostCtrl(LLUICtrl* host_ctrl) +{ + const LLUICtrl* pCurHostCtrl = mHostHandle.get(); + if (pCurHostCtrl != host_ctrl) + { + mHostCtrlFocusLostConn.disconnect(); + mHostHandle.markDead(); + mNameCommitCb = {}; + + if (!mHelperHandle.isDead()) + { + mHelperHandle.get()->closeFloater(); + } + + if (host_ctrl) + { + mHostHandle = host_ctrl->getHandle(); + mHostCtrlFocusLostConn = host_ctrl->setFocusLostCallback(std::bind([&]() { hideHelper(getHostCtrl()); })); + } + } +} diff --git a/indra/llui/llchatmentionhelper.h b/indra/llui/llchatmentionhelper.h new file mode 100644 index 0000000000..5f95d06f31 --- /dev/null +++ b/indra/llui/llchatmentionhelper.h @@ -0,0 +1,66 @@ +/** +* @file llchatmentionhelper.h +* @brief Header file for LLChatMentionHelper +* +* $LicenseInfo:firstyear=2025&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2025, 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$ +*/ + +#pragma once + +#include "llhandle.h" +#include "llsingleton.h" + +#include <boost/signals2.hpp> + +class LLFloater; +class LLUICtrl; + +class LLChatMentionHelper : public LLSingleton<LLChatMentionHelper> +{ + LLSINGLETON(LLChatMentionHelper) {} + ~LLChatMentionHelper() override {} + +public: + + bool isActive(const LLUICtrl* ctrl) const; + bool isCursorInNameMention(const LLWString& wtext, S32 cursor_pos, S32* mention_start_pos = nullptr) const; + void showHelper(LLUICtrl* host_ctrl, S32 local_x, S32 local_y, const std::string& av_name, std::function<void(std::string)> commit_cb); + void hideHelper(const LLUICtrl* ctrl = nullptr); + + bool handleKey(const LLUICtrl* ctrl, KEY key, MASK mask); + void onCommitName(std::string name_url); + + void updateAvatarList(std::vector<std::string> av_names) { mAvatarNames = av_names; } + +protected: + void setHostCtrl(LLUICtrl* host_ctrl); + LLUICtrl* getHostCtrl() const { return mHostHandle.get(); } + +private: + LLHandle<LLUICtrl> mHostHandle; + LLHandle<LLFloater> mHelperHandle; + boost::signals2::connection mHostCtrlFocusLostConn; + boost::signals2::connection mHelperCommitConn; + std::function<void(std::string)> mNameCommitCb; + + std::vector<std::string> mAvatarNames; +}; diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 135f128692..4068741978 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -36,8 +36,8 @@ // Constants // -const bool RADIO_STYLE = true; -const bool CHECK_STYLE = false; +constexpr bool RADIO_STYLE = true; +constexpr bool CHECK_STYLE = false; // // Classes @@ -94,7 +94,7 @@ public: // LLUICtrl interface virtual void setValue(const LLSD& value ); virtual LLSD getValue() const; - bool get() { return (bool)getValue().asBoolean(); } + bool get() const { return (bool)getValue().asBoolean(); } void set(bool value) { setValue(value); } virtual void setTentative(bool b); @@ -106,7 +106,7 @@ public: virtual void onCommit(); // LLCheckBoxCtrl interface - virtual bool toggle() { return mButton->toggleState(); } // returns new state + virtual bool toggle() { return mButton->toggleState(); } // returns new state void setBtnFocus() { mButton->setFocus(true); } diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h index c6dd401e85..2675d21c22 100644 --- a/indra/llui/llcontainerview.h +++ b/indra/llui/llcontainerview.h @@ -65,21 +65,21 @@ protected: public: ~LLContainerView(); - /*virtual*/ bool postBuild(); - /*virtual*/ bool addChild(LLView* view, S32 tab_group = 0); + bool postBuild() override; + bool addChild(LLView* view, S32 tab_group = 0) override; - /*virtual*/ bool handleDoubleClick(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleMouseUp(S32 x, S32 y, MASK mask); + bool handleDoubleClick(S32 x, S32 y, MASK mask) override; + bool handleMouseDown(S32 x, S32 y, MASK mask) override; + bool handleMouseUp(S32 x, S32 y, MASK mask) override; - /*virtual*/ void draw(); - /*virtual*/ void reshape(S32 width, S32 height, bool called_from_parent = true); - /*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options. + void draw() override; + void reshape(S32 width, S32 height, bool called_from_parent = true) override; + LLRect getRequiredRect() override; // Return the height of this object, given the set options. void setLabel(const std::string& label); void showLabel(bool show) { mShowLabel = show; } void setDisplayChildren(bool displayChildren); - bool getDisplayChildren() { return mDisplayChildren; } + bool getDisplayChildren() const { return mDisplayChildren; } void setScrollContainer(LLScrollContainer* scroll) {mScrollContainer = scroll;} private: diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 3effc977db..9c516e23a4 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -112,8 +112,8 @@ public: virtual bool overlapsScreenChannel() { return mOverlapsScreenChannel && getVisible() && isDocked(); } virtual void setOverlapsScreenChannel(bool overlaps) { mOverlapsScreenChannel = overlaps; } - bool getUniqueDocking() { return mUniqueDocking; } - bool getUseTongue() { return mUseTongue; } + bool getUniqueDocking() const { return mUniqueDocking; } + bool getUseTongue() const { return mUseTongue; } void setUseTongue(bool use_tongue) { mUseTongue = use_tongue;} private: diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp index 11dbad8c09..1a00c03856 100644 --- a/indra/llui/lldockcontrol.cpp +++ b/indra/llui/lldockcontrol.cpp @@ -156,7 +156,7 @@ void LLDockControl::repositionDockable() } } -bool LLDockControl::isDockVisible() +bool LLDockControl::isDockVisible() const { bool res = true; diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h index 7e31330713..b6ac9c19dd 100644 --- a/indra/llui/lldockcontrol.h +++ b/indra/llui/lldockcontrol.h @@ -61,19 +61,19 @@ public: void off(); void forceRecalculatePosition(); void setDock(LLView* dockWidget); - LLView* getDock() + LLView* getDock() const { return mDockWidgetHandle.get(); } void repositionDockable(); void drawToungue(); - bool isDockVisible(); + bool isDockVisible() const; // gets a rect that bounds possible positions for a dockable control (EXT-1111) void getAllowedRect(LLRect& rect); - S32 getTongueWidth() { return mDockTongue->getWidth(); } - S32 getTongueHeight() { return mDockTongue->getHeight(); } + S32 getTongueWidth() const { return mDockTongue->getWidth(); } + S32 getTongueHeight() const { return mDockTongue->getHeight(); } private: virtual void moveDockable(); diff --git a/indra/llui/lldraghandle.h b/indra/llui/lldraghandle.h index a522e63243..73211d5292 100644 --- a/indra/llui/lldraghandle.h +++ b/indra/llui/lldraghandle.h @@ -66,7 +66,7 @@ public: void setMaxTitleWidth(S32 max_width) {mMaxTitleWidth = llmin(max_width, mMaxTitleWidth); } S32 getMaxTitleWidth() const { return mMaxTitleWidth; } void setButtonsRect(const LLRect& rect){ mButtonsRect = rect; } - LLRect getButtonsRect() { return mButtonsRect; } + LLRect getButtonsRect() const { return mButtonsRect; } void setTitleVisible(bool visible); virtual void setTitle( const std::string& title ) = 0; diff --git a/indra/llui/llfiltereditor.h b/indra/llui/llfiltereditor.h index 686827d94c..685219c9f6 100644 --- a/indra/llui/llfiltereditor.h +++ b/indra/llui/llfiltereditor.h @@ -49,7 +49,7 @@ protected: LLFilterEditor(const Params&); friend class LLUICtrlFactory; - /*virtual*/ void handleKeystroke(); + void handleKeystroke() override; }; #endif // LL_FILTEREDITOR_H diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp index c3db24c987..54f54653e2 100644 --- a/indra/llui/llflashtimer.cpp +++ b/indra/llui/llflashtimer.cpp @@ -85,12 +85,12 @@ void LLFlashTimer::stopFlashing() mCurrentTickCount = 0; } -bool LLFlashTimer::isFlashingInProgress() +bool LLFlashTimer::isFlashingInProgress() const { return mIsFlashingInProgress; } -bool LLFlashTimer::isCurrentlyHighlighted() +bool LLFlashTimer::isCurrentlyHighlighted() const { return mIsCurrentlyHighlighted; } diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h index b55ce53fc0..4ef70faf2d 100644 --- a/indra/llui/llflashtimer.h +++ b/indra/llui/llflashtimer.h @@ -51,8 +51,8 @@ public: void startFlashing(); void stopFlashing(); - bool isFlashingInProgress(); - bool isCurrentlyHighlighted(); + bool isFlashingInProgress() const; + bool isCurrentlyHighlighted() const; /* * Use this instead of deleting this object. * The next call to tick() will return true and that will destroy this object. diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp index 53f39766c6..5be20bd314 100644 --- a/indra/llui/llflatlistview.cpp +++ b/indra/llui/llflatlistview.cpp @@ -459,6 +459,7 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p) , mNoItemsCommentTextbox(NULL) , mIsConsecutiveSelection(false) , mKeepSelectionVisibleOnReshape(p.keep_selection_visible_on_reshape) + , mFocusOnItemClicked(true) { mBorderThickness = getBorderWidth(); @@ -610,7 +611,10 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask) return; } - setFocus(true); + if (mFocusOnItemClicked) + { + setFocus(true); + } bool select_item = !isSelected(item_pair); @@ -1337,14 +1341,22 @@ void LLFlatListViewEx::updateNoItemsMessage(const std::string& filter_string) } } -bool LLFlatListViewEx::getForceShowingUnmatchedItems() +bool LLFlatListViewEx::getForceShowingUnmatchedItems() const { return mForceShowingUnmatchedItems; } -void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show) +void LLFlatListViewEx::setForceShowingUnmatchedItems(bool show, bool notify_parent) +{ + if (mForceShowingUnmatchedItems != show) { mForceShowingUnmatchedItems = show; + if (!mFilterSubString.empty()) + { + updateNoItemsMessage(mFilterSubString); + filterItems(false, true); + } + } } void LLFlatListViewEx::setFilterSubString(const std::string& filter_str, bool notify_parent) @@ -1412,6 +1424,7 @@ void LLFlatListViewEx::filterItems(bool re_sort, bool notify_parent) if (visibility_changed && notify_parent) { + rearrangeItems(); notifyParentItemsRectChanged(); } } diff --git a/indra/llui/llflatlistview.h b/indra/llui/llflatlistview.h index 6d75e9f282..1f22360a8a 100644 --- a/indra/llui/llflatlistview.h +++ b/indra/llui/llflatlistview.h @@ -113,7 +113,7 @@ public: }; // disable traversal when finding widget to hand focus off to - /*virtual*/ bool canFocusChildren() const { return false; } + /*virtual*/ bool canFocusChildren() const override { return false; } /** * Connects callback to signal called when Return key is pressed. @@ -121,15 +121,15 @@ public: boost::signals2::connection setReturnCallback( const commit_signal_t::slot_type& cb ) { return mOnReturnSignal.connect(cb); } /** Overridden LLPanel's reshape, height is ignored, the list sets its height to accommodate all items */ - virtual void reshape(S32 width, S32 height, bool called_from_parent = true); + virtual void reshape(S32 width, S32 height, bool called_from_parent = true) override; /** Returns full rect of child panel */ const LLRect& getItemsRect() const; - LLRect getRequiredRect() { return getItemsRect(); } + LLRect getRequiredRect() override { return getItemsRect(); } /** Returns distance between items */ - const S32 getItemsPad() { return mItemPad; } + const S32 getItemsPad() const { return mItemPad; } /** * Adds and item and LLSD value associated with it to the list at specified position @@ -264,13 +264,13 @@ public: void setCommitOnSelectionChange(bool b) { mCommitOnSelectionChange = b; } /** Get number of selected items in the list */ - U32 numSelected() const {return static_cast<U32>(mSelectedItemPairs.size()); } + U32 numSelected() const { return static_cast<U32>(mSelectedItemPairs.size()); } /** Get number of (visible) items in the list */ U32 size(const bool only_visible_items = true) const; /** Removes all items from the list */ - virtual void clear(); + virtual void clear() override; /** * Removes all items that can be detached from the list but doesn't destroy @@ -294,10 +294,12 @@ public: void scrollToShowFirstSelectedItem(); - void selectFirstItem (); - void selectLastItem (); + void selectFirstItem(); + void selectLastItem(); - virtual S32 notify(const LLSD& info) ; + virtual S32 notify(const LLSD& info) override; + + void setFocusOnItemClicked(bool b) { mFocusOnItemClicked = b; } virtual ~LLFlatListView(); @@ -346,8 +348,8 @@ protected: virtual bool selectNextItemPair(bool is_up_direction, bool reset_selection); - virtual bool canSelectAll() const; - virtual void selectAll(); + virtual bool canSelectAll() const override; + virtual void selectAll() override; virtual bool isSelected(item_pair_t* item_pair) const; @@ -364,15 +366,15 @@ protected: */ void notifyParentItemsRectChanged(); - virtual bool handleKeyHere(KEY key, MASK mask); + virtual bool handleKeyHere(KEY key, MASK mask) override; - virtual bool postBuild(); + virtual bool postBuild() override; - virtual void onFocusReceived(); + virtual void onFocusReceived() override; - virtual void onFocusLost(); + virtual void onFocusLost() override; - virtual void draw(); + virtual void draw() override; LLRect getLastSelectedItemRect(); @@ -423,6 +425,8 @@ private: bool mKeepSelectionVisibleOnReshape; + bool mFocusOnItemClicked; + /** All pairs of the list */ pairs_list_t mItemPairs; @@ -478,15 +482,19 @@ public: void setNoItemsMsg(const std::string& msg) { mNoItemsMsg = msg; } void setNoFilteredItemsMsg(const std::string& msg) { mNoFilteredItemsMsg = msg; } - bool getForceShowingUnmatchedItems(); + bool getForceShowingUnmatchedItems() const; - void setForceShowingUnmatchedItems(bool show); + /** + * Sets filtered out items to stay visible. Can result in rect changes, + * so can notify_parent if rect changes + */ + void setForceShowingUnmatchedItems(bool show, bool notify_parent); /** * Sets up new filter string and filters the list. */ void setFilterSubString(const std::string& filter_str, bool notify_parent); - std::string getFilterSubString() { return mFilterSubString; } + std::string getFilterSubString() const { return mFilterSubString; } /** * Filters the list, rearranges and notifies parent about shape changes. diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 4b904f09e0..fd07b2ec5d 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2165,7 +2165,7 @@ void LLFloater::setCanDrag(bool can_drag) } } -bool LLFloater::getCanDrag() +bool LLFloater::getCanDrag() const { return mDragHandle->getEnabled(); } diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index eae2435117..9e1594bdd2 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -46,24 +46,24 @@ class LLMultiFloater; class LLFloater; -const bool RESIZE_YES = true; -const bool RESIZE_NO = false; +constexpr bool RESIZE_YES = true; +constexpr bool RESIZE_NO = false; -const bool DRAG_ON_TOP = false; -const bool DRAG_ON_LEFT = true; +constexpr bool DRAG_ON_TOP = false; +constexpr bool DRAG_ON_LEFT = true; -const bool MINIMIZE_YES = true; -const bool MINIMIZE_NO = false; +constexpr bool MINIMIZE_YES = true; +constexpr bool MINIMIZE_NO = false; -const bool CLOSE_YES = true; -const bool CLOSE_NO = false; +constexpr bool CLOSE_YES = true; +constexpr bool CLOSE_NO = false; -const bool ADJUST_VERTICAL_YES = true; -const bool ADJUST_VERTICAL_NO = false; +constexpr bool ADJUST_VERTICAL_YES = true; +constexpr bool ADJUST_VERTICAL_NO = false; -const F32 CONTEXT_CONE_IN_ALPHA = 0.f; -const F32 CONTEXT_CONE_OUT_ALPHA = 1.f; -const F32 CONTEXT_CONE_FADE_TIME = .08f; +constexpr F32 CONTEXT_CONE_IN_ALPHA = 0.f; +constexpr F32 CONTEXT_CONE_OUT_ALPHA = 1.f; +constexpr F32 CONTEXT_CONE_FADE_TIME = .08f; namespace LLFloaterEnums { @@ -228,7 +228,7 @@ public: /*virtual*/ void setIsChrome(bool is_chrome); /*virtual*/ void setRect(const LLRect &rect); void setIsSingleInstance(bool is_single_instance); - bool getIsSingleInstance() { return mSingleInstance; } + bool getIsSingleInstance() const { return mSingleInstance; } void initFloater(const Params& p); @@ -274,17 +274,17 @@ public: static bool isShown(const LLFloater* floater); static bool isVisible(const LLFloater* floater); static bool isMinimized(const LLFloater* floater); - bool isFirstLook() { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts + bool isFirstLook() const { return mFirstLook; } // EXT-2653: This function is necessary to prevent overlapping for secondary showed toasts virtual bool isFrontmost(); - bool isDependent() { return !mDependeeHandle.isDead(); } + bool isDependent() const { return !mDependeeHandle.isDead(); } void setCanMinimize(bool can_minimize); void setCanClose(bool can_close); void setCanTearOff(bool can_tear_off); virtual void setCanResize(bool can_resize); void setCanDrag(bool can_drag); - bool getCanDrag(); + bool getCanDrag() const; void setHost(LLMultiFloater* host); - bool isResizable() const { return mResizable; } + bool isResizable() const { return mResizable; } void setResizeLimits( S32 min_width, S32 min_height ); void getResizeLimits( S32* min_width, S32* min_height ) { *min_width = mMinWidth; *min_height = mMinHeight; } @@ -347,7 +347,7 @@ public: virtual void setDocked(bool docked, bool pop_on_undock = true); virtual void setTornOff(bool torn_off) { mTornOff = torn_off; } - bool isTornOff() {return mTornOff;} + bool isTornOff() const { return mTornOff; } void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mPositioning = pos;} @@ -425,7 +425,6 @@ protected: private: void setForeground(bool b); // called only by floaterview void cleanupHandles(); // remove handles to dead floaters - void createMinimizeButton(); void buildButtons(const Params& p); // Images and tooltips are named in the XML, but we want to look them diff --git a/indra/llui/llfloaterreglistener.h b/indra/llui/llfloaterreglistener.h index a36072892c..28f6e7c66b 100644 --- a/indra/llui/llfloaterreglistener.h +++ b/indra/llui/llfloaterreglistener.h @@ -30,7 +30,6 @@ #define LL_LLFLOATERREGLISTENER_H #include "lleventapi.h" -#include <string> class LLSD; diff --git a/indra/llui/llflyoutbutton.h b/indra/llui/llflyoutbutton.h index 7a49501318..73190fc984 100644 --- a/indra/llui/llflyoutbutton.h +++ b/indra/llui/llflyoutbutton.h @@ -54,7 +54,7 @@ protected: LLFlyoutButton(const Params&); friend class LLUICtrlFactory; public: - virtual void draw(); + void draw() override; void setToggleState(bool state); diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 1fa0ac137e..89fee5c9f1 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -97,7 +97,7 @@ public: LLFocusableElement* getLastKeyboardFocus() const { return mLastKeyboardFocus; } bool childHasKeyboardFocus( const LLView* parent ) const; void removeKeyboardFocusWithoutCallback( const LLFocusableElement* focus ); - bool getKeystrokesOnly() { return mKeystrokesOnly; } + bool getKeystrokesOnly() const { return mKeystrokesOnly; } void setKeystrokesOnly(bool keystrokes_only) { mKeystrokesOnly = keystrokes_only; } F32 getFocusFlashAmt() const; diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 7ed10d9223..368a86ea84 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -124,11 +124,11 @@ public: void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); } void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); } - bool getAllowMultiSelect() { return mAllowMultiSelect; } - bool getAllowDrag() { return mAllowDrag; } + bool getAllowMultiSelect() const { return mAllowMultiSelect; } + bool getAllowDrag() const { return mAllowDrag; } void setSingleFolderMode(bool is_single_mode) { mSingleFolderMode = is_single_mode; } - bool isSingleFolderMode() { return mSingleFolderMode; } + bool isSingleFolderMode() const { return mSingleFolderMode; } // Close all folders in the view void closeAllFolders(); @@ -142,7 +142,7 @@ public: virtual S32 getItemHeight() const; void arrangeAll() { mArrangeGeneration++; } - S32 getArrangeGeneration() { return mArrangeGeneration; } + S32 getArrangeGeneration() const { return mArrangeGeneration; } // applies filters to control visibility of items virtual void filter( LLFolderViewFilter& filter); @@ -221,33 +221,34 @@ public: void scrollToShowSelection(); void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect); void setScrollContainer( LLScrollContainer* parent ) { mScrollContainer = parent; } + LLScrollContainer* getScrollContainer() { return mScrollContainer; } LLRect getVisibleRect(); bool search(LLFolderViewItem* first_item, const std::string &search_string, bool backward); void setShowSelectionContext(bool show) { mShowSelectionContext = show; } bool getShowSelectionContext(); void setShowSingleSelection(bool show); - bool getShowSingleSelection() { return mShowSingleSelection; } - F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } - bool getUseEllipses() { return mUseEllipses; } - S32 getSelectedCount() { return (S32)mSelectedItems.size(); } + bool getShowSingleSelection() const { return mShowSingleSelection; } + F32 getSelectionFadeElapsedTime() const { return mMultiSelectionFadeTimer.getElapsedTimeF32(); } + bool getUseEllipses() const { return mUseEllipses; } + S32 getSelectedCount() const { return (S32)mSelectedItems.size(); } - void update(); // needs to be called periodically (e.g. once per frame) + void update(); // needs to be called periodically (e.g. once per frame) - bool needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; } - bool needsAutoRename() { return mNeedsAutoRename; } + bool needsAutoSelect() const { return mNeedsAutoSelect && !mAutoSelectOverride; } + bool needsAutoRename() const { return mNeedsAutoRename; } void setNeedsAutoRename(bool val) { mNeedsAutoRename = val; } void setPinningSelectedItem(bool val) { mPinningSelectedItem = val; } void setAutoSelectOverride(bool val) { mAutoSelectOverride = val; } - bool showItemLinkOverlays() { return mShowItemLinkOverlays; } + bool showItemLinkOverlays() const { return mShowItemLinkOverlays; } void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; } void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; } void setForceArrange(bool force) { mForceArrange = force; } - LLPanel* getParentPanel() { return mParentPanel.get(); } + LLPanel* getParentPanel() const { return mParentPanel.get(); } // DEBUG only void dumpSelectionInformation(); @@ -255,7 +256,7 @@ public: void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; } - bool useLabelSuffix() { return mUseLabelSuffix; } + bool useLabelSuffix() const { return mUseLabelSuffix; } virtual void updateMenu(); void finishRenamingItem( void ); @@ -391,7 +392,7 @@ public: virtual ~LLSelectFirstFilteredItem() {} virtual void doFolder(LLFolderViewFolder* folder); virtual void doItem(LLFolderViewItem* item); - bool wasItemSelected() { return mItemSelected || mFolderSelected; } + bool wasItemSelected() const { return mItemSelected || mFolderSelected; } protected: bool mItemSelected; bool mFolderSelected; diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 6d0cfcba95..9ca77dbe46 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -31,11 +31,12 @@ #include "llfolderviewitem.h" #include "llfolderview.h" #include "llfolderviewmodel.h" -#include "llpanel.h" #include "llcallbacklist.h" #include "llcriticaldamp.h" #include "llclipboard.h" #include "llfocusmgr.h" // gFocusMgr +#include "llnotificationsutil.h" +#include "llpanel.h" #include "lltrans.h" #include "llwindow.h" @@ -60,7 +61,11 @@ LLUIColor LLFolderViewItem::sSearchStatusColor; S32 LLFolderViewItem::sTopPad = 0; LLUIImagePtr LLFolderViewItem::sFolderArrowImg; LLUIImagePtr LLFolderViewItem::sSelectionImg; +LLUIImagePtr LLFolderViewItem::sFavoriteImg; +LLUIImagePtr LLFolderViewItem::sFavoriteContentImg; LLFontGL* LLFolderViewItem::sSuffixFont = nullptr; +LLUIColor LLFolderViewItem::sFavoriteColor; +bool LLFolderViewItem::sColorSetInitialized = false; // only integers can be initialized in header const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f; @@ -68,6 +73,9 @@ const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f; const LLColor4U DEFAULT_WHITE(255, 255, 255); +constexpr S32 FAVORITE_IMAGE_SIZE = 14; +constexpr S32 FAVORITE_IMAGE_PAD = 3; + //static LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style) @@ -102,6 +110,8 @@ void LLFolderViewItem::initClass() sTopPad = default_params.item_top_pad; sFolderArrowImg = default_params.folder_arrow_image; sSelectionImg = default_params.selection_image; + sFavoriteImg = default_params.favorite_image; + sFavoriteContentImg = default_params.favorite_content_image; sSuffixFont = getLabelFontForStyle(LLFontGL::NORMAL); sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); @@ -121,6 +131,8 @@ void LLFolderViewItem::cleanupClass() sFonts.clear(); sFolderArrowImg = nullptr; sSelectionImg = nullptr; + sFavoriteImg = nullptr; + sFavoriteContentImg = nullptr; sSuffixFont = nullptr; } @@ -129,13 +141,15 @@ void LLFolderViewItem::cleanupClass() LLFolderViewItem::Params::Params() : root(), listener(), + favorite_image("favorite_image"), + favorite_content_image("favorite_content_image"), folder_arrow_image("folder_arrow_image"), folder_indentation("folder_indentation"), selection_image("selection_image"), item_height("item_height"), item_top_pad("item_top_pad"), creation_date(), - allow_wear("allow_wear", true), + marketplace_item("marketplace_item", false), allow_drop("allow_drop", true), font_color("font_color"), font_highlight_color("font_highlight_color"), @@ -155,6 +169,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) : LLView(p), mLabelWidth(0), mLabelWidthDirty(false), + mIsFavorite(false), + mHasFavorites(false), mSuffixNeedsRefresh(false), mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT), mParentFolder( NULL ), @@ -175,7 +191,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mRoot(p.root), mViewModelItem(p.listener), mIsMouseOverTitle(false), - mAllowWear(p.allow_wear), + mMarketplaceItem(p.marketplace_item), mAllowDrop(p.allow_drop), mFontColor(p.font_color), mFontHighlightColor(p.font_highlight_color), @@ -189,6 +205,21 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mMaxFolderItemOverlap(p.max_folder_item_overlap), mDoubleClickOverride(p.double_click_override) { + if (!sColorSetInitialized) + { + sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); + sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE); + sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE); + sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE); + sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE); + sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); + sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE); + sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); + sFavoriteColor = LLUIColorTable::instance().getColor("InventoryFavoriteColor", DEFAULT_WHITE); + sColorSetInitialized = true; + } + if (mViewModelItem) { mViewModelItem->setFolderViewItem(this); @@ -211,6 +242,7 @@ bool LLFolderViewItem::postBuild() // getDisplayName() is expensive (due to internal getLabelSuffix() and name building) // it also sets search strings so it requires a filter reset mLabel = utf8str_to_wstring(vmi->getDisplayName()); + mIsFavorite = vmi->isFavorite() && !vmi->isItemInTrash(); setToolTip(vmi->getName()); // Dirty the filter flag of the model from the view (CHUI-849) @@ -325,6 +357,7 @@ void LLFolderViewItem::refresh() mLabel = utf8str_to_wstring(vmi.getDisplayName()); mLabelFontBuffer.reset(); + mIsFavorite = vmi.isFavorite() && !vmi.isItemInTrash(); setToolTip(vmi.getName()); // icons are slightly expensive to get, can be optimized // see LLInventoryIcon::getIcon() @@ -359,6 +392,8 @@ void LLFolderViewItem::refreshSuffix() mIconOpen = vmi->getIconOpen(); mIconOverlay = vmi->getIconOverlay(); + mIsFavorite = vmi->isFavorite() && !vmi->isItemInTrash(); + if (mRoot->useLabelSuffix()) { // Very Expensive! @@ -428,6 +463,10 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height ) } mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel.c_str()) + getLabelFontForStyle(LLFontGL::NORMAL)->getWidth(mLabelSuffix.c_str()) + mLabelPaddingRight; mLabelWidthDirty = false; + if (mIsFavorite) + { + mLabelWidth += FAVORITE_IMAGE_SIZE + FAVORITE_IMAGE_PAD; + } } *width = llmax(*width, mLabelWidth); @@ -554,10 +593,15 @@ void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags) void LLFolderViewItem::openItem( void ) { - if (mAllowWear || !getViewModelItem()->isItemWearable()) + if (!mMarketplaceItem || !getViewModelItem()->isItemWearable()) { getViewModelItem()->openItem(); } + else if (mMarketplaceItem) + { + // Wearing an object from any listing, active or not, is verbotten + LLNotificationsUtil::add("AlertMerchantListingCannotWear"); + } } void LLFolderViewItem::rename(const std::string& new_name) @@ -771,6 +815,45 @@ void LLFolderViewItem::drawOpenFolderArrow() } } +void LLFolderViewItem::drawFavoriteIcon() +{ + static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true); + static LLUICachedControl<bool> draw_hollow_star("InventoryFavoritesUseHollowStar", true); + + LLUIImage* favorite_image = nullptr; + if (draw_star && mIsFavorite) + { + favorite_image = sFavoriteImg; + } + else if (draw_hollow_star && mHasFavorites && !isOpen()) + { + favorite_image = sFavoriteContentImg; + } + + if (favorite_image) + { + S32 x_offset = 0; + LLScrollContainer* scroll = mRoot->getScrollContainer(); + if (scroll) + { + S32 width = scroll->getVisibleContentRect().getWidth(); + S32 offset = scroll->getDocPosHorizontal(); + x_offset = width + offset; + } + else + { + x_offset = getRect().getWidth(); + } + gl_draw_scaled_image( + x_offset - FAVORITE_IMAGE_SIZE - FAVORITE_IMAGE_PAD, + getRect().getHeight() - mItemHeight + FAVORITE_IMAGE_PAD, + FAVORITE_IMAGE_SIZE, + FAVORITE_IMAGE_SIZE, + favorite_image->getImage(), + sFgColor); + } +} + /*virtual*/ bool LLFolderViewItem::isHighlightAllowed() { return mIsSelected; @@ -928,6 +1011,7 @@ void LLFolderViewItem::draw() { drawOpenFolderArrow(); } + drawFavoriteIcon(); drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); @@ -999,7 +1083,20 @@ void LLFolderViewItem::draw() } } - LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor; + static LLUICachedControl<bool> highlight_color("InventoryFavoritesColorText", true); + LLColor4 color; + if (mIsSelected && filled) + { + color = mFontHighlightColor; + } + else if (mIsFavorite && highlight_color) + { + color = sFavoriteColor; + } + else + { + color = mFontColor; + } if (isFadeItem()) { @@ -1093,7 +1190,8 @@ LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): mIsFolderComplete(false), // folder might have children that are not loaded yet. mAreChildrenInited(false), // folder might have children that are not built yet. mLastArrangeGeneration( -1 ), - mLastCalculatedWidth(0) + mLastCalculatedWidth(0), + mFavoritesDirtyFlags(0) { } @@ -1119,6 +1217,11 @@ LLFolderViewFolder::~LLFolderViewFolder( void ) // The LLView base class takes care of object destruction. make sure that we // don't have mouse or keyboard focus gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit() + + if (mFavoritesDirtyFlags) + { + gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, this); + } } // addToFolder() returns true if it succeeds. false otherwise @@ -1762,6 +1865,140 @@ bool LLFolderViewFolder::isMovable() return true; } +void LLFolderViewFolder::updateHasFavorites(bool new_childs_value) +{ + if (mFavoritesDirtyFlags == 0) + { + gIdleCallbacks.addFunction(&LLFolderViewFolder::onIdleUpdateFavorites, this); + } + if (new_childs_value) + { + mFavoritesDirtyFlags |= FAVORITE_ADDED; + } + else + { + mFavoritesDirtyFlags |= FAVORITE_REMOVED; + } +} + +void LLFolderViewFolder::onIdleUpdateFavorites(void* data) +{ + LLFolderViewFolder* self = reinterpret_cast<LLFolderViewFolder*>(data); + if (self->mFavoritesDirtyFlags == 0) + { + // already processed either on previous run or by a different callback + gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self); + return; + } + + if (self->getViewModelItem()->isItemInTrash()) + { + // do not display favorite-stars in trash + self->mFavoritesDirtyFlags = 0; + gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self); + return; + } + + if (self->mFavoritesDirtyFlags == FAVORITE_ADDED) + { + if (!self->mHasFavorites) + { + // propagate up, exclude root + LLFolderViewFolder* parent = self; + while (parent + && (!parent->hasFavorites() || parent->mFavoritesDirtyFlags) + && !parent->getViewModelItem()->isAgentInventoryRoot()) + { + parent->setHasFavorites(true); + if (parent->mFavoritesDirtyFlags) + { + // Parent will remove onIdleUpdateFavorites later, don't remove now, + // We are inside gIdleCallbacks. Removing 'self' callback is safe, + // but removing 'parent' can invalidate following iterator + parent->mFavoritesDirtyFlags = 0; + } + parent = parent->getParentFolder(); + } + } + else + { + // already up to date + self->mFavoritesDirtyFlags = 0; + gIdleCallbacks.deleteFunction(&LLFolderViewFolder::onIdleUpdateFavorites, self); + } + } + else if (self->mFavoritesDirtyFlags > FAVORITE_ADDED) + { + // full check + LLFolderViewFolder* parent = self; + while (parent && !parent->getViewModelItem()->isAgentInventoryRoot()) + { + bool has_favorites = false; + for (items_t::iterator iter = parent->mItems.begin(); + iter != parent->mItems.end();) + { + items_t::iterator iit = iter++; + if ((*iit)->isFavorite()) + { + has_favorites = true; + break; + } + } + + for (folders_t::iterator iter = parent->mFolders.begin(); + iter != parent->mFolders.end() && !has_favorites;) + { + folders_t::iterator fit = iter++; + if ((*fit)->isFavorite() || (*fit)->hasFavorites()) + { + has_favorites = true; + break; + } + } + + if (!has_favorites) + { + if (parent->hasFavorites()) + { + parent->setHasFavorites(false); + } + else + { + // Nothing changed + break; + } + } + else + { + // propagate up, exclude root + while (parent + && (!parent->hasFavorites() || parent->mFavoritesDirtyFlags) + && !parent->getViewModelItem()->isAgentInventoryRoot()) + { + parent->setHasFavorites(true); + if (parent->mFavoritesDirtyFlags) + { + // Parent will remove onIdleUpdateFavorites later, don't remove now, + // We are inside gIdleCallbacks. Removing 'self' callback is safe, + // but removing 'parent' can invalidate following iterator + parent->mFavoritesDirtyFlags = 0; + } + parent = parent->getParentFolder(); + } + break; + } + if (parent->mFavoritesDirtyFlags) + { + // Parent will remove onIdleUpdateFavorites later, don't remove now. + // We are inside gIdleCallbacks. Removing 'self' callback is safe, + // but removing 'parent' can invalidate following iterator + parent->mFavoritesDirtyFlags = 0; + } + parent = parent->getParentFolder(); + } + } +} + bool LLFolderViewFolder::isRemovable() { diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index cc8a7d934c..c9b003b892 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -50,7 +50,9 @@ class LLFolderViewItem : public LLView public: struct Params : public LLInitParam::Block<Params, LLView::Params> { - Optional<LLUIImage*> folder_arrow_image, + Optional<LLUIImage*> favorite_image, + favorite_content_image, + folder_arrow_image, selection_image; Mandatory<LLFolderView*> root; Mandatory<LLFolderViewModelItem*> listener; @@ -60,7 +62,7 @@ public: item_top_pad; Optional<time_t> creation_date; - Optional<bool> allow_wear; + Optional<bool> marketplace_item; Optional<bool> allow_drop; Optional<LLUIColor> font_color; @@ -93,6 +95,8 @@ protected: LLWString mLabel; S32 mLabelWidth; bool mLabelWidthDirty; + bool mIsFavorite; + bool mHasFavorites; S32 mLabelPaddingRight; LLFolderViewFolder* mParentFolder; LLPointer<LLFolderViewModelItem> mViewModelItem; @@ -122,7 +126,7 @@ protected: mIsCurSelection, mDragAndDropTarget, mIsMouseOverTitle, - mAllowWear, + mMarketplaceItem, mAllowDrop, mSingleFolderMode, mDoubleClickOverride, @@ -133,6 +137,7 @@ protected: LLUIColor mFontColor; LLUIColor mFontHighlightColor; + static bool sColorSetInitialized; // For now assuming all colors are the same in derived classes. static LLUIColor sFgColor; @@ -145,6 +150,8 @@ protected: static LLUIColor sFilterTextColor; static LLUIColor sSuffixColor; static LLUIColor sSearchStatusColor; + static LLUIColor sFavoriteColor; + // this is an internal method used for adding items to folders. A // no-op at this level, but reimplemented in derived classes. @@ -154,7 +161,7 @@ protected: virtual bool isHighlightActive(); virtual bool isFadeItem(); virtual bool isFlashing() { return false; } - virtual void setFlashState(bool) { } + virtual void setFlashState(bool, bool) { } static LLFontGL* getLabelFontForStyle(U8 style); const LLFontGL* getLabelFont(); @@ -208,6 +215,8 @@ public: // Returns true is this object and all of its children can be moved virtual bool isMovable(); + bool isFavorite() const { return mIsFavorite; } + // destroys this item recursively virtual void destroyView(); @@ -282,7 +291,7 @@ public: // Does not need filter update virtual void refreshSuffix(); - bool isSingleFolderMode() { return mSingleFolderMode; } + bool isSingleFolderMode() const { return mSingleFolderMode; } // LLView functionality virtual bool handleRightMouseDown( S32 x, S32 y, MASK mask ); @@ -298,6 +307,7 @@ public: // virtual void handleDropped(); virtual void draw(); void drawOpenFolderArrow(); + void drawFavoriteIcon(); void drawHighlight(bool showContent, bool hasKeyboardFocus, const LLUIColor& selectColor, const LLUIColor& flashColor, const LLUIColor& outlineColor, const LLUIColor& mouseOverColor); void drawLabel(const LLFontGL* font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x); virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, @@ -311,6 +321,8 @@ private: static S32 sTopPad; static LLUIImagePtr sFolderArrowImg; static LLUIImagePtr sSelectionImg; + static LLUIImagePtr sFavoriteImg; + static LLUIImagePtr sFavoriteContentImg; static LLFontGL* sSuffixFont; LLFontVertexBuffer mLabelFontBuffer; @@ -400,6 +412,18 @@ public: // Returns true is this object and all of its children can be moved virtual bool isMovable(); + bool isFavorite() const { return mIsFavorite; } + bool hasFavorites() const { return mHasFavorites; } + void setHasFavorites(bool val) { mHasFavorites = val; } + void updateHasFavorites(bool new_childs_value); +private: + static void onIdleUpdateFavorites(void* data); + + constexpr static S32 FAVORITE_ADDED = 1; + constexpr static S32 FAVORITE_REMOVED = 2; + S32 mFavoritesDirtyFlags { 0 }; +public: + // destroys this folder, and all children virtual void destroyView(); void destroyRoot(); @@ -415,9 +439,6 @@ public: // doesn't delete it. virtual void extractItem( LLFolderViewItem* item, bool deparent_model = true); - // This function is called by a child that needs to be resorted. - void resort(LLFolderViewItem* item); - void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; } // folders can be opened. This will usually be called by internal diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 9372818ca5..2865b789b9 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -162,6 +162,7 @@ public: virtual void navigateToFolder(bool new_window = false, bool change_mode = false) = 0; + virtual bool isFavorite() const = 0; virtual bool isItemWearable() const { return false; } virtual bool isItemRenameable() const = 0; @@ -170,7 +171,8 @@ public: virtual bool isItemMovable( void ) const = 0; // Can be moved to another folder virtual void move( LLFolderViewModelItem* parent_listener ) = 0; - virtual bool isItemRemovable( bool check_worn = true ) const = 0; // Can be destroyed + virtual bool isItemRemovable( bool check_worn = true) const = 0; // Can be destroyed + virtual bool isItemInTrash(void) const = 0; virtual bool removeItem() = 0; virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0; @@ -183,6 +185,9 @@ public: virtual void pasteFromClipboard() = 0; virtual void pasteLinkFromClipboard() = 0; + virtual bool isAgentInventory() const = 0; + virtual bool isAgentInventoryRoot() const = 0; + virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet? @@ -219,6 +224,7 @@ public: virtual S32 getSortVersion() = 0; virtual void setSortVersion(S32 version) = 0; virtual void setParent(LLFolderViewModelItem* parent) = 0; + virtual const LLFolderViewModelItem* getParent() = 0; virtual bool hasParent() = 0; protected: @@ -249,14 +255,14 @@ public: mChildren.clear(); } - void requestSort() { mSortVersion = -1; } - S32 getSortVersion() { return mSortVersion; } - void setSortVersion(S32 version) { mSortVersion = version;} + void requestSort() override { mSortVersion = -1; } + S32 getSortVersion() override { return mSortVersion; } + void setSortVersion(S32 version) override { mSortVersion = version;} - S32 getLastFilterGeneration() const { return mLastFilterGeneration; } + S32 getLastFilterGeneration() const override { return mLastFilterGeneration; } S32 getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; } - S32 getMarkedDirtyGeneration() const { return mMarkedDirtyGeneration; } - void dirtyFilter() + S32 getMarkedDirtyGeneration() const override { return mMarkedDirtyGeneration; } + void dirtyFilter() override { if(mMarkedDirtyGeneration < 0) { @@ -271,7 +277,7 @@ public: mParent->dirtyFilter(); } } - void dirtyDescendantsFilter() + void dirtyDescendantsFilter() override { mMostFilteredDescendantGeneration = -1; if (mParent) @@ -279,13 +285,13 @@ public: mParent->dirtyDescendantsFilter(); } } - bool hasFilterStringMatch(); - std::string::size_type getFilterStringOffset(); - std::string::size_type getFilterStringSize(); + bool hasFilterStringMatch() override; + std::string::size_type getFilterStringOffset() override; + std::string::size_type getFilterStringSize() override; - typedef std::list<LLFolderViewModelItem*> child_list_t; + typedef std::list<LLPointer<LLFolderViewModelItem> > child_list_t; - virtual void addChild(LLFolderViewModelItem* child) + virtual void addChild(LLFolderViewModelItem* child) override { mChildren.push_back(child); child->setParent(this); @@ -293,15 +299,15 @@ public: requestSort(); } - virtual void removeChild(LLFolderViewModelItem* child) + virtual void removeChild(LLFolderViewModelItem* child) override final { - mChildren.remove(child); child->setParent(NULL); + mChildren.remove(child); dirtyDescendantsFilter(); dirtyFilter(); } - virtual void clearChildren() + virtual void clearChildren() override { // We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); }); @@ -314,7 +320,7 @@ public: child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); } child_list_t::size_type getChildrenCount() const { return mChildren.size(); } - void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) + void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) override { mPassedFilter = passed; mLastFilterGeneration = filter_generation; @@ -323,20 +329,20 @@ public: mMarkedDirtyGeneration = -1; } - void setPassedFolderFilter(bool passed, S32 filter_generation) + void setPassedFolderFilter(bool passed, S32 filter_generation) override { mPassedFolderFilter = passed; mLastFolderFilterGeneration = filter_generation; } - virtual bool potentiallyVisible() + virtual bool potentiallyVisible() override { return passedFilter() // we've passed the filter || (getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration()) // or we don't know yet || descendantsPassedFilter(); } - virtual bool passedFilter(S32 filter_generation = -1) + virtual bool passedFilter(S32 filter_generation = -1) override { if (filter_generation < 0) { @@ -347,7 +353,7 @@ public: return passed_folder_filter && (passed_filter || descendantsPassedFilter(filter_generation)); } - virtual bool descendantsPassedFilter(S32 filter_generation = -1) + virtual bool descendantsPassedFilter(S32 filter_generation = -1) override { if (filter_generation < 0) { @@ -356,10 +362,10 @@ public: return mMostFilteredDescendantGeneration >= filter_generation; } - protected: - virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; } - virtual bool hasParent() { return mParent != NULL; } + virtual void setParent(LLFolderViewModelItem* parent) override final { mParent = parent; } + virtual const LLFolderViewModelItem* getParent() override { return mParent; }; + virtual bool hasParent() override { return mParent != NULL; } S32 mSortVersion; bool mPassedFilter; @@ -376,7 +382,7 @@ protected: LLFolderViewModelItem* mParent; LLFolderViewModelInterface& mRootViewModel; - void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;} + void setFolderViewItem(LLFolderViewItem* folder_view_item) override { mFolderViewItem = folder_view_item;} LLFolderViewItem* mFolderViewItem; }; @@ -390,15 +396,15 @@ public: mFolderView(NULL) {} - virtual void requestSortAll() + virtual void requestSortAll() override { // sort everything mTargetSortVersion++; } - virtual std::string getStatusText(bool is_empty_folder = false); - virtual void filter(); + virtual std::string getStatusText(bool is_empty_folder = false) override; + virtual void filter() override; - void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;} + void setFolderView(LLFolderView* folder_view) override { mFolderView = folder_view;} protected: bool needsSort(class LLFolderViewModelItem* item); @@ -428,14 +434,14 @@ public: virtual const SortType& getSorter() const { return *mSorter; } virtual void setSorter(const SortType& sorter) { mSorter.reset(new SortType(sorter)); requestSortAll(); } - virtual FilterType& getFilter() { return *mFilter; } - virtual const FilterType& getFilter() const { return *mFilter; } + virtual FilterType& getFilter() override { return *mFilter; } + virtual const FilterType& getFilter() const override { return *mFilter; } virtual void setFilter(const FilterType& filter) { mFilter.reset(new FilterType(filter)); } // By default, we assume the content is available. If a network fetch mechanism is implemented for the model, // this method needs to be overloaded and return the relevant fetch status. - virtual bool contentsReady() { return true; } - virtual bool isFolderComplete(LLFolderViewFolder* folder) { return true; } + virtual bool contentsReady() override { return true; } + virtual bool isFolderComplete(LLFolderViewFolder* folder) override { return true; } struct ViewModelCompare { @@ -456,7 +462,7 @@ public: const SortType& mSorter; }; - void sort(LLFolderViewFolder* folder) + void sort(LLFolderViewFolder* folder) override { if (needsSort(folder->getViewModelItem())) { diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 7bf43c22c1..2bea8fb4ed 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -170,7 +170,7 @@ std::string LLKeywords::getAttribute(std::string_view key) return (it != mAttributes.end()) ? it->second : ""; } -LLUIColor LLKeywords::getColorGroup(std::string_view key_in) +LLUIColor LLKeywords::getColorGroup(std::string_view key_in) const { std::string color_group = "ScriptText"; if (key_in == "functions") diff --git a/indra/llui/llkeywords.h b/indra/llui/llkeywords.h index 328561c92a..5892238593 100644 --- a/indra/llui/llkeywords.h +++ b/indra/llui/llkeywords.h @@ -111,8 +111,8 @@ public: ~LLKeywords(); void clearLoaded() { mLoaded = false; } - LLUIColor getColorGroup(std::string_view key_in); - bool isLoaded() const { return mLoaded; } + LLUIColor getColorGroup(std::string_view key_in) const; + bool isLoaded() const { return mLoaded; } void findSegments(std::vector<LLTextSegmentPtr> *seg_list, const LLWString& text, diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 1c59938f90..fe0591ce4b 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -36,8 +36,8 @@ #include "lliconctrl.h" #include "boost/foreach.hpp" -static const F32 MIN_FRACTIONAL_SIZE = 0.00001f; -static const F32 MAX_FRACTIONAL_SIZE = 1.f; +static constexpr F32 MIN_FRACTIONAL_SIZE = 0.00001f; +static constexpr F32 MAX_FRACTIONAL_SIZE = 1.f; static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack"); static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel"); diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 8459921c60..9e3536aaff 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -75,9 +75,6 @@ public: /*virtual*/ bool addChild(LLView* child, S32 tab_group = 0); /*virtual*/ void reshape(S32 width, S32 height, bool called_from_parent = true); - - static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); - typedef enum e_animate { NO_ANIMATE, @@ -86,7 +83,7 @@ public: void addPanel(LLLayoutPanel* panel, EAnimate animate = NO_ANIMATE); void collapsePanel(LLPanel* panel, bool collapsed = true); - S32 getNumPanels() { return static_cast<S32>(mPanels.size()); } + S32 getNumPanels() const { return static_cast<S32>(mPanels.size()); } void updateLayout(); @@ -190,7 +187,6 @@ public: bool isCollapsed() const { return mCollapsed;} void setOrientation(LLView::EOrientation orientation); - void storeOriginalDim(); void setIgnoreReshape(bool ignore) { mIgnoreReshape = ignore; } diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 66b274c33f..b534c8d4e8 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -2230,6 +2230,9 @@ void LLLineEditor::clear() { mText.clear(); setCursor(0); + mFontBufferPreSelection.reset(); + mFontBufferSelection.reset(); + mFontBufferPostSelection.reset(); } //virtual @@ -2505,9 +2508,24 @@ void LLLineEditor::resetPreedit() if (hasPreeditString()) { const S32 preedit_pos = mPreeditPositions.front(); - mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos); - mText.insert(preedit_pos, mPreeditOverwrittenWString); - setCursor(preedit_pos); + const S32 end = mPreeditPositions.back(); + const S32 len = end - preedit_pos; + const S32 size = mText.length(); + if (preedit_pos < size + && end <= size + && preedit_pos >= 0 + && len > 0) + { + mText.erase(preedit_pos, len); + mText.insert(preedit_pos, mPreeditOverwrittenWString); + setCursor(preedit_pos); + } + else + { + LL_WARNS() << "Index out of bounds. Start: " << preedit_pos + << ", end:" << end + << ", full string length: " << size << LL_ENDL; + } mPreeditWString.clear(); mPreeditOverwrittenWString.clear(); diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 12fe800acb..7533f76f1d 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -306,8 +306,6 @@ public: S32 calcCursorPos(S32 mouse_x); bool handleSpecialKey(KEY key, MASK mask); bool handleSelectionKey(KEY key, MASK mask); - bool handleControlKey(KEY key, MASK mask); - S32 handleCommitKey(KEY key, MASK mask); void updateTextPadding(); // Draw the background image depending on enabled/focused state. @@ -444,7 +442,7 @@ private: mText = ed->getText(); } - void doRollback( LLLineEditor* ed ) + void doRollback(LLLineEditor* ed) const { ed->mCursorPos = mCursorPos; ed->mScrollHPos = mScrollHPos; @@ -455,7 +453,7 @@ private: ed->mPrevText = mText; } - std::string getText() { return mText; } + std::string getText() const { return mText; } private: std::string mText; diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h index a77ae7dae7..3f96b28246 100644 --- a/indra/llui/llmenubutton.h +++ b/indra/llui/llmenubutton.h @@ -65,8 +65,8 @@ public: boost::signals2::connection setMouseDownCallback( const mouse_signal_t::slot_type& cb ); - /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleKeyHere(KEY key, MASK mask ); + bool handleMouseDown(S32 x, S32 y, MASK mask) override; + bool handleKeyHere(KEY key, MASK mask) override; void hideMenu(); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index c11b42a348..2ca2454040 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -46,6 +46,7 @@ #include "llfocusmgr.h" #include "llcoord.h" #include "llwindow.h" +#include "llemojihelper.h" #include "llcriticaldamp.h" #include "lluictrlfactory.h" @@ -1411,6 +1412,7 @@ void LLMenuItemBranchDownGL::openMenu( void ) } else { + LLEmojiHelper::instance().hideHelper(nullptr, true); if (branch->getTornOff()) { LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 66f84393fe..ff9456acc6 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -439,8 +439,6 @@ protected: public: virtual ~LLMenuGL( void ); - void parseChildXML(LLXMLNodePtr child, LLView* parent); - // LLView Functionality /*virtual*/ bool handleUnicodeCharHere( llwchar uni_char ); /*virtual*/ bool handleHover( S32 x, S32 y, MASK mask ); diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index c5c31f7252..225ff607ad 100644 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -28,6 +28,7 @@ #include "llmodaldialog.h" +#include "llemojihelper.h" #include "llfocusmgr.h" #include "v4color.h" #include "v2math.h" @@ -35,6 +36,7 @@ #include "llwindow.h" #include "llkeyboard.h" #include "llmenugl.h" + // static std::list<LLModalDialog*> LLModalDialog::sModalStack; @@ -98,7 +100,7 @@ void LLModalDialog::onOpen(const LLSD& key) { if (mModal) { - // If Modal, Hide the active modal dialog + // If Modal, hide the active modal dialog if (!sModalStack.empty()) { LLModalDialog* front = sModalStack.front(); @@ -155,6 +157,12 @@ void LLModalDialog::setVisible( bool visible ) { if( visible ) { + // Hide all menus currently shown + LLMenuGL::sMenuContainer->hideMenus(); + + // Hide EmojiPicker if it is shown + LLEmojiHelper::instance().hideHelper(nullptr, true); + // This is a modal dialog. It sucks up all mouse and keyboard operations. gFocusMgr.setMouseCapture( this ); @@ -301,7 +309,6 @@ void LLModalDialog::centerOnScreen() centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY]))); } - // static void LLModalDialog::onAppFocusLost() { @@ -333,6 +340,7 @@ void LLModalDialog::onAppFocusGained() } } +// static void LLModalDialog::shutdownModals() { // This method is only for use during app shutdown. ~LLModalDialog() diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp index a7f9b8b2d9..f53e22c349 100644 --- a/indra/llui/llmultifloater.cpp +++ b/indra/llui/llmultifloater.cpp @@ -390,7 +390,7 @@ LLFloater* LLMultiFloater::getActiveFloater() return (LLFloater*)mTabContainer->getCurrentPanel(); } -S32 LLMultiFloater::getFloaterCount() +S32 LLMultiFloater::getFloaterCount() const { return mTabContainer->getTabCount(); } diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h index eb0f917695..e0cd58aa3f 100644 --- a/indra/llui/llmultifloater.h +++ b/indra/llui/llmultifloater.h @@ -66,7 +66,7 @@ public: virtual LLFloater* getActiveFloater(); virtual bool isFloaterFlashing(LLFloater* floaterp); - virtual S32 getFloaterCount(); + virtual S32 getFloaterCount() const; virtual void setFloaterFlashing(LLFloater* floaterp, bool flashing); virtual bool closeAllFloaters(); //Returns false if the floater could not be closed due to pending confirmation dialogs diff --git a/indra/llui/llmultislider.h b/indra/llui/llmultislider.h index b2bfc8bc84..af255bcc8f 100644 --- a/indra/llui/llmultislider.h +++ b/indra/llui/llmultislider.h @@ -117,10 +117,10 @@ public: /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask) override; /*virtual*/ void draw() override; - S32 getMaxNumSliders() { return mMaxNumSliders; } - S32 getCurNumSliders() { return static_cast<S32>(mValue.size()); } - F32 getOverlapThreshold() { return mOverlapThreshold; } - bool canAddSliders() { return mValue.size() < mMaxNumSliders; } + S32 getMaxNumSliders() const { return mMaxNumSliders; } + S32 getCurNumSliders() const { return static_cast<S32>(mValue.size()); } + F32 getOverlapThreshold() const { return mOverlapThreshold; } + bool canAddSliders() const { return mValue.size() < mMaxNumSliders; } protected: diff --git a/indra/llui/llmultisliderctrl.h b/indra/llui/llmultisliderctrl.h index dec6cb48b9..2c2bc5e4d9 100644 --- a/indra/llui/llmultisliderctrl.h +++ b/indra/llui/llmultisliderctrl.h @@ -124,10 +124,10 @@ public: F32 getMinValue() const { return mMultiSlider->getMinValue(); } F32 getMaxValue() const { return mMultiSlider->getMaxValue(); } - S32 getMaxNumSliders() { return mMultiSlider->getMaxNumSliders(); } - S32 getCurNumSliders() { return mMultiSlider->getCurNumSliders(); } - F32 getOverlapThreshold() { return mMultiSlider->getOverlapThreshold(); } - bool canAddSliders() { return mMultiSlider->canAddSliders(); } + S32 getMaxNumSliders() const { return mMultiSlider->getMaxNumSliders(); } + S32 getCurNumSliders() const { return mMultiSlider->getCurNumSliders(); } + F32 getOverlapThreshold() const { return mMultiSlider->getOverlapThreshold(); } + bool canAddSliders() const { return mMultiSlider->canAddSliders(); } void setLabel(const std::string& label) { if (mLabelBox) mLabelBox->setText(label); } void setLabelColor(const LLUIColor& c) { mTextEnabledColor = c; } @@ -147,7 +147,6 @@ public: static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata); static void onEditorGainFocus(LLFocusableElement* caller, void *userdata); - static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); private: void updateText(); diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 138f1969d5..3c8e1e85fa 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -247,7 +247,6 @@ public: LLNotificationForm(const LLSD& sd); LLNotificationForm(const std::string& name, const Params& p); - void fromLLSD(const LLSD& sd); LLSD asLLSD() const; S32 getNumElements() { return static_cast<S32>(mFormData.size()); } @@ -266,8 +265,8 @@ public: bool getIgnored(); void setIgnored(bool ignored); - EIgnoreType getIgnoreType() { return mIgnore; } - std::string getIgnoreMessage() { return mIgnoreMsg; } + EIgnoreType getIgnoreType()const { return mIgnore; } + std::string getIgnoreMessage() const { return mIgnoreMsg; } private: LLSD mFormData; @@ -971,8 +970,6 @@ private: /*virtual*/ void initSingleton() override; /*virtual*/ void cleanupSingleton() override; - void loadPersistentNotifications(); - bool expirationFilter(LLNotificationPtr pNotification); bool expirationHandler(const LLSD& payload); bool uniqueFilter(LLNotificationPtr pNotification); diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h index 0d5d32cf21..7245bbf1cf 100644 --- a/indra/llui/llprogressbar.h +++ b/indra/llui/llprogressbar.h @@ -48,9 +48,9 @@ public: LLProgressBar(const Params&); virtual ~LLProgressBar(); - void setValue(const LLSD& value); + void setValue(const LLSD& value) override; - /*virtual*/ void draw(); + void draw() override; private: F32 mPercentDone; diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index 4b0f435834..68bf0fd95e 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -61,7 +61,7 @@ public: void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; } void setEnableSnapping(bool enable) { mSnappingEnabled = enable; } void setAllowDoubleClickSnapping(bool allow) { mAllowDoubleClickSnapping = allow; } - bool canResize() { return getEnabled() && mMaxSize > mMinSize; } + bool canResize() const { return getEnabled() && mMaxSize > mMinSize; } void setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;} void setImagePanel(LLPanel * panelp); LLPanel * getImagePanel() const; diff --git a/indra/llui/llresizehandle.h b/indra/llui/llresizehandle.h index 9cc4123544..caec33405c 100644 --- a/indra/llui/llresizehandle.h +++ b/indra/llui/llresizehandle.h @@ -50,10 +50,10 @@ protected: LLResizeHandle(const LLResizeHandle::Params&); friend class LLUICtrlFactory; public: - virtual void draw(); - virtual bool handleHover(S32 x, S32 y, MASK mask); - virtual bool handleMouseDown(S32 x, S32 y, MASK mask); - virtual bool handleMouseUp(S32 x, S32 y, MASK mask); + void draw() override; + bool handleHover(S32 x, S32 y, MASK mask) override; + bool handleMouseDown(S32 x, S32 y, MASK mask) override; + bool handleMouseUp(S32 x, S32 y, MASK mask) override; void setResizeLimits( S32 min_width, S32 min_height ) { mMinWidth = min_width; mMinHeight = min_height; } @@ -71,8 +71,8 @@ private: const ECorner mCorner; }; -const S32 RESIZE_HANDLE_HEIGHT = 11; -const S32 RESIZE_HANDLE_WIDTH = 11; +constexpr S32 RESIZE_HANDLE_HEIGHT = 11; +constexpr S32 RESIZE_HANDLE_WIDTH = 11; #endif // LL_RESIZEHANDLE_H diff --git a/indra/llui/llrngwriter.h b/indra/llui/llrngwriter.h index 33ec049a1a..2c39472607 100644 --- a/indra/llui/llrngwriter.h +++ b/indra/llui/llrngwriter.h @@ -37,7 +37,7 @@ public: void writeRNG(const std::string& name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace); void addDefinition(const std::string& type_name, const LLInitParam::BaseBlock& block); - /*virtual*/ std::string getCurrentElementName() { return LLStringUtil::null; } + std::string getCurrentElementName() override { return LLStringUtil::null; } LLRNGWriter(); diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index e7ff5c8424..7dded3c0b7 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -105,7 +105,7 @@ public: virtual const LLSD getAltValue() const; virtual void setValue(const LLSD& value) { } virtual void setAltValue(const LLSD& value) { } - virtual const std::string &getToolTip() const { return mToolTip; } + virtual const std::string& getToolTip() const { return mToolTip; } virtual void setToolTip(const std::string &str) { mToolTip = str; } virtual bool getVisible() const { return true; } virtual void setWidth(S32 width) { mWidth = width; } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 245339b107..ff77b4d482 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1007,7 +1007,7 @@ void LLScrollListCtrl::deleteItems(const LLSD& sd) void LLScrollListCtrl::deleteSelectedItems() { item_list::iterator iter; - for (iter = mItemList.begin(); iter < mItemList.end(); ) + for (iter = mItemList.begin(); iter != mItemList.end(); ) { LLScrollListItem* itemp = *iter; if (itemp->getSelected()) diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index c24784338a..1f04100306 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -165,7 +165,6 @@ public: void deleteAllItems() { clearRows(); } // Sets an array of column descriptors - void setColumnHeadings(const LLSD& headings); void sortByColumnIndex(U32 column, bool ascending); // LLCtrlListInterface functions @@ -318,7 +317,7 @@ public: void setAllowKeyboardMovement(bool b) { mAllowKeyboardMovement = b; } void setMaxSelectable(U32 max_selected) { mMaxSelectable = max_selected; } - S32 getMaxSelectable() { return mMaxSelectable; } + S32 getMaxSelectable() const { return mMaxSelectable; } virtual S32 getScrollPos() const; @@ -334,7 +333,7 @@ public: // support right-click context menus for avatar/group lists enum ContextMenuType { MENU_NONE, MENU_AVATAR, MENU_GROUP }; void setContextMenu(const ContextMenuType &menu) { mContextMenuType = menu; } - ContextMenuType getContextMenuType() { return mContextMenuType; } + ContextMenuType getContextMenuType() const { return mContextMenuType; } // Overridden from LLView /*virtual*/ void draw(); @@ -362,7 +361,6 @@ public: virtual void fitContents(S32 max_width, S32 max_height); virtual LLRect getRequiredRect(); - static bool rowPreceeds(LLScrollListItem *new_row, LLScrollListItem *test_row); LLRect getItemListRect() { return mItemListRect; } @@ -384,7 +382,6 @@ public: * then display all items. */ void setPageLines(S32 page_lines ); - void setCollapseEmptyColumns(bool collapse); LLScrollListItem* hitItem(S32 x,S32 y); virtual void scrollToShowSelected(); @@ -401,7 +398,7 @@ public: void setNumDynamicColumns(S32 num) { mNumDynamicWidthColumns = num; } void updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width); - S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; } + S32 getTotalStaticColumnWidth() const { return mTotalStaticColumnWidth; } std::string getSortColumnName(); bool getSortAscending() { return mSortColumns.empty() ? true : mSortColumns.back().second; } diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h index 311377a61f..23ce8fd955 100644 --- a/indra/llui/llsliderctrl.h +++ b/indra/llui/llsliderctrl.h @@ -132,7 +132,6 @@ public: static void onEditorCommit(LLUICtrl* ctrl, const LLSD& userdata); static void onEditorGainFocus(LLFocusableElement* caller, void *userdata); - static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); protected: virtual std::string _getSearchText() const diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index 58b38dc630..4ba8c97c63 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -94,7 +94,6 @@ public: void onEditorCommit(const LLSD& data); static void onEditorGainFocus(LLFocusableElement* caller, void *userdata); static void onEditorLostFocus(LLFocusableElement* caller, void *userdata); - static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); void onUpBtn(const LLSD& data); void onDownBtn(const LLSD& data); diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index c36a138566..bbbf0b3a19 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -67,7 +67,7 @@ public: void setStat(const std::string& stat_name); void setRange(F32 bar_min, F32 bar_max); - void getRange(F32& bar_min, F32& bar_max) { bar_min = mTargetMinBar; bar_max = mTargetMaxBar; } + void getRange(F32& bar_min, F32& bar_max) const { bar_min = mTargetMinBar; bar_max = mTargetMaxBar; } /*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options. diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index d97051247e..0af717d447 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -36,7 +36,6 @@ #include "llglheaders.h" #include "lltracerecording.h" #include "lltracethreadrecorder.h" -//#include "llviewercontrol.h" /////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index c254821870..6d9e3d1064 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -99,9 +99,7 @@ public: void setMin(const F32 min); void setMax(const F32 max); - virtual void draw(); - - /*virtual*/ void setValue(const LLSD& value); + void draw() override; private: LLTrace::StatType<LLTrace::CountAccumulator>* mNewStatFloatp; @@ -133,9 +131,6 @@ private: }; typedef std::vector<Threshold> threshold_vec_t; threshold_vec_t mThresholds; - //S32 mNumThresholds; - //F32 mThresholds[4]; - //LLColor4 mThresholdColors[4]; }; #endif // LL_LLSTATGRAPH_H diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h index b5187f886d..a396773057 100644 --- a/indra/llui/llstatview.h +++ b/indra/llui/llstatview.h @@ -29,7 +29,6 @@ #include "llstatbar.h" #include "llcontainerview.h" -#include <vector> class LLStatBar; diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index 4714665e8b..7a0e620d61 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -38,11 +38,13 @@ LLStyle::Params::Params() color("color", LLColor4::black), readonly_color("readonly_color", LLColor4::black), selected_color("selected_color", LLColor4::black), + highlight_bg_color("highlight_bg_color", LLColor4::green), alpha("alpha", 1.f), font("font", LLStyle::getDefaultFont()), image("image"), link_href("href"), - is_link("is_link") + is_link("is_link"), + draw_highlight_bg("draw_highlight_bg", false) {} @@ -51,12 +53,14 @@ LLStyle::LLStyle(const LLStyle::Params& p) mColor(p.color), mReadOnlyColor(p.readonly_color), mSelectedColor(p.selected_color), + mHighlightBgColor(p.highlight_bg_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()), - mAlpha(p.alpha) + mAlpha(p.alpha), + mDrawHighlightBg(p.draw_highlight_bg) {} void LLStyle::setFont(const LLFontGL* font) diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 0c78fe5a9f..71c3f88109 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -43,15 +43,25 @@ public: Optional<LLFontGL::ShadowType> drop_shadow; Optional<LLUIColor> color, readonly_color, - selected_color; + selected_color, + highlight_bg_color; Optional<F32> alpha; Optional<const LLFontGL*> font; Optional<LLUIImage*> image; Optional<std::string> link_href; Optional<bool> is_link; + Optional<bool> draw_highlight_bg; Params(); }; LLStyle(const Params& p = Params()); + + enum EUnderlineLink + { + UNDERLINE_ALWAYS = 0, + UNDERLINE_ON_HOVER, + UNDERLINE_NEVER + }; + public: const LLUIColor& getColor() const { return mColor; } void setColor(const LLUIColor &color) { mColor = color; } @@ -84,6 +94,9 @@ public: bool isImage() const { return mImagep.notNull(); } + bool getDrawHighlightBg() const { return mDrawHighlightBg; } + const LLUIColor& getHighlightBgColor() const { return mHighlightBgColor; } + bool operator==(const LLStyle &rhs) const { return @@ -91,11 +104,13 @@ public: && mColor == rhs.mColor && mReadOnlyColor == rhs.mReadOnlyColor && mSelectedColor == rhs.mSelectedColor + && mHighlightBgColor == rhs.mHighlightBgColor && mFont == rhs.mFont && mLink == rhs.mLink && mImagep == rhs.mImagep && mDropShadow == rhs.mDropShadow - && mAlpha == rhs.mAlpha; + && mAlpha == rhs.mAlpha + && mDrawHighlightBg == rhs.mDrawHighlightBg; } bool operator!=(const LLStyle& rhs) const { return !(*this == rhs); } @@ -112,11 +127,13 @@ private: LLUIColor mColor; LLUIColor mReadOnlyColor; LLUIColor mSelectedColor; + LLUIColor mHighlightBgColor; const LLFontGL* mFont; LLPointer<LLUIImage> mImagep; F32 mAlpha; bool mVisible; bool mIsLink; + bool mDrawHighlightBg; }; typedef LLPointer<LLStyle> LLStyleSP; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 595ab0bd2b..5e0985c79c 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1370,17 +1370,17 @@ LLPanel* LLTabContainer::getCurrentPanel() return NULL; } -S32 LLTabContainer::getCurrentPanelIndex() +S32 LLTabContainer::getCurrentPanelIndex() const { return mCurrentTabIdx; } -S32 LLTabContainer::getTabCount() +S32 LLTabContainer::getTabCount() const { return static_cast<S32>(mTabList.size()); } -LLPanel* LLTabContainer::getPanelByIndex(S32 index) +LLPanel* LLTabContainer::getPanelByIndex(S32 index) const { if (index >= 0 && index < (S32)mTabList.size()) { @@ -1389,7 +1389,7 @@ LLPanel* LLTabContainer::getPanelByIndex(S32 index) return NULL; } -S32 LLTabContainer::getIndexForPanel(LLPanel* panel) +S32 LLTabContainer::getIndexForPanel(LLPanel* panel) const { for (S32 index = 0; index < (S32)mTabList.size(); index++) { @@ -1401,7 +1401,7 @@ S32 LLTabContainer::getIndexForPanel(LLPanel* panel) return -1; } -S32 LLTabContainer::getPanelIndexByTitle(std::string_view title) +S32 LLTabContainer::getPanelIndexByTitle(std::string_view title) const { for (S32 index = 0 ; index < (S32)mTabList.size(); index++) { diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 40f272ffa8..4ac7e73d25 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -182,15 +182,15 @@ public: void removeTabPanel( LLPanel* child ); void lockTabs(S32 num_tabs = 0); void unlockTabs(); - S32 getNumLockedTabs() { return mLockedTabCount; } + S32 getNumLockedTabs() const { return mLockedTabCount; } void enableTabButton(S32 which, bool enable); void deleteAllTabs(); LLPanel* getCurrentPanel(); - S32 getCurrentPanelIndex(); - S32 getTabCount(); - LLPanel* getPanelByIndex(S32 index); - S32 getIndexForPanel(LLPanel* panel); - S32 getPanelIndexByTitle(std::string_view title); + S32 getCurrentPanelIndex() const; + S32 getTabCount() const; + LLPanel* getPanelByIndex(S32 index) const; + S32 getIndexForPanel(LLPanel* panel) const; + S32 getPanelIndexByTitle(std::string_view title) const; LLPanel* getPanelByName(std::string_view name); S32 getTotalTabWidth() const; void setCurrentTabName(const std::string& name); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 41e7094163..d5755ae4b6 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -460,6 +460,62 @@ std::vector<LLRect> LLTextBase::getSelectionRects() return selection_rects; } +std::vector<std::pair<LLRect, LLUIColor>> LLTextBase::getHighlightedBgRects() +{ + std::vector<std::pair<LLRect, LLUIColor>> highlight_rects; + + LLRect content_display_rect = getVisibleDocumentRect(); + + // binary search for line that starts before top of visible buffer + line_list_t::const_iterator line_iter = + std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); + line_list_t::const_iterator end_iter = + std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); + + for (; line_iter != end_iter; ++line_iter) + { + segment_set_t::iterator segment_iter; + S32 segment_offset; + getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); + + // Use F32 otherwise a string of multiple segments + // will accumulate a large error + F32 left_precise = (F32)line_iter->mRect.mLeft; + F32 right_precise = (F32)line_iter->mRect.mLeft; + + for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) + { + LLTextSegmentPtr segmentp = *segment_iter; + + S32 segment_line_start = segmentp->getStart() + segment_offset; + S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); + + if (segment_line_start > segment_line_end) + break; + + F32 segment_width = 0; + S32 segment_height = 0; + + S32 num_chars = segment_line_end - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + + if (segmentp->getStyle()->getDrawHighlightBg()) + { + LLRect selection_rect; + selection_rect.mLeft = (S32)left_precise; + selection_rect.mRight = (S32)right_precise; + selection_rect.mBottom = line_iter->mRect.mBottom; + selection_rect.mTop = line_iter->mRect.mTop; + + highlight_rects.push_back(std::pair(selection_rect, segmentp->getStyle()->getHighlightBgColor())); + } + left_precise += segment_width; + } + } + return highlight_rects; +} + // Draws the black box behind the selected text void LLTextBase::drawSelectionBackground() { @@ -529,6 +585,71 @@ void LLTextBase::drawSelectionBackground() } } +void LLTextBase::drawHighlightedBackground() +{ + if (!mLineInfoList.empty()) + { + std::vector<std::pair<LLRect, LLUIColor>> highlight_rects = getHighlightedBgRects(); + + if (highlight_rects.empty()) + return; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + LLRect content_display_rect = getVisibleDocumentRect(); + + for (std::vector<std::pair<LLRect, LLUIColor>>::iterator rect_it = highlight_rects.begin(); + rect_it != highlight_rects.end(); ++rect_it) + { + LLRect selection_rect = rect_it->first; + const LLColor4& color = rect_it->second; + if (mScroller) + { + // If scroller is On content_display_rect has correct rect and safe to use as is + // Note: we might need to account for border + selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom); + } + else + { + // If scroller is Off content_display_rect will have rect from document, adjusted to text width, heigh and position + // and we have to acount for offset depending on position + S32 v_delta = 0; + S32 h_delta = 0; + switch (mVAlign) + { + case LLFontGL::TOP: + v_delta = mVisibleTextRect.mTop - content_display_rect.mTop - mVPad; + break; + case LLFontGL::VCENTER: + v_delta = (llmax(mVisibleTextRect.getHeight() - content_display_rect.mTop, -content_display_rect.mBottom) + (mVisibleTextRect.mBottom - content_display_rect.mBottom)) / 2; + break; + case LLFontGL::BOTTOM: + v_delta = mVisibleTextRect.mBottom - content_display_rect.mBottom; + break; + default: + break; + } + switch (mHAlign) + { + case LLFontGL::LEFT: + h_delta = mVisibleTextRect.mLeft - content_display_rect.mLeft + mHPad; + break; + case LLFontGL::HCENTER: + h_delta = (llmax(mVisibleTextRect.getWidth() - content_display_rect.mLeft, -content_display_rect.mRight) + (mVisibleTextRect.mRight - content_display_rect.mRight)) / 2; + break; + case LLFontGL::RIGHT: + h_delta = mVisibleTextRect.mRight - content_display_rect.mRight; + break; + default: + break; + } + selection_rect.translate(h_delta, v_delta); + } + gl_rect_2d(selection_rect, color); + } + } +} + void LLTextBase::drawCursor() { F32 alpha = getDrawContext().mAlpha; @@ -1399,6 +1520,7 @@ void LLTextBase::draw() drawChild(mDocumentView); } + drawHighlightedBackground(); drawSelectionBackground(); drawText(); drawCursor(); @@ -2105,7 +2227,9 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) registrar.add("Url.RemoveFriend", boost::bind(&LLUrlAction::removeFriend, url)); registrar.add("Url.ReportAbuse", boost::bind(&LLUrlAction::reportAbuse, url)); registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url)); + registrar.add("Url.ZoomInObject", boost::bind(&LLUrlAction::zoomInObject, url)); registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url)); + registrar.add("Url.ShowParcelOnMap", boost::bind(&LLUrlAction::showParcelOnMap, url)); registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url)); registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url)); @@ -2200,20 +2324,20 @@ static LLUIImagePtr image_from_icon_name(const std::string& icon_name) } -void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params) +void LLTextBase::appendTextImpl(const std::string& new_text, const LLStyle::Params& input_params, bool force_slurl) { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; LLStyle::Params style_params(getStyleParams()); style_params.overwriteFrom(input_params); S32 part = (S32)LLTextParser::WHOLE; - if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358). + if ((mParseHTML || force_slurl) && !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::replaceUrl, this, _1, _2, _3), isContentTrusted() || mAlwaysShowIcons)) + boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3), isContentTrusted() || mAlwaysShowIcons, force_slurl)) { start = match.getStart(); end = match.getEnd()+1; @@ -2245,7 +2369,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para } // output the styled Url - appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.underlineOnHoverOnly()); + appendAndHighlightTextImpl(match.getLabel(), part, link_params, match.getUnderline()); bool tooltip_required = !match.getTooltip().empty(); // set the tooltip for the Url label @@ -2260,7 +2384,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para { link_params.color = LLColor4::grey; link_params.readonly_color = LLColor4::grey; - appendAndHighlightTextImpl(label, part, link_params, match.underlineOnHoverOnly()); + appendAndHighlightTextImpl(label, part, link_params, match.getUnderline()); // set the tooltip for the query part of url if (tooltip_required) @@ -2428,7 +2552,7 @@ void LLTextBase::appendWidget(const LLInlineViewSegment::Params& params, const s insertStringNoUndo(getLength(), widget_wide_text, &segments); } -void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) +void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, e_underline underline_link) { // Save old state S32 selection_start = mSelectionStart; @@ -2458,7 +2582,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 cur_length = getLength(); LLStyleConstSP sp(new LLStyle(highlight_params)); LLTextSegmentPtr segmentp; - if (underline_on_hover_only || mSkipLinkUnderline) + if ((underline_link == e_underline::UNDERLINE_ON_HOVER) || mSkipLinkUnderline) { highlight_params.font.style("NORMAL"); LLStyleConstSP normal_sp(new LLStyle(highlight_params)); @@ -2482,7 +2606,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig S32 segment_start = old_length; S32 segment_end = old_length + static_cast<S32>(wide_text.size()); LLStyleConstSP sp(new LLStyle(style_params)); - if (underline_on_hover_only || mSkipLinkUnderline) + if ((underline_link == e_underline::UNDERLINE_ON_HOVER) || mSkipLinkUnderline) { LLStyle::Params normal_style_params(style_params); normal_style_params.font.style("NORMAL"); @@ -2516,7 +2640,7 @@ void LLTextBase::appendAndHighlightTextImpl(const std::string &new_text, S32 hig } } -void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only) +void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, e_underline underline_link) { if (new_text.empty()) { @@ -2531,7 +2655,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig if (pos != start) { std::string str = std::string(new_text,start,pos-start); - appendAndHighlightTextImpl(str, highlight_part, style_params, underline_on_hover_only); + appendAndHighlightTextImpl(str, highlight_part, style_params, underline_link); } appendLineBreakSegment(style_params); start = pos+1; @@ -2539,7 +2663,7 @@ void LLTextBase::appendAndHighlightText(const std::string &new_text, S32 highlig } std::string str = std::string(new_text, start, new_text.length() - start); - appendAndHighlightTextImpl(str, highlight_part, style_params, underline_on_hover_only); + appendAndHighlightTextImpl(str, highlight_part, style_params, underline_link); } @@ -3336,6 +3460,7 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e mLastGeneration(-1) { mFontHeight = mStyle->getFont()->getLineHeight(); + mCanEdit = !mStyle->getDrawHighlightBg(); LLUIImagePtr image = mStyle->getImage(); if (image.notNull()) diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 76d4e160af..8ca653acb9 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -35,6 +35,7 @@ #include "llstyle.h" #include "llkeywords.h" #include "llpanel.h" +#include "llurlmatch.h" #include <string> #include <vector> @@ -139,13 +140,12 @@ public: /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; /*virtual*/ void updateLayout(const class LLTextBase& editor); /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); - /*virtual*/ bool canEdit() const { return true; } + /*virtual*/ bool canEdit() const { return mCanEdit; } /*virtual*/ const LLUIColor& getColor() const { return mStyle->getColor(); } /*virtual*/ LLStyleConstSP getStyle() const { return mStyle; } /*virtual*/ void setStyle(LLStyleConstSP style) { mStyle = style; } /*virtual*/ void setToken( LLKeywordToken* token ) { mToken = token; } /*virtual*/ LLKeywordToken* getToken() const { return mToken; } - /*virtual*/ bool getToolTip( std::string& msg ) const; /*virtual*/ void setToolTip(const std::string& tooltip); /*virtual*/ void dump() const; @@ -162,6 +162,8 @@ protected: virtual const LLWString& getWText() const; virtual const S32 getLength() const; + void setAllowEdit(bool can_edit) { mCanEdit = can_edit; } + protected: class LLTextBase& mEditor; LLStyleConstSP mStyle; @@ -170,6 +172,8 @@ protected: std::string mTooltip; boost::signals2::connection mImageLoadedConnection; + bool mCanEdit { true }; + // font rendering LLFontVertexBuffer mFontBufferPreSelection; LLFontVertexBuffer mFontBufferSelection; @@ -450,7 +454,7 @@ public: virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style /*virtual*/ const std::string& getText() const override; void setMaxTextLength(S32 length) { mMaxTextByteLength = length; } - S32 getMaxTextLength() { return mMaxTextByteLength; } + S32 getMaxTextLength() const { return mMaxTextByteLength; } // wide-char versions void setWText(const LLWString& text); @@ -489,10 +493,10 @@ public: LLRect getTextBoundingRect(); LLRect getVisibleDocumentRect() const; - S32 getVPad() { return mVPad; } - S32 getHPad() { return mHPad; } - F32 getLineSpacingMult() { return mLineSpacingMult; } - S32 getLineSpacingPixels() { return mLineSpacingPixels; } // only for multiline + S32 getVPad() const { return mVPad; } + S32 getHPad() const { return mHPad; } + F32 getLineSpacingMult() const { return mLineSpacingMult; } + S32 getLineSpacingPixels() const { return mLineSpacingPixels; } // only for multiline S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, bool round, bool hit_past_end_of_line = true) const; LLRect getLocalRectFromDocIndex(S32 pos) const; @@ -502,7 +506,7 @@ public: bool getReadOnly() const { return mReadOnly; } void setSkipLinkUnderline(bool skip_link_underline) { mSkipLinkUnderline = skip_link_underline; } - bool getSkipLinkUnderline() { return mSkipLinkUnderline; } + bool getSkipLinkUnderline() const { return mSkipLinkUnderline; } void setParseURLs(bool parse_urls) { mParseHTML = parse_urls; } @@ -516,8 +520,8 @@ public: void endOfLine(); void startOfDoc(); void endOfDoc(); - void changePage( S32 delta ); - void changeLine( S32 delta ); + void changePage(S32 delta); + void changeLine(S32 delta); bool scrolledToStart(); bool scrolledToEnd(); @@ -607,6 +611,7 @@ protected: bool operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const; }; typedef std::multiset<LLTextSegmentPtr, compare_segment_end> segment_set_t; + typedef LLStyle::EUnderlineLink e_underline; // member functions LLTextBase(const Params &p); @@ -620,12 +625,13 @@ protected: virtual void drawSelectionBackground(); // draws the black box behind the selected text void drawCursor(); void drawText(); + void drawHighlightedBackground(); // modify contents S32 insertStringNoUndo(S32 pos, const LLWString &wstr, segment_vec_t* segments = NULL); // returns num of chars actually inserted S32 removeStringNoUndo(S32 pos, S32 length); S32 overwriteCharNoUndo(S32 pos, llwchar wc); - void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep, bool underline_on_hover_only = false); + void appendAndHighlightText(const std::string &new_text, S32 highlight_part, const LLStyle::Params& stylep, e_underline underline_link = e_underline::UNDERLINE_ALWAYS); // manage segments @@ -673,8 +679,8 @@ protected: // 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); + void appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params = LLStyle::Params(), bool force_slurl = false); + void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, e_underline underline_link = e_underline::UNDERLINE_ALWAYS); S32 normalizeUri(std::string& uri); protected: @@ -685,6 +691,7 @@ protected: } std::vector<LLRect> getSelectionRects(); + std::vector<std::pair<LLRect, LLUIColor>> getHighlightedBgRects(); protected: // text segmentation and flow diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 500dc8669f..507d8f3ee6 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -46,39 +46,39 @@ protected: friend class LLUICtrlFactory; public: - virtual ~LLTextBox(); + ~LLTextBox() override; - /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleMouseUp(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask); + bool handleMouseDown(S32 x, S32 y, MASK mask) override; + bool handleMouseUp(S32 x, S32 y, MASK mask) override; + bool handleHover(S32 x, S32 y, MASK mask) override; - /*virtual*/ void setEnabled(bool enabled); + void setEnabled(bool enabled) override; - /*virtual*/ void setText( const LLStringExplicit& text, const LLStyle::Params& input_params = LLStyle::Params() ); + void setText(const LLStringExplicit& text, const LLStyle::Params& input_params = LLStyle::Params()) override; - void setRightAlign() { mHAlign = LLFontGL::RIGHT; } - void setHAlign( LLFontGL::HAlign align ) { mHAlign = align; } - void setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL ); + void setRightAlign() { mHAlign = LLFontGL::RIGHT; } + void setHAlign(LLFontGL::HAlign align) { mHAlign = align; } + void setClickedCallback(boost::function<void(void*)> cb, void* userdata = NULL); - void reshapeToFitText(bool called_from_parent = false); + void reshapeToFitText(bool called_from_parent = false); - S32 getTextPixelWidth(); - S32 getTextPixelHeight(); + S32 getTextPixelWidth(); + S32 getTextPixelHeight(); - /*virtual*/ LLSD getValue() const; - /*virtual*/ bool setTextArg( const std::string& key, const LLStringExplicit& text ); + LLSD getValue() const override; + bool setTextArg(const std::string& key, const LLStringExplicit& text) override; - void setShowCursorHand(bool show_cursor) { mShowCursorHand = show_cursor; } + void setShowCursorHand(bool show_cursor) { mShowCursorHand = show_cursor; } protected: - void onUrlLabelUpdated(const std::string &url, const std::string &label); + void onUrlLabelUpdated(const std::string& url, const std::string& label); LLUIString mText; callback_t mClickedCallback; bool mShowCursorHand; protected: - virtual std::string _getSearchText() const + virtual std::string _getSearchText() const override { return LLTextBase::_getSearchText() + mText.getString(); } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index fe4cce29ab..58b785fcdd 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -60,6 +60,7 @@ #include "llurlregistry.h" #include "lltooltip.h" #include "llmenugl.h" +#include "llchatmentionhelper.h" #include <queue> #include "llcombobox.h" @@ -270,9 +271,12 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : mPrevalidator(p.prevalidator()), mShowContextMenu(p.show_context_menu), mShowEmojiHelper(p.show_emoji_helper), + mShowChatMentionPicker(false), mEnableTooltipPaste(p.enable_tooltip_paste), mPassDelete(false), - mKeepSelectionOnReturn(false) + mKeepSelectionOnReturn(false), + mSelectAllOnFocusReceived(false), + mSelectedOnFocusReceived(false) { mSourceID.generate(); @@ -396,6 +400,7 @@ void LLTextEditor::selectNext(const std::string& search_text_in, bool case_insen setCursorPos(loc); mIsSelecting = true; + mSelectedOnFocusReceived = false; mSelectionEnd = mCursorPos; mSelectionStart = llmin((S32)getLength(), (S32)(mCursorPos + search_text.size())); } @@ -675,6 +680,13 @@ bool LLTextEditor::canSelectAll() const return true; } +//virtual +void LLTextEditor::deselect() +{ + LLTextBase::deselect(); + mSelectedOnFocusReceived = false; +} + // virtual void LLTextEditor::selectAll() { @@ -692,6 +704,11 @@ void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_p endSelection(); } +void LLTextEditor::setSelectAllOnFocusReceived(bool b) +{ + mSelectAllOnFocusReceived = b; +} + void LLTextEditor::insertEmoji(llwchar emoji) { LL_INFOS() << "LLTextEditor::insertEmoji(" << wchar_utf8_preview(emoji) << ")" << LL_ENDL; @@ -714,6 +731,30 @@ void LLTextEditor::handleEmojiCommit(llwchar emoji) } } +void LLTextEditor::handleMentionCommit(std::string name_url) +{ + S32 mention_start_pos; + if (LLChatMentionHelper::instance().isCursorInNameMention(getWText(), mCursorPos, &mention_start_pos)) + { + remove(mention_start_pos, mCursorPos - mention_start_pos, true); + insert(mention_start_pos, utf8str_to_wstring(name_url), false, LLTextSegmentPtr()); + + std::string new_text(wstring_to_utf8str(getConvertedText())); + clear(); + appendTextImpl(new_text, LLStyle::Params(), true); + + segment_set_t::const_iterator it = getSegIterContaining(mention_start_pos); + if (it != mSegments.end()) + { + setCursorPos((*it)->getEnd() + 1); + } + else + { + setCursorPos(mention_start_pos); + } + } +} + bool LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { bool handled = false; @@ -769,8 +810,16 @@ bool LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) // Delay cursor flashing resetCursorBlink(); + mSelectedOnFocusReceived = false; if (handled && !gFocusMgr.getMouseCapture()) { + if (!mask && mSelectAllOnFocusReceived) + { + mIsSelecting = false; + mSelectionStart = getLength(); + mSelectionEnd = 0; + mSelectedOnFocusReceived = true; + } gFocusMgr.setMouseCapture( this ); } return handled; @@ -1103,6 +1152,7 @@ void LLTextEditor::removeCharOrTab() } tryToShowEmojiHelper(); + tryToShowMentionHelper(); } else { @@ -1128,6 +1178,7 @@ void LLTextEditor::removeChar() setCursorPos(mCursorPos - 1); removeChar(mCursorPos); tryToShowEmojiHelper(); + tryToShowMentionHelper(); } else { @@ -1189,6 +1240,7 @@ void LLTextEditor::addChar(llwchar wc) setCursorPos(mCursorPos + addChar( mCursorPos, wc )); tryToShowEmojiHelper(); + tryToShowMentionHelper(); if (!mReadOnly && mAutoreplaceCallback != NULL) { @@ -1247,6 +1299,31 @@ void LLTextEditor::tryToShowEmojiHelper() } } +void LLTextEditor::tryToShowMentionHelper() +{ + if (mReadOnly || !mShowChatMentionPicker) + return; + + S32 mention_start_pos; + LLWString text(getWText()); + if (LLChatMentionHelper::instance().isCursorInNameMention(text, mCursorPos, &mention_start_pos)) + { + const LLRect cursor_rect(getLocalRectFromDocIndex(mention_start_pos)); + std::string name_part(wstring_to_utf8str(text.substr(mention_start_pos, mCursorPos - mention_start_pos))); + name_part.erase(0, 1); + auto cb = [this](std::string name_url) + { + handleMentionCommit(name_url); + }; + LLChatMentionHelper::instance().showHelper(this, cursor_rect.mLeft, cursor_rect.mTop, name_part, cb); + } + else + { + LLChatMentionHelper::instance().hideHelper(); + } +} + + void LLTextEditor::addLineBreakChar(bool group_together) { if( !getEnabled() ) @@ -1873,7 +1950,7 @@ bool LLTextEditor::handleKeyHere(KEY key, MASK mask ) // not handled and let the parent take care of field movement. if (KEY_TAB == key && mTabsToNextField) { - return false; + return mShowChatMentionPicker && LLChatMentionHelper::instance().handleKey(this, key, mask); } if (mReadOnly && mScroller) @@ -1884,9 +1961,13 @@ bool LLTextEditor::handleKeyHere(KEY key, MASK mask ) } else { - if (!mReadOnly && mShowEmojiHelper && LLEmojiHelper::instance().handleKey(this, key, mask)) + if (!mReadOnly) { - return true; + if ((mShowEmojiHelper && LLEmojiHelper::instance().handleKey(this, key, mask)) || + (mShowChatMentionPicker && LLChatMentionHelper::instance().handleKey(this, key, mask))) + { + return true; + } } if (mEnableTooltipPaste && @@ -2142,6 +2223,11 @@ void LLTextEditor::focusLostHelper() gEditMenuHandler = NULL; } + if (mSelectedOnFocusReceived) + { + deselect(); + } + if (mCommitOnFocusLost) { onCommit(); @@ -3083,3 +3169,21 @@ S32 LLTextEditor::spacesPerTab() { return SPACES_PER_TAB; } + +LLWString LLTextEditor::getConvertedText() const +{ + LLWString text = getWText(); + S32 diff = 0; + for (auto segment : mSegments) + { + if (segment && segment->getStyle() && segment->getStyle()->getDrawHighlightBg()) + { + S32 seg_length = segment->getEnd() - segment->getStart(); + std::string slurl = segment->getStyle()->getLinkHREF(); + + text.replace(segment->getStart() + diff, seg_length, utf8str_to_wstring(slurl)); + diff += (S32)slurl.size() - seg_length; + } + } + return text; +} diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index b2b14b01e2..cdfcbcdd63 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -95,6 +95,8 @@ public: void insertEmoji(llwchar emoji); void handleEmojiCommit(llwchar emoji); + void handleMentionCommit(std::string name_url); + // mousehandler overrides virtual bool handleMouseDown(S32 x, S32 y, MASK mask); virtual bool handleMouseUp(S32 x, S32 y, MASK mask); @@ -142,8 +144,10 @@ public: virtual bool canDoDelete() const; virtual void selectAll(); virtual bool canSelectAll() const; + virtual void deselect(); void selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos); + void setSelectAllOnFocusReceived(bool b); virtual bool canLoadOrSaveToFile(); @@ -200,7 +204,6 @@ public: const LLUUID& getSourceID() const { return mSourceID; } const LLTextSegmentPtr getPreviousSegment() const; - const LLTextSegmentPtr getLastSegment() const; void getSelectedSegments(segment_vec_t& segments) const; void setShowContextMenu(bool show) { mShowContextMenu = show; } @@ -213,12 +216,12 @@ public: void setPassDelete(bool b) { mPassDelete = b; } + LLWString getConvertedText() const; + protected: void showContextMenu(S32 x, S32 y); void drawPreeditMarker(); - void assignEmbedded(const std::string &s); - void removeCharOrTab(); void indentSelectedLines( S32 spaces ); @@ -238,7 +241,6 @@ protected: void autoIndent(); - void findEmbeddedItemSegments(S32 start, S32 end); void getSegmentsInRange(segment_vec_t& segments, S32 start, S32 end, bool include_partial) const; virtual llwchar pasteEmbeddedItem(llwchar ext_char) { return ext_char; } @@ -258,6 +260,7 @@ protected: S32 remove(S32 pos, S32 length, bool group_with_next_op); void tryToShowEmojiHelper(); + void tryToShowMentionHelper(); void focusLostHelper(); void updateAllowingLanguageInput(); bool hasPreeditString() const; @@ -295,6 +298,7 @@ protected: bool mAutoIndent; bool mParseOnTheFly; + bool mShowChatMentionPicker; void updateLinkSegments(); void keepSelectionOnReturn(bool keep) { mKeepSelectionOnReturn = keep; } @@ -305,7 +309,7 @@ private: // Methods // void pasteHelper(bool is_primary); - void cleanStringForPaste(LLWString & clean_string); + void cleanStringForPaste(LLWString& clean_string); void pasteTextWithLinebreaks(LLWString & clean_string); void onKeyStroke(); @@ -334,6 +338,8 @@ private: bool mEnableTooltipPaste; bool mPassDelete; bool mKeepSelectionOnReturn; // disabling of removing selected text after pressing of Enter + bool mSelectAllOnFocusReceived; + bool mSelectedOnFocusReceived; LLUUID mSourceID; diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h index c57c979525..5556406fbd 100644 --- a/indra/llui/lltoolbar.h +++ b/indra/llui/lltoolbar.h @@ -68,7 +68,7 @@ public: void reshape(S32 width, S32 height, bool called_from_parent = true); void setEnabled(bool enabled); void setCommandId(const LLCommandId& id) { mId = id; } - LLCommandId getCommandId() { return mId; } + LLCommandId getCommandId() const { return mId; } void setStartDragCallback(tool_startdrag_callback_t cb) { mStartDragItemCallback = cb; } void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; } @@ -256,7 +256,7 @@ public: // Methods used in loading and saving toolbar settings void setButtonType(LLToolBarEnums::ButtonType button_type); - LLToolBarEnums::ButtonType getButtonType() { return mButtonType; } + LLToolBarEnums::ButtonType getButtonType() const { return mButtonType; } command_id_list_t& getCommandsList() { return mButtonCommands; } void clearCommandsList(); diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 86525c2f7e..74f03618cf 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -390,22 +390,22 @@ void LLToolTip::draw() } } -bool LLToolTip::isFading() +bool LLToolTip::isFading() const { return mFadeTimer.getStarted(); } -F32 LLToolTip::getVisibleTime() +F32 LLToolTip::getVisibleTime() const { return mVisibleTimer.getStarted() ? mVisibleTimer.getElapsedTimeF32() : 0.f; } -bool LLToolTip::hasClickCallback() +bool LLToolTip::hasClickCallback() const { return mHasClickCallback; } -void LLToolTip::getToolTipMessage(std::string & message) +void LLToolTip::getToolTipMessage(std::string& message) const { if (mTextBox) { diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index 8515504e3b..760acddd6f 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -44,15 +44,15 @@ public: Params(); }; LLToolTipView(const LLToolTipView::Params&); - /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleMiddleMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleRightMouseDown(S32 x, S32 y, MASK mask); - /*virtual*/ bool handleScrollWheel( S32 x, S32 y, S32 clicks ); + bool handleHover(S32 x, S32 y, MASK mask) override; + bool handleMouseDown(S32 x, S32 y, MASK mask) override; + bool handleMiddleMouseDown(S32 x, S32 y, MASK mask) override; + bool handleRightMouseDown(S32 x, S32 y, MASK mask) override; + bool handleScrollWheel( S32 x, S32 y, S32 clicks ) override; void drawStickyRect(); - /*virtual*/ void draw(); + void draw() override; }; class LLToolTip : public LLPanel @@ -98,20 +98,20 @@ public: Params(); }; - /*virtual*/ void draw(); - /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask); - /*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask); - /*virtual*/ void setVisible(bool visible); + void draw() override; + bool handleHover(S32 x, S32 y, MASK mask) override; + void onMouseLeave(S32 x, S32 y, MASK mask) override; + void setVisible(bool visible) override; - bool isFading(); - F32 getVisibleTime(); - bool hasClickCallback(); + bool isFading() const; + F32 getVisibleTime() const; + bool hasClickCallback() const; LLToolTip(const Params& p); virtual void initFromParams(const LLToolTip::Params& params); - void getToolTipMessage(std::string & message); - bool isTooltipPastable() { return mIsTooltipPastable; } + void getToolTipMessage(std::string & message) const; + bool isTooltipPastable() const { return mIsTooltipPastable; } protected: void updateTextBox(); diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 9890d3f7ef..b2dcb6dc88 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -154,7 +154,7 @@ public: sanitizeRange(); } - S32 clamp(S32 input) + S32 clamp(S32 input) const { if (input < mMin) return mMin; if (input > mMax) return mMax; @@ -168,8 +168,8 @@ public: sanitizeRange(); } - S32 getMin() { return mMin; } - S32 getMax() { return mMax; } + S32 getMin() const { return mMin; } + S32 getMax() const { return mMax; } bool operator==(const RangeS32& other) const { @@ -223,7 +223,7 @@ public: mValue = clamp(value); } - S32 get() + S32 get() const { return mValue; } @@ -253,7 +253,7 @@ public: static std::string getLanguage(); // static for lldateutil_test compatibility //helper functions (should probably move free standing rendering helper functions here) - LLView* getRootView() { return mRootView; } + LLView* getRootView() const { return mRootView; } void setRootView(LLView* view) { mRootView = view; } /** * Walk the LLView tree to resolve a path @@ -296,7 +296,7 @@ public: LLControlGroup& getControlControlGroup (std::string_view controlname); F32 getMouseIdleTime() { return mMouseIdleTimer.getElapsedTimeF32(); } void resetMouseIdleTimer() { mMouseIdleTimer.reset(); } - LLWindow* getWindow() { return mWindow; } + LLWindow* getWindow() const { return mWindow; } void addPopup(LLView*); void removePopup(LLView*); diff --git a/indra/llui/lluiconstants.h b/indra/llui/lluiconstants.h index 5fdfd37c6e..a317c66008 100644 --- a/indra/llui/lluiconstants.h +++ b/indra/llui/lluiconstants.h @@ -28,23 +28,23 @@ #define LL_LLUICONSTANTS_H // spacing for small font lines of text, like LLTextBoxes -const S32 LINE = 16; +constexpr S32 LINE = 16; // spacing for larger lines of text -const S32 LINE_BIG = 24; +constexpr S32 LINE_BIG = 24; // default vertical padding -const S32 VPAD = 4; +constexpr S32 VPAD = 4; // default horizontal padding -const S32 HPAD = 4; +constexpr S32 HPAD = 4; // Account History, how far to look into past -const S32 SUMMARY_INTERVAL = 7; // one week -const S32 SUMMARY_MAX = 8; // -const S32 DETAILS_INTERVAL = 1; // one day -const S32 DETAILS_MAX = 30; // one month -const S32 TRANSACTIONS_INTERVAL = 1;// one day -const S32 TRANSACTIONS_MAX = 30; // one month +constexpr S32 SUMMARY_INTERVAL = 7; // one week +constexpr S32 SUMMARY_MAX = 8; // +constexpr S32 DETAILS_INTERVAL = 1; // one day +constexpr S32 DETAILS_MAX = 30; // one month +constexpr S32 TRANSACTIONS_INTERVAL = 1;// one day +constexpr S32 TRANSACTIONS_MAX = 30; // one month #endif diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 8cd9950917..bcaf479b0f 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -39,9 +39,9 @@ #include "llviewmodel.h" // *TODO move dependency to .cpp file #include "llsearchablecontrol.h" -const bool TAKE_FOCUS_YES = true; -const bool TAKE_FOCUS_NO = false; -const S32 DROP_SHADOW_FLOATER = 5; +constexpr bool TAKE_FOCUS_YES = true; +constexpr bool TAKE_FOCUS_NO = false; +constexpr S32 DROP_SHADOW_FLOATER = 5; class LLUICtrl : public LLView, public boost::signals2::trackable diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 75e7e396bc..91221dc7f3 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -184,7 +184,7 @@ fail: template<class T> static T* getDefaultWidget(std::string_view name) { - typename T::Params widget_params; + typename T::Params widget_params{}; widget_params.name = std::string(name); return create<T>(widget_params); } diff --git a/indra/llui/llundo.h b/indra/llui/llundo.h index dc40702be0..990745e530 100644 --- a/indra/llui/llundo.h +++ b/indra/llui/llundo.h @@ -42,7 +42,7 @@ public: LLUndoAction(): mClusterID(0) {}; virtual ~LLUndoAction(){}; private: - S32 mClusterID; + S32 mClusterID; }; LLUndoBuffer( LLUndoAction (*create_func()), S32 initial_count ); @@ -51,8 +51,8 @@ public: LLUndoAction *getNextAction(bool setClusterBegin = true); bool undoAction(); bool redoAction(); - bool canUndo() { return (mNextAction != mFirstAction); } - bool canRedo() { return (mNextAction != mLastAction); } + bool canUndo() const { return (mNextAction != mFirstAction); } + bool canRedo() const { return (mNextAction != mLastAction); } void flushActions(); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index b6b450c2a1..8b320b59cc 100644 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -30,6 +30,7 @@ #include "llview.h" #include "llwindow.h" #include "llurlregistry.h" +#include "v3dmath.h" // global state for the callback functions @@ -116,6 +117,16 @@ void LLUrlAction::teleportToLocation(std::string url) } } +void LLUrlAction::zoomInObject(std::string url) +{ + LLUrlMatch match; + std::string object_id = getObjectId(url); + if (LLUUID::validate(object_id) && LLUrlRegistry::instance().findUrl(url, match)) + { + executeSLURL("secondlife:///app/object/" + object_id + "/zoomin/" + match.getLocation()); + } +} + void LLUrlAction::showLocationOnMap(std::string url) { LLUrlMatch match; @@ -128,6 +139,23 @@ void LLUrlAction::showLocationOnMap(std::string url) } } +void LLUrlAction::showParcelOnMap(std::string url) +{ + LLSD path_array = LLURI(url).pathArray(); + auto path_parts = path_array.size(); + + if (path_parts < 3) // no parcel id + { + LL_WARNS() << "Global coordinates are missing in url: [" << url << "]" << LL_ENDL; + return; + } + + LLVector3d parcel_pos = LLUrlEntryParcel::getParcelPos(LLUUID(LLURI::unescape(path_array[2]))); + std::ostringstream pos; + pos << parcel_pos.mdV[VX] << '/' << parcel_pos.mdV[VY] << '/' << parcel_pos.mdV[VZ]; + executeSLURL("secondlife:///app/worldmap_global/" + pos.str()); +} + void LLUrlAction::copyURLToClipboard(std::string url) { LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(url)); @@ -142,6 +170,16 @@ void LLUrlAction::copyLabelToClipboard(std::string url) } } +std::string LLUrlAction::getURLLabel(std::string url) +{ + LLUrlMatch match; + if (LLUrlRegistry::instance().findUrl(url, match)) + { + return match.getLabel(); + } + return ""; +} + void LLUrlAction::showProfile(std::string url) { // Get id from 'secondlife:///app/{cmd}/{id}/{action}' diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index 0f54b66299..56d459bb26 100644 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -45,8 +45,6 @@ class LLUrlAction { public: - LLUrlAction(); - /// load a Url in the user's preferred web browser static void openURL(std::string url); @@ -62,9 +60,15 @@ public: /// if the Url specifies an SL location, teleport there static void teleportToLocation(std::string url); + /// If the Url specifies an object id, attempt to zoom in. + /// If not possible to zoom in, show on map + static void zoomInObject(std::string url); + /// if the Url specifies an SL location, show it on a map static void showLocationOnMap(std::string url); + static void showParcelOnMap(std::string url); + /// perform the appropriate action for left-clicking on a Url static void clickAction(std::string url, bool trusted_content); @@ -74,6 +78,8 @@ public: /// copy a Url to the clipboard static void copyURLToClipboard(std::string url); + static std::string getURLLabel(std::string url); + /// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile static void showProfile(std::string url); static std::string getUserID(std::string url); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index 77f132e9d8..95603d7ed5 100644 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -29,7 +29,6 @@ #include "llurlentry.h" #include "lluictrl.h" #include "lluri.h" -#include "llurlmatch.h" #include "llurlregistry.h" #include "lluriparser.h" @@ -42,13 +41,12 @@ #include "lluicolortable.h" #include "message.h" #include "llexperiencecache.h" - -#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" +#include "v3dmath.h" // Utility functions std::string localize_slapp_label(const std::string& url, const std::string& full_name); - +LLUUID LLUrlEntryBase::sAgentID(LLUUID::null); LLUrlEntryBase::LLUrlEntryBase() { } @@ -68,7 +66,7 @@ std::string LLUrlEntryBase::getIcon(const std::string &url) return mIcon; } -LLStyle::Params LLUrlEntryBase::getStyle() const +LLStyle::Params LLUrlEntryBase::getStyle(const std::string &url) const { LLStyle::Params style_params; style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); @@ -631,6 +629,11 @@ LLUUID LLUrlEntryAgent::getID(const std::string &string) const return LLUUID(getIDStringFromUrl(string)); } +bool LLUrlEntryAgent::isAgentID(const std::string& url) const +{ + return sAgentID == getID(url); +} + std::string LLUrlEntryAgent::getTooltip(const std::string &string) const { // return a tooltip corresponding to the URL type instead of the generic one @@ -667,10 +670,14 @@ std::string LLUrlEntryAgent::getTooltip(const std::string &string) const return LLTrans::getString("TooltipAgentUrl"); } -bool LLUrlEntryAgent::underlineOnHoverOnly(const std::string &string) const +LLStyle::EUnderlineLink LLUrlEntryAgent::getUnderline(const std::string& string) const { std::string url = getUrl(string); - return LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect"); + if (LLStringUtil::endsWith(url, "/about") || LLStringUtil::endsWith(url, "/inspect")) + { + return LLStyle::EUnderlineLink::UNDERLINE_ON_HOVER; + } + return LLStyle::EUnderlineLink::UNDERLINE_ALWAYS; } std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCallback &cb) @@ -712,11 +719,12 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa } } -LLStyle::Params LLUrlEntryAgent::getStyle() const +LLStyle::Params LLUrlEntryAgent::getStyle(const std::string &url) const { - LLStyle::Params style_params = LLUrlEntryBase::getStyle(); + LLStyle::Params style_params = LLUrlEntryBase::getStyle(url); style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); + return style_params; } @@ -751,6 +759,10 @@ std::string localize_slapp_label(const std::string& url, const std::string& full { return LLTrans::getString("SLappAgentRemoveFriend") + " " + full_name; } + if (LLStringUtil::endsWith(url, "/mention")) + { + return "@" + full_name; + } return full_name; } @@ -762,6 +774,36 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url) return mIcon; } +/// +/// LLUrlEntryAgentMention Describes a chat mention Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/mention +/// +LLUrlEntryAgentMention::LLUrlEntryAgentMention() +{ + mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/mention", boost::regex::perl | boost::regex::icase); + mMenuName = "menu_url_agent.xml"; + mIcon = std::string(); +} + +LLStyle::EUnderlineLink LLUrlEntryAgentMention::getUnderline(const std::string& string) const +{ + return LLStyle::EUnderlineLink::UNDERLINE_NEVER; +} + +LLStyle::Params LLUrlEntryAgentMention::getStyle(const std::string& url) const +{ + LLStyle::Params style_params = LLUrlEntryAgent::getStyle(url); + style_params.color = LLUIColorTable::instance().getColor("ChatMentionFont"); + style_params.readonly_color = LLUIColorTable::instance().getColor("ChatMentionFont"); + style_params.font.style = "NORMAL"; + style_params.draw_highlight_bg = true; + + LLUUID agent_id(getIDStringFromUrl(url)); + style_params.highlight_bg_color = LLUIColorTable::instance().getColor((agent_id == sAgentID) ? "ChatSelfMentionHighlight" : "ChatMentionHighlight"); + + return style_params; +} + // // LLUrlEntryAgentName describes a Second Life agent name Url, e.g., // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username) @@ -823,7 +865,7 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab } } -LLStyle::Params LLUrlEntryAgentName::getStyle() const +LLStyle::Params LLUrlEntryAgentName::getStyle(const std::string &url) const { // don't override default colors return LLStyle::Params().is_link(false); @@ -959,9 +1001,9 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa } } -LLStyle::Params LLUrlEntryGroup::getStyle() const +LLStyle::Params LLUrlEntryGroup::getStyle(const std::string &url) const { - LLStyle::Params style_params = LLUrlEntryBase::getStyle(); + LLStyle::Params style_params = LLUrlEntryBase::getStyle(url); style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor"); style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor"); return style_params; @@ -1037,11 +1079,11 @@ std::string LLUrlEntryChat::getLabel(const std::string &url, const LLUrlLabelCal } // LLUrlEntryParcel statics. -LLUUID LLUrlEntryParcel::sAgentID(LLUUID::null); LLUUID LLUrlEntryParcel::sSessionID(LLUUID::null); LLHost LLUrlEntryParcel::sRegionHost; bool LLUrlEntryParcel::sDisconnected(false); std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers; +std::map<LLUUID, LLVector3d> LLUrlEntryParcel::sParcelPos; /// /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g., @@ -1134,6 +1176,20 @@ void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data) url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label); } } + if (sParcelPos.find(parcel_data.parcel_id) == sParcelPos.end()) + { + sParcelPos[parcel_data.parcel_id] = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); + } +} + +// static +LLVector3d LLUrlEntryParcel::getParcelPos(const LLUUID& parcel_id) +{ + if (sParcelPos.find(parcel_id) != sParcelPos.end()) + { + return sParcelPos[parcel_id]; + } + return LLVector3d(); } // @@ -1371,17 +1427,17 @@ std::string LLUrlEntrySLLabel::getTooltip(const std::string &string) const return LLUrlEntryBase::getTooltip(string); } -bool LLUrlEntrySLLabel::underlineOnHoverOnly(const std::string &string) const +LLStyle::EUnderlineLink LLUrlEntrySLLabel::getUnderline(const std::string& string) const { std::string url = getUrl(string); - LLUrlMatch match; + LLUrlMatch match; if (LLUrlRegistry::instance().findUrl(url, match)) { - return match.underlineOnHoverOnly(); + return match.getUnderline(); } // unrecognized URL? should not happen - return LLUrlEntryBase::underlineOnHoverOnly(string); + return LLUrlEntryBase::getUnderline(string); } // @@ -1445,7 +1501,7 @@ std::string LLUrlEntryNoLink::getLabel(const std::string &url, const LLUrlLabelC return getUrl(url); } -LLStyle::Params LLUrlEntryNoLink::getStyle() const +LLStyle::Params LLUrlEntryNoLink::getStyle(const std::string &url) const { // Don't render as URL (i.e. no context menu or hand cursor). return LLStyle::Params().is_link(false); diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h index fffee88496..efb5081103 100644 --- a/indra/llui/llurlentry.h +++ b/indra/llui/llurlentry.h @@ -41,6 +41,9 @@ #include <map> class LLAvatarName; +class LLVector3d; + +#define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))" typedef boost::signals2::signal<void (const std::string& url, const std::string& label, @@ -85,7 +88,7 @@ public: virtual std::string getIcon(const std::string &url); /// Return the style to render the displayed text - virtual LLStyle::Params getStyle() const; + virtual LLStyle::Params getStyle(const std::string &url) const; /// Given a matched Url, return a tooltip string for the hyperlink virtual std::string getTooltip(const std::string &string) const { return mTooltip; } @@ -96,12 +99,14 @@ public: /// Return the name of a SL location described by this Url, if any virtual std::string getLocation(const std::string &url) const { return ""; } - /// Should this link text be underlined only when mouse is hovered over it? - virtual bool underlineOnHoverOnly(const std::string &string) const { return false; } + virtual LLStyle::EUnderlineLink getUnderline(const std::string& string) const { return LLStyle::EUnderlineLink::UNDERLINE_ALWAYS; } virtual bool isTrusted() const { return false; } + virtual bool getSkipProfileIcon(const std::string& string) const { return false; } + virtual LLUUID getID(const std::string &string) const { return LLUUID::null; } + virtual bool isAgentID(const std::string& url) const { return false; } bool isLinkDisabled() const; @@ -109,6 +114,8 @@ public: virtual bool isSLURLvalid(const std::string &url) const { return true; }; + static void setAgentID(const LLUUID& id) { sAgentID = id; } + protected: std::string getIDStringFromUrl(const std::string &url) const; std::string escapeUrl(const std::string &url) const; @@ -130,6 +137,8 @@ protected: std::string mMenuName; std::string mTooltip; std::multimap<std::string, LLUrlEntryObserver> mObservers; + + static LLUUID sAgentID; }; /// @@ -224,9 +233,13 @@ public: /*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*/ LLStyle::Params getStyle(const std::string &url) const; /*virtual*/ LLUUID getID(const std::string &string) const; - /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const; + + bool isAgentID(const std::string& url) const; + + LLStyle::EUnderlineLink getUnderline(const std::string& string) const; + protected: /*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon); private: @@ -237,6 +250,19 @@ private: }; /// +/// LLUrlEntryAgentMention Describes a chat mention Url, e.g., +/// secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/mention +class LLUrlEntryAgentMention : public LLUrlEntryAgent +{ +public: + LLUrlEntryAgentMention(); + + LLStyle::Params getStyle(const std::string& url) const; + LLStyle::EUnderlineLink getUnderline(const std::string& string) const; + bool getSkipProfileIcon(const std::string& string) const { return true; }; +}; + +/// /// 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 @@ -257,7 +283,7 @@ public: mAvatarNameCacheConnections.clear(); } /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); - /*virtual*/ LLStyle::Params getStyle() const; + /*virtual*/ LLStyle::Params getStyle(const std::string &url) const; protected: // override this to pull out relevant name fields virtual std::string getName(const LLAvatarName& avatar_name) = 0; @@ -339,7 +365,7 @@ class LLUrlEntryGroup : public LLUrlEntryBase public: LLUrlEntryGroup(); /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); - /*virtual*/ LLStyle::Params getStyle() const; + /*virtual*/ LLStyle::Params getStyle(const std::string &url) const; /*virtual*/ LLUUID getID(const std::string &string) const; private: void onGroupNameReceived(const LLUUID& id, const std::string& name, bool is_group); @@ -411,21 +437,22 @@ public: // Processes parcel label and triggers notifying observers. static void processParcelInfo(const LLParcelData& parcel_data); - // Next 4 setters are used to update agent and viewer connection information + static LLVector3d getParcelPos(const LLUUID& parcel_id); + + // Next setters are used to update agent and viewer connection information // upon events like user login, viewer disconnect and user changing region host. // These setters are made public to be accessible from newview and should not be // used in other cases. - static void setAgentID(const LLUUID& id) { sAgentID = id; } static void setSessionID(const LLUUID& id) { sSessionID = id; } static void setRegionHost(const LLHost& host) { sRegionHost = host; } static void setDisconnected(bool disconnected) { sDisconnected = disconnected; } private: - static LLUUID sAgentID; static LLUUID sSessionID; static LLHost sRegionHost; static bool sDisconnected; static std::set<LLUrlEntryParcel*> sParcelInfoObservers; + static std::map<LLUUID, LLVector3d> sParcelPos; }; /// @@ -486,7 +513,7 @@ public: /*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb); /*virtual*/ std::string getUrl(const std::string &string) const; /*virtual*/ std::string getTooltip(const std::string &string) const; - /*virtual*/ bool underlineOnHoverOnly(const std::string &string) const; + LLStyle::EUnderlineLink getUnderline(const std::string& string) const; }; /// @@ -510,7 +537,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; + /*virtual*/ LLStyle::Params getStyle(const std::string &url) const; }; /// diff --git a/indra/llui/llurlmatch.cpp b/indra/llui/llurlmatch.cpp index bfa3b167b1..f093934ca9 100644 --- a/indra/llui/llurlmatch.cpp +++ b/indra/llui/llurlmatch.cpp @@ -37,8 +37,9 @@ LLUrlMatch::LLUrlMatch() : mIcon(""), mMenuName(""), mLocation(""), - mUnderlineOnHoverOnly(false), - mTrusted(false) + mUnderline(e_underline::UNDERLINE_ALWAYS), + mTrusted(false), + mSkipProfileIcon(false) { } @@ -46,7 +47,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std const std::string& query, const std::string &tooltip, const std::string &icon, const LLStyle::Params& style, const std::string &menu, const std::string &location, - const LLUUID& id, bool underline_on_hover_only, bool trusted) + const LLUUID& id, e_underline underline, bool trusted, bool skip_icon) { mStart = start; mEnd = end; @@ -60,6 +61,7 @@ void LLUrlMatch::setValues(U32 start, U32 end, const std::string &url, const std mMenuName = menu; mLocation = location; mID = id; - mUnderlineOnHoverOnly = underline_on_hover_only; + mUnderline = underline; mTrusted = trusted; + mSkipProfileIcon = skip_icon; } diff --git a/indra/llui/llurlmatch.h b/indra/llui/llurlmatch.h index ba822fbda6..418a21f963 100644 --- a/indra/llui/llurlmatch.h +++ b/indra/llui/llurlmatch.h @@ -31,7 +31,6 @@ //#include "linden_common.h" #include <string> -#include <vector> #include "llstyle.h" /// @@ -80,18 +79,20 @@ public: /// return the SL location that this Url describes, or "" if none. std::string getLocation() const { return mLocation; } - /// Should this link text be underlined only when mouse is hovered over it? - bool underlineOnHoverOnly() const { return mUnderlineOnHoverOnly; } + typedef LLStyle::EUnderlineLink e_underline; + e_underline getUnderline() const { return mUnderline; } /// Return true if Url is trusted. bool isTrusted() const { return mTrusted; } + bool getSkipProfileIcon() const { return mSkipProfileIcon; } + /// 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& query, const std::string &tooltip, const std::string &icon, const LLStyle::Params& style, const std::string &menu, const std::string &location, const LLUUID& id, - bool underline_on_hover_only = false, bool trusted = false); + e_underline underline = e_underline::UNDERLINE_ALWAYS, bool trusted = false, bool skip_icon = false); const LLUUID& getID() const { return mID; } private: @@ -106,8 +107,9 @@ private: std::string mLocation; LLUUID mID; LLStyle::Params mStyle; - bool mUnderlineOnHoverOnly; + e_underline mUnderline; bool mTrusted; + bool mSkipProfileIcon; }; #endif diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp index cec1ddfc57..cb101d325d 100644 --- a/indra/llui/llurlregistry.cpp +++ b/indra/llui/llurlregistry.cpp @@ -62,6 +62,8 @@ LLUrlRegistry::LLUrlRegistry() registerUrl(new LLUrlEntryAgentUserName()); // LLUrlEntryAgent*Name must appear before LLUrlEntryAgent since // LLUrlEntryAgent is a less specific (catchall for agent urls) + mUrlEntryAgentMention = new LLUrlEntryAgentMention(); + registerUrl(mUrlEntryAgentMention); registerUrl(new LLUrlEntryAgent()); registerUrl(new LLUrlEntryChat()); registerUrl(new LLUrlEntryGroup()); @@ -155,7 +157,7 @@ static bool stringHasUrl(const std::string &text) text.find("@") != std::string::npos); } -bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted) +bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb, bool is_content_trusted, bool skip_non_mentions) { // avoid costly regexes if there is clearly no URL in the text if (! stringHasUrl(text)) @@ -176,6 +178,11 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL continue; } + if (skip_non_mentions && (mUrlEntryAgentMention != *it)) + { + continue; + } + LLUrlEntryBase *url_entry = *it; U32 start = 0, end = 0; @@ -233,12 +240,13 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL match_entry->getQuery(url), match_entry->getTooltip(url), match_entry->getIcon(url), - match_entry->getStyle(), + match_entry->getStyle(url), match_entry->getMenuName(), match_entry->getLocation(url), match_entry->getID(url), - match_entry->underlineOnHoverOnly(url), - match_entry->isTrusted()); + match_entry->getUnderline(url), + match_entry->isTrusted(), + match_entry->getSkipProfileIcon(url)); return true; } @@ -274,7 +282,9 @@ bool LLUrlRegistry::findUrl(const LLWString &text, LLUrlMatch &match, const LLUr match.getMenuName(), match.getLocation(), match.getID(), - match.underlineOnHoverOnly()); + match.getUnderline(), + false, + match.getSkipProfileIcon()); return true; } return false; @@ -317,3 +327,30 @@ void LLUrlRegistry::setKeybindingHandler(LLKeyBindingToStringHandler* handler) LLUrlEntryKeybinding *entry = (LLUrlEntryKeybinding*)mUrlEntryKeybinding; entry->setHandler(handler); } + +bool LLUrlRegistry::containsAgentMention(const std::string& text) +{ + // avoid costly regexes if there is clearly no URL in the text + if (!stringHasUrl(text)) + { + return false; + } + + try + { + boost::sregex_iterator it(text.begin(), text.end(), mUrlEntryAgentMention->getPattern()); + boost::sregex_iterator end; + for (; it != end; ++it) + { + if (mUrlEntryAgentMention->isAgentID(it->str())) + { + return true; + } + } + } + catch (boost::regex_error&) + { + LL_INFOS() << "Regex error for: " << text << LL_ENDL; + } + return false; +} diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h index 64cfec3960..592e422487 100644 --- a/indra/llui/llurlregistry.h +++ b/indra/llui/llurlregistry.h @@ -34,7 +34,6 @@ #include "llstring.h" #include <string> -#include <vector> class LLKeyBindingToStringHandler; @@ -76,7 +75,7 @@ public: /// your callback is invoked if the matched Url's label changes in the future bool findUrl(const std::string &text, LLUrlMatch &match, const LLUrlLabelCallback &cb = &LLUrlRegistryNullCallback, - bool is_content_trusted = false); + bool is_content_trusted = false, bool skip_non_mentions = false); /// a slightly less efficient version of findUrl for wide strings bool findUrl(const LLWString &text, LLUrlMatch &match, @@ -93,6 +92,8 @@ public: // Set handler for url registry to be capable of parsing and populating keybindings void setKeybindingHandler(LLKeyBindingToStringHandler* handler); + bool containsAgentMention(const std::string& text); + private: std::vector<LLUrlEntryBase *> mUrlEntry; LLUrlEntryBase* mUrlEntryTrusted; @@ -102,6 +103,7 @@ private: LLUrlEntryBase* mUrlEntrySLLabel; LLUrlEntryBase* mUrlEntryNoLink; LLUrlEntryBase* mUrlEntryKeybinding; + LLUrlEntryBase* mUrlEntryAgentMention; }; #endif diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 710ec3d05e..97212a9d2d 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -54,17 +54,17 @@ class LLSD; -const U32 FOLLOWS_NONE = 0x00; -const U32 FOLLOWS_LEFT = 0x01; -const U32 FOLLOWS_RIGHT = 0x02; -const U32 FOLLOWS_TOP = 0x10; -const U32 FOLLOWS_BOTTOM = 0x20; -const U32 FOLLOWS_ALL = 0x33; +constexpr U32 FOLLOWS_NONE = 0x00; +constexpr U32 FOLLOWS_LEFT = 0x01; +constexpr U32 FOLLOWS_RIGHT = 0x02; +constexpr U32 FOLLOWS_TOP = 0x10; +constexpr U32 FOLLOWS_BOTTOM = 0x20; +constexpr U32 FOLLOWS_ALL = 0x33; -const bool MOUSE_OPAQUE = true; -const bool NOT_MOUSE_OPAQUE = false; +constexpr bool MOUSE_OPAQUE = true; +constexpr bool NOT_MOUSE_OPAQUE = false; -const U32 GL_NAME_UI_RESERVED = 2; +constexpr U32 GL_NAME_UI_RESERVED = 2; // maintains render state during traversal of UI tree @@ -241,7 +241,7 @@ public: void setUseBoundingRect( bool use_bounding_rect ); bool getUseBoundingRect() const; - ECursorType getHoverCursor() { return mHoverCursor; } + ECursorType getHoverCursor() const { return mHoverCursor; } static F32 getTooltipTimeout(); virtual const std::string getToolTip() const; @@ -265,7 +265,7 @@ public: void setDefaultTabGroup(S32 d) { mDefaultTabGroup = d; } S32 getDefaultTabGroup() const { return mDefaultTabGroup; } - S32 getLastTabGroup() { return mLastTabGroup; } + S32 getLastTabGroup() const { return mLastTabGroup; } bool isInVisibleChain() const; bool isInEnabledChain() const; diff --git a/indra/llui/llviewborder.h b/indra/llui/llviewborder.h index 1f118a0d20..a4bb748b77 100644 --- a/indra/llui/llviewborder.h +++ b/indra/llui/llviewborder.h @@ -92,7 +92,6 @@ public: private: void drawOnePixelLines(); void drawTwoPixelLines(); - void drawTextures(); EBevel mBevel; EStyle mStyle; diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h index 9e752e8090..5636c068d8 100644 --- a/indra/llui/llviewereventrecorder.h +++ b/indra/llui/llviewereventrecorder.h @@ -61,7 +61,7 @@ public: std::string get_xui(); void update_xui(std::string xui); - bool getLoggingStatus(){return logEvents;}; + bool getLoggingStatus() const { return logEvents; } void setEventLoggingOn(); void setEventLoggingOff(); diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h index 61a78b2398..fbfda04585 100644 --- a/indra/llui/llvirtualtrackball.h +++ b/indra/llui/llvirtualtrackball.h @@ -78,20 +78,20 @@ public: }; - virtual ~LLVirtualTrackball(); - /*virtual*/ bool postBuild(); + ~LLVirtualTrackball() override; + bool postBuild() override; - virtual bool handleHover(S32 x, S32 y, MASK mask); - virtual bool handleMouseUp(S32 x, S32 y, MASK mask); - virtual bool handleMouseDown(S32 x, S32 y, MASK mask); - virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask); - virtual bool handleKeyHere(KEY key, MASK mask); + bool handleHover(S32 x, S32 y, MASK mask) override; + bool handleMouseUp(S32 x, S32 y, MASK mask) override; + bool handleMouseDown(S32 x, S32 y, MASK mask) override; + bool handleRightMouseDown(S32 x, S32 y, MASK mask) override; + bool handleKeyHere(KEY key, MASK mask) override; - virtual void draw(); + void draw() override; - virtual void setValue(const LLSD& value); - void setValue(F32 x, F32 y, F32 z, F32 w); - virtual LLSD getValue() const; + void setValue(const LLSD& value) override; + void setValue(F32 x, F32 y, F32 z, F32 w); + LLSD getValue() const override; void setRotation(const LLQuaternion &value); LLQuaternion getRotation() const; @@ -102,7 +102,6 @@ public: protected: friend class LLUICtrlFactory; LLVirtualTrackball(const Params&); - void onEditChange(); protected: LLTextBox* mNLabel; diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h index da29188943..ee230cd2f6 100644 --- a/indra/llui/llwindowshade.h +++ b/indra/llui/llwindowshade.h @@ -49,7 +49,7 @@ public: }; void show(LLNotificationPtr); - /*virtual*/ void draw(); + void draw() override; void hide(); bool isShown() const; diff --git a/indra/llui/llxyvector.h b/indra/llui/llxyvector.h index bc41213c13..646771f387 100644 --- a/indra/llui/llxyvector.h +++ b/indra/llui/llxyvector.h @@ -65,18 +65,18 @@ public: }; - virtual ~LLXYVector(); - /*virtual*/ bool postBuild(); + ~LLXYVector() override; + bool postBuild() override; - virtual bool handleHover(S32 x, S32 y, MASK mask); - virtual bool handleMouseUp(S32 x, S32 y, MASK mask); - virtual bool handleMouseDown(S32 x, S32 y, MASK mask); + bool handleHover(S32 x, S32 y, MASK mask) override; + bool handleMouseUp(S32 x, S32 y, MASK mask) override; + bool handleMouseDown(S32 x, S32 y, MASK mask) override; - virtual void draw(); + void draw() override; - virtual void setValue(const LLSD& value); - void setValue(F32 x, F32 y); - virtual LLSD getValue() const; + void setValue(const LLSD& value) override; + void setValue(F32 x, F32 y); + LLSD getValue() const override; protected: friend class LLUICtrlFactory; diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 0daa767766..20951ff816 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -430,9 +430,7 @@ void ll_set_device_module_capture_device(rtc::scoped_refptr<webrtc::AudioDeviceM // has it at 0 device_module->SetRecordingDevice(device + 1); #endif - device_module->SetStereoRecording(false); device_module->InitMicrophone(); - device_module->InitRecording(); } void LLWebRTCImpl::setCaptureDevice(const std::string &id) @@ -473,6 +471,8 @@ void LLWebRTCImpl::setCaptureDevice(const std::string &id) ll_set_device_module_capture_device(mPeerDeviceModule, recordingDevice); if (recording) { + mPeerDeviceModule->SetStereoRecording(false); + mPeerDeviceModule->InitRecording(); mPeerDeviceModule->StartRecording(); } }); @@ -494,9 +494,7 @@ void ll_set_device_module_render_device(rtc::scoped_refptr<webrtc::AudioDeviceMo #else device_module->SetPlayoutDevice(device + 1); #endif - device_module->SetStereoPlayout(true); device_module->InitSpeaker(); - device_module->InitPlayout(); } void LLWebRTCImpl::setRenderDevice(const std::string &id) @@ -540,6 +538,8 @@ void LLWebRTCImpl::setRenderDevice(const std::string &id) ll_set_device_module_render_device(mPeerDeviceModule, playoutDevice); if (playing) { + mPeerDeviceModule->SetStereoPlayout(true); + mPeerDeviceModule->InitPlayout(); mPeerDeviceModule->StartPlayout(); } }); @@ -670,7 +670,10 @@ LLWebRTCPeerConnectionInterface *LLWebRTCImpl::newPeerConnection() peerConnection->init(this); mPeerConnections.emplace_back(peerConnection); - peerConnection->enableSenderTracks(!mMute); + // Should it really start disabled? + // Seems like something doesn't get the memo and senders need to be reset later + // to remove the voice indicator from taskbar + peerConnection->enableSenderTracks(false); if (mPeerConnections.empty()) { setRecording(true); @@ -704,7 +707,7 @@ void LLWebRTCImpl::freePeerConnection(LLWebRTCPeerConnectionInterface* peer_conn LLWebRTCPeerConnectionImpl::LLWebRTCPeerConnectionImpl() : mWebRTCImpl(nullptr), mPeerConnection(nullptr), - mMute(true), + mMute(MUTE_INITIAL), mAnswerReceived(false) { } @@ -739,6 +742,19 @@ void LLWebRTCPeerConnectionImpl::terminate() } } + // to remove 'Secondlife is recording' icon from taskbar + // if user was speaking + auto senders = mPeerConnection->GetSenders(); + for (auto& sender : senders) + { + auto track = sender->track(); + if (track) + { + track->set_enabled(false); + } + } + mPeerConnection->SetAudioRecording(false); + mPeerConnection->Close(); if (mLocalStream) { @@ -828,6 +844,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti audioOptions.auto_gain_control = true; audioOptions.echo_cancellation = true; audioOptions.noise_suppression = true; + audioOptions.init_recording_on_send = false; mLocalStream = mPeerConnectionFactory->CreateLocalMediaStream("SLStream"); @@ -887,6 +904,7 @@ void LLWebRTCPeerConnectionImpl::enableSenderTracks(bool enable) // set_enabled shouldn't be done on the worker thread. if (mPeerConnection) { + mPeerConnection->SetAudioRecording(enable); auto senders = mPeerConnection->GetSenders(); for (auto &sender : senders) { @@ -932,12 +950,23 @@ void LLWebRTCPeerConnectionImpl::AnswerAvailable(const std::string &sdp) void LLWebRTCPeerConnectionImpl::setMute(bool mute) { - mMute = mute; + EMicMuteState new_state = mute ? MUTE_MUTED : MUTE_UNMUTED; + if (new_state == mMute) + { + return; // no change + } + bool force_reset = mMute == MUTE_INITIAL && mute; + bool enable = !mute; + mMute = new_state; + mWebRTCImpl->PostSignalingTask( - [this]() + [this, force_reset, enable]() { if (mPeerConnection) { + // SetAudioRecording must be called before enabling/disabling tracks. + mPeerConnection->SetAudioRecording(enable); + auto senders = mPeerConnection->GetSenders(); RTC_LOG(LS_INFO) << __FUNCTION__ << (mMute ? "disabling" : "enabling") << " streams count " << senders.size(); @@ -946,7 +975,14 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute) auto track = sender->track(); if (track) { - track->set_enabled(!mMute); + if (force_reset) + { + // Force notify observers + // Was it disabled too early? + // Without this microphone icon in Win's taskbar will stay + track->set_enabled(true); + } + track->set_enabled(enable); } } } @@ -955,7 +991,17 @@ void LLWebRTCPeerConnectionImpl::setMute(bool mute) void LLWebRTCPeerConnectionImpl::resetMute() { - setMute(mMute); + switch(mMute) + { + case MUTE_MUTED: + setMute(true); + break; + case MUTE_UNMUTED: + setMute(false); + break; + default: + break; + } } void LLWebRTCPeerConnectionImpl::setReceiveVolume(float volume) diff --git a/indra/llwebrtc/llwebrtc_impl.h b/indra/llwebrtc/llwebrtc_impl.h index b93a1fdb01..b6294dbd4a 100644 --- a/indra/llwebrtc/llwebrtc_impl.h +++ b/indra/llwebrtc/llwebrtc_impl.h @@ -417,7 +417,12 @@ class LLWebRTCPeerConnectionImpl : public LLWebRTCPeerConnectionInterface, rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> mPeerConnectionFactory; - bool mMute; + typedef enum { + MUTE_INITIAL, + MUTE_MUTED, + MUTE_UNMUTED, + } EMicMuteState; + EMicMuteState mMute; // signaling std::vector<LLWebRTCSignalingObserver *> mSignalingObserverList; diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index d40e549559..58a17227a7 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -629,7 +629,7 @@ attributedStringInfo getSegments(NSAttributedString *str) }; int string_length = [aString length]; - unichar* text = (unichar*)malloc(sizeof(unichar) * string_length); + unichar *text = new unichar[string_length]; attributedStringInfo segments; // I used 'respondsToSelector:@selector(string)' // to judge aString is an attributed string or not. @@ -647,7 +647,6 @@ attributedStringInfo getSegments(NSAttributedString *str) segments.seg_standouts.push_back(true); } setMarkedText(text, selected, replacement, string_length, segments); - free(text); if (string_length > 0) { mHasMarkedText = TRUE; @@ -658,6 +657,8 @@ attributedStringInfo getSegments(NSAttributedString *str) // we must clear the marked text when aString is null. [self unmarkText]; } + + delete [] text; } else { if (mHasMarkedText) { diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index 378e633cd2..eb11a28360 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -103,7 +103,6 @@ LLWindow::LLWindow(LLWindowCallbacks* callbacks, bool fullscreen, U32 flags) mFullscreen(fullscreen), mFullscreenWidth(0), mFullscreenHeight(0), - mFullscreenBits(0), mFullscreenRefresh(0), mSupportedResolutions(NULL), mNumSupportedResolutions(0), diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 5e06e665f3..151028113a 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -223,7 +223,6 @@ protected: bool mFullscreen; S32 mFullscreenWidth; S32 mFullscreenHeight; - S32 mFullscreenBits; S32 mFullscreenRefresh; LLWindowResolution* mSupportedResolutions; S32 mNumSupportedResolutions; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index e46e3de4c0..6afbdffc1a 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -76,6 +76,11 @@ #pragma comment(lib, "dxguid.lib") // needed for llurlentry test to build on some systems #pragma comment(lib, "dinput8") +#pragma comment(lib, "UxTheme.lib") +#pragma comment(lib, "Dwmapi.lib") +#include <Uxtheme.h> +#include <dwmapi.h> // needed for DwmSetWindowAttribute to set window theme + const S32 MAX_MESSAGE_PER_UPDATE = 20; const S32 BITS_PER_PIXEL = 32; const S32 MAX_NUM_RESOLUTIONS = 32; @@ -85,6 +90,10 @@ const F32 ICON_FLASH_TIME = 0.5f; #define USER_DEFAULT_SCREEN_DPI 96 // Win7 #endif +#ifndef WM_DWMCOLORIZATIONCOLORCHANGED +#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320 +#endif + // Claim a couple unused GetMessage() message IDs const UINT WM_DUMMY_(WM_USER + 0x0017); const UINT WM_POST_FUNCTION_(WM_USER + 0x0018); @@ -104,6 +113,7 @@ static std::thread::id sMainThreadId; LPWSTR gIconResource = IDI_APPLICATION; +LPWSTR gIconSmallResource = IDI_APPLICATION; LPDIRECTINPUT8 gDirectInput8; LLW32MsgCallback gAsyncMsgCallback = NULL; @@ -137,6 +147,17 @@ typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)( _Out_ UINT *dpiX, _Out_ UINT *dpiY); +typedef enum PREFERRED_APP_MODE +{ + DEFAULT, + ALLOW_DARK, + FORCE_DARK, + FORCE_LIGHT, + MAX +} PREFERRED_APP_MODE; + +typedef PREFERRED_APP_MODE(WINAPI* fnSetPreferredAppMode)(PREFERRED_APP_MODE mode); + // // LLWindowWin32 // @@ -350,10 +371,14 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool LLWindowWin32Thread(); void run() override; - void close() override; - // closes queue, wakes thread, waits until thread closes - void wakeAndDestroy(); + // Detroys handles and window + // Either post to or call from window thread + void destroyWindow(); + + // Closes queue, wakes thread, waits until thread closes. + // Call from main thread + bool wakeAndDestroy(); void glReady() { @@ -410,6 +435,7 @@ struct LLWindowWin32::LLWindowWin32Thread : public LL::ThreadPool // until after some graphics setup. See SL-20177. -Cosmic,2023-09-18 bool mGLReady = false; bool mGotGLBuffer = false; + LLAtomicBool mDeleteOnExit = false; }; @@ -507,6 +533,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, mFSAASamples = fsaa_samples; mIconResource = gIconResource; + mIconSmallResource = gIconSmallResource; mOverrideAspectRatio = 0.f; mNativeAspectRatio = 0.f; mInputProcessingPaused = false; @@ -695,8 +722,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, } if (dev_mode.dmPelsWidth == width && - dev_mode.dmPelsHeight == height && - dev_mode.dmBitsPerPel == BITS_PER_PIXEL) + dev_mode.dmPelsHeight == height) { success = true; if ((dev_mode.dmDisplayFrequency - current_refresh) @@ -736,7 +762,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, // If we found a good resolution, use it. if (success) { - success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); + success = setDisplayResolution(width, height, closest_refresh); } // Keep a copy of the actual current device mode in case we minimize @@ -749,7 +775,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, mFullscreen = true; mFullscreenWidth = dev_mode.dmPelsWidth; mFullscreenHeight = dev_mode.dmPelsHeight; - mFullscreenBits = dev_mode.dmBitsPerPel; mFullscreenRefresh = dev_mode.dmDisplayFrequency; LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth @@ -763,7 +788,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, mFullscreen = false; mFullscreenWidth = -1; mFullscreenHeight = -1; - mFullscreenBits = -1; mFullscreenRefresh = -1; std::map<std::string,std::string> args; @@ -842,6 +866,8 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, // Initialize (boot strap) the Language text input management, // based on the system's (or user's) default settings. allowLanguageTextInput(NULL, false); + updateWindowTheme(); + setCustomIcon(); } @@ -853,6 +879,7 @@ LLWindowWin32::~LLWindowWin32() } delete mDragDrop; + mDragDrop = NULL; delete [] mWindowTitle; mWindowTitle = NULL; @@ -864,6 +891,7 @@ LLWindowWin32::~LLWindowWin32() mWindowClassName = NULL; delete mWindowThread; + mWindowThread = NULL; } void LLWindowWin32::show() @@ -972,7 +1000,7 @@ void LLWindowWin32::close() // Restore gamma to the system values. restoreGamma(); - LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; + LL_INFOS("Window") << "Destroying Window Thread" << LL_ENDL; if (sWindowHandleForMessageBox == mWindowHandle) { @@ -982,7 +1010,11 @@ void LLWindowWin32::close() mhDC = NULL; mWindowHandle = NULL; - mWindowThread->wakeAndDestroy(); + if (mWindowThread->wakeAndDestroy()) + { + // thread will delete itselfs once done + mWindowThread = NULL; + } } bool LLWindowWin32::isValid() @@ -1185,7 +1217,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo // If we found a good resolution, use it. if (success) { - success = setDisplayResolution(width, height, BITS_PER_PIXEL, closest_refresh); + success = setDisplayResolution(width, height, closest_refresh); } // Keep a copy of the actual current device mode in case we minimize @@ -1197,7 +1229,6 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo mFullscreen = true; mFullscreenWidth = dev_mode.dmPelsWidth; mFullscreenHeight = dev_mode.dmPelsHeight; - mFullscreenBits = dev_mode.dmBitsPerPel; mFullscreenRefresh = dev_mode.dmDisplayFrequency; LL_INFOS("Window") << "Running at " << dev_mode.dmPelsWidth @@ -1223,7 +1254,6 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo mFullscreen = false; mFullscreenWidth = -1; mFullscreenHeight = -1; - mFullscreenBits = -1; mFullscreenRefresh = -1; LL_INFOS("Window") << "Unable to run fullscreen at " << width << "x" << height << LL_ENDL; @@ -3015,6 +3045,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ WINDOW_IMP_POST(window_imp->mMouseVanish = true); } } + // Check if theme-related settings changed + else if (l_param && (wcscmp((LPCWSTR)l_param, L"ImmersiveColorSet") == 0)) + { + WINDOW_IMP_POST(window_imp->updateWindowTheme()); + } + } + break; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + { + WINDOW_IMP_POST(window_imp->updateWindowTheme()); } break; @@ -3107,10 +3148,14 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ break; } } - else + else // (NULL == window_imp) { - // (NULL == window_imp) LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL; + if (u_msg == WM_DESTROY) + { + PostQuitMessage(0); // Posts WM_QUIT with an exit code of 0 + return 0; + } } // pass unhandled messages down to Windows @@ -3520,7 +3565,7 @@ F32 LLWindowWin32::getPixelAspectRatio() // Change display resolution. Returns true if successful. // protected -bool LLWindowWin32::setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh) +bool LLWindowWin32::setDisplayResolution(S32 width, S32 height, S32 refresh) { DEVMODE dev_mode; ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); @@ -3532,7 +3577,6 @@ bool LLWindowWin32::setDisplayResolution(S32 width, S32 height, S32 bits, S32 re { if (dev_mode.dmPelsWidth == width && dev_mode.dmPelsHeight == height && - dev_mode.dmBitsPerPel == bits && dev_mode.dmDisplayFrequency == refresh ) { // ...display mode identical, do nothing @@ -3544,9 +3588,8 @@ bool LLWindowWin32::setDisplayResolution(S32 width, S32 height, S32 bits, S32 re dev_mode.dmSize = sizeof(dev_mode); dev_mode.dmPelsWidth = width; dev_mode.dmPelsHeight = height; - dev_mode.dmBitsPerPel = bits; dev_mode.dmDisplayFrequency = refresh; - dev_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; + dev_mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; // CDS_FULLSCREEN indicates that this is a temporary change to the device mode. LONG cds_result = ChangeDisplaySettings(&dev_mode, CDS_FULLSCREEN); @@ -3556,7 +3599,7 @@ bool LLWindowWin32::setDisplayResolution(S32 width, S32 height, S32 bits, S32 re if (!success) { LL_WARNS("Window") << "setDisplayResolution failed, " - << width << "x" << height << "x" << bits << " @ " << refresh << LL_ENDL; + << width << "x" << height << " @ " << refresh << LL_ENDL; } return success; @@ -3567,7 +3610,7 @@ bool LLWindowWin32::setFullscreenResolution() { if (mFullscreen) { - return setDisplayResolution( mFullscreenWidth, mFullscreenHeight, mFullscreenBits, mFullscreenRefresh); + return setDisplayResolution( mFullscreenWidth, mFullscreenHeight, mFullscreenRefresh); } else { @@ -4042,7 +4085,15 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont) break; } - logfont->lfHeight = mPreeditor->getPreeditFontSize(); + if (mPreeditor) + { + logfont->lfHeight = mPreeditor->getPreeditFontSize(); + } + else + { + // todo: extract from some font * LLUI::getScaleFactor() intead + logfont->lfHeight = 10; + } logfont->lfWeight = FW_NORMAL; } @@ -4573,25 +4624,11 @@ std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList() #endif // LL_WINDOWS inline LLWindowWin32::LLWindowWin32Thread::LLWindowWin32Thread() - : LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, true /*should be false, temporary workaround for SL-18721*/) + : LL::ThreadPool("Window Thread", 1, MAX_QUEUE_SIZE, false) { LL::ThreadPool::start(); } -void LLWindowWin32::LLWindowWin32Thread::close() -{ - if (!mQueue->isClosed()) - { - LL_WARNS() << "Closing window thread without using destroy_window_handler" << LL_ENDL; - LL::ThreadPool::close(); - - // Workaround for SL-18721 in case window closes too early and abruptly - LLSplashScreen::show(); - LLSplashScreen::update("..."); // will be updated later - } -} - - /** * LogChange is to log changes in status while trying to avoid spamming the * log with repeated messages, especially in a tight loop. It refuses to log @@ -4815,108 +4852,110 @@ void LLWindowWin32::LLWindowWin32Thread::run() } #endif } + + destroyWindow(); + + if (mDeleteOnExit) + { + delete this; + } +} + +void LLWindowWin32::LLWindowWin32Thread::destroyWindow() +{ + if (mWindowHandleThrd != NULL && IsWindow(mWindowHandleThrd)) + { + if (mhDCThrd) + { + if (!ReleaseDC(mWindowHandleThrd, mhDCThrd)) + { + LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL; + } + mhDCThrd = NULL; + } + + // This causes WM_DESTROY to be sent *immediately* + if (!destroy_window_handler(mWindowHandleThrd)) + { + LL_WARNS("Window") << "Failed to destroy Window! " << std::hex << GetLastError() << LL_ENDL; + } + } + else + { + // Something killed the window while we were busy destroying gl or handle somehow got broken + LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL; + } + mWindowHandleThrd = NULL; + mhDCThrd = NULL; } -void LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() +bool LLWindowWin32::LLWindowWin32Thread::wakeAndDestroy() { if (mQueue->isClosed()) { - LL_WARNS() << "Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL; - return; + LL_WARNS("Window") << "Tried to close Queue. Win32 thread Queue already closed." << LL_ENDL; + return false; } - // Make sure we don't leave a blank toolbar button. - // Also hiding window now prevents user from suspending it - // via some action (like dragging it around) - ShowWindow(mWindowHandleThrd, SW_HIDE); + // Hide the window immediately to prevent user interaction during shutdown + if (mWindowHandleThrd) + { + ShowWindow(mWindowHandleThrd, SW_HIDE); + } + else + { + LL_WARNS("Window") << "Tried to hide window, but Win32 window handle is NULL." << LL_ENDL; + return false; + } + + mGLReady = false; - // Schedule destruction + // Capture current handle before we lose it HWND old_handle = mWindowHandleThrd; - post([this]() - { - if (IsWindow(mWindowHandleThrd)) - { - if (mhDCThrd) - { - if (!ReleaseDC(mWindowHandleThrd, mhDCThrd)) - { - LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL; - } - mhDCThrd = NULL; - } - - // This causes WM_DESTROY to be sent *immediately* - if (!destroy_window_handler(mWindowHandleThrd)) - { - LL_WARNS("Window") << "Failed to destroy Window! " << std::hex << GetLastError() << LL_ENDL; - } - } - else - { - // Something killed the window while we were busy destroying gl or handle somehow got broken - LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL; - } - mWindowHandleThrd = NULL; - mhDCThrd = NULL; - mGLReady = false; - }); + // Clear the user data to prevent callbacks from finding us + if (old_handle) + { + SetWindowLongPtr(old_handle, GWLP_USERDATA, NULL); + } + + // Signal thread to clean up when done + mDeleteOnExit = true; + + // Close the queue first LL_DEBUGS("Window") << "Closing window's pool queue" << LL_ENDL; mQueue->close(); - // Post a nonsense user message to wake up the thread in - // case it is waiting for a getMessage() + // Wake up the thread if it's stuck in GetMessage() if (old_handle) { WPARAM wparam{ 0xB0B0 }; LL_DEBUGS("Window") << "PostMessage(" << std::hex << old_handle << ", " << WM_DUMMY_ << ", " << wparam << ")" << std::dec << LL_ENDL; - PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337); - } - // There are cases where window will refuse to close, - // can't wait forever on join, check state instead - LLTimer timeout; - timeout.setTimerExpirySec(2.0); - while (!getQueue().done() && !timeout.hasExpired() && mWindowHandleThrd) - { - ms_sleep(100); + // Use PostMessage to signal thread to wake up + PostMessage(old_handle, WM_DUMMY_, wparam, 0x1337); } - if (getQueue().done() || mWindowHandleThrd == NULL) + // Cleanly detach threads instead of joining them to avoid blocking the main thread + // This is acceptable since the thread will self-delete with mDeleteOnExit + for (auto& pair : mThreads) { - // Window is closed, started closing or is cleaning up - // now wait for our single thread to die. - if (mWindowHandleThrd) - { - LL_INFOS("Window") << "Window is closing, waiting on pool's thread to join, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL; - } - else - { - LL_DEBUGS("Window") << "Waiting on pool's thread, time since post: " << timeout.getElapsedSeconds() << "s" << LL_ENDL; + try { + // Only detach if the thread is joinable + if (pair.second.joinable()) + { + pair.second.detach(); + } } - for (auto& pair : mThreads) - { - pair.second.join(); + catch (const std::system_error& e) { + LL_WARNS("Window") << "Exception detaching thread: " << e.what() << LL_ENDL; } } - else - { - // Something suspended window thread, can't afford to wait forever - // so kill thread instead - // Ex: This can happen if user starts dragging window arround (if it - // was visible) or a modal notification pops up - LL_WARNS("Window") << "Window is frozen, couldn't perform clean exit" << LL_ENDL; - for (auto& pair : mThreads) - { - // very unsafe - TerminateThread(pair.second.native_handle(), 0); - pair.second.detach(); - } - } LL_DEBUGS("Window") << "thread pool shutdown complete" << LL_ENDL; + return true; } void LLWindowWin32::post(const std::function<void()>& func) @@ -4963,3 +5002,69 @@ void LLWindowWin32::updateWindowRect() }); } } + +bool LLWindowWin32::isSystemAppDarkMode() +{ + HKEY hKey; + DWORD dwValue = 1; // Default to light theme + DWORD dwSize = sizeof(DWORD); + + // Check registry for system theme preference + LSTATUS ret_code = + RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", 0, KEY_READ, &hKey); + if (ERROR_SUCCESS == ret_code) + { + if (RegQueryValueExW(hKey, L"AppsUseLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS) + { + // If AppsUseLightTheme is not found, check SystemUsesLightTheme + dwSize = sizeof(DWORD); + RegQueryValueExW(hKey, L"SystemUsesLightTheme", NULL, NULL, (LPBYTE)&dwValue, &dwSize); + } + RegCloseKey(hKey); + } + + // Return true if dark mode + return dwValue == 0; +} + +void LLWindowWin32::updateWindowTheme() +{ + bool use_dark_mode = isSystemAppDarkMode(); + if (use_dark_mode == mCurrentDarkMode) + { + return; + } + mCurrentDarkMode = use_dark_mode; + + HMODULE hUxTheme = LoadLibraryExW(L"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (hUxTheme) + { + auto SetPreferredAppMode = (fnSetPreferredAppMode)GetProcAddress(hUxTheme, "SetPreferredAppMode"); + if (SetPreferredAppMode) + { + SetPreferredAppMode(use_dark_mode ? ALLOW_DARK : FORCE_LIGHT); + } + FreeLibrary(hUxTheme); + } + BOOL dark_mode(use_dark_mode); + DwmSetWindowAttribute(mWindowHandle, DWMWA_USE_IMMERSIVE_DARK_MODE, &dark_mode, sizeof(dark_mode)); + + LL_INFOS("Window") << "Viewer window theme is set to " << (use_dark_mode ? "dark" : "light") << " mode" << LL_ENDL; +} + +void LLWindowWin32::setCustomIcon() +{ + if (mWindowHandle) + { + HICON hDefaultIcon = LoadIcon(mhInstance, mIconResource); + HICON hSmallIcon = LoadIcon(mhInstance, mIconSmallResource); + mWindowThread->post([=]() + { + SendMessage(mWindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hDefaultIcon); + SendMessage(mWindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hSmallIcon); + + SetClassLongPtr(mWindowHandle, GCLP_HICON, (LONG_PTR)hDefaultIcon); + SetClassLongPtr(mWindowHandle, GCLP_HICONSM, (LONG_PTR)hSmallIcon); + }); + } +} diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 36e89e4586..7196706f87 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -150,7 +150,7 @@ protected: virtual LLSD getNativeKeyData(); // Changes display resolution. Returns true if successful - bool setDisplayResolution(S32 width, S32 height, S32 bits, S32 refresh); + bool setDisplayResolution(S32 width, S32 height, S32 refresh); // Go back to last fullscreen display resolution. bool setFullscreenResolution(); @@ -214,6 +214,7 @@ protected: bool mCustomGammaSet; LPWSTR mIconResource; + LPWSTR mIconSmallResource; bool mInputProcessingPaused; // The following variables are for Language Text Input control. @@ -246,6 +247,11 @@ protected: RECT mRect; RECT mClientRect; + void updateWindowTheme(); + bool isSystemAppDarkMode(); + void setCustomIcon(); + bool mCurrentDarkMode { false }; + struct LLWindowWin32Thread; LLWindowWin32Thread* mWindowThread = nullptr; LLThreadSafeQueue<std::function<void()>> mFunctionQueue; @@ -281,6 +287,7 @@ private: extern LLW32MsgCallback gAsyncMsgCallback; extern LPWSTR gIconResource; +extern LPWSTR gIconSmallResource; S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 type); diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index bb590ebd76..562a30e8d1 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -157,6 +157,9 @@ LLControlVariable::LLControlVariable(const std::string& name, eControlType type, { if ((persist != PERSIST_NO) && mComment.empty()) { + // File isn't actually missing, but something is wrong with it + // so the main point is to warn user to reinstall + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL; } //Push back versus setValue'ing here, since we don't want to call a signal yet diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 23b0a7723e..117473554e 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -15,6 +15,9 @@ include(CMakeCopyIfDifferent) include(CubemapToEquirectangularJS) include(DBusGlib) include(DragDrop) +if (USE_DISCORD) + include(Discord) +endif () include(EXPAT) include(Hunspell) include(JPEGEncoderBasic) @@ -76,6 +79,7 @@ set(viewer_SOURCE_FILES gltf/accessor.cpp gltf/primitive.cpp gltf/animation.cpp + gltf/llgltfloader.cpp groupchatlistener.cpp llaccountingcostmanager.cpp llaisapi.cpp @@ -178,11 +182,11 @@ set(viewer_SOURCE_FILES llflexibleobject.cpp llfloater360capture.cpp llfloaterabout.cpp + llfloateravatarwelcomepack.cpp llfloaterbvhpreview.cpp llfloateraddpaymentmethod.cpp llfloaterauction.cpp llfloaterautoreplacesettings.cpp - llfloateravatar.cpp llfloateravatarpicker.cpp llfloateravatarrendersettings.cpp llfloateravatartextures.cpp @@ -201,6 +205,7 @@ set(viewer_SOURCE_FILES llfloatercamera.cpp llfloatercamerapresets.cpp llfloaterchangeitemthumbnail.cpp + llfloaterchatmentionpicker.cpp llfloaterchatvoicevolume.cpp llfloaterclassified.cpp llfloatercolorpicker.cpp @@ -337,6 +342,7 @@ set(viewer_SOURCE_FILES llhudeffectpointat.cpp llhudeffecttrail.cpp llhudeffectblob.cpp + llhudeffectresetskeleton.cpp llhudicon.cpp llhudmanager.cpp llhudnametag.cpp @@ -362,6 +368,7 @@ set(viewer_SOURCE_FILES llinventorygallerymenu.cpp llinventoryicon.cpp llinventoryitemslist.cpp + llinventorylistener.cpp llinventorylistitem.cpp llinventorymodel.cpp llinventorymodelbackgroundfetch.cpp @@ -745,6 +752,7 @@ set(viewer_HEADER_FILES gltf/buffer_util.h gltf/primitive.h gltf/animation.h + gltf/llgltfloader.h llaccountingcost.h llaccountingcostmanager.h llaisapi.h @@ -848,11 +856,11 @@ set(viewer_HEADER_FILES llflexibleobject.h llfloater360capture.h llfloaterabout.h + llfloateravatarwelcomepack.h llfloaterbvhpreview.h llfloateraddpaymentmethod.h llfloaterauction.h llfloaterautoreplacesettings.h - llfloateravatar.h llfloateravatarpicker.h llfloateravatarrendersettings.h llfloateravatartextures.h @@ -870,6 +878,7 @@ set(viewer_HEADER_FILES llfloaterbuyland.h llfloatercamerapresets.h llfloaterchangeitemthumbnail.h + llfloaterchatmentionpicker.h llfloatercamera.h llfloaterchatvoicevolume.h llfloaterclassified.h @@ -1009,6 +1018,7 @@ set(viewer_HEADER_FILES llhudeffectpointat.h llhudeffecttrail.h llhudeffectblob.h + llhudeffectresetskeleton.h llhudicon.h llhudmanager.h llhudnametag.h @@ -1033,6 +1043,7 @@ set(viewer_HEADER_FILES llinventorygallerymenu.h llinventoryicon.h llinventoryitemslist.h + llinventorylistener.h llinventorylistitem.h llinventorymodel.h llinventorymodelbackgroundfetch.h @@ -1564,6 +1575,7 @@ if (WINDOWS) res-sdl/ll_icon.BMP res/ll_icon.BMP res/ll_icon.ico + res/ll_icon_small.ico res/resource.h res/toolpickobject.cur res/toolpickobject2.cur @@ -1656,7 +1668,7 @@ set(viewer_APPSETTINGS_FILES app_settings/toolbars.xml app_settings/trees.xml app_settings/viewerart.xml - ${CMAKE_SOURCE_DIR}/../etc/message.xml + app_settings/message.xml ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg packages-info.txt featuretable.txt @@ -1750,7 +1762,7 @@ if (WINDOWS) set(COPY_INPUT_DEPENDENCIES # The following commented dependencies are determined variably at build time. Can't do this here. - ${CMAKE_SOURCE_DIR}/../etc/message.xml + app_settings/message.xml ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg ${SHARED_LIB_STAGING_DIR}/openjp2.dll ${SHARED_LIB_STAGING_DIR}/llwebrtc.dll @@ -1779,6 +1791,12 @@ if (WINDOWS) ) endif (ADDRESS_SIZE EQUAL 64) + if (TARGET ll::discord_sdk) + list(APPEND COPY_INPUT_DEPENDENCIES + ${SHARED_LIB_STAGING_DIR}/discord_partner_sdk.dll + ) + endif () + if (TARGET ll::openal) list(APPEND COPY_INPUT_DEPENDENCIES ${SHARED_LIB_STAGING_DIR}/OpenAL32.dll @@ -1795,6 +1813,7 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--discord=${USE_DISCORD}" "--openal=${USE_OPENAL}" "--tracy=${USE_TRACY}" --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1833,6 +1852,7 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--discord=${USE_DISCORD}" "--openal=${USE_OPENAL}" "--tracy=${USE_TRACY}" --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1897,6 +1917,7 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--discord=${USE_DISCORD}" "--openal=${USE_OPENAL}" "--tracy=${USE_TRACY}" --build=${CMAKE_CURRENT_BINARY_DIR} @@ -1993,6 +2014,10 @@ target_link_libraries(${VIEWER_BINARY_NAME} ll::openxr ) +if (USE_DISCORD) + target_link_libraries(${VIEWER_BINARY_NAME} ll::discord_sdk ) +endif () + if( TARGET ll::intel_memops ) target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops ) endif() @@ -2049,6 +2074,7 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--discord=${USE_DISCORD}" "--openal=${USE_OPENAL}" "--tracy=${USE_TRACY}" --build=${CMAKE_CURRENT_BINARY_DIR} @@ -2077,6 +2103,7 @@ if (LINUX) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--discord=${USE_DISCORD}" "--openal=${USE_OPENAL}" "--tracy=${USE_TRACY}" --build=${CMAKE_CURRENT_BINARY_DIR} @@ -2151,6 +2178,7 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--discord=${USE_DISCORD}" "--openal=${USE_OPENAL}" "--tracy=${USE_TRACY}" --build=${CMAKE_CURRENT_BINARY_DIR} @@ -2183,6 +2211,7 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--discord=${USE_DISCORD}" "--openal=${USE_OPENAL}" "--tracy=${USE_TRACY}" --build=${CMAKE_CURRENT_BINARY_DIR} diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 991d8e5c5f..b26a34e470 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.1.13 +7.2.1 diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 4a3dfffde1..7bcfecf9fa 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -26,9 +26,9 @@ label_ref="Command_Avatar_Label" tooltip_ref="Command_Avatar_Tooltip" execute_function="Floater.ToggleOrBringToFront" - execute_parameters="avatar" + execute_parameters="avatar_welcome_pack" is_running_function="Floater.IsOpen" - is_running_parameters="avatar" + is_running_parameters="avatar_welcome_pack" /> <command name="build" available_in_toybox="true" diff --git a/indra/newview/app_settings/message.xml b/indra/newview/app_settings/message.xml new file mode 100755 index 0000000000..dee3fd72dd --- /dev/null +++ b/indra/newview/app_settings/message.xml @@ -0,0 +1,751 @@ +<?xml version="1.0"?> +<llsd> + <map> + <key>serverDefaults</key> + <!-- + a map of server names to default message transport + --> + <map> + <key>simulator</key> + <string>template</string> + + <key>spaceserver</key> + <string>template</string> + + <key>dataserver</key> + <string>template</string> + + <key>logDataserver</key> + <string>template</string> + + <key>inventoryDataserver</key> + <string>template</string> + + <key>rpcserver</key> + <string>template</string> + + <key>mapserver</key> + <string>template</string> + + <key>viewer</key> + <string>template</string> + + </map> + <key>messages</key> + <!-- + a map of individual message names that override defaults + --> + <map> + <!-- + Circuit related messages + --> + <key>PacketAck</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>OpenCircuit</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>CloseCircuit</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>StartPingCheck</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>CompletePingCheck</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>AddCircuitCode</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>UseCircuitCode</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>CreateTrustedCircuit</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>RequestTrustedCircuit</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <!-- + Simulator to Launcher + until we get a HTTP server in the launcher + --> + <key>ReportAutosaveCrash</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>SetCPURatio</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <!-- + Viewer to simulator messages sent before UntrustedSimulatorMessage cap received. + --> + <key>CompleteAgentMovement</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>EconomyDataRequest</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ViewerEffect</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>RegionHandshakeReply</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <!-- + Viewer to simulator messages sent unreliably. + --> + <key>AgentUpdate</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <!-- + Messages created by LLThrottleGroup clients + --> + <key>ImagePacket</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>LayerData</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ObjectUpdateCached</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ObjectUpdateCompressed</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ObjectUpdate</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ImprovedTerseObjectUpdate</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>AvatarAnimation</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ObjectAnimation</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>AvatarAppearance</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <!-- Simulator to simulator reliable messages --> + <key>GodKickUser</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>RoutedMoneyBalanceReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <!-- Simulator to simulator unreliable messages --> + <key>EdgeDataPacket</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>CoarseLocationUpdate</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>true</boolean> + <key>only-send-latest</key> + <boolean>true</boolean> + </map> + + <key>SimulatorLoad</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>EstablishAgentCommunication</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>AgentGroupDataUpdate</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>AgentDropGroup</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ChatterBoxSessionStartReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ChatterBoxSessionEventReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ForceCloseChatterBoxSession</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ChatterBoxSessionAgentListUpdates</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ChatterBoxSessionUpdate</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ChatterBoxInvitation</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <!-- Client to server --> + <key>ParcelVoiceInfoRequest</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <!-- Server to client --> + <key>DisplayNameUpdate</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ParcelVoiceInfo</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ParcelNavigateMedia</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ParcelObjectOwnersReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>ParcelProperties</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>LandStatReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>PlacesReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>SetDisplayNameReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>SimConsoleResponse</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>DirLandReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>avatarnotesrequest</key> + <map> + <key>service_name</key> + <string>avatar-notes</string> + <key>builder</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>avatarclassifiedsrequest</key> + <map> + <key>service_name</key> + <string>avatar-classifieds</string> + <key>builder</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>avatarpicksrequest</key> + <map> + <key>service_name</key> + <string>avatar-pick</string> + <key>builder</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>pickinforequest</key> + <map> + <key>service_name</key> + <string>pick-info</string> + <key>builder</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ProvisionVoiceAccountRequest</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>VoiceSignalingRequest</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + <!-- Server to client --> + <key>RequiredVoiceVersion</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>EnableSimulator</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>TeleportFinish</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>TeleportFailed</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>CrossedRegion</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>NavMeshStatusUpdate</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <key>AgentStateUpdate</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + <!-- UDPDeprecated Messages --> + <key>ScriptRunningReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>LandStatReply</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>StartGroupProposal</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>FetchInventoryDescendents</key> + <map> + <key>flavor</key> + <string>template</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>GroupProposalBallot</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>RpcScriptRequestInboundForward</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>false</boolean> + </map> + + <key>ObjectPhysicsProperties</key> + <map> + <key>flavor</key> + <string>llsd</string> + <key>trusted-sender</key> + <boolean>true</boolean> + </map> + + </map> + <key>capBans</key> + <map> + <key>MapLayer</key> + <boolean>false</boolean> + + <key>MapLayerGod</key> + <boolean>false</boolean> + + <key>NewFileAgentInventory</key> + <boolean>false</boolean> + + <key>UpdateGestureAgentInventory</key> + <boolean>false</boolean> + + <key>UpdateNotecardAgentInventory</key> + <boolean>false</boolean> + + <key>UpdateScriptAgentInventory</key> + <boolean>false</boolean> + + <key>UpdateGestureTaskInventory</key> + <boolean>false</boolean> + + <key>UpdateNotecardTaskInventory</key> + <boolean>false</boolean> + + <key>UpdateScriptTaskInventory</key> + <boolean>false</boolean> + + <key>ViewerStartAuction</key> + <boolean>true</boolean> + + <key>ParcelGodReserveForNewbie</key> + <boolean>true</boolean> + + <key>SendUserReport</key> + <boolean>false</boolean> + + <key>SendUserReportWithScreenshot</key> + <boolean>false</boolean> + + <key>RequestTextureDownload</key> + <boolean>true</boolean> + + <key>EventQueueGet</key> + <boolean>false</boolean> + + <key>UntrustedSimulatorMessage</key> + <boolean>false</boolean> + + <key>SendPostcard</key> + <boolean>false</boolean> + + <key>SendPostcard2</key> + <boolean>true</boolean> + + <key>SendPostcard3</key> + <boolean>true</boolean> + + <key>ParcelVoiceInfoRequest</key> + <boolean>false</boolean> + + <key>ChatSessionRequest</key> + <boolean>false</boolean> + + <key>ProvisionVoiceAccountRequest</key> + <boolean>false</boolean> + + <key>VoiceSignalingRequest</key> + <boolean>false</boolean> + + <key>RemoteParcelRequest</key> + <boolean>false</boolean> + + <key>SearchStatTracking</key> + <boolean>false</boolean> + + <key>ParcelPropertiesUpdate</key> + <boolean>false</boolean> + + <key>EstateChangeInfo</key> + <boolean>true</boolean> + + <key>FetchInventoryDescendents2</key> + <boolean>false</boolean> + + <key>FetchInventory2</key> + <boolean>false</boolean> + + <key>FetchLibDescendents2</key> + <boolean>false</boolean> + + <key>FetchLib2</key> + <boolean>false</boolean> + + <key>UploadBakedTexture</key> + <boolean>true</boolean> + + <key>ObjectMedia</key> + <boolean>false</boolean> + + <key>ObjectMediaNavigate</key> + <boolean>false</boolean> + + </map> + + <key>messageBans</key> + <map> + <key>trusted</key> + <map> + </map> + + <key>untrusted</key> + <map> + </map> + </map> + + <key>maxQueuedEvents</key> + <integer>100</integer> + </map> +</llsd> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 1025c9299d..d64f82d303 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2,7 +2,7 @@ <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="llsd.xsd"> <map> - <key>ImporterDebug</key> + <key>ImporterDebugVerboseLogging</key> <map> <key>Comment</key> <string>Enable debug output to more precisely identify sources of import errors. Warning: the output can slow down import on many machines.</string> @@ -27,7 +27,7 @@ <key>ImporterModelLimit</key> <map> <key>Comment</key> - <string>Limits amount of importer generated models for dae files</string> + <string>Limits amount of importer generated (when over 8 faces) models for dae and gltf files</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -35,6 +35,17 @@ <key>Value</key> <integer>768</integer> </map> + <key>ImporterDebugMode</key> + <map> + <key>Comment</key> + <string>At 0 does nothing, at 1 dumps skinning data near orifinal file, at 2 dumps skining data and positions/weights of first 5 models, at 3 dumps skinning data and models as llsd</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ImporterPreprocessDAE</key> <map> <key>Comment</key> @@ -91,7 +102,7 @@ <key>Type</key> <string>S32</string> <key>Value</key> - <real>300.0</real> + <real>300</real> </map> <key>AckCollectTime</key> <map> @@ -621,16 +632,16 @@ <key>Value</key> <real>16.0</real> </map> - <key>AvatarPickerURL</key> + <key>AvatarWelcomePack</key> <map> - <key>Comment</key> - <string>Avatar picker contents</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/avatars.html</string> + <key>Comment</key> + <string>Avatar Welcome Pack contents</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/vawp/index.html</string> </map> <!--AvatarBakedTextureUploadTimeout is in use by QA--> <key>AvatarBakedTextureUploadTimeout</key> @@ -1139,6 +1150,39 @@ <key>Value</key> <integer>1</integer> </map> + <key>EnableDiscord</key> + <map> + <key>Comment</key> + <string>When set, connect to Discord to enable Rich Presence</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>ShowDiscordActivityDetails</key> + <map> + <key>Comment</key> + <string>When set, show avatar name on Discord Rich Presence</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>ShowDiscordActivityState</key> + <map> + <key>Comment</key> + <string>When set, show location on Discord Rich Presence</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>EnableDiskCacheDebugInfo</key> <map> <key>Comment</key> @@ -1153,13 +1197,13 @@ <key>DiskCachePercentOfTotal</key> <map> <key>Comment</key> - <string>The percent of total cache size (defined by CacheSize) to use for the disk cache</string> + <string>The percent of total cache size (defined by CacheSize) to use for the disk cache (ex: asset storage, excludes textures)</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>F32</string> <key>Value</key> - <real>40.0</real> + <real>35.0</real> </map> <key>DiskCacheDirName</key> <map> @@ -1203,7 +1247,7 @@ <key>Type</key> <string>U32</string> <key>Value</key> - <integer>4096</integer> + <integer>6144</integer> </map> <key>CacheValidateCounter</key> <map> @@ -1864,6 +1908,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>DebugSelectionLODs</key> + <map> + <key>Comment</key> + <string>Force selection to show specific LOD, -1 for off, 0 - lowest, 4 - high.</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>-1</integer> + </map> <key>AnimatedObjectsAllowLeftClick</key> <map> <key>Comment</key> @@ -6361,6 +6416,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>PlaySoundChatMention</key> + <map> + <key>Comment</key> + <string>Plays a sound when got mentioned in a chat</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>PluginAttachDebuggerToPlugins</key> <map> <key>Comment</key> @@ -7830,7 +7896,7 @@ <key>RenderMinFreeMainMemoryThreshold</key> <map> <key>Comment</key> - <string>Minimum of available physical memory in MB before textures get scaled down</string> + <string>If available free physical memory is below this value textures get agresively scaled down</string> <key>Persist</key> <integer>0</integer> <key>Type</key> @@ -9584,6 +9650,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>ObscureBalanceInStatusBar</key> + <map> + <key>Comment</key> + <string>If true, balance will be shows as '*'</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>RenderUIBuffer</key> <map> <key>Comment</key> @@ -11477,6 +11554,28 @@ <key>Value</key> <string>fss.txt</string> </map> + <key>StatsFrametimeSampleSeconds</key> + <map> + <key>Comment</key> + <string>The number of seconds to sample extended frametime data (percentiles, stddev).</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>5</integer> + </map> + <key>StatsFrametimeEventThreshold</key> + <map> + <key>Comment</key> + <string>The percentage that the frametime difference must exceed in order to register a frametime event. 0.1 = 10%, 0.25 = 25%, etc.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.1</real> + </map> <key>SystemLanguage</key> <map> <key>Comment</key> @@ -12395,6 +12494,28 @@ <key>Value</key> <string>2ca849ba-2885-4bc3-90ef-d4987a5b983a</string> </map> + <key>UISndChatMention</key> + <map> + <key>Comment</key> + <string>Sound file for chat mention(uuid for sound asset)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>03e77cb5-592c-5b33-d271-2e46497c3fb3</string> + </map> + <key>UISndChatPing</key> + <map> + <key>Comment</key> + <string>Sound file for chat ping(uuid for sound asset)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>7dd36df6-2624-5438-f988-fdf8588a0ad9</string> + </map> <key>UISndClick</key> <map> <key>Comment</key> @@ -13687,7 +13808,7 @@ <key>FullScreen</key> <map> <key>Comment</key> - <string>run a fullscreen session</string> + <string>Run a fullscreen session. MacOS not supported</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -14185,10 +14306,32 @@ <key>Value</key> <integer>1</integer> </map> - <key>OutfitGallerySortByName</key> + <key>OutfitGallerySortOrder</key> + <map> + <key>Comment</key> + <string>Gallery sorting: 0 - sort outfits by name, 1 - images frst, 2 - favorites first</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>OutfitListSortOrder</key> <map> <key>Comment</key> - <string>Always sort outfits by name in Outfit Gallery</string> + <string>How outfit list in Avatar's floater is sorted. 0 - by name 1 - favorites to top</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>OutfitListFilterFullList</key> + <map> + <key>Comment</key> + <string> 0 - show only matches. 1 - show all items in outfit as long as outfit or item inside matches.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -16069,6 +16212,50 @@ <key>Value</key> <integer>0</integer> </map> + <key>InventoryFavoritesUseStar</key> + <map> + <key>Comment</key> + <string>Show star near favorited items in inventory</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>InventoryFavoritesUseHollowStar</key> + <map> + <key>Comment</key> + <string>Show star near folders that contain favorites</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>InventoryFavoritesColorText</key> + <map> + <key>Comment</key> + <string>render favorite items using InventoryFavoriteText as color</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>InventoryAddAttachmentBehavior</key> + <map> + <key>Comment</key> + <string>Defines behavior when hitting return on an inventory item</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>StatsReportMaxDuration</key> <map> <key>Comment</key> @@ -16157,5 +16344,71 @@ <key>Value</key> <integer>1</integer> </map> + <key>MediaAutoPlayHuds</key> + <map> + <key>Comment</key> + <string>Automatically play HUD media</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>MediaFirstClickInteract</key> + <map> + <key>Comment</key> + <string>This setting controls which media (once loaded) does not require a first click to focus before interaction can begin. This allows clicks to be passed directly to media bypassing the focus click requirement. This setting is a bitfield, precomputed values are as follows: Disabled=0; Worn HUDs only=1; Owned objects=2; Friend objects=4; Group objects=8; Landowner objects=16; Any object=32767; All MOAP=32768. For complete details see lltoolpie.h enum MediaFirstClickTypes.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>31</integer> + </map> + <key>EnableSelectionHints</key> + <map> + <key>Comment</key> + <string>Whether or not to send editing hints to animate the arm when editing an object.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>EnableLookAtTarget</key> + <map> + <key>Comment</key> + <string>Whether or not to animate the avatar head and send look at targets when moving the cursor or focusing on objects</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> + <key>LimitLookAtTarget</key> + <map> + <key>Comment</key> + <string>Whether or not to clamp the look at targets around the avatar head before sending</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> + <key>LimitLookAtTargetDistance</key> + <map> + <key>Comment</key> + <string>Distance to limit look at target to</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <integer>2</integer> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 6b788dd78f..99c43acd49 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -329,7 +329,7 @@ <key>KeepConversationLogTranscripts</key> <map> <key>Comment</key> - <string>Keep a conversation log and transcripts</string> + <string>Keep a conversation log and transcripts 2 - both, 1 - logs, 0 - none</string> <key>Persist</key> <integer>1</integer> <key>Type</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl index a63b8d7c2b..774ccb6baf 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl @@ -117,27 +117,34 @@ uniform float exposure; uniform float tonemap_mix; uniform int tonemap_type; + vec3 toneMap(vec3 color) { #ifndef NO_POST - float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; - - color *= exposure * exp_scale; + vec3 linear_input_color = color; - vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; + float final_exposure = exposure * exp_scale; + vec3 exposed_color = color * final_exposure; + vec3 tonemapped_color = exposed_color; switch(tonemap_type) { case 0: - color = PBRNeutralToneMapping(color); + tonemapped_color = PBRNeutralToneMapping(exposed_color); break; case 1: - color = toneMapACES_Hill(color); + tonemapped_color = toneMapACES_Hill(exposed_color); break; } - // mix tonemapped and linear here to provide adjustment - color = mix(clamped_color, color, tonemap_mix); + vec3 exposed_linear_input = linear_input_color * final_exposure; + color = mix(exposed_linear_input, tonemapped_color, tonemap_mix); + + color = clamp(color, 0.0, 1.0); +#else + color *= exposure * texture(exposureMap, vec2(0.5,0.5)).r; + color = clamp(color, 0.0, 1.0); #endif return color; @@ -147,20 +154,24 @@ vec3 toneMap(vec3 color) vec3 toneMapNoExposure(vec3 color) { #ifndef NO_POST - vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0)); + vec3 linear_input_color = color; + vec3 tonemapped_color = color; switch(tonemap_type) { case 0: - color = PBRNeutralToneMapping(color); + tonemapped_color = PBRNeutralToneMapping(color); break; case 1: - color = toneMapACES_Hill(color); + tonemapped_color = toneMapACES_Hill(color); break; } - // mix tonemapped and linear here to provide adjustment - color = mix(clamped_color, color, tonemap_mix); + color = mix(linear_input_color, tonemapped_color, tonemap_mix); + + color = clamp(color, 0.0, 1.0); +#else + color = clamp(color, 0.0, 1.0); #endif return color; diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index c0009d24ee..1090dd8ffb 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 73 +version 74 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 5940d1ec12..c3e2dd0c41 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 72 +version 73 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended diff --git a/indra/newview/gltf/accessor.cpp b/indra/newview/gltf/accessor.cpp index d1845605d4..03f7331893 100644 --- a/indra/newview/gltf/accessor.cpp +++ b/indra/newview/gltf/accessor.cpp @@ -159,7 +159,7 @@ bool Buffer::prep(Asset& asset) std::string dir = gDirUtilp->getDirName(asset.mFilename); std::string bin_file = dir + gDirUtilp->getDirDelimiter() + mUri; - std::ifstream file(bin_file, std::ios::binary); + llifstream file(bin_file.c_str(), std::ios::binary); if (!file.is_open()) { LL_WARNS("GLTF") << "Failed to open file: " << bin_file << LL_ENDL; diff --git a/indra/newview/gltf/asset.cpp b/indra/newview/gltf/asset.cpp index c210b9c61d..28f30ae1c9 100644 --- a/indra/newview/gltf/asset.cpp +++ b/indra/newview/gltf/asset.cpp @@ -50,6 +50,10 @@ namespace LL "KHR_texture_transform" }; + static std::unordered_set<std::string> ExtensionsIgnored = { + "KHR_materials_pbrSpecularGlossiness" + }; + Material::AlphaMode gltf_alpha_mode_to_enum(const std::string& alpha_mode) { if (alpha_mode == "OPAQUE") @@ -472,11 +476,14 @@ void Asset::update() for (auto& image : mImages) { - if (image.mTexture.notNull()) - { // HACK - force texture to be loaded full rez - // TODO: calculate actual vsize - image.mTexture->addTextureStats(2048.f * 2048.f); - image.mTexture->setBoostLevel(LLViewerTexture::BOOST_HIGH); + if (image.mLoadIntoTexturePipe) + { + if (image.mTexture.notNull()) + { // HACK - force texture to be loaded full rez + // TODO: calculate actual vsize + image.mTexture->addTextureStats(2048.f * 2048.f); + image.mTexture->setBoostLevel(LLViewerTexture::BOOST_HIGH); + } } } } @@ -486,18 +493,23 @@ void Asset::update() bool Asset::prep() { LL_PROFILE_ZONE_SCOPED_CATEGORY_GLTF; - // check required extensions and fail if not supported - bool unsupported = false; + // check required extensions for (auto& extension : mExtensionsRequired) { if (ExtensionsSupported.find(extension) == ExtensionsSupported.end()) { - LL_WARNS() << "Unsupported extension: " << extension << LL_ENDL; - unsupported = true; + if (ExtensionsIgnored.find(extension) == ExtensionsIgnored.end()) + { + LL_WARNS() << "Unsupported extension: " << extension << LL_ENDL; + mUnsupportedExtensions.push_back(extension); + } + else + { + mIgnoredExtensions.push_back(extension); + } } } - - if (unsupported) + if (mUnsupportedExtensions.size() > 0) { return false; } @@ -513,7 +525,7 @@ bool Asset::prep() for (auto& image : mImages) { - if (!image.prep(*this)) + if (!image.prep(*this, mLoadIntoVRAM)) { return false; } @@ -542,102 +554,110 @@ bool Asset::prep() return false; } } + if (mLoadIntoVRAM) + { + // prepare vertex buffers - // prepare vertex buffers - - // material count is number of materials + 1 for default material - U32 mat_count = (U32) mMaterials.size() + 1; - - if (LLGLSLShader::sCurBoundShaderPtr == nullptr) - { // make sure a shader is bound to satisfy mVertexBuffer->setBuffer - gDebugProgram.bind(); - } + // material count is number of materials + 1 for default material + U32 mat_count = (U32) mMaterials.size() + 1; - for (S32 double_sided = 0; double_sided < 2; ++double_sided) - { - RenderData& rd = mRenderData[double_sided]; - for (U32 i = 0; i < LLGLSLShader::NUM_GLTF_VARIANTS; ++i) - { - rd.mBatches[i].resize(mat_count); + if (LLGLSLShader::sCurBoundShaderPtr == nullptr) + { // make sure a shader is bound to satisfy mVertexBuffer->setBuffer + gDebugProgram.bind(); } - // for each material - for (S32 mat_id = -1; mat_id < (S32)mMaterials.size(); ++mat_id) + for (S32 double_sided = 0; double_sided < 2; ++double_sided) { - // for each shader variant - U32 vertex_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 }; - U32 index_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 }; - - S32 ds_mat = mat_id == -1 ? 0 : mMaterials[mat_id].mDoubleSided; - if (ds_mat != double_sided) + RenderData& rd = mRenderData[double_sided]; + for (U32 i = 0; i < LLGLSLShader::NUM_GLTF_VARIANTS; ++i) { - continue; + rd.mBatches[i].resize(mat_count); } - for (U32 variant = 0; variant < LLGLSLShader::NUM_GLTF_VARIANTS; ++variant) + // for each material + for (S32 mat_id = -1; mat_id < (S32)mMaterials.size(); ++mat_id) { - U32 attribute_mask = 0; - // for each mesh - for (auto& mesh : mMeshes) - { - // for each primitive - for (auto& primitive : mesh.mPrimitives) - { - if (primitive.mMaterial == mat_id && primitive.mShaderVariant == variant) - { - // accumulate vertex and index counts - primitive.mVertexOffset = vertex_count[variant]; - primitive.mIndexOffset = index_count[variant]; - - vertex_count[variant] += primitive.getVertexCount(); - index_count[variant] += primitive.getIndexCount(); + // for each shader variant + U32 vertex_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 }; + U32 index_count[LLGLSLShader::NUM_GLTF_VARIANTS] = { 0 }; - // all primitives of a given variant and material should all have the same attribute mask - llassert(attribute_mask == 0 || primitive.mAttributeMask == attribute_mask); - attribute_mask |= primitive.mAttributeMask; - } - } + S32 ds_mat = mat_id == -1 ? 0 : mMaterials[mat_id].mDoubleSided; + if (ds_mat != double_sided) + { + continue; } - // allocate vertex buffer and pack it - if (vertex_count[variant] > 0) + for (U32 variant = 0; variant < LLGLSLShader::NUM_GLTF_VARIANTS; ++variant) { - U32 mat_idx = mat_id + 1; - LLVertexBuffer* vb = new LLVertexBuffer(attribute_mask); - - rd.mBatches[variant][mat_idx].mVertexBuffer = vb; - vb->allocateBuffer(vertex_count[variant], - index_count[variant] * 2); // hack double index count... TODO: find a better way to indicate 32-bit indices will be used - vb->setBuffer(); - +#ifdef SHOW_ASSERT + U32 attribute_mask = 0; +#endif + // for each mesh for (auto& mesh : mMeshes) { + // for each primitive for (auto& primitive : mesh.mPrimitives) { if (primitive.mMaterial == mat_id && primitive.mShaderVariant == variant) { - primitive.upload(vb); + // accumulate vertex and index counts + primitive.mVertexOffset = vertex_count[variant]; + primitive.mIndexOffset = index_count[variant]; + + vertex_count[variant] += primitive.getVertexCount(); + index_count[variant] += primitive.getIndexCount(); + + // all primitives of a given variant and material should all have the same attribute mask + llassert(attribute_mask == 0 || primitive.mAttributeMask == attribute_mask); +#ifdef SHOW_ASSERT + attribute_mask |= primitive.mAttributeMask; +#endif } } } - vb->unmapBuffer(); + // allocate vertex buffer and pack it + if (vertex_count[variant] > 0) + { + U32 mat_idx = mat_id + 1; + #if 0 + LLVertexBuffer* vb = new LLVertexBuffer(attribute_mask); + + rd.mBatches[variant][mat_idx].mVertexBuffer = vb; + vb->allocateBuffer(vertex_count[variant], + index_count[variant] * 2); // hack double index count... TODO: find a better way to indicate 32-bit indices will be used + vb->setBuffer(); + + for (auto& mesh : mMeshes) + { + for (auto& primitive : mesh.mPrimitives) + { + if (primitive.mMaterial == mat_id && primitive.mShaderVariant == variant) + { + primitive.upload(vb); + } + } + } + + vb->unmapBuffer(); - vb->unbind(); + vb->unbind(); + #endif + } } } } - } - // sanity check that all primitives have a vertex buffer - for (auto& mesh : mMeshes) - { - for (auto& primitive : mesh.mPrimitives) + // sanity check that all primitives have a vertex buffer + for (auto& mesh : mMeshes) { - llassert(primitive.mVertexBuffer.notNull()); + for (auto& primitive : mesh.mPrimitives) + { + //llassert(primitive.mVertexBuffer.notNull()); + } } } - + #if 0 // build render batches for (S32 node_id = 0; node_id < mNodes.size(); ++node_id) { @@ -664,6 +684,7 @@ bool Asset::prep() } } } + #endif return true; } @@ -672,13 +693,14 @@ Asset::Asset(const Value& src) *this = src; } -bool Asset::load(std::string_view filename) +bool Asset::load(std::string_view filename, bool loadIntoVRAM) { LL_PROFILE_ZONE_SCOPED_CATEGORY_GLTF; + mLoadIntoVRAM = loadIntoVRAM; mFilename = filename; std::string ext = gDirUtilp->getExtension(mFilename); - std::ifstream file(filename.data(), std::ios::binary); + llifstream file(filename.data(), std::ios::binary); if (file.is_open()) { std::string str((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); @@ -692,7 +714,7 @@ bool Asset::load(std::string_view filename) } else if (ext == "glb") { - return loadBinary(str); + return loadBinary(str, mLoadIntoVRAM); } else { @@ -709,8 +731,9 @@ bool Asset::load(std::string_view filename) return false; } -bool Asset::loadBinary(const std::string& data) +bool Asset::loadBinary(const std::string& data, bool loadIntoVRAM) { + mLoadIntoVRAM = loadIntoVRAM; // load from binary gltf const U8* ptr = (const U8*)data.data(); const U8* end = ptr + data.size(); @@ -935,8 +958,9 @@ void Asset::eraseBufferView(S32 bufferView) LLViewerFetchedTexture* fetch_texture(const LLUUID& id); -bool Image::prep(Asset& asset) +bool Image::prep(Asset& asset, bool loadIntoVRAM) { + mLoadIntoTexturePipe = loadIntoVRAM; LLUUID id; if (mUri.size() == UUID_STR_SIZE && LLUUID::parseUUID(mUri, &id) && id.notNull()) { // loaded from an asset, fetch the texture from the asset system @@ -951,12 +975,12 @@ bool Image::prep(Asset& asset) { // embedded in a buffer, load the texture from the buffer BufferView& bufferView = asset.mBufferViews[mBufferView]; Buffer& buffer = asset.mBuffers[bufferView.mBuffer]; - - U8* data = buffer.mData.data() + bufferView.mByteOffset; - - mTexture = LLViewerTextureManager::getFetchedTextureFromMemory(data, bufferView.mByteLength, mMimeType); - - if (mTexture.isNull()) + if (mLoadIntoTexturePipe) + { + U8* data = buffer.mData.data() + bufferView.mByteOffset; + mTexture = LLViewerTextureManager::getFetchedTextureFromMemory(data, bufferView.mByteLength, mMimeType); + } + else if (mTexture.isNull() && mLoadIntoTexturePipe) { LL_WARNS("GLTF") << "Failed to load image from buffer:" << LL_ENDL; LL_WARNS("GLTF") << " image: " << mName << LL_ENDL; @@ -971,12 +995,12 @@ bool Image::prep(Asset& asset) std::string img_file = dir + gDirUtilp->getDirDelimiter() + mUri; LLUUID tracking_id = LLLocalBitmapMgr::getInstance()->addUnit(img_file); - if (tracking_id.notNull()) + if (tracking_id.notNull() && mLoadIntoTexturePipe) { LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); mTexture = LLViewerTextureManager::getFetchedTexture(world_id); } - else + else if (mLoadIntoTexturePipe) { LL_WARNS("GLTF") << "Failed to load image from file:" << LL_ENDL; LL_WARNS("GLTF") << " image: " << mName << LL_ENDL; @@ -991,7 +1015,7 @@ bool Image::prep(Asset& asset) return false; } - if (!asset.mFilename.empty()) + if (!asset.mFilename.empty() && mLoadIntoTexturePipe) { // local preview, boost image so it doesn't discard and force to save raw image in case we save out or upload mTexture->setBoostLevel(LLViewerTexture::BOOST_PREVIEW); mTexture->forceToSaveRawImage(0, F32_MAX); diff --git a/indra/newview/gltf/asset.h b/indra/newview/gltf/asset.h index 27821659db..b9554d753c 100644 --- a/indra/newview/gltf/asset.h +++ b/indra/newview/gltf/asset.h @@ -286,6 +286,7 @@ namespace LL void serialize(boost::json::object& dst) const; }; + // Image is for images that we want to load for the given asset. This acts as an interface into the viewer's texture pipe. class Image { public: @@ -301,6 +302,8 @@ namespace LL S32 mBits = -1; S32 mPixelType = -1; + bool mLoadIntoTexturePipe = false; + LLPointer<LLViewerFetchedTexture> mTexture; const Image& operator=(const Value& src); @@ -316,7 +319,7 @@ namespace LL // preserve only uri and name void clearData(Asset& asset); - bool prep(Asset& asset); + bool prep(Asset& asset, bool loadIntoVRAM); }; // Render Batch -- vertex buffer and list of primitives to render using @@ -391,6 +394,10 @@ namespace LL // UBO for storing material data U32 mMaterialsUBO = 0; + bool mLoadIntoVRAM = false; + + std::vector<std::string> mUnsupportedExtensions; + std::vector<std::string> mIgnoredExtensions; // prepare for first time use bool prep(); @@ -428,12 +435,12 @@ namespace LL // accepts .gltf and .glb files // Any existing data will be lost // returns result of prep() on success - bool load(std::string_view filename); + bool load(std::string_view filename, bool loadIntoVRAM); // load .glb contents from memory // data - binary contents of .glb file // returns result of prep() on success - bool loadBinary(const std::string& data); + bool loadBinary(const std::string& data, bool loadIntoVRAM); const Asset& operator=(const Value& src); void serialize(boost::json::object& dst) const; diff --git a/indra/newview/gltf/buffer_util.h b/indra/newview/gltf/buffer_util.h index ef9bba8128..be36c5e90b 100644 --- a/indra/newview/gltf/buffer_util.h +++ b/indra/newview/gltf/buffer_util.h @@ -159,6 +159,12 @@ namespace LL } template<> + inline void copyVec3<F32, LLColor4U>(F32* src, LLColor4U& dst) + { + dst.set((U8)(src[0] * 255.f), (U8)(src[1] * 255.f), (U8)(src[2] * 255.f), 255); + } + + template<> inline void copyVec3<U16, LLColor4U>(U16* src, LLColor4U& dst) { dst.set((U8)(src[0]), (U8)(src[1]), (U8)(src[2]), 255); @@ -369,6 +375,11 @@ namespace LL template<class T> inline void copy(Asset& asset, Accessor& accessor, LLStrider<T>& dst) { + if (accessor.mBufferView == INVALID_INDEX) + { + LL_WARNS("GLTF") << "Invalid buffer" << LL_ENDL; + return; + } const BufferView& bufferView = asset.mBufferViews[accessor.mBufferView]; const Buffer& buffer = asset.mBuffers[bufferView.mBuffer]; const U8* src = buffer.mData.data() + bufferView.mByteOffset + accessor.mByteOffset; diff --git a/indra/newview/gltf/llgltfloader.cpp b/indra/newview/gltf/llgltfloader.cpp new file mode 100644 index 0000000000..dd1d327683 --- /dev/null +++ b/indra/newview/gltf/llgltfloader.cpp @@ -0,0 +1,1822 @@ +/** + * @file LLGLTFLoader.cpp + * @brief LLGLTFLoader class implementation + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, 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 "llgltfloader.h" +#include "meshoptimizer.h" +#include <glm/gtc/packing.hpp> + +// Import & define single-header gltf import/export lib +#define TINYGLTF_IMPLEMENTATION +#define TINYGLTF_USE_CPP14 // default is C++ 11 + +// tinygltf by default loads image files using STB +#define STB_IMAGE_IMPLEMENTATION +// to use our own image loading: +// 1. replace this definition with TINYGLTF_NO_STB_IMAGE +// 2. provide image loader callback with TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data) + +// tinygltf saves image files using STB +#define STB_IMAGE_WRITE_IMPLEMENTATION +// similarly, can override with TINYGLTF_NO_STB_IMAGE_WRITE and TinyGLTF::SetImageWriter(fxn, data) + +// Additionally, disable inclusion of STB header files entirely with +// TINYGLTF_NO_INCLUDE_STB_IMAGE +// TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE +#include "tinygltf/tiny_gltf.h" + + +// TODO: includes inherited from dae loader. Validate / prune + +#include "llsdserialize.h" +#include "lljoint.h" +#include "llbase64.h" +#include "lldir.h" + +#include "llmatrix4a.h" + +#include <boost/regex.hpp> +#include <boost/algorithm/string/replace.hpp> +#include <boost/exception/diagnostic_information.hpp> +#include <fstream> + +static const std::string lod_suffix[LLModel::NUM_LODS] = +{ + "_LOD0", + "_LOD1", + "_LOD2", + "", + "_PHYS", +}; + +// Premade rotation matrix, GLTF is Y-up while SL is Z-up +static const glm::mat4 coord_system_rotation( + 1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 1.f +); + + +static const glm::mat4 coord_system_rotationxy( + 0.f, 1.f, 0.f, 0.f, + -1.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f +); + +static const S32 VERTEX_SPLIT_SAFETY_MARGIN = 3 * 3 + 1; // 10 vertices: 3 complete triangles plus remapping overhead +static const S32 VERTEX_LIMIT = USHRT_MAX - VERTEX_SPLIT_SAFETY_MARGIN; + +LLGLTFLoader::LLGLTFLoader(std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void * opaque_userdata, + JointTransformMap & jointTransformMap, + JointNameSet & jointsFromNodes, + std::map<std::string, std::string, std::less<>> & jointAliasMap, + U32 maxJointsPerMesh, + U32 modelLimit, + U32 debugMode, + std::vector<LLJointData> viewer_skeleton) //, + //bool preprocess) + : LLModelLoader( filename, + lod, + load_cb, + joint_lookup_func, + texture_load_func, + state_cb, + opaque_userdata, + jointTransformMap, + jointsFromNodes, + jointAliasMap, + maxJointsPerMesh, + modelLimit, + debugMode) + , mViewerJointData(viewer_skeleton) + , mGltfLoaded(false) + , mApplyXYRotation(false) +{ +} + +LLGLTFLoader::~LLGLTFLoader() {} + +bool LLGLTFLoader::OpenFile(const std::string &filename) +{ + // Clear the material cache for new file + mMaterialCache.clear(); + + tinygltf::TinyGLTF loader; + std::string filename_lc(filename); + LLStringUtil::toLower(filename_lc); + + try + { + mGltfLoaded = mGLTFAsset.load(filename, false); + } + catch (const std::exception& e) + { + LL_WARNS() << "Exception in LLModelLoader::run: " << e.what() << LL_ENDL; + LLSD args; + args["Message"] = "ParsingErrorException"; + args["FILENAME"] = filename; + args["EXCEPTION"] = e.what(); + mWarningsArray.append(args); + setLoadState(ERROR_PARSING); + return false; + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION("LLGLTFLoader"); + LLSD args; + args["Message"] = "ParsingErrorException"; + args["FILENAME"] = filename; + args["EXCEPTION"] = boost::current_exception_diagnostic_information(); + mWarningsArray.append(args); + setLoadState(ERROR_PARSING); + return false; + } + + if (!mGltfLoaded) + { + notifyUnsupportedExtension(true); + + for (const auto& buffer : mGLTFAsset.mBuffers) + { + if (buffer.mByteLength > 0 && buffer.mData.empty()) + { + bool bin_file = buffer.mUri.ends_with(".bin"); + LLSD args; + args["Message"] = bin_file ? "ParsingErrorMissingBufferBin" : "ParsingErrorMissingBuffer"; + args["BUFFER_NAME"] = buffer.mName; + args["BUFFER_URI"] = buffer.mUri; + mWarningsArray.append(args); + } + } + setLoadState(ERROR_PARSING); + return false; + } + + notifyUnsupportedExtension(false); + + bool meshesLoaded = parseMeshes(); + + setLoadState(DONE); + + return meshesLoaded; +} + +void LLGLTFLoader::addModelToScene( + LLModel* pModel, + const std::string& model_name, + U32 submodel_limit, + const LLMatrix4& transformation, + const LLVolumeParams& volume_params, + const material_map& mats) +{ + U32 volume_faces = pModel->getNumVolumeFaces(); + + // Side-steps all manner of issues when splitting models + // and matching lower LOD materials to base models + // + pModel->sortVolumeFacesByMaterialName(); + + int submodelID = 0; + + // remove all faces that definitely won't fit into one model and submodel limit + U32 face_limit = (submodel_limit + 1) * LL_SCULPT_MESH_MAX_FACES; + if (face_limit < volume_faces) + { + LL_WARNS("GLTF_IMPORT") << "Model contains " << volume_faces + << " faces, exceeding the limit of " << face_limit << LL_ENDL; + + LLSD args; + args["Message"] = "ModelTooManySubmodels"; + args["MODEL_NAME"] = pModel->mLabel; + args["SUBMODEL_COUNT"] = static_cast<S32>(llfloor((F32)volume_faces / LL_SCULPT_MESH_MAX_FACES)); + args["SUBMODEL_LIMIT"] = static_cast<S32>(submodel_limit); + mWarningsArray.append(args); + + pModel->setNumVolumeFaces(face_limit); + } + + LLVolume::face_list_t remainder; + std::vector<LLModel*> ready_models; + LLModel* current_model = pModel; + + do + { + current_model->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); + + volume_faces = static_cast<U32>(remainder.size()); + + // Don't add to scene yet because weights and materials aren't ready. + // Just save it + ready_models.push_back(current_model); + + // If we have left-over volume faces, create another model + // to absorb them. + if (volume_faces) + { + LLModel* next = new LLModel(volume_params, 0.f); + next->ClearFacesAndMaterials(); + next->mSubmodelID = ++submodelID; + + std::string instance_name = model_name; + if (next->mSubmodelID > 0) + { + instance_name += (char)((int)'a' + next->mSubmodelID); + } + // Check for duplicates and add copy suffix if needed + int duplicate_count = 0; + for (const auto& inst : mScene[transformation]) + { + if (inst.mLabel == instance_name) + { + ++duplicate_count; + } + } + if (duplicate_count > 0) { + instance_name += "_copy_" + std::to_string(duplicate_count); + } + next->mLabel = instance_name; + + next->getVolumeFaces() = remainder; + next->mNormalizedScale = current_model->mNormalizedScale; + next->mNormalizedTranslation = current_model->mNormalizedTranslation; + next->mSkinWeights = current_model->mSkinWeights; + next->mPosition = current_model->mPosition; + + const LLMeshSkinInfo& current_skin_info = current_model->mSkinInfo; + LLMeshSkinInfo& next_skin_info = next->mSkinInfo; + next_skin_info.mJointNames = current_skin_info.mJointNames; + next_skin_info.mJointNums = current_skin_info.mJointNums; + next_skin_info.mBindShapeMatrix = current_skin_info.mBindShapeMatrix; + next_skin_info.mInvBindMatrix = current_skin_info.mInvBindMatrix; + next_skin_info.mAlternateBindMatrix = current_skin_info.mAlternateBindMatrix; + next_skin_info.mPelvisOffset = current_skin_info.mPelvisOffset; + + + if (current_model->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES) + { + next->mMaterialList.assign(current_model->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, current_model->mMaterialList.end()); + current_model->mMaterialList.resize(LL_SCULPT_MESH_MAX_FACES); + } + + current_model = next; + } + + remainder.clear(); + + } while (volume_faces); + + for (auto model : ready_models) + { + // remove unused/redundant vertices + model->remapVolumeFaces(); + + mModelList.push_back(model); + + std::map<std::string, LLImportMaterial> materials; + for (U32 i = 0; i < (U32)model->mMaterialList.size(); ++i) + { + material_map::const_iterator found = mats.find(model->mMaterialList[i]); + if (found != mats.end()) + { + materials[model->mMaterialList[i]] = found->second; + } + else + { + materials[model->mMaterialList[i]] = LLImportMaterial(); + } + } + // Keep base name for scene instance. + std::string instance_name = model->mLabel; + // Add suffix. Suffix is nessesary for model matching logic + // because sometimes higher lod can be used as a lower one, so models + // need unique names not just in scope of one lod, but across lods. + model->mLabel += lod_suffix[mLod]; + mScene[transformation].push_back(LLModelInstance(model, instance_name, transformation, materials)); + stretch_extents(model, transformation); + } +} + +bool LLGLTFLoader::parseMeshes() +{ + if (!mGltfLoaded) return false; + + // 2022-04 DJH Volume params from dae example. TODO understand PCODE + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + + mTransform.setIdentity(); + + for (auto& node : mGLTFAsset.mNodes) + { + // Make node matrix valid for correct transformation + node.makeMatrixValid(); + } + + if (mGLTFAsset.mSkins.size() > 0) + { + checkForXYrotation(mGLTFAsset.mSkins[0]); + populateJointGroups(); + } + + // Populate the joints from skins first. + // Multiple meshes can share the same skin, so preparing skins beforehand. + for (S32 i = 0; i < mGLTFAsset.mSkins.size(); i++) + { + populateJointsFromSkin(i); + } + + // Track how many times each mesh name has been used + std::map<std::string, S32> mesh_name_counts; + + // For now use mesh count, but might be better to do 'mNodes.size() - joints count'. + U32 submodel_limit = mGLTFAsset.mMeshes.size() > 0 ? mGeneratedModelLimit / (U32)mGLTFAsset.mMeshes.size() : 0; + + // Check if we have scenes defined + if (!mGLTFAsset.mScenes.empty()) + { + // Process the default scene (or first scene if no default) + S32 scene_idx = mGLTFAsset.mScene >= 0 ? mGLTFAsset.mScene : 0; + + if (scene_idx < mGLTFAsset.mScenes.size()) + { + const LL::GLTF::Scene& scene = mGLTFAsset.mScenes[scene_idx]; + + LL_INFOS("GLTF_IMPORT") << "Processing scene " << scene_idx << " with " << scene.mNodes.size() << " root nodes" << LL_ENDL; + + // Process all root nodes defined in the scene + for (S32 root_idx : scene.mNodes) + { + if (root_idx >= 0 && root_idx < static_cast<S32>(mGLTFAsset.mNodes.size())) + { + processNodeHierarchy(root_idx, mesh_name_counts, submodel_limit, volume_params); + } + } + } + } + else + { + LL_WARNS("GLTF_IMPORT") << "No scenes defined in GLTF file" << LL_ENDL; + + LLSD args; + args["Message"] = "NoScenesFound"; + mWarningsArray.append(args); + return false; + } + + checkGlobalJointUsage(); + + return true; +} + +void LLGLTFLoader::processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params) +{ + if (node_idx < 0 || node_idx >= static_cast<S32>(mGLTFAsset.mNodes.size())) + return; + + const LL::GLTF::Node& node = mGLTFAsset.mNodes[node_idx]; + + LL_DEBUGS("GLTF_IMPORT") << "Processing node " << node_idx << " (" << node.mName << ")" + << " - has mesh: " << (node.mMesh >= 0 ? "yes" : "no") + << " - children: " << node.mChildren.size() << LL_ENDL; + + // Process this node's mesh if it has one + if (node.mMesh >= 0 && node.mMesh < mGLTFAsset.mMeshes.size()) + { + LLMatrix4 transformation; + material_map mats; + + LLModel* pModel = new LLModel(volume_params, 0.f); + const LL::GLTF::Mesh& mesh = mGLTFAsset.mMeshes[node.mMesh]; + + // Get base mesh name and track usage + std::string base_name = getLodlessLabel(mesh); + if (base_name.empty()) + { + base_name = "mesh_" + std::to_string(node.mMesh); + } + + S32 instance_count = mesh_name_counts[base_name]++; + + // make name unique + if (instance_count > 0) + { + base_name = base_name + "_copy_" + std::to_string(instance_count); + } + + if (populateModelFromMesh(pModel, base_name, mesh, node, mats) && + (LLModel::NO_ERRORS == pModel->getStatus()) && + validate_model(pModel)) + { + mTransform.setIdentity(); + transformation = mTransform; + + // adjust the transformation to compensate for mesh normalization + LLVector3 mesh_scale_vector; + LLVector3 mesh_translation_vector; + pModel->getNormalizedScaleTranslation(mesh_scale_vector, mesh_translation_vector); + + LLMatrix4 mesh_translation; + mesh_translation.setTranslation(mesh_translation_vector); + mesh_translation *= transformation; + transformation = mesh_translation; + + LLMatrix4 mesh_scale; + mesh_scale.initScale(mesh_scale_vector); + mesh_scale *= transformation; + transformation = mesh_scale; + + if (node.mSkin >= 0) + { + // "Bind Shape Matrix" is supposed to transform the geometry of the skinned mesh + // into the coordinate space of the joints. + // In GLTF, this matrix is omitted, and it is assumed that this transform is either + // premultiplied with the mesh data, or postmultiplied to the inverse bind matrices. + // + // TODO: There appears to be missing rotation when joints rotate the model + // or inverted bind matrices are missing inherited rotation + // (based of values the 'bento shoes' mesh might be missing 90 degrees horizontaly + // prior to skinning) + + pModel->mSkinInfo.mBindShapeMatrix.loadu(mesh_scale); + LL_INFOS("GLTF_DEBUG") << "Model: " << pModel->mLabel << " mBindShapeMatrix: " << pModel->mSkinInfo.mBindShapeMatrix << LL_ENDL; + } + + if (transformation.determinant() < 0) + { // negative scales are not supported + LL_INFOS("GLTF_IMPORT") << "Negative scale detected, unsupported post-normalization transform. domInstance_geometry: " + << pModel->mLabel << LL_ENDL; + LLSD args; + args["Message"] = "NegativeScaleNormTrans"; + args["LABEL"] = pModel->mLabel; + mWarningsArray.append(args); + } + + addModelToScene(pModel, base_name, submodel_limit, transformation, volume_params, mats); + mats.clear(); + } + else + { + setLoadState(ERROR_MODEL + pModel->getStatus()); + delete pModel; + return; + } + } + else if (node.mMesh >= 0) + { + // Log invalid mesh reference + LL_WARNS("GLTF_IMPORT") << "Node " << node_idx << " (" << node.mName + << ") references invalid mesh " << node.mMesh + << " (total meshes: " << mGLTFAsset.mMeshes.size() << ")" << LL_ENDL; + + LLSD args; + args["Message"] = "InvalidMeshReference"; + args["NODE_NAME"] = node.mName; + args["MESH_INDEX"] = node.mMesh; + args["TOTAL_MESHES"] = static_cast<S32>(mGLTFAsset.mMeshes.size()); + mWarningsArray.append(args); + } + + // Process all children recursively + for (S32 child_idx : node.mChildren) + { + processNodeHierarchy(child_idx, mesh_name_counts, submodel_limit, volume_params); + } +} + +void LLGLTFLoader::computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const +{ + if (node_index < 0 || node_index >= static_cast<S32>(asset.mNodes.size())) + { + combined_transform = glm::mat4(1.0f); + return; + } + + const auto& node = asset.mNodes[node_index]; + + // Ensure the node's matrix is valid + const_cast<LL::GLTF::Node&>(node).makeMatrixValid(); + + // Start with this node's transform + combined_transform = node.mMatrix; + + // Find and apply parent transform if it exists + for (size_t i = 0; i < asset.mNodes.size(); ++i) + { + const auto& potential_parent = asset.mNodes[i]; + auto it = std::find(potential_parent.mChildren.begin(), potential_parent.mChildren.end(), node_index); + + if (it != potential_parent.mChildren.end()) + { + // Found parent - recursively get its combined transform and apply it + glm::mat4 parent_transform; + computeCombinedNodeTransform(asset, static_cast<S32>(i), parent_transform); + combined_transform = parent_transform * combined_transform; + return; // Early exit - a node can only have one parent + } + } +} + +bool LLGLTFLoader::addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx) +{ + const std::string& legal_name = mJointNames[gltf_skin_idx][gltf_joint_idx]; + if (legal_name.empty()) + { + llassert(false); // should have been stopped by gltf_joint_index_use[i] == -1 + return false; + } + skin_info.mJointNames.push_back(legal_name); + skin_info.mJointNums.push_back(-1); + + // In scope of same skin multiple meshes reuse same bind matrices + skin_info.mInvBindMatrix.push_back(mInverseBindMatrices[gltf_skin_idx][gltf_joint_idx]); + skin_info.mAlternateBindMatrix.push_back(mAlternateBindMatrices[gltf_skin_idx][gltf_joint_idx]); + + // Track joint usage for this skin, for the sake of unused joints detection + mJointUsage[gltf_skin_idx][gltf_joint_idx]++; + + return true; +} + +LLGLTFLoader::LLGLTFImportMaterial LLGLTFLoader::processMaterial(S32 material_index, S32 fallback_index) +{ + // Check cache first + auto cached = mMaterialCache.find(material_index); + if (cached != mMaterialCache.end()) + { + return cached->second; + } + + LLImportMaterial impMat; + impMat.mDiffuseColor = LLColor4::white; // Default color + + // Generate material name + std::string materialName = generateMaterialName(material_index, fallback_index); + + // Process material if available + if (material_index >= 0 && material_index < mGLTFAsset.mMaterials.size()) + { + LL::GLTF::Material* material = &mGLTFAsset.mMaterials[material_index]; + + // Set diffuse color from base color factor + impMat.mDiffuseColor = LLColor4( + material->mPbrMetallicRoughness.mBaseColorFactor[0], + material->mPbrMetallicRoughness.mBaseColorFactor[1], + material->mPbrMetallicRoughness.mBaseColorFactor[2], + material->mPbrMetallicRoughness.mBaseColorFactor[3] + ); + + // Process base color texture if it exists + if (material->mPbrMetallicRoughness.mBaseColorTexture.mIndex >= 0) + { + S32 texIndex = material->mPbrMetallicRoughness.mBaseColorTexture.mIndex; + std::string filename = processTexture(texIndex, "base_color", material->mName); + + if (!filename.empty()) + { + impMat.mDiffuseMapFilename = filename; + impMat.mDiffuseMapLabel = material->mName.empty() ? filename : material->mName; + + // Check if the texture is already loaded + S32 sourceIndex; + if (validateTextureIndex(texIndex, sourceIndex)) + { + LL::GLTF::Image& image = mGLTFAsset.mImages[sourceIndex]; + if (image.mTexture.notNull()) + { + mTexturesNeedScaling |= image.mHeight > LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT || image.mWidth > LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT; + impMat.setDiffuseMap(image.mTexture->getID()); + LL_INFOS("GLTF_IMPORT") << "Using existing texture ID: " << image.mTexture->getID().asString() << LL_ENDL; + } + else + { + LL_INFOS("GLTF_IMPORT") << "Texture needs loading: " << impMat.mDiffuseMapFilename << LL_ENDL; + } + } + } + } + } + + // Create cached material with both material and name + LLGLTFImportMaterial cachedMat(impMat, materialName); + + // Cache the processed material + mMaterialCache[material_index] = cachedMat; + return cachedMat; +} + +std::string LLGLTFLoader::processTexture(S32 texture_index, const std::string& texture_type, const std::string& material_name) +{ + S32 sourceIndex; + if (!validateTextureIndex(texture_index, sourceIndex)) + return ""; + + LL::GLTF::Image& image = mGLTFAsset.mImages[sourceIndex]; + + // Process URI-based textures + if (!image.mUri.empty()) + { + std::string filename = image.mUri; + size_t pos = filename.find_last_of("/\\"); + if (pos != std::string::npos) + { + filename = filename.substr(pos + 1); + } + + LL_INFOS("GLTF_IMPORT") << "Found texture: " << filename << " for material: " << material_name << LL_ENDL; + + LLSD args; + args["Message"] = "TextureFound"; + args["TEXTURE_NAME"] = filename; + args["MATERIAL_NAME"] = material_name; + mWarningsArray.append(args); + + return filename; + } + + // Process embedded textures + if (image.mBufferView >= 0) + { + return extractTextureToTempFile(texture_index, texture_type); + } + + return ""; +} + +bool LLGLTFLoader::validateTextureIndex(S32 texture_index, S32& source_index) +{ + if (texture_index < 0 || texture_index >= mGLTFAsset.mTextures.size()) + return false; + + source_index = mGLTFAsset.mTextures[texture_index].mSource; + if (source_index < 0 || source_index >= mGLTFAsset.mImages.size()) + return false; + + return true; +} + +std::string LLGLTFLoader::generateMaterialName(S32 material_index, S32 fallback_index) +{ + if (material_index >= 0 && material_index < mGLTFAsset.mMaterials.size()) + { + LL::GLTF::Material* material = &mGLTFAsset.mMaterials[material_index]; + std::string materialName = material->mName; + + if (materialName.empty()) + { + materialName = "mat" + std::to_string(material_index); + } + return materialName; + } + else + { + return fallback_index >= 0 ? "mat_default" + std::to_string(fallback_index) : "mat_default"; + } +} + +bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh& mesh, const LL::GLTF::Node& nodeno, material_map& mats) +{ + // Set the requested label for the floater display and uploading + pModel->mRequestedLabel = gDirUtilp->getBaseFileName(mFilename, true); + // Set only name, suffix will be added later + pModel->mLabel = base_name; + + LL_DEBUGS("GLTF_DEBUG") << "Processing model " << pModel->mLabel << LL_ENDL; + + pModel->ClearFacesAndMaterials(); + + S32 skinIdx = nodeno.mSkin; + + // Compute final combined transform matrix (hierarchy + coordinate rotation) + S32 node_index = static_cast<S32>(&nodeno - &mGLTFAsset.mNodes[0]); + glm::mat4 hierarchy_transform; + computeCombinedNodeTransform(mGLTFAsset, node_index, hierarchy_transform); + + // Combine transforms: coordinate rotation applied to hierarchy transform + glm::mat4 final_transform = coord_system_rotation * hierarchy_transform; + if (mApplyXYRotation) + { + final_transform = coord_system_rotationxy * final_transform; + } + + // Check if we have a negative scale (flipped coordinate system) + bool hasNegativeScale = glm::determinant(final_transform) < 0.0f; + + // Pre-compute normal transform matrix (transpose of inverse of upper-left 3x3) + const glm::mat3 normal_transform = glm::transpose(glm::inverse(glm::mat3(final_transform))); + + // Mark unsuported joints with '-1' so that they won't get added into weights + // GLTF maps all joints onto all meshes. Gather use count per mesh to cut unused ones. + std::vector<S32> gltf_joint_index_use; + if (skinIdx >= 0 && mGLTFAsset.mSkins.size() > skinIdx) + { + LL::GLTF::Skin& gltf_skin = mGLTFAsset.mSkins[skinIdx]; + + size_t jointCnt = gltf_skin.mJoints.size(); + gltf_joint_index_use.resize(jointCnt, 0); + + for (size_t i = 0; i < jointCnt; ++i) + { + if (mJointNames[skinIdx][i].empty()) + { + // This might need to hold a substitute index + gltf_joint_index_use[i] = -1; // mark as unsupported + } + } + } + + for (size_t prim_idx = 0; prim_idx < mesh.mPrimitives.size(); ++prim_idx) + { + const LL::GLTF::Primitive& prim = mesh.mPrimitives[prim_idx]; + + // So primitives already have all of the data we need for a given face in SL land. + // Primitives may only ever have a single material assigned to them - as the relation is 1:1 in terms of intended draw call + // count. Just go ahead and populate faces direct from the GLTF primitives here. -Geenz 2025-04-07 + LLVolumeFace face; + std::vector<GLTFVertex> vertices; + + // Use cached material processing + LLGLTFImportMaterial cachedMat = processMaterial(prim.mMaterial, pModel->getNumVolumeFaces() - 1); + LLImportMaterial impMat = cachedMat; + std::string materialName = cachedMat.name; + mats[materialName] = impMat; + + if (prim.getIndexCount() % 3 != 0) + { + LL_WARNS("GLTF_IMPORT") << "Mesh '" << mesh.mName << "' primitive " << prim_idx + << ": Invalid index count " << prim.getIndexCount() + << " (not divisible by 3). GLTF files must contain triangulated geometry." << LL_ENDL; + + LLSD args; + args["Message"] = "InvalidGeometryNonTriangulated"; + args["MESH_NAME"] = mesh.mName; + args["PRIMITIVE_INDEX"] = static_cast<S32>(prim_idx); + args["INDEX_COUNT"] = static_cast<S32>(prim.getIndexCount()); + mWarningsArray.append(args); + return false; // Skip this primitive + } + + // Apply the global scale and center offset to all vertices + for (U32 i = 0; i < prim.getVertexCount(); i++) + { + // Use pre-computed final_transform + glm::vec4 pos(prim.mPositions[i][0], prim.mPositions[i][1], prim.mPositions[i][2], 1.0f); + glm::vec4 transformed_pos = final_transform * pos; + + GLTFVertex vert; + vert.position = glm::vec3(transformed_pos); + + if (!prim.mNormals.empty()) + { + // Use pre-computed normal_transform + glm::vec3 normal_vec(prim.mNormals[i][0], prim.mNormals[i][1], prim.mNormals[i][2]); + vert.normal = glm::normalize(normal_transform * normal_vec); + } + else + { + // Use default normal (pointing up in model space) + vert.normal = glm::normalize(normal_transform * glm::vec3(0.0f, 0.0f, 1.0f)); + LL_DEBUGS("GLTF_IMPORT") << "No normals found for primitive, using default normal." << LL_ENDL; + } + + vert.uv0 = glm::vec2(prim.mTexCoords0[i][0], -prim.mTexCoords0[i][1]); + + if (skinIdx >= 0) + { + vert.weights = glm::vec4(prim.mWeights[i]); + + auto accessorIdx = prim.mAttributes.at("JOINTS_0"); + LL::GLTF::Accessor::ComponentType componentType = LL::GLTF::Accessor::ComponentType::UNSIGNED_BYTE; + if (accessorIdx >= 0) + { + auto accessor = mGLTFAsset.mAccessors[accessorIdx]; + componentType = accessor.mComponentType; + } + + // The GLTF spec allows for either an unsigned byte for joint indices, or an unsigned short. + // Detect and unpack accordingly. + if (componentType == LL::GLTF::Accessor::ComponentType::UNSIGNED_BYTE) + { + auto ujoint = glm::unpackUint4x8((U32)(prim.mJoints[i] & 0xFFFFFFFF)); + vert.joints = glm::u16vec4(ujoint.x, ujoint.y, ujoint.z, ujoint.w); + } + else if (componentType == LL::GLTF::Accessor::ComponentType::UNSIGNED_SHORT) + { + vert.joints = glm::unpackUint4x16(prim.mJoints[i]); + } + else + { + vert.joints = glm::zero<glm::u16vec4>(); + vert.weights = glm::zero<glm::vec4>(); + } + } + vertices.push_back(vert); + } + + // Check for empty vertex array before processing + if (vertices.empty()) + { + LL_WARNS("GLTF_IMPORT") << "Empty vertex array for primitive " << prim_idx << " in model " << mesh.mName << LL_ENDL; + LLSD args; + args["Message"] = "EmptyVertexArray"; + args["MESH_NAME"] = mesh.mName; + args["PRIMITIVE_INDEX"] = static_cast<S32>(prim_idx); + args["INDEX_COUNT"] = static_cast<S32>(prim.getIndexCount()); + mWarningsArray.append(args); + return false; // Skip this primitive + } + + std::vector<LLVolumeFace::VertexData> faceVertices; + glm::vec3 min = glm::vec3(FLT_MAX); + glm::vec3 max = glm::vec3(-FLT_MAX); + + for (U32 i = 0; i < vertices.size(); i++) + { + LLVolumeFace::VertexData vert; + + // Update min/max bounds + if (i == 0) + { + min = max = vertices[i].position; + } + else + { + min.x = std::min(min.x, vertices[i].position.x); + min.y = std::min(min.y, vertices[i].position.y); + min.z = std::min(min.z, vertices[i].position.z); + max.x = std::max(max.x, vertices[i].position.x); + max.y = std::max(max.y, vertices[i].position.y); + max.z = std::max(max.z, vertices[i].position.z); + } + + LLVector4a position = LLVector4a(vertices[i].position.x, vertices[i].position.y, vertices[i].position.z); + LLVector4a normal = LLVector4a(vertices[i].normal.x, vertices[i].normal.y, vertices[i].normal.z); + vert.setPosition(position); + vert.setNormal(normal); + vert.mTexCoord = LLVector2(vertices[i].uv0.x, vertices[i].uv0.y); + faceVertices.push_back(vert); + + if (skinIdx >= 0) + { + // create list of weights that influence this vertex + LLModel::weight_list weight_list; + + // Drop joints that viewer doesn't support (negative in gltf_joint_index_use_count) + // don't reindex them yet, more indexes will be removed + // Also drop joints that have no weight. GLTF stores 4 per vertex, so there might be + // 'empty' ones + if (gltf_joint_index_use[vertices[i].joints.x] >= 0 + && vertices[i].weights.x > 0.f) + { + weight_list.push_back(LLModel::JointWeight(vertices[i].joints.x, vertices[i].weights.x)); + gltf_joint_index_use[vertices[i].joints.x]++; + } + if (gltf_joint_index_use[vertices[i].joints.y] >= 0 + && vertices[i].weights.y > 0.f) + { + weight_list.push_back(LLModel::JointWeight(vertices[i].joints.y, vertices[i].weights.y)); + gltf_joint_index_use[vertices[i].joints.y]++; + } + if (gltf_joint_index_use[vertices[i].joints.z] >= 0 + && vertices[i].weights.z > 0.f) + { + weight_list.push_back(LLModel::JointWeight(vertices[i].joints.z, vertices[i].weights.z)); + gltf_joint_index_use[vertices[i].joints.z]++; + } + if (gltf_joint_index_use[vertices[i].joints.w] >= 0 + && vertices[i].weights.w > 0.f) + { + weight_list.push_back(LLModel::JointWeight(vertices[i].joints.w, vertices[i].weights.w)); + gltf_joint_index_use[vertices[i].joints.w]++; + } + + std::sort(weight_list.begin(), weight_list.end(), LLModel::CompareWeightGreater()); + + std::vector<LLModel::JointWeight> wght; + F32 total = 0.f; + + for (U32 j = 0; j < llmin((U32)4, (U32)weight_list.size()); ++j) + { + // take up to 4 most significant weights + // Ported from the DAE loader - however, GLTF right now only supports up to four weights per vertex. + wght.push_back(weight_list[j]); + total += weight_list[j].mWeight; + } + + if (total != 0.f) + { + F32 scale = 1.f / total; + if (scale != 1.f) + { // normalize weights + for (U32 j = 0; j < wght.size(); ++j) + { + wght[j].mWeight *= scale; + } + } + } + + if (wght.size() > 0) + { + pModel->mSkinWeights[LLVector3(vertices[i].position)] = wght; + } + } + } + + // Indices handling + if (faceVertices.size() >= VERTEX_LIMIT) + { + // Will have to remap 32 bit indices into 16 bit indices + // For the sake of simplicity build vector of 32 bit indices first + std::vector<U32> indices_32; + for (U32 i = 0; i < prim.getIndexCount(); i += 3) + { + // When processing indices, flip winding order if needed + if (hasNegativeScale) + { + // Flip winding order for negative scale + indices_32.push_back(prim.mIndexArray[i]); + indices_32.push_back(prim.mIndexArray[i + 2]); // Swap these two + indices_32.push_back(prim.mIndexArray[i + 1]); + } + else + { + indices_32.push_back(prim.mIndexArray[i]); + indices_32.push_back(prim.mIndexArray[i + 1]); + indices_32.push_back(prim.mIndexArray[i + 2]); + } + } + + // Generates a vertex remap table with no gaps in the resulting sequence + std::vector<U32> remap(faceVertices.size()); + size_t vertex_count = meshopt_generateVertexRemap(&remap[0], &indices_32[0], indices_32.size(), &faceVertices[0], faceVertices.size(), sizeof(LLVolumeFace::VertexData)); + + // Manually remap vertices + std::vector<LLVolumeFace::VertexData> optimized_vertices(vertex_count); + for (size_t i = 0; i < vertex_count; ++i) + { + optimized_vertices[i] = faceVertices[remap[i]]; + } + + std::vector<U32> optimized_indices(indices_32.size()); + meshopt_remapIndexBuffer(&optimized_indices[0], &indices_32[0], indices_32.size(), &remap[0]); + + // Sort indices to improve mesh splits (reducing amount of duplicated indices) + meshopt_optimizeVertexCache(&optimized_indices[0], &optimized_indices[0], indices_32.size(), vertex_count); + + std::vector<U16> indices_16; + std::vector<S64> vertices_remap; + vertices_remap.resize(vertex_count, -1); + S32 created_faces = 0; + std::vector<LLVolumeFace::VertexData> face_verts; + min = glm::vec3(FLT_MAX); + max = glm::vec3(-FLT_MAX); + + for (size_t idx = 0; idx < optimized_indices.size(); idx++) + { + size_t vert_index = optimized_indices[idx]; + if (vertices_remap[vert_index] == -1) + { + // First encounter, add it + size_t new_vert_idx = face_verts.size(); + vertices_remap[vert_index] = (S64)new_vert_idx; + face_verts.push_back(optimized_vertices[vert_index]); + vert_index = new_vert_idx; + + // Update min/max bounds + const LLVector4a& vec = face_verts[new_vert_idx].getPosition(); + if (new_vert_idx == 0) + { + min.x = vec[0]; + min.y = vec[1]; + min.z = vec[2]; + max = min; + } + else + { + min.x = std::min(min.x, vec[0]); + min.y = std::min(min.y, vec[1]); + min.z = std::min(min.z, vec[2]); + max.x = std::max(max.x, vec[0]); + max.y = std::max(max.y, vec[1]); + max.z = std::max(max.z, vec[2]); + } + } + else + { + // already in vector, get position + vert_index = (size_t)vertices_remap[vert_index]; + } + indices_16.push_back((U16)vert_index); + + if (indices_16.size() % 3 == 0 && face_verts.size() >= VERTEX_LIMIT) + { + LLVolumeFace face; + face.fillFromLegacyData(face_verts, indices_16); + face.mExtents[0] = LLVector4a(min.x, min.y, min.z, 0); + face.mExtents[1] = LLVector4a(max.x, max.y, max.z, 0); + pModel->getVolumeFaces().push_back(face); + pModel->getMaterialList().push_back(materialName); + created_faces++; + + std::fill(vertices_remap.begin(), vertices_remap.end(), -1); + indices_16.clear(); + face_verts.clear(); + + min = glm::vec3(FLT_MAX); + max = glm::vec3(-FLT_MAX); + } + } + if (indices_16.size() > 0 && face_verts.size() > 0) + { + LLVolumeFace face; + face.fillFromLegacyData(face_verts, indices_16); + face.mExtents[0] = LLVector4a(min.x, min.y, min.z, 0); + face.mExtents[1] = LLVector4a(max.x, max.y, max.z, 0); + pModel->getVolumeFaces().push_back(face); + pModel->getMaterialList().push_back(materialName); + created_faces++; + } + + LL_INFOS("GLTF_IMPORT") << "Primitive " << (S32)prim_idx << " from model " << pModel->mLabel + << " is over vertices limit, it was split into " << created_faces + << " faces" << LL_ENDL; + LLSD args; + args["Message"] = "ModelSplitPrimitive"; + args["MODEL_NAME"] = pModel->mLabel; + args["FACE_COUNT"] = created_faces; + mWarningsArray.append(args); + } + else + { + // can use indices directly + std::vector<U16> indices; + for (U32 i = 0; i < prim.getIndexCount(); i += 3) + { + // When processing indices, flip winding order if needed + if (hasNegativeScale) + { + // Flip winding order for negative scale + indices.push_back(prim.mIndexArray[i]); + indices.push_back(prim.mIndexArray[i + 2]); // Swap these two + indices.push_back(prim.mIndexArray[i + 1]); + } + else + { + indices.push_back(prim.mIndexArray[i]); + indices.push_back(prim.mIndexArray[i + 1]); + indices.push_back(prim.mIndexArray[i + 2]); + } + } + + face.fillFromLegacyData(faceVertices, indices); + face.mExtents[0] = LLVector4a(min.x, min.y, min.z, 0); + face.mExtents[1] = LLVector4a(max.x, max.y, max.z, 0); + + pModel->getVolumeFaces().push_back(face); + pModel->getMaterialList().push_back(materialName); + } + } + + // Call normalizeVolumeFacesAndWeights to compute proper extents + pModel->normalizeVolumeFacesAndWeights(); + + // Fill joint names, bind matrices and remap weight indices + if (skinIdx >= 0) + { + LL::GLTF::Skin& gltf_skin = mGLTFAsset.mSkins[skinIdx]; + LLMeshSkinInfo& skin_info = pModel->mSkinInfo; + S32 valid_joints_count = mValidJointsCount[skinIdx]; + + S32 replacement_index = 0; + std::vector<S32> gltfindex_to_joitindex_map; + size_t jointCnt = gltf_skin.mJoints.size(); + gltfindex_to_joitindex_map.resize(jointCnt, -1); + + if (valid_joints_count > (S32)mMaxJointsPerMesh) + { + std::map<std::string, S32> goup_use_count; + + for (const auto& elem : mJointGroups) + { + goup_use_count[elem.second.mGroup] = 0; + goup_use_count[elem.second.mParentGroup] = 0; + } + + // Assume that 'Torso' group is always in use since that's what everything else is attached to + goup_use_count["Torso"] = 1; + // Note that Collisions and Extra groups are all over the place, might want to include them from the start + // or add individual when parents are added + + // Check which groups are in use + for (size_t i = 0; i < jointCnt; ++i) + { + std::string& joint_name = mJointNames[skinIdx][i]; + if (!joint_name.empty()) + { + if (gltf_joint_index_use[i] > 0) + { + const JointGroups &group = mJointGroups[joint_name]; + // Joint in use, increment it's groups + goup_use_count[group.mGroup]++; + goup_use_count[group.mParentGroup]++; + } + } + } + + // 1. add joints that are in use directly + for (size_t i = 0; i < jointCnt; ++i) + { + // Process joint name and idnex + S32 joint = gltf_skin.mJoints[i]; + if (gltf_joint_index_use[i] <= 0) + { + // unsupported (-1) joint, drop it + // unused (0) joint, drop it + continue; + } + + if (addJointToModelSkin(skin_info, skinIdx, i)) + { + gltfindex_to_joitindex_map[i] = replacement_index++; + } + } + + // 2. add joints from groups that this model's joints belong to + // It's perfectly valid to have more joints than is in use + // Ex: sandals that make your legs digitigrade despite not skining to + // knees or the like. + // Todo: sort and add by usecount + for (size_t i = 0; i < jointCnt; ++i) + { + S32 joint = gltf_skin.mJoints[i]; + if (gltf_joint_index_use[i] != 0) + { + // this step needs only joints that have zero uses + continue; + } + if (skin_info.mInvBindMatrix.size() > mMaxJointsPerMesh) + { + break; + } + const std::string& legal_name = mJointNames[skinIdx][i]; + std::string group_name = mJointGroups[legal_name].mGroup; + if (goup_use_count[group_name] > 0) + { + if (addJointToModelSkin(skin_info, skinIdx, i)) + { + gltfindex_to_joitindex_map[i] = replacement_index++; + } + } + } + } + else + { + // Less than 110, just add every valid joint + for (size_t i = 0; i < jointCnt; ++i) + { + // Process joint name and idnex + S32 joint = gltf_skin.mJoints[i]; + if (gltf_joint_index_use[i] < 0) + { + // unsupported (-1) joint, drop it + continue; + } + + if (addJointToModelSkin(skin_info, skinIdx, i)) + { + gltfindex_to_joitindex_map[i] = replacement_index++; + } + } + } + + if (skin_info.mInvBindMatrix.size() > mMaxJointsPerMesh) + { + // mMaxJointsPerMesh ususlly is equal to LL_MAX_JOINTS_PER_MESH_OBJECT + // and is 110. + LL_WARNS("GLTF_IMPORT") << "Too many jonts in " << pModel->mLabel + << " Count: " << (S32)skin_info.mInvBindMatrix.size() + << " Limit:" << (S32)mMaxJointsPerMesh << LL_ENDL; + LLSD args; + args["Message"] = "ModelTooManyJoints"; + args["MODEL_NAME"] = pModel->mLabel; + args["JOINT_COUNT"] = (S32)skin_info.mInvBindMatrix.size(); + args["MAX"] = (S32)mMaxJointsPerMesh; + mWarningsArray.append(args); + } + + // Remap indices for pModel->mSkinWeights + for (auto& weights : pModel->mSkinWeights) + { + for (auto& weight : weights.second) + { + weight.mJointIdx = gltfindex_to_joitindex_map[weight.mJointIdx]; + } + } + } + + return true; +} + +void LLGLTFLoader::populateJointsFromSkin(S32 skin_idx) +{ + const LL::GLTF::Skin& skin = mGLTFAsset.mSkins[skin_idx]; + + LL_INFOS("GLTF_DEBUG") << "populateJointFromSkin: Processing skin " << skin_idx << " with " << skin.mJoints.size() << " joints" << LL_ENDL; + + if (skin.mInverseBindMatrices > 0 && skin.mJoints.size() != skin.mInverseBindMatricesData.size()) + { + LL_INFOS("GLTF_IMPORT") << "Bind matrices count mismatch joints count" << LL_ENDL; + LLSD args; + args["Message"] = "InvBindCountMismatch"; + mWarningsArray.append(args); + } + + S32 joint_count = (S32)skin.mJoints.size(); + S32 inverse_count = (S32)skin.mInverseBindMatricesData.size(); + if (mInverseBindMatrices.size() <= skin_idx) + { + mInverseBindMatrices.resize(skin_idx + 1); + mAlternateBindMatrices.resize(skin_idx + 1); + mJointNames.resize(skin_idx + 1); + mJointUsage.resize(skin_idx + 1); + mValidJointsCount.resize(skin_idx + 1, 0); + } + + // fill up joints related data + joints_data_map_t joints_data; + joints_name_to_node_map_t names_to_nodes; + for (S32 i = 0; i < joint_count; i++) + { + S32 joint = skin.mJoints[i]; + const LL::GLTF::Node &jointNode = mGLTFAsset.mNodes[joint]; + JointNodeData& data = joints_data[joint]; + data.mNodeIdx = joint; + data.mJointListIdx = i; + data.mGltfRestMatrix = buildGltfRestMatrix(joint, skin); + data.mGltfMatrix = jointNode.mMatrix; + data.mOverrideMatrix = glm::mat4(1.f); + + if (mJointMap.find(jointNode.mName) != mJointMap.end()) + { + data.mName = mJointMap[jointNode.mName]; + data.mIsValidViewerJoint = true; + mValidJointsCount[skin_idx]++; + } + else + { + data.mName = jointNode.mName; + data.mIsValidViewerJoint = false; + } + names_to_nodes[data.mName] = joint; + + for (S32 child : jointNode.mChildren) + { + JointNodeData& child_data = joints_data[child]; + child_data.mParentNodeIdx = joint; + child_data.mIsParentValidViewerJoint = data.mIsValidViewerJoint; + } + } + + // Go over viewer joints and build overrides + // This is needed because gltf skeleton doesn't necessarily match viewer's skeleton. + glm::mat4 ident(1.0); + for (auto &viewer_data : mViewerJointData) + { + buildOverrideMatrix(viewer_data, joints_data, names_to_nodes, ident, ident); + } + + for (S32 i = 0; i < joint_count; i++) + { + S32 joint = skin.mJoints[i]; + const LL::GLTF::Node &jointNode = mGLTFAsset.mNodes[joint]; + std::string legal_name(jointNode.mName); + + // Viewer supports a limited set of joints, mark them as legal + bool legal_joint = false; + if (mJointMap.find(legal_name) != mJointMap.end()) + { + legal_name = mJointMap[legal_name]; + legal_joint = true; + mJointNames[skin_idx].push_back(legal_name); + } + else + { + mJointNames[skin_idx].emplace_back(); + } + mJointUsage[skin_idx].push_back(0); + + // Compute bind matrices + + if (!legal_joint) + { + // Add placeholder to not break index. + // Not going to be used by viewer, will be stripped from skin_info. + LLMatrix4 gltf_transform; + gltf_transform.setIdentity(); + mInverseBindMatrices[skin_idx].push_back(LLMatrix4a(gltf_transform)); + } + else if (inverse_count > i) + { + // Transalte existing bind matrix to viewer's overriden skeleton + glm::mat4 original_bind_matrix = glm::inverse(skin.mInverseBindMatricesData[i]); + glm::mat4 rotated_original = coord_system_rotation * original_bind_matrix; + glm::mat4 skeleton_transform = computeGltfToViewerSkeletonTransform(joints_data, joint, legal_name); + glm::mat4 tranlated_original = skeleton_transform * rotated_original; + glm::mat4 final_inverse_bind_matrix = glm::inverse(tranlated_original); + + LLMatrix4 gltf_transform = LLMatrix4(glm::value_ptr(final_inverse_bind_matrix)); + LL_DEBUGS("GLTF_DEBUG") << "mInvBindMatrix name: " << legal_name << " Translated val: " << gltf_transform << LL_ENDL; + mInverseBindMatrices[skin_idx].push_back(LLMatrix4a(gltf_transform)); + } + else + { + // If bind matrices aren't present (they are optional in gltf), + // assume an identy matrix + // todo: find a model with this, might need to use YZ rotated matrix + glm::mat4 inv_bind(1.0f); + glm::mat4 skeleton_transform = computeGltfToViewerSkeletonTransform(joints_data, joint, legal_name); + inv_bind = glm::inverse(skeleton_transform * inv_bind); + + LLMatrix4 gltf_transform = LLMatrix4(glm::value_ptr(inv_bind)); + LL_DEBUGS("GLTF_DEBUG") << "mInvBindMatrix name: " << legal_name << " Generated val: " << gltf_transform << LL_ENDL; + mInverseBindMatrices[skin_idx].push_back(LLMatrix4a(gltf_transform)); + } + + // Compute Alternative matrices also known as overrides + LLMatrix4 original_joint_transform(glm::value_ptr(joints_data[joint].mOverrideMatrix)); + + // Viewer seems to care only about translation part, + // but for parity with collada taking original value + LLMatrix4 newInverse = LLMatrix4(mInverseBindMatrices[skin_idx].back().getF32ptr()); + newInverse.setTranslation(original_joint_transform.getTranslation()); + + LL_DEBUGS("GLTF_DEBUG") << "mAlternateBindMatrix name: " << legal_name << " val: " << newInverse << LL_ENDL; + mAlternateBindMatrices[skin_idx].push_back(LLMatrix4a(newInverse)); + + if (legal_joint) + { + // Might be needed for uploader UI to correctly identify overriden joints + // but going to be incorrect if multiple skins are present + mJointList[legal_name] = newInverse; + mJointsFromNode.push_front(legal_name); + } + } + + S32 valid_joints = mValidJointsCount[skin_idx]; + if (valid_joints < joint_count) + { + LL_INFOS("GLTF_IMPORT") << "Skin " << skin_idx + << " defines " << joint_count + << " joints, but only " << valid_joints + << " were recognized and are compatible." << LL_ENDL; + LLSD args; + args["Message"] = "SkinUsupportedJoints"; + args["SKIN_INDEX"] = skin_idx; + args["JOINT_COUNT"] = joint_count; + args["LEGAL_COUNT"] = valid_joints; + mWarningsArray.append(args); + } +} + +void LLGLTFLoader::populateJointGroups() +{ + std::string parent; + for (auto& viewer_data : mViewerJointData) + { + buildJointGroup(viewer_data, parent); + } +} + +void LLGLTFLoader::buildJointGroup(LLJointData& viewer_data, const std::string &parent_group) +{ + JointGroups& jount_group_data = mJointGroups[viewer_data.mName]; + jount_group_data.mGroup = viewer_data.mGroup; + jount_group_data.mParentGroup = parent_group; + + for (LLJointData& child_data : viewer_data.mChildren) + { + buildJointGroup(child_data, viewer_data.mGroup); + } +} + +void LLGLTFLoader::buildOverrideMatrix(LLJointData& viewer_data, joints_data_map_t &gltf_nodes, joints_name_to_node_map_t &names_to_nodes, glm::mat4& parent_rest, glm::mat4& parent_support_rest) const +{ + glm::mat4 rest(1.f); + joints_name_to_node_map_t::iterator found_node = names_to_nodes.find(viewer_data.mName); + if (found_node != names_to_nodes.end()) + { + S32 gltf_node_idx = found_node->second; + JointNodeData& node = gltf_nodes[gltf_node_idx]; + node.mIsOverrideValid = true; + node.mViewerRestMatrix = viewer_data.mRestMatrix; + + glm::mat4 gltf_joint_rest_pose = coord_system_rotation * node.mGltfRestMatrix; + if (mApplyXYRotation) + { + gltf_joint_rest_pose = coord_system_rotationxy * gltf_joint_rest_pose; + } + + glm::mat4 translated_joint; + // Example: + // Viewer has pelvis->spine1->spine2->torso. + // gltf example model has pelvis->torso + // By doing glm::inverse(transalted_rest_spine2) * gltf_rest_torso + // We get what torso would have looked like if gltf had a spine2 + if (viewer_data.mIsJoint) + { + translated_joint = glm::inverse(parent_rest) * gltf_joint_rest_pose; + } + else + { + translated_joint = glm::inverse(parent_support_rest) * gltf_joint_rest_pose; + } + + glm::vec3 translation_override; + glm::vec3 skew; + glm::vec3 scale; + glm::vec4 perspective; + glm::quat rotation; + glm::decompose(translated_joint, scale, rotation, translation_override, skew, perspective); + + // Viewer allows overrides, which are base joint with applied translation override. + // fortunately normal bones use only translation, without rotation or scale + node.mOverrideMatrix = glm::recompose(glm::vec3(1, 1, 1), glm::identity<glm::quat>(), translation_override, glm::vec3(0, 0, 0), glm::vec4(0, 0, 0, 1)); + + glm::mat4 overriden_joint = node.mOverrideMatrix; + + // todo: if gltf bone had rotation or scale, they probably should be saved here + // then applied to bind matrix + rest = parent_rest * overriden_joint; + if (viewer_data.mIsJoint) + { + node.mOverrideRestMatrix = rest; + } + else + { + // This is likely incomplete or even wrong. + // Viewer Collision bones specify rotation and scale. + // Importer should apply rotation and scale to this matrix and save as needed + // then subsctruct them from bind matrix + // Todo: get models that use collision bones, made by different programs + + overriden_joint = glm::scale(overriden_joint, viewer_data.mScale); + node.mOverrideRestMatrix = parent_support_rest * overriden_joint; + } + } + else + { + // No override for this joint + rest = parent_rest * viewer_data.mJointMatrix; + } + + glm::mat4 support_rest(1.f); + if (viewer_data.mSupport == LLJointData::SUPPORT_BASE) + { + support_rest = rest; + } + else + { + support_rest = parent_support_rest; + } + + for (LLJointData& child_data : viewer_data.mChildren) + { + buildOverrideMatrix(child_data, gltf_nodes, names_to_nodes, rest, support_rest); + } +} + +glm::mat4 LLGLTFLoader::buildGltfRestMatrix(S32 joint_node_index, const LL::GLTF::Skin& gltf_skin) const +{ + // This is inefficient since we are recalculating some joints multiple times over + // Todo: cache it? + + if (joint_node_index < 0 || joint_node_index >= static_cast<S32>(mGLTFAsset.mNodes.size())) + { + return glm::mat4(1.0f); + } + + const auto& node = mGLTFAsset.mNodes[joint_node_index]; + + // Find and apply parent transform if it exists + for (size_t i = 0; i < mGLTFAsset.mNodes.size(); ++i) + { + const auto& potential_parent = mGLTFAsset.mNodes[i]; + auto it = std::find(potential_parent.mChildren.begin(), potential_parent.mChildren.end(), joint_node_index); + + if (it != potential_parent.mChildren.end()) + { + // Found parent + if (std::find(gltf_skin.mJoints.begin(), gltf_skin.mJoints.end(), joint_node_index) != gltf_skin.mJoints.end()) + { + // parent is a joint - recursively combine transform + // assumes that matrix is already valid + return buildGltfRestMatrix(static_cast<S32>(i), gltf_skin) * node.mMatrix; + } + } + } + // Should we return armature or stop earlier? + return node.mMatrix; +} + +glm::mat4 LLGLTFLoader::buildGltfRestMatrix(S32 joint_node_index, const joints_data_map_t& joint_data) const +{ + // This is inefficient since we are recalculating some joints multiple times over + // Todo: cache it? + + if (joint_node_index < 0 || joint_node_index >= static_cast<S32>(mGLTFAsset.mNodes.size())) + { + return glm::mat4(1.0f); + } + + auto& data = joint_data.at(joint_node_index); + + if (data.mParentNodeIdx >=0) + { + return buildGltfRestMatrix(data.mParentNodeIdx, joint_data) * data.mGltfMatrix; + } + // Should we return armature or stop earlier? + return data.mGltfMatrix; +} + +// This function computes the transformation matrix needed to convert from GLTF skeleton space +// to viewer skeleton space for a specific joint + +glm::mat4 LLGLTFLoader::computeGltfToViewerSkeletonTransform(const joints_data_map_t& joints_data_map, S32 gltf_node_index, const std::string& joint_name) const +{ + const JointNodeData& node_data = joints_data_map.at(gltf_node_index); + if (!node_data.mIsOverrideValid) + { + // For now assume they are identical and return an identity (for ease of debuging) + return glm::mat4(1.0f); + } + + // Get the GLTF joint's rest pose (in GLTF coordinate system) + const glm::mat4 &gltf_joint_rest_pose = node_data.mGltfRestMatrix; + glm::mat4 rest_pose = coord_system_rotation * gltf_joint_rest_pose; + + LL_INFOS("GLTF_DEBUG") << "rest matrix for joint " << joint_name << ": "; + + LLMatrix4 transform(glm::value_ptr(rest_pose)); + + LL_CONT << transform << LL_ENDL; + + // Compute transformation from GLTF space to viewer space + // This assumes both skeletons are in rest pose initially + return node_data.mOverrideRestMatrix * glm::inverse(rest_pose); +} + +bool LLGLTFLoader::checkForXYrotation(const LL::GLTF::Skin& gltf_skin, S32 joint_idx, S32 bind_indx) +{ + glm::mat4 gltf_joint_rest = buildGltfRestMatrix(joint_idx, gltf_skin); + glm::mat4 test_mat = glm::inverse(gltf_joint_rest) * gltf_skin.mInverseBindMatricesData[bind_indx]; + // Normally for shoulders it should be something close to + // {1,0,0,0;0,-1,0,0;0,0,-1,0;0,0,0,1} + // rotated one will look like + // {0,0,0,-1;1,0,0,0;0,-1,0,0;0,0,0,1} + // Todo: This is a cheap hack, + // figure out how rotation is supposed to work + return abs(test_mat[0][0]) < 0.5 && abs(test_mat[1][1]) < 0.5 && abs(test_mat[2][2]) < 0.5; +} + +void LLGLTFLoader::checkForXYrotation(const LL::GLTF::Skin& gltf_skin) +{ + // HACK: figure out model's rotation from shoulders' matrix. + // This is wrong on many levels: + // Too limited (only models that have shoulders), + // Will not work well with things that emulate 3 hands in some manner + // Only supports xy 90 degree rotation + // Todo: figure out how to find skeleton's orientation Correctly + // when model is rotated at a triangle level + constexpr char right_shoulder_str[] = "mShoulderRight"; + constexpr char left_shoulder_str[] = "mShoulderLeft"; + + S32 size = (S32)gltf_skin.mJoints.size(); + S32 joints_found = 0; + for (S32 i= 0; i < size; i++) + { + S32 joint = gltf_skin.mJoints[i]; + const LL::GLTF::Node &joint_node = mGLTFAsset.mNodes[joint]; + + // todo: we are doing this search thing everywhere, + // just pre-translate every joint + JointMap::iterator found = mJointMap.find(joint_node.mName); + if (found == mJointMap.end()) + { + // unsupported joint + continue; + } + if (found->second == right_shoulder_str || found->second == left_shoulder_str) + { + if (checkForXYrotation(gltf_skin, joint, i)) + { + joints_found++; + } + else + { + return; + } + } + } + + if (joints_found == 2) + { + // Both joints in a weird position/rotation, assume rotated model + mApplyXYRotation = true; + } +} + +void LLGLTFLoader::checkGlobalJointUsage() +{ + // Check if some joints remained unused + for (S32 skin_idx = 0; skin_idx < (S32)mGLTFAsset.mSkins.size(); ++skin_idx) + { + const LL::GLTF::Skin& gltf_skin = mGLTFAsset.mSkins[skin_idx]; + S32 joint_count = (S32)gltf_skin.mJoints.size(); + S32 used_joints = 0; + for (S32 i = 0; i < joint_count; ++i) + { + S32 joint = gltf_skin.mJoints[i]; + if (mJointUsage[skin_idx][i] == 0) + { + // Joint is unused, log it + LL_INFOS("GLTF_DEBUG") << "Joint " << mJointNames[skin_idx][i] + << " in skin " << skin_idx << " is unused." << LL_ENDL; + } + else + { + used_joints++; + } + } + + S32 valid_joints = mValidJointsCount[skin_idx]; + if (valid_joints > used_joints) + { + S32 unsed_joints = valid_joints - used_joints; + LL_INFOS("GLTF_IMPORT") << "Skin " << skin_idx + << " declares " << valid_joints + << " valid joints, of them " << unsed_joints + << " remained unused" << LL_ENDL; + LLSD args; + args["Message"] = "SkinUnusedJoints"; + args["SKIN_INDEX"] = (S32)skin_idx; + args["JOINT_COUNT"] = valid_joints; + args["USED_COUNT"] = used_joints; + mWarningsArray.append(args); + } + } +} + +std::string LLGLTFLoader::extractTextureToTempFile(S32 textureIndex, const std::string& texture_type) +{ + if (textureIndex < 0 || textureIndex >= mGLTFAsset.mTextures.size()) + return ""; + + S32 sourceIndex = mGLTFAsset.mTextures[textureIndex].mSource; + if (sourceIndex < 0 || sourceIndex >= mGLTFAsset.mImages.size()) + return ""; + + LL::GLTF::Image& image = mGLTFAsset.mImages[sourceIndex]; + + // Handle URI-based textures + if (!image.mUri.empty()) + { + return image.mUri; // Return URI directly + } + + // Handle embedded textures + if (image.mBufferView >= 0) + { + if (image.mBufferView < mGLTFAsset.mBufferViews.size()) + { + const LL::GLTF::BufferView& buffer_view = mGLTFAsset.mBufferViews[image.mBufferView]; + if (buffer_view.mBuffer < mGLTFAsset.mBuffers.size()) + { + const LL::GLTF::Buffer& buffer = mGLTFAsset.mBuffers[buffer_view.mBuffer]; + + if (buffer_view.mByteOffset + buffer_view.mByteLength <= buffer.mData.size()) + { + // Extract image data + const U8* data_ptr = &buffer.mData[buffer_view.mByteOffset]; + U32 data_size = buffer_view.mByteLength; + + // Determine the file extension + std::string extension = ".png"; // Default + if (!image.mMimeType.empty()) + { + if (image.mMimeType == "image/jpeg") + extension = ".jpg"; + else if (image.mMimeType == "image/png") + extension = ".png"; + } + else if (data_size >= 4) + { + if (data_ptr[0] == 0xFF && data_ptr[1] == 0xD8) + extension = ".jpg"; // JPEG magic bytes + else if (data_ptr[0] == 0x89 && data_ptr[1] == 0x50 && data_ptr[2] == 0x4E && data_ptr[3] == 0x47) + extension = ".png"; // PNG magic bytes + } + + // Create a temporary file + std::string temp_dir = gDirUtilp->getTempDir(); + std::string temp_filename = temp_dir + gDirUtilp->getDirDelimiter() + + "gltf_embedded_" + texture_type + "_" + std::to_string(sourceIndex) + extension; + + // Write the image data to the temporary file + std::ofstream temp_file(temp_filename, std::ios::binary); + if (temp_file.is_open()) + { + temp_file.write(reinterpret_cast<const char*>(data_ptr), data_size); + temp_file.close(); + + LL_INFOS("GLTF_IMPORT") << "Extracted embedded " << texture_type << " texture to: " << temp_filename << LL_ENDL; + return temp_filename; + } + else + { + LL_WARNS("GLTF_IMPORT") << "Failed to create temporary file for " << texture_type << " texture: " << temp_filename << LL_ENDL; + + LLSD args; + args["Message"] = "FailedToCreateTempFile"; + args["TEXTURE_INDEX"] = sourceIndex; + args["TEXTURE_TYPE"] = texture_type; + args["TEMP_FILE"] = temp_filename; + mWarningsArray.append(args); + } + } + } + } + } + + return ""; +} + +void LLGLTFLoader::notifyUnsupportedExtension(bool unsupported) +{ + std::vector<std::string> extensions = unsupported ? mGLTFAsset.mUnsupportedExtensions : mGLTFAsset.mIgnoredExtensions; + if (extensions.size() > 0) + { + LLSD args; + args["Message"] = unsupported ? "UnsupportedExtension" : "IgnoredExtension"; + std::string del; + std::string ext; + for (auto& extension : extensions) + { + ext += del; + ext += extension; + del = ","; + } + args["EXT"] = ext; + mWarningsArray.append(args); + + LL_WARNS("GLTF_IMPORT") << "Model uses unsupported extension: " << ext << LL_ENDL; + } +} + +size_t LLGLTFLoader::getSuffixPosition(const std::string &label) +{ + if ((label.find("_LOD") != -1) || (label.find("_PHYS") != -1)) + { + return label.rfind('_'); + } + return -1; +} + +std::string LLGLTFLoader::getLodlessLabel(const LL::GLTF::Mesh& mesh) +{ + size_t ext_pos = getSuffixPosition(mesh.mName); + if (ext_pos != -1) + { + return mesh.mName.substr(0, ext_pos); + } + return mesh.mName; +} + diff --git a/indra/newview/gltf/llgltfloader.h b/indra/newview/gltf/llgltfloader.h new file mode 100644 index 0000000000..e8b91996c7 --- /dev/null +++ b/indra/newview/gltf/llgltfloader.h @@ -0,0 +1,216 @@ +/** + * @file LLGLTFLoader.h + * @brief LLGLTFLoader class definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLGLTFLoader_H +#define LL_LLGLTFLoader_H + +#include "tinygltf/tiny_gltf.h" + +#include "asset.h" + +#include "llglheaders.h" +#include "lljointdata.h" +#include "llmodelloader.h" + +class LLGLTFLoader : public LLModelLoader +{ + public: + typedef std::map<std::string, LLImportMaterial> material_map; + typedef std::map<std::string, std::string> joint_viewer_parent_map_t; + typedef std::map<std::string, glm::mat4> joint_viewer_rest_map_t; + typedef std::map<S32, glm::mat4> joint_node_mat4_map_t; + + struct JointNodeData + { + JointNodeData() + : mJointListIdx(-1) + , mNodeIdx(-1) + , mParentNodeIdx(-1) + , mIsValidViewerJoint(false) + , mIsParentValidViewerJoint(false) + , mIsOverrideValid(false) + { + + } + S32 mJointListIdx; + S32 mNodeIdx; + S32 mParentNodeIdx; + glm::mat4 mGltfRestMatrix; + glm::mat4 mViewerRestMatrix; + glm::mat4 mOverrideRestMatrix; + glm::mat4 mGltfMatrix; + glm::mat4 mOverrideMatrix; + std::string mName; + bool mIsValidViewerJoint; + bool mIsParentValidViewerJoint; + bool mIsOverrideValid; + }; + typedef std::map <S32, JointNodeData> joints_data_map_t; + typedef std::map <std::string, S32> joints_name_to_node_map_t; + + class LLGLTFImportMaterial : public LLImportMaterial + { + public: + std::string name; + LLGLTFImportMaterial() = default; + LLGLTFImportMaterial(const LLImportMaterial& mat, const std::string& n) : LLImportMaterial(mat), name(n) {} + }; + + LLGLTFLoader(std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void * opaque_userdata, + JointTransformMap & jointTransformMap, + JointNameSet & jointsFromNodes, + std::map<std::string, std::string, std::less<>> & jointAliasMap, + U32 maxJointsPerMesh, + U32 modelLimit, + U32 debugMode, + std::vector<LLJointData> viewer_skeleton); //, + //bool preprocess ); + virtual ~LLGLTFLoader(); + + virtual bool OpenFile(const std::string &filename); + + struct GLTFVertex + { + glm::vec3 position; + glm::vec3 normal; + glm::vec2 uv0; + glm::u16vec4 joints; + glm::vec4 weights; + }; + +protected: + LL::GLTF::Asset mGLTFAsset; + tinygltf::Model mGltfModel; + bool mGltfLoaded = false; + bool mApplyXYRotation = false; + + // GLTF isn't aware of viewer's skeleton and uses it's own, + // so need to take viewer's joints and use them to + // recalculate iverse bind matrices + std::vector<LLJointData> mViewerJointData; + + // vector of vectors because of a posibility of having more than one skin + typedef std::vector<LLMeshSkinInfo::matrix_list_t> bind_matrices_t; + typedef std::vector<std::vector<std::string> > joint_names_t; + bind_matrices_t mInverseBindMatrices; + bind_matrices_t mAlternateBindMatrices; + joint_names_t mJointNames; // empty string when no legal name for a given idx + std::vector<std::vector<S32>> mJointUsage; // detect and warn about unsed joints + + // what group a joint belongs to. + // For purpose of stripping unused groups when joints are over limit. + struct JointGroups + { + std::string mGroup; + std::string mParentGroup; + }; + typedef std::map<std::string, JointGroups, std::less<> > joint_to_group_map_t; + joint_to_group_map_t mJointGroups; + + // per skin joint count, needs to be tracked for the sake of limits check. + std::vector<S32> mValidJointsCount; + + // Cached material information + typedef std::map<S32, LLGLTFImportMaterial> MaterialCache; + MaterialCache mMaterialCache; + +private: + bool parseMeshes(); + void computeCombinedNodeTransform(const LL::GLTF::Asset& asset, S32 node_index, glm::mat4& combined_transform) const; + void processNodeHierarchy(S32 node_idx, std::map<std::string, S32>& mesh_name_counts, U32 submodel_limit, const LLVolumeParams& volume_params); + bool addJointToModelSkin(LLMeshSkinInfo& skin_info, S32 gltf_skin_idx, size_t gltf_joint_idx); + LLGLTFImportMaterial processMaterial(S32 material_index, S32 fallback_index); + std::string processTexture(S32 texture_index, const std::string& texture_type, const std::string& material_name); + bool validateTextureIndex(S32 texture_index, S32& source_index); + std::string generateMaterialName(S32 material_index, S32 fallback_index = -1); + bool populateModelFromMesh(LLModel* pModel, const std::string& base_name, const LL::GLTF::Mesh &mesh, const LL::GLTF::Node &node, material_map& mats); + void populateJointsFromSkin(S32 skin_idx); + void populateJointGroups(); + void addModelToScene(LLModel* pModel, const std::string& model_name, U32 submodel_limit, const LLMatrix4& transformation, const LLVolumeParams& volume_params, const material_map& mats); + void buildJointGroup(LLJointData& viewer_data, const std::string& parent_group); + void buildOverrideMatrix(LLJointData& data, joints_data_map_t &gltf_nodes, joints_name_to_node_map_t &names_to_nodes, glm::mat4& parent_rest, glm::mat4& support_rest) const; + glm::mat4 buildGltfRestMatrix(S32 joint_node_index, const LL::GLTF::Skin& gltf_skin) const; + glm::mat4 buildGltfRestMatrix(S32 joint_node_index, const joints_data_map_t& joint_data) const; + glm::mat4 computeGltfToViewerSkeletonTransform(const joints_data_map_t& joints_data_map, S32 gltf_node_index, const std::string& joint_name) const; + bool checkForXYrotation(const LL::GLTF::Skin& gltf_skin, S32 joint_idx, S32 bind_indx); + void checkForXYrotation(const LL::GLTF::Skin& gltf_skin); + void checkGlobalJointUsage(); + + std::string extractTextureToTempFile(S32 textureIndex, const std::string& texture_type); + + void notifyUnsupportedExtension(bool unsupported); + + static size_t getSuffixPosition(const std::string& label); + static std::string getLodlessLabel(const LL::GLTF::Mesh& mesh); + + // bool mPreprocessGLTF; + + /* Below inherited from dae loader - unknown if/how useful here + + void processElement(gltfElement *element, bool &badElement, GLTF *gltf); + void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin); + + material_map getMaterials(LLModel *model, gltfInstance_geometry *instance_geo, GLTF *gltf); + LLImportMaterial profileToMaterial(gltfProfile_COMMON *material, GLTF *gltf); + LLColor4 getGltfColor(gltfElement *element); + + gltfElement *getChildFromElement(gltfElement *pElement, std::string const &name); + + bool isNodeAJoint(gltfNode *pNode); + void processJointNode(gltfNode *pNode, std::map<std::string, LLMatrix4> &jointTransforms); + void extractTranslation(gltfTranslate *pTranslate, LLMatrix4 &transform); + void extractTranslationViaElement(gltfElement *pTranslateElement, LLMatrix4 &transform); + void extractTranslationViaSID(gltfElement *pElement, LLMatrix4 &transform); + void buildJointToNodeMappingFromScene(gltfElement *pRoot); + void processJointToNodeMapping(gltfNode *pNode); + void processChildJoints(gltfNode *pParentNode); + + bool verifyCount(int expected, int result); + + // Verify that a controller matches vertex counts + bool verifyController(gltfController *pController); + + static bool addVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh, LLSD &log_msg); + static bool createVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh); + + static LLModel *loadModelFromGltfMesh(gltfMesh *mesh); + + // Loads a mesh breaking it into one or more models as necessary + // to get around volume face limitations while retaining >8 materials + // + bool loadModelsFromGltfMesh(gltfMesh *mesh, std::vector<LLModel *> &models_out, U32 submodel_limit); + + static std::string preprocessGLTF(std::string filename); + */ + +}; +#endif // LL_LLGLTFLLOADER_H diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index e0cd762776..ac452b38a0 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -220,6 +220,7 @@ void GLTFSceneManager::uploadSelection() LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost, + LLUUID::null, false, finish, failure)); @@ -283,6 +284,7 @@ void GLTFSceneManager::uploadSelection() LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost, + LLUUID::null, false, finish, failure)); @@ -317,7 +319,7 @@ void GLTFSceneManager::load(const std::string& filename) { std::shared_ptr<Asset> asset = std::make_shared<Asset>(); - if (asset->load(filename)) + if (asset->load(filename, true)) { gDebugProgram.bind(); // bind a shader to satisfy LLVertexBuffer assertions asset->updateTransforms(); @@ -559,6 +561,7 @@ void GLTFSceneManager::update() LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost, + LLUUID::null, false, finish, failure)); @@ -643,6 +646,12 @@ void GLTFSceneManager::render(Asset& asset, U8 variant) return; } + if (gGLTFPBRMetallicRoughnessProgram.mGLTFVariants.size() <= variant) + { + llassert(false); // mGLTFVariants should have been initialized + return; + } + for (U32 ds = 0; ds < 2; ++ds) { RenderData& rd = asset.mRenderData[ds]; diff --git a/indra/newview/icons/release/secondlife.icns b/indra/newview/icons/release/secondlife.icns Binary files differindex a30b51b67a..00d9867814 100644 --- a/indra/newview/icons/release/secondlife.icns +++ b/indra/newview/icons/release/secondlife.icns diff --git a/indra/newview/icons/release/secondlife.iconset/icon_128x128.png b/indra/newview/icons/release/secondlife.iconset/icon_128x128.png Binary files differnew file mode 100644 index 0000000000..4c519db265 --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_128x128.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_128x128@2x.png b/indra/newview/icons/release/secondlife.iconset/icon_128x128@2x.png Binary files differnew file mode 100644 index 0000000000..2a3a0092b2 --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_128x128@2x.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_16x16.png b/indra/newview/icons/release/secondlife.iconset/icon_16x16.png Binary files differnew file mode 100644 index 0000000000..fda2f276ee --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_16x16.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_16x16@2x.png b/indra/newview/icons/release/secondlife.iconset/icon_16x16@2x.png Binary files differnew file mode 100644 index 0000000000..aa4a74f204 --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_16x16@2x.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_256x256.png b/indra/newview/icons/release/secondlife.iconset/icon_256x256.png Binary files differnew file mode 100644 index 0000000000..2a3a0092b2 --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_256x256.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_256x256@2x.png b/indra/newview/icons/release/secondlife.iconset/icon_256x256@2x.png Binary files differnew file mode 100644 index 0000000000..4c28add76c --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_256x256@2x.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_32x32.png b/indra/newview/icons/release/secondlife.iconset/icon_32x32.png Binary files differnew file mode 100644 index 0000000000..aa4a74f204 --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_32x32.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_32x32@2x.png b/indra/newview/icons/release/secondlife.iconset/icon_32x32@2x.png Binary files differnew file mode 100644 index 0000000000..23a36f66cb --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_32x32@2x.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_512x512.png b/indra/newview/icons/release/secondlife.iconset/icon_512x512.png Binary files differnew file mode 100644 index 0000000000..4c28add76c --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_512x512.png diff --git a/indra/newview/icons/release/secondlife.iconset/icon_512x512@2x.png b/indra/newview/icons/release/secondlife.iconset/icon_512x512@2x.png Binary files differnew file mode 100644 index 0000000000..a53a6697f1 --- /dev/null +++ b/indra/newview/icons/release/secondlife.iconset/icon_512x512@2x.png diff --git a/indra/newview/icons/release/secondlife_1024.png b/indra/newview/icons/release/secondlife_1024.png Binary files differnew file mode 100644 index 0000000000..a53a6697f1 --- /dev/null +++ b/indra/newview/icons/release/secondlife_1024.png diff --git a/indra/newview/icons/release/secondlife_128.png b/indra/newview/icons/release/secondlife_128.png Binary files differdeleted file mode 100644 index 2f21c1c7fc..0000000000 --- a/indra/newview/icons/release/secondlife_128.png +++ /dev/null diff --git a/indra/newview/icons/release/secondlife_16.png b/indra/newview/icons/release/secondlife_16.png Binary files differdeleted file mode 100644 index 68f1427309..0000000000 --- a/indra/newview/icons/release/secondlife_16.png +++ /dev/null diff --git a/indra/newview/icons/release/secondlife_256.png b/indra/newview/icons/release/secondlife_256.png Binary files differdeleted file mode 100644 index 8f324910e7..0000000000 --- a/indra/newview/icons/release/secondlife_256.png +++ /dev/null diff --git a/indra/newview/icons/release/secondlife_32.png b/indra/newview/icons/release/secondlife_32.png Binary files differdeleted file mode 100644 index 2b7cdef03d..0000000000 --- a/indra/newview/icons/release/secondlife_32.png +++ /dev/null diff --git a/indra/newview/icons/release/secondlife_48.png b/indra/newview/icons/release/secondlife_48.png Binary files differdeleted file mode 100644 index c2ef372dd7..0000000000 --- a/indra/newview/icons/release/secondlife_48.png +++ /dev/null diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 2161dbe19e..085155714a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -121,8 +121,8 @@ const F32 MIN_FIDGET_TIME = 8.f; // seconds const F32 MAX_FIDGET_TIME = 20.f; // seconds const S32 UI_FEATURE_VERSION = 1; -// For version 1: 1 - inventory, 2 - gltf -const S32 UI_FEATURE_FLAGS = 3; +// For version 1, flag holds: 1 - inventory thumbnails, 2 - gltf, 4 - inventory favorites +const S32 UI_FEATURE_FLAGS = 7; // The agent instance. LLAgent gAgent; @@ -223,7 +223,6 @@ private: LLVector3d mPosGlobal; }; - class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation { public: @@ -604,7 +603,7 @@ void LLAgent::getFeatureVersionAndFlags(S32& version, S32& flags) if (feature_version.isInteger()) { version = feature_version.asInteger(); - flags = 1; // inventory flag + flags = 3; // show 'favorites' notification } else if (feature_version.isMap()) { @@ -630,13 +629,8 @@ void LLAgent::showLatestFeatureNotification(const std::string key) if (key == "inventory") { - // Notify user about new thumbnail support - flag = 1; - } - - if (key == "gltf") - { - flag = 2; + // Notify user about new favorites support + flag = 4; } if ((flags & flag) == 0) @@ -843,7 +837,6 @@ void LLAgent::movePitch(F32 mag) } } - // Does this parcel allow you to fly? bool LLAgent::canFly() { @@ -923,7 +916,6 @@ void LLAgent::setFlying(bool fly, bool fail_sound) LLFloaterMove::setFlyingMode(fly); } - // UI based mechanism of setting fly state //----------------------------------------------------------------------------- // toggleFlying() @@ -1002,7 +994,6 @@ void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id, LLViewerRegion } } - //----------------------------------------------------------------------------- // setRegion() //----------------------------------------------------------------------------- @@ -1108,7 +1099,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) mRegionChangedSignal(); } - //----------------------------------------------------------------------------- // getRegion() //----------------------------------------------------------------------------- @@ -1117,7 +1107,6 @@ LLViewerRegion *LLAgent::getRegion() const return mRegionp; } - LLHost LLAgent::getRegionHost() const { if (mRegionp) @@ -1148,7 +1137,6 @@ bool LLAgent::inPrelude() return mRegionp && mRegionp->isPrelude(); } - std::string LLAgent::getRegionCapability(const std::string &name) { if (!mRegionp) @@ -1157,7 +1145,6 @@ std::string LLAgent::getRegionCapability(const std::string &name) return mRegionp->getCapability(name); } - //----------------------------------------------------------------------------- // canManageEstate() //----------------------------------------------------------------------------- @@ -1185,7 +1172,6 @@ void LLAgent::sendMessage() gMessageSystem->sendMessage(mRegionp->getHost()); } - //----------------------------------------------------------------------------- // sendReliableMessage() //----------------------------------------------------------------------------- @@ -1219,7 +1205,6 @@ LLVector3 LLAgent::getVelocity() const } } - //----------------------------------------------------------------------------- // setPositionAgent() //----------------------------------------------------------------------------- @@ -1293,7 +1278,6 @@ const LLVector3 &LLAgent::getPositionAgent() } } - return mFrameAgent.getOrigin(); } @@ -1302,7 +1286,6 @@ boost::signals2::connection LLAgent::whenPositionChanged(position_signal_t::slot return mOnPositionChanged.connect(fn); } - //----------------------------------------------------------------------------- // getRegionsVisited() //----------------------------------------------------------------------------- @@ -1319,7 +1302,6 @@ F64 LLAgent::getDistanceTraveled() const return mDistanceTraveled; } - //----------------------------------------------------------------------------- // getPosAgentFromGlobal() //----------------------------------------------------------------------------- @@ -1330,7 +1312,6 @@ LLVector3 LLAgent::getPosAgentFromGlobal(const LLVector3d &pos_global) const return pos_agent; } - //----------------------------------------------------------------------------- // getPosGlobalFromAgent() //----------------------------------------------------------------------------- @@ -1346,7 +1327,6 @@ void LLAgent::sitDown() setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); } - //----------------------------------------------------------------------------- // resetAxes() //----------------------------------------------------------------------------- @@ -1355,7 +1335,6 @@ void LLAgent::resetAxes() mFrameAgent.resetAxes(); } - // Copied from LLCamera::setOriginAndLookAt // Look_at must be unit vector //----------------------------------------------------------------------------- @@ -1384,7 +1363,6 @@ void LLAgent::resetAxes(const LLVector3 &look_at) mFrameAgent.setAxes(look_at, left, up); } - //----------------------------------------------------------------------------- // rotate() //----------------------------------------------------------------------------- @@ -1393,7 +1371,6 @@ void LLAgent::rotate(F32 angle, const LLVector3 &axis) mFrameAgent.rotate(angle, axis); } - //----------------------------------------------------------------------------- // rotate() //----------------------------------------------------------------------------- @@ -1402,7 +1379,6 @@ void LLAgent::rotate(F32 angle, F32 x, F32 y, F32 z) mFrameAgent.rotate(angle, x, y, z); } - //----------------------------------------------------------------------------- // rotate() //----------------------------------------------------------------------------- @@ -1411,7 +1387,6 @@ void LLAgent::rotate(const LLMatrix3 &matrix) mFrameAgent.rotate(matrix); } - //----------------------------------------------------------------------------- // rotate() //----------------------------------------------------------------------------- @@ -1420,7 +1395,6 @@ void LLAgent::rotate(const LLQuaternion &quaternion) mFrameAgent.rotate(quaternion); } - //----------------------------------------------------------------------------- // getReferenceUpVector() //----------------------------------------------------------------------------- @@ -1449,7 +1423,6 @@ LLVector3 LLAgent::getReferenceUpVector() return up_vector; } - // Radians, positive is forward into ground //----------------------------------------------------------------------------- // pitch() @@ -1493,7 +1466,6 @@ void LLAgent::pitch(F32 angle) } } - //----------------------------------------------------------------------------- // roll() //----------------------------------------------------------------------------- @@ -1502,7 +1474,6 @@ void LLAgent::roll(F32 angle) mFrameAgent.roll(angle); } - //----------------------------------------------------------------------------- // yaw() //----------------------------------------------------------------------------- @@ -1514,7 +1485,6 @@ void LLAgent::yaw(F32 angle) } } - // Returns a quat that represents the rotation of the agent in the absolute frame //----------------------------------------------------------------------------- // getQuat() @@ -1540,7 +1510,6 @@ void LLAgent::setControlFlags(U32 mask) mControlFlags |= mask; } - //----------------------------------------------------------------------------- // clearControlFlags() //----------------------------------------------------------------------------- @@ -1628,7 +1597,6 @@ bool LLAgent::isDoNotDisturb() const return mIsDoNotDisturb; } - //----------------------------------------------------------------------------- // startAutoPilotGlobal() //----------------------------------------------------------------------------- @@ -1734,7 +1702,6 @@ void LLAgent::startAutoPilotGlobal( mAutoPilotNoProgressFrameCount = 0; } - //----------------------------------------------------------------------------- // setAutoPilotTargetGlobal //----------------------------------------------------------------------------- @@ -1788,7 +1755,6 @@ void LLAgent::startFollowPilot(const LLUUID &leader_id, bool allow_flying, F32 s allow_flying); } - //----------------------------------------------------------------------------- // stopAutoPilot() //----------------------------------------------------------------------------- @@ -1830,7 +1796,6 @@ void LLAgent::stopAutoPilot(bool user_cancel) } } - // Returns necessary agent pitch and yaw changes, radians. //----------------------------------------------------------------------------- // autoPilot() @@ -2019,7 +1984,6 @@ void LLAgent::autoPilot(F32 *delta_yaw) } } - //----------------------------------------------------------------------------- // propagate() //----------------------------------------------------------------------------- @@ -2040,18 +2004,19 @@ void LLAgent::propagate(const F32 dt) } // handle rotation based on keyboard levels - constexpr F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second - F32 angle = YAW_RATE * gAgentCamera.getYawKey() * dt; - if (fabs(angle) > 0.0f) + if (fabs(dt) > 1e-6) { - yaw(angle); - } + if (fabs(gAgentCamera.getYawKey()) > 1e-6) + { + static const F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second + yaw(YAW_RATE * gAgentCamera.getYawKey() * dt); + } - constexpr F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second - angle = PITCH_RATE * gAgentCamera.getPitchKey() * dt; - if (fabs(angle) > 0.0f) - { - pitch(angle); + if (fabs(gAgentCamera.getPitchKey()) > 1e-6) + { + static const F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second + pitch(PITCH_RATE * gAgentCamera.getPitchKey() * dt); + } } // handle auto-land behavior @@ -2213,7 +2178,6 @@ void LLAgent::clearRenderState(U8 clearstate) mRenderState &= ~clearstate; } - //----------------------------------------------------------------------------- // getRenderState() //----------------------------------------------------------------------------- @@ -2255,6 +2219,7 @@ void LLAgent::endAnimationUpdateUI() { return; } + if (gAgentCamera.getCameraMode() == gAgentCamera.getLastCameraMode()) { // We're already done endAnimationUpdateUI for this transition. @@ -2320,7 +2285,6 @@ void LLAgent::endAnimationUpdateUI() mViewsPushed = false; } - gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR); if( gMorphView ) { @@ -2952,7 +2916,6 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) } } - void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferredMaturity) { U8 maturity = SIM_ACCESS_MIN; @@ -3022,7 +2985,6 @@ void LLAgent::changeInterestListMode(const std::string &new_mode) } } - bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure) { if (getRegion()) @@ -3349,7 +3311,6 @@ void LLAgent::sendAnimationStateReset() sendReliableMessage(); } - // Send a message to the region to revoke sepecified permissions on ALL scripts in the region // If the target is an object in the region, permissions in scripts on that object are cleared. // If it is the region ID, all scripts clear the permissions for this agent @@ -4279,7 +4240,6 @@ void LLAgent::onCapabilitiesReceivedAfterTeleport() check_merchant_status(); } - void LLAgent::teleportRequest( const U64& region_handle, const LLVector3& pos_local, @@ -4393,7 +4353,6 @@ void LLAgent::doTeleportViaLure(const LLUUID& lure_id, bool godlike) } } - // James Cook, July 28, 2005 void LLAgent::teleportCancel() { @@ -4518,7 +4477,6 @@ LLAgent::ETeleportState LLAgent::getTeleportState() const TELEPORT_NONE : mTeleportState; } - void LLAgent::setTeleportState(ETeleportState state) { if (mTeleportRequest && (state != TELEPORT_NONE) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed)) @@ -4563,7 +4521,6 @@ void LLAgent::setTeleportState(ETeleportState state) } } - void LLAgent::stopCurrentAnimations() { LL_DEBUGS("Avatar") << "Stopping current animations" << LL_ENDL; @@ -4678,7 +4635,6 @@ void LLAgent::stopFidget() gAgent.sendAnimationRequests(anims, ANIM_REQUEST_STOP); } - void LLAgent::requestEnterGodMode() { LLMessageSystem* msg = gMessageSystem; @@ -4799,7 +4755,6 @@ void LLAgent::sendAgentUpdateUserInfo(const std::string& directory_visibility) } } - void LLAgent::updateAgentUserInfoCoro(std::string capurl, std::string directory_visibility) { LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 81e79a2ed9..b2c66b1bac 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1462,13 +1462,12 @@ void LLAgentCamera::updateCamera() // LL_INFOS() << "Current FOV Zoom: " << mCameraCurrentFOVZoomFactor << " Target FOV Zoom: " << mCameraFOVZoomFactor << " Object penetration: " << mFocusObjectDist << LL_ENDL; LLVector3 focus_agent = gAgent.getPosAgentFromGlobal(mFocusGlobal); + LLVector3 position_agent = gAgent.getPosAgentFromGlobal(camera_pos_global); - mCameraPositionAgent = gAgent.getPosAgentFromGlobal(camera_pos_global); + // Try to move the camera - // Move the camera - - LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent); - //LLViewerCamera::getInstance()->updateCameraLocation(mCameraPositionAgent, camera_skyward, focus_agent); + if (!LLViewerCamera::getInstance()->updateCameraLocation(position_agent, mCameraUpVector, focus_agent)) + return; // Change FOV LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor)); @@ -1476,7 +1475,7 @@ void LLAgentCamera::updateCamera() // follow camera when in customize mode if (cameraCustomizeAvatar()) { - setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent); + setLookAt(LOOKAT_TARGET_FOCUS, NULL, position_agent); } // update the travel distance stat @@ -1495,8 +1494,8 @@ void LLAgentCamera::updateCamera() LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() + LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() + LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation(); - LLVector3 diff = mCameraPositionAgent - head_pos; - diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation(); + LLVector3 diff = position_agent - head_pos; + diff *= ~gAgentAvatarp->mRoot->getWorldRotation(); LLJoint* torso_joint = gAgentAvatarp->mTorsop; LLJoint* chest_joint = gAgentAvatarp->mChestp; @@ -1753,7 +1752,6 @@ F32 LLAgentCamera::calcCameraFOVZoomFactor() LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(bool *hit_limit) { // Compute base camera position and look-at points. - F32 camera_land_height; LLVector3d frame_center_global = !isAgentAvatarValid() ? gAgent.getPositionGlobal() : gAgent.getPosGlobalFromAgent(getAvatarRootPosition()); @@ -1988,22 +1986,13 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(bool *hit_limit) isConstrained = true; } } - -// JC - Could constrain camera based on parcel stuff here. -// LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromPosGlobal(camera_position_global); -// -// if (regionp && !regionp->mParcelOverlay->isBuildCameraAllowed(regionp->getPosRegionFromGlobal(camera_position_global))) -// { -// camera_position_global = last_position_global; -// -// isConstrained = true; -// } } - // Don't let camera go underground - F32 camera_min_off_ground = getCameraMinOffGround(); - camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global); - F32 minZ = llmax(F_ALMOST_ZERO, camera_land_height + camera_min_off_ground); + // Don't let camera go underground if constrained + // If not constrained, permit going 1000m below 0, use case: retrieving objects + F32 camera_min_off_ground = getCameraMinOffGround(); // checks isDisableCameraConstraints + F32 camera_land_height = LLWorld::getInstance()->resolveLandHeightGlobal(camera_position_global); + F32 minZ = camera_land_height + camera_min_off_ground; if (camera_position_global.mdV[VZ] < minZ) { camera_position_global.mdV[VZ] = minZ; @@ -2266,7 +2255,8 @@ void LLAgentCamera::changeCameraToFollow(bool animate) mCameraMode = CAMERA_MODE_FOLLOW; // bang-in the current focus, position, and up vector of the follow cam - mFollowCam.reset(mCameraPositionAgent, LLViewerCamera::getInstance()->getPointOfInterest(), LLVector3::z_axis); + const LLViewerCamera& camera = LLViewerCamera::instance(); + mFollowCam.reset(camera.getOrigin(), camera.getPointOfInterest(), LLVector3::z_axis); if (gBasicToolset) { diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 52571f3c55..d277fd6158 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -112,6 +112,7 @@ private: //-------------------------------------------------------------------- public: void switchCameraPreset(ECameraPreset preset); + ECameraPreset getCameraPreset() const { return mCameraPreset; } /** Determines default camera offset depending on the current camera preset */ LLVector3 getCameraOffsetInitial(); /** Determines default focus offset depending on the current camera preset */ @@ -138,13 +139,14 @@ private: //-------------------------------------------------------------------- public: LLVector3d getCameraPositionGlobal() const; - const LLVector3 &getCameraPositionAgent() const; + const LLVector3& getCameraPositionAgent() const; LLVector3d calcCameraPositionTargetGlobal(bool *hit_limit = NULL); // Calculate the camera position target F32 getCameraMinOffGround(); // Minimum height off ground for this mode, meters void setCameraCollidePlane(const LLVector4 &plane) { mCameraCollidePlane = plane; } bool calcCameraMinDistance(F32 &obj_min_distance); - F32 getCurrentCameraBuildOffset() { return (F32)mCameraFocusOffset.length(); } + F32 getCurrentCameraBuildOffset() const { return (F32)mCameraFocusOffset.length(); } void clearCameraLag() { mCameraLag.clearVec(); } + const LLVector3& getCameraUpVector() const { return mCameraUpVector; } private: LLVector3 getAvatarRootPosition(); @@ -154,7 +156,6 @@ private: F32 mCameraCurrentFOVZoomFactor; // Interpolated fov zoom LLVector4 mCameraCollidePlane; // Colliding plane for camera F32 mCameraZoomFraction; // Mousewheel driven fraction of zoom - LLVector3 mCameraPositionAgent; // Camera position in agent coordinates LLVector3 mCameraVirtualPositionAgent; // Camera virtual position (target) before performing FOV zoom LLVector3d mCameraSmoothingLastPositionGlobal; LLVector3d mCameraSmoothingLastPositionAgent; @@ -278,7 +279,7 @@ public: F32 getAgentHUDTargetZoom(); void resetCameraZoomFraction(); - F32 getCurrentCameraZoomFraction() { return mCameraZoomFraction; } + F32 getCurrentCameraZoomFraction() const { return mCameraZoomFraction; } //-------------------------------------------------------------------- // Pan diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp index 0b5198bbd3..8b18b7d5a2 100644 --- a/indra/newview/llagentpilot.cpp +++ b/indra/newview/llagentpilot.cpp @@ -322,9 +322,7 @@ void LLAgentPilot::moveCamera() LLViewerCamera::getInstance()->setView(view); LLViewerCamera::getInstance()->setOrigin(origin); - LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]); - LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]); - LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]); + LLViewerCamera::getInstance()->setAxes(mat); } } diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index cd4222dddf..25f5cbd78f 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1094,12 +1094,12 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it { gAgentAvatarp->setCompositeUpdatesEnabled(true); - // If we have not yet declouded, we may want to use + // If we have not yet loaded core parts, we may want to use // baked texture UUIDs sent from the first objectUpdate message - // don't overwrite these. If we have already declouded, we've saved - // these ids as the last known good textures and can invalidate without - // re-clouding. - if (!gAgentAvatarp->getIsCloud()) + // don't overwrite these. If we have parts already, we've saved + // these texture ids as the last known good textures and can + // invalidate without having to recloud avatar. + if (!gAgentAvatarp->getHasMissingParts()) { gAgentAvatarp->invalidateAll(); } diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp index 11c5ffecb6..5114ac8a08 100644 --- a/indra/newview/llaisapi.cpp +++ b/indra/newview/llaisapi.cpp @@ -839,7 +839,7 @@ void AISAPI::onUpdateReceived(const LLSD& update, COMMAND_TYPE type, const LLSD& if ( (type == UPDATECATEGORY || type == UPDATEITEM) && gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) { - dump_sequential_xml(gAgentAvatarp->getFullname() + "_ais_update", update); + dump_sequential_xml(gAgentAvatarp->getDebugName() + "_ais_update", update); } AISUpdate ais_update(update, type, request_body); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index e9d455ae53..6fa23727b1 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -856,7 +856,7 @@ void LLWearableHoldingPattern::checkMissingWearables() // was requested but none was found, create a default asset as a replacement. // In all other cases, don't do anything. // For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud - // due to logic in LLVOAvatarSelf::getIsCloud(). + // due to logic in LLVOAvatarSelf::getHasMissingParts(). // For non-critical types (tatoo, socks, etc.) the wearable will just be missing. (requested_by_type[type] > 0) && ((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT))) @@ -2045,7 +2045,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id) } // Moved from LLWearableList::ContextMenu for wider utility. -bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const +bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids, bool warn_on_type_mismatch) const { // TODO: investigate wearables may not be loaded at this point EXT-8231 @@ -2075,7 +2075,10 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const } else { + if (warn_on_type_mismatch) + { LL_WARNS() << "Unexpected wearable type" << LL_ENDL; + } return false; } } @@ -2266,7 +2269,7 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) } if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) { - dump_sequential_xml(gAgentAvatarp->getFullname() + "_slam_request", contents); + dump_sequential_xml(gAgentAvatarp->getDebugName() + "_slam_request", contents); } slam_inventory_folder(getCOF(), contents, link_waiter); @@ -3959,7 +3962,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL; if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage")) { - dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", result); + dump_sequential_xml(gAgentAvatarp->getDebugName() + "_appearance_request_ok", result); } } while (bRetry); @@ -3968,7 +3971,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd /*static*/ void LLAppearanceMgr::debugAppearanceUpdateCOF(const LLSD& content) { - dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content); + dump_sequential_xml(gAgentAvatarp->getDebugName() + "_appearance_request_error", content); LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger() << " ================================= " << LL_ENDL; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index bc7dc9506b..0a41a91750 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -103,7 +103,7 @@ public: bool getCanReplaceCOF(const LLUUID& outfit_cat_id); // Can we add all referenced items to the avatar? - bool canAddWearables(const uuid_vec_t& item_ids) const; + bool canAddWearables(const uuid_vec_t& item_ids, bool warn_on_type_mismatch = true) const; // Copy all items in a category. void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id, diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 2fa94cd27b..2c5c7b6348 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -268,6 +268,16 @@ using namespace LL; #include "glib.h" #endif // (LL_LINUX) && LL_GTK +#ifdef LL_DISCORD +#define DISCORDPP_IMPLEMENTATION +#include <discordpp.h> +static std::shared_ptr<discordpp::Client> gDiscordClient; +static uint64_t gDiscordTimestampsStart; +static std::string gDiscordActivityDetails; +static int32_t gDiscordPartyCurrentSize; +static int32_t gDiscordPartyMaxSize; +#endif + static LLAppViewerListener sAppViewerListener(LLAppViewer::instance); ////// Windows-specific includes to the bottom - nasty defines in these pollute the preprocessor @@ -443,13 +453,28 @@ static bool app_metrics_qa_mode = false; void idle_afk_check() { + // Don't check AFK status during startup states + if (LLStartUp::getStartupState() < STATE_STARTED) + { + return; + } + // check idle timers F32 current_idle = gAwayTriggerTimer.getElapsedTimeF32(); static LLCachedControl<S32> afk_timeout(gSavedSettings, "AFKTimeout", 300); - if (afk_timeout() && (current_idle > (F32)afk_timeout()) && !gAgent.getAFK()) + if (afk_timeout() && (current_idle > afk_timeout())) { - LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL; - gAgent.setAFK(); + if (!gAgent.getAFK()) + { + LL_INFOS("IdleAway") << "Idle more than " << afk_timeout << " seconds: automatically changing to Away status" << LL_ENDL; + gAgent.setAFK(); + } + else + { + // Refresh timer so that random one click or hover won't clear the status. + // But expanding the window still should lift afk status + gAwayTimer.reset(); + } } } @@ -475,7 +500,7 @@ static void deferred_ui_audio_callback(const LLUUID& uuid) bool create_text_segment_icon_from_url_match(LLUrlMatch* match,LLTextBase* base) { - if(!match || !base || base->getPlainText()) + if (!match || match->getSkipProfileIcon() || !base || base->getPlainText()) return false; LLUUID match_id = match->getID(); @@ -1321,6 +1346,13 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { +#ifdef LL_DISCORD + { + LL_PROFILE_ZONE_NAMED("discord_callbacks"); + discordpp::RunCallbacks(); + } +#endif + LL_RECORD_BLOCK_TIME(FTM_FRAME); LL_PROFILE_GPU_ZONE("Frame"); { @@ -1840,36 +1872,6 @@ bool LLAppViewer::cleanup() // Clean up before GL is shut down because we might be holding on to objects with texture references LLSelectMgr::cleanupGlobals(); - LL_INFOS() << "Shutting down OpenGL" << LL_ENDL; - - // Shut down OpenGL - if( gViewerWindow) - { - gViewerWindow->shutdownGL(); - - // Destroy window, and make sure we're not fullscreen - // This may generate window reshape and activation events. - // Therefore must do this before destroying the message system. - delete gViewerWindow; - gViewerWindow = NULL; - LL_INFOS() << "ViewerWindow deleted" << LL_ENDL; - } - - LLSplashScreen::show(); - LLSplashScreen::update(LLTrans::getString("ShuttingDown")); - - LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL; - - // viewer UI relies on keyboard so keep it aound until viewer UI isa gone - delete gKeyboard; - gKeyboard = NULL; - - if (LLViewerJoystick::instanceExists()) - { - // Turn off Space Navigator and similar devices - LLViewerJoystick::getInstance()->terminate(); - } - LL_INFOS() << "Cleaning up Objects" << LL_ENDL; LLViewerObject::cleanupVOClasses(); @@ -2030,6 +2032,36 @@ bool LLAppViewer::cleanup() sTextureFetch->shutDownTextureCacheThread() ; LLLFSThread::sLocal->shutdown(); + LL_INFOS() << "Shutting down OpenGL" << LL_ENDL; + + // Shut down OpenGL + if (gViewerWindow) + { + gViewerWindow->shutdownGL(); + + // Destroy window, and make sure we're not fullscreen + // This may generate window reshape and activation events. + // Therefore must do this before destroying the message system. + delete gViewerWindow; + gViewerWindow = NULL; + LL_INFOS() << "ViewerWindow deleted" << LL_ENDL; + } + + LLSplashScreen::show(); + LLSplashScreen::update(LLTrans::getString("ShuttingDown")); + + LL_INFOS() << "Cleaning up Keyboard & Joystick" << LL_ENDL; + + // viewer UI relies on keyboard so keep it aound until viewer UI isa gone + delete gKeyboard; + gKeyboard = NULL; + + if (LLViewerJoystick::instanceExists()) + { + // Turn off Space Navigator and similar devices + LLViewerJoystick::getInstance()->terminate(); + } + LL_INFOS() << "Shutting down message system" << LL_ENDL; end_messaging_system(); @@ -2250,10 +2282,7 @@ void errorCallback(LLError::ELevel level, const std::string &error_string) // Callback for LLError::LLUserWarningMsg void errorHandler(const std::string& title_string, const std::string& message_string, S32 code) { - if (!message_string.empty()) - { - OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK); - } + // message is going to hang viewer, create marker first switch (code) { case LLError::LLUserWarningMsg::ERROR_OTHER: @@ -2261,6 +2290,10 @@ void errorHandler(const std::string& title_string, const std::string& message_st break; case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC: LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC); + // When system run out of memory and errorHandler gets called from a thread, + // main thread might keep going while OSMessageBox freezes the caller. + // Todo: handle it better, but for now disconnect to avoid making things worse + gDisconnected = true; break; case LLError::LLUserWarningMsg::ERROR_MISSING_FILES: LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES); @@ -2268,6 +2301,10 @@ void errorHandler(const std::string& title_string, const std::string& message_st default: break; } + if (!message_string.empty()) + { + OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK); + } } void LLAppViewer::initLoggingAndGetLastDuration() @@ -3093,7 +3130,15 @@ bool LLAppViewer::initWindow() .height(gSavedSettings.getU32("WindowHeight")) .min_width(gSavedSettings.getU32("MinWindowWidth")) .min_height(gSavedSettings.getU32("MinWindowHeight")) +#ifdef LL_DARWIN + // Setting it to true causes black screen with no UI displayed. + // Given that it's a DEBUG settings and application goes fullscreen + // on mac simply by expanding it, it was decided to not support/use + // this setting on mac. + .fullscreen(false) +#else // LL_DARWIN .fullscreen(gSavedSettings.getBOOL("FullScreen")) +#endif .ignore_pixel_depth(ignorePixelDepth) .first_run(mIsFirstRun); @@ -4258,7 +4303,7 @@ U32 LLAppViewer::getTextureCacheVersion() U32 LLAppViewer::getDiskCacheVersion() { // Viewer disk cache version intorduced in Simple Cache Viewer, change if the cache format changes. - const U32 DISK_CACHE_VERSION = 2; + const U32 DISK_CACHE_VERSION = 3; return DISK_CACHE_VERSION ; } @@ -4284,8 +4329,8 @@ bool LLAppViewer::initCache() const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); const U32 MB = 1024 * 1024; - const uintmax_t MIN_CACHE_SIZE = 256 * MB; - const uintmax_t MAX_CACHE_SIZE = 9984ll * MB; + const uintmax_t MIN_CACHE_SIZE = 896 * MB; + const uintmax_t MAX_CACHE_SIZE = 32768ll * MB; const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB; const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); @@ -5691,9 +5736,31 @@ void LLAppViewer::forceErrorThreadCrash() thread->start(); } -void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) +void LLAppViewer::forceExceptionThreadCrash() +{ + class LLCrashTestThread : public LLThread + { + public: + + LLCrashTestThread() : LLThread("Crash logging test thread") + { + } + + void run() + { + const std::string exception_text = "This is a deliberate exception in a thread"; + throw std::runtime_error(exception_text); + } + }; + + LL_WARNS() << "This is a deliberate exception in a thread" << LL_ENDL; + LLCrashTestThread* thread = new LLCrashTestThread(); + thread->start(); +} + +void LLAppViewer::initMainloopTimeout(std::string_view state, F32 secs) { - if(!mMainloopTimeout) + if (!mMainloopTimeout) { mMainloopTimeout = new LLWatchdogTimeout(); resumeMainloopTimeout(state, secs); @@ -5702,20 +5769,20 @@ void LLAppViewer::initMainloopTimeout(const std::string& state, F32 secs) void LLAppViewer::destroyMainloopTimeout() { - if(mMainloopTimeout) + if (mMainloopTimeout) { delete mMainloopTimeout; - mMainloopTimeout = NULL; + mMainloopTimeout = nullptr; } } -void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs) +void LLAppViewer::resumeMainloopTimeout(std::string_view state, F32 secs) { - if(mMainloopTimeout) + if (mMainloopTimeout) { - if(secs < 0.0f) + if (secs < 0.0f) { - static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); + static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60.f); secs = mainloop_timeout; } @@ -5726,19 +5793,19 @@ void LLAppViewer::resumeMainloopTimeout(const std::string& state, F32 secs) void LLAppViewer::pauseMainloopTimeout() { - if(mMainloopTimeout) + if (mMainloopTimeout) { mMainloopTimeout->stop(); } } -void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs) +void LLAppViewer::pingMainloopTimeout(std::string_view state, F32 secs) { LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; - if(mMainloopTimeout) + if (mMainloopTimeout) { - if(secs < 0.0f) + if (secs < 0.0f) { static LLCachedControl<F32> mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); secs = mainloop_timeout; @@ -5866,3 +5933,103 @@ void LLAppViewer::metricsSend(bool enable_reporting) gViewerAssetStats->restart(); } +#ifdef LL_DISCORD + +void LLAppViewer::initDiscordSocial() +{ + gDiscordPartyCurrentSize = 1; + gDiscordPartyMaxSize = 0; + gDiscordTimestampsStart = time(nullptr); + gDiscordClient = std::make_shared<discordpp::Client>(); + gDiscordClient->SetApplicationId(1394782217405862001); + updateDiscordActivity(); +} + +void LLAppViewer::updateDiscordActivity() +{ + LL_PROFILE_ZONE_SCOPED; + + static LLCachedControl<bool> integration_enabled(gSavedSettings, "EnableDiscord", true); + if (!integration_enabled) + { + gDiscordClient->ClearRichPresence(); + return; + } + + discordpp::Activity activity; + activity.SetType(discordpp::ActivityTypes::Playing); + discordpp::ActivityTimestamps timestamps; + timestamps.SetStart(gDiscordTimestampsStart); + activity.SetTimestamps(timestamps); + + if (gAgent.getID() == LLUUID::null) + { + gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {}); + return; + } + + static LLCachedControl<bool> show_details(gSavedSettings, "ShowDiscordActivityDetails", false); + if (show_details) + { + if (gDiscordActivityDetails.empty()) + { + LLAvatarName av_name; + LLAvatarNameCache::get(gAgent.getID(), &av_name); + gDiscordActivityDetails = av_name.getUserName(); + auto displayName = av_name.getDisplayName(); + if (gDiscordActivityDetails != displayName) + gDiscordActivityDetails = displayName + " (" + gDiscordActivityDetails + ")"; + } + activity.SetDetails(gDiscordActivityDetails); + } + + auto agent_pos_region = gAgent.getPositionAgent(); + S32 pos_x = S32(agent_pos_region.mV[VX] + 0.5f); + S32 pos_y = S32(agent_pos_region.mV[VY] + 0.5f); + S32 pos_z = S32(agent_pos_region.mV[VZ] + 0.5f); + F32 velocity_mag_sq = gAgent.getVelocity().magVecSquared(); + const F32 FLY_CUTOFF = 6.f; + const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF; + const F32 WALK_CUTOFF = 1.5f; + const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF; + if (velocity_mag_sq > FLY_CUTOFF_SQ) + { + pos_x -= pos_x % 4; + pos_y -= pos_y % 4; + } + else if (velocity_mag_sq > WALK_CUTOFF_SQ) + { + pos_x -= pos_x % 2; + pos_y -= pos_y % 2; + } + + std::string location = "Hidden Region"; + static LLCachedControl<bool> show_state(gSavedSettings, "ShowDiscordActivityState", false); + if (show_state) + { + location = llformat("%s (%d, %d, %d)", gAgent.getRegion()->getName().c_str(), pos_x, pos_y, pos_z); + } + activity.SetState(location); + + discordpp::ActivityParty party; + party.SetId(location); + party.SetCurrentSize(gDiscordPartyCurrentSize); + party.SetMaxSize(gDiscordPartyMaxSize); + activity.SetParty(party); + + gDiscordClient->UpdateRichPresence(activity, [](discordpp::ClientResult) {}); +} + +void LLAppViewer::updateDiscordPartyCurrentSize(int32_t size) +{ + gDiscordPartyCurrentSize = size; + updateDiscordActivity(); +} + +void LLAppViewer::updateDiscordPartyMaxSize(int32_t size) +{ + gDiscordPartyMaxSize = size; + updateDiscordActivity(); +} + +#endif diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 3da0246ccf..132d7bfe25 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -175,6 +175,7 @@ public: virtual void forceErrorCoroprocedureCrash(); virtual void forceErrorWorkQueueCrash(); virtual void forceErrorThreadCrash(); + virtual void forceExceptionThreadCrash(); // The list is found in app_settings/settings_files.xml // but since they are used explicitly in code, @@ -197,11 +198,11 @@ public: // For thread debugging. // llstartup needs to control init. // llworld, send_agent_pause() also controls pause/resume. - void initMainloopTimeout(const std::string& state, F32 secs = -1.0f); + void initMainloopTimeout(std::string_view state, F32 secs = -1.0f); void destroyMainloopTimeout(); void pauseMainloopTimeout(); - void resumeMainloopTimeout(const std::string& state = "", F32 secs = -1.0f); - void pingMainloopTimeout(const std::string& state, F32 secs = -1.0f); + void resumeMainloopTimeout(std::string_view state = "", F32 secs = -1.0f); + void pingMainloopTimeout(std::string_view state, F32 secs = -1.0f); // Handle the 'login completed' event. // *NOTE:Mani Fix this for login abstraction!! @@ -250,6 +251,13 @@ public: // Note: mQuitRequested can be aborted by user. void outOfMemorySoftQuit(); +#ifdef LL_DISCORD + static void initDiscordSocial(); + static void updateDiscordActivity(); + static void updateDiscordPartyCurrentSize(int32_t size); + static void updateDiscordPartyMaxSize(int32_t size); +#endif + protected: virtual bool initWindow(); // Initialize the viewer's window. virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 2fb1ae7906..6386d0636a 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -448,6 +448,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, // *FIX: global gIconResource = MAKEINTRESOURCE(IDI_LL_ICON); + gIconSmallResource = MAKEINTRESOURCE(IDI_LL_ICON_SMALL); LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(ll_convert_wide_to_string(pCmdLine).c_str()); @@ -816,6 +817,29 @@ bool LLAppViewerWin32::reportCrashToBugsplat(void* pExcepInfo) return false; } +bool LLAppViewerWin32::initWindow() +{ + // This is a workaround/hotfix for a change in Windows 11 24H2 (and possibly later) + // Where the window width and height need to correctly reflect an available FullScreen size + if (gSavedSettings.getBOOL("FullScreen")) + { + DEVMODE dev_mode; + ::ZeroMemory(&dev_mode, sizeof(DEVMODE)); + dev_mode.dmSize = sizeof(DEVMODE); + if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode)) + { + gSavedSettings.setU32("WindowWidth", dev_mode.dmPelsWidth); + gSavedSettings.setU32("WindowHeight", dev_mode.dmPelsHeight); + } + else + { + LL_WARNS("AppInit") << "Unable to set WindowWidth and WindowHeight for FullScreen mode" << LL_ENDL; + } + } + + return LLAppViewer::initWindow(); +} + void LLAppViewerWin32::initLoggingAndGetLastDuration() { LLAppViewer::initLoggingAndGetLastDuration(); diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index 250e72edf3..3fad53ec72 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -46,6 +46,7 @@ public: bool reportCrashToBugsplat(void* pExcepInfo) override; protected: + bool initWindow() override; // Override to initialize the viewer's window. void initLoggingAndGetLastDuration() override; // Override to clean stack_trace info. void initConsole() override; // Initialize OS level debugging console. bool initHardwareTest() override; // Win32 uses DX9 to test hardware. diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index f200ca8e31..1ea2899ba4 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -536,11 +536,12 @@ LLAutoReplaceSettings::AddListResult LLAutoReplaceSettings::replaceList(const LL S32 search_index; LLSD targetList; // The following is working around the fact that LLSD arrays containing maps also seem to have undefined entries... see LLSD-30 - for ( search_index = 0, targetList = mLists[0]; + for ( search_index = 0; !listFound && search_index < mLists.size(); - search_index += 1, targetList = mLists[search_index] + search_index += 1 ) { + targetList = mLists[search_index]; if ( targetList.isMap() ) { if ( listNameMatches( targetList, listName) ) diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp index 8f858fe4e1..f206474e71 100644 --- a/indra/newview/llavatarlist.cpp +++ b/indra/newview/llavatarlist.cpp @@ -141,6 +141,7 @@ LLAvatarList::LLAvatarList(const Params& p) , mShowSpeakingIndicator(p.show_speaking_indicator) , mShowPermissions(p.show_permissions_granted) , mShowCompleteName(false) +, mForceCompleteName(false) { setCommitOnSelectionChange(true); @@ -177,7 +178,7 @@ void LLAvatarList::setShowIcons(std::string param_name) std::string LLAvatarList::getAvatarName(LLAvatarName av_name) { - return mShowCompleteName? av_name.getCompleteName(false) : av_name.getDisplayName(); + return mShowCompleteName? av_name.getCompleteName(false, mForceCompleteName) : av_name.getDisplayName(); } // virtual @@ -364,7 +365,7 @@ void LLAvatarList::updateAvatarNames() for( std::vector<LLPanel*>::const_iterator it = items.begin(); it != items.end(); it++) { LLAvatarListItem* item = static_cast<LLAvatarListItem*>(*it); - item->setShowCompleteName(mShowCompleteName); + item->setShowCompleteName(mShowCompleteName, mForceCompleteName); item->updateAvatarName(); } mNeedUpdateNames = false; @@ -404,6 +405,11 @@ boost::signals2::connection LLAvatarList::setItemDoubleClickCallback(const mouse return mItemDoubleClickSignal.connect(cb); } +boost::signals2::connection LLAvatarList::setItemClickedCallback(const mouse_signal_t::slot_type& cb) +{ + return mItemClickedSignal.connect(cb); +} + //virtual S32 LLAvatarList::notifyParent(const LLSD& info) { @@ -418,7 +424,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->setShowCompleteName(mShowCompleteName); + item->setShowCompleteName(mShowCompleteName, mForceCompleteName); // This sets the name as a side effect item->setAvatarId(id, mSessionID, mIgnoreOnlineStatus); item->setOnline(mIgnoreOnlineStatus ? true : is_online); @@ -432,6 +438,7 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, bool is item->setDoubleClickCallback(boost::bind(&LLAvatarList::onItemDoubleClicked, this, _1, _2, _3, _4)); + item->setMouseDownCallback(boost::bind(&LLAvatarList::onItemClicked, this, _1, _2, _3, _4)); addItem(item, id, pos); } @@ -550,6 +557,11 @@ void LLAvatarList::onItemDoubleClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask) mItemDoubleClickSignal(ctrl, x, y, mask); } +void LLAvatarList::onItemClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask) +{ + mItemClickedSignal(ctrl, x, y, mask); +} + bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const { const LLAvatarListItem* avatar_item1 = dynamic_cast<const LLAvatarListItem*>(item1); diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h index af5bfefcde..f99da93a3d 100644 --- a/indra/newview/llavatarlist.h +++ b/indra/newview/llavatarlist.h @@ -96,11 +96,13 @@ public: boost::signals2::connection setItemDoubleClickCallback(const mouse_signal_t::slot_type& cb); + boost::signals2::connection setItemClickedCallback(const mouse_signal_t::slot_type& cb); + virtual S32 notifyParent(const LLSD& info); void handleDisplayNamesOptionChanged(); - void setShowCompleteName(bool show) { mShowCompleteName = show;}; + void setShowCompleteName(bool show, bool force = false) { mShowCompleteName = show; mForceCompleteName = force; }; protected: void refresh(); @@ -113,6 +115,7 @@ protected: void updateLastInteractionTimes(); void rebuildNames(); void onItemDoubleClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask); + void onItemClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask); void updateAvatarNames(); private: @@ -127,6 +130,7 @@ private: bool mShowSpeakingIndicator; bool mShowPermissions; bool mShowCompleteName; + bool mForceCompleteName; LLTimer* mLITUpdateTimer; // last interaction time update timer std::string mIconParamName; @@ -138,6 +142,7 @@ private: commit_signal_t mRefreshCompleteSignal; mouse_signal_t mItemDoubleClickSignal; + mouse_signal_t mItemClickedSignal; }; /** Abstract comparator for avatar items */ diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 880910d18e..80c7f8beca 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -78,6 +78,7 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/) mShowProfileBtn(true), mShowPermissions(false), mShowCompleteName(false), + mForceCompleteName(false), mHovered(false), mAvatarNameCacheConnection(), mGreyOutUsername("") @@ -324,13 +325,12 @@ void LLAvatarListItem::setShowProfileBtn(bool show) void LLAvatarListItem::showSpeakingIndicator(bool visible) { - // Already done? Then do nothing. - if (mSpeakingIndicator->getVisible() == (bool)visible) - return; -// Disabled to not contradict with SpeakingIndicatorManager functionality. EXT-3976 -// probably this method should be totally removed. -// mSpeakingIndicator->setVisible(visible); -// updateChildren(); + // used only to hide indicator to not contradict with SpeakingIndicatorManager functionality + if (mSpeakingIndicator && !visible) + { + mSpeakingIndicator->setIsActiveChannel(visible); + mSpeakingIndicator->setShowParticipantsSpeaking(visible); + } } void LLAvatarListItem::setAvatarIconVisible(bool visible) @@ -417,8 +417,8 @@ void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name) mAvatarNameCacheConnection.disconnect(); mGreyOutUsername = ""; - std::string name_string = mShowCompleteName? av_name.getCompleteName(false) : av_name.getDisplayName(); - if(av_name.getCompleteName() != av_name.getUserName()) + std::string name_string = mShowCompleteName? av_name.getCompleteName(false, mForceCompleteName) : av_name.getDisplayName(); + if(av_name.getCompleteName(false, mForceCompleteName) != av_name.getUserName()) { mGreyOutUsername = "[ " + av_name.getUserName(true) + " ]"; LLStringUtil::toLower(mGreyOutUsername); diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index 2e4c597d30..2ec7a41055 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -106,7 +106,7 @@ public: void setShowPermissions(bool show) { mShowPermissions = show; }; void showLastInteractionTime(bool show); void setAvatarIconVisible(bool visible); - void setShowCompleteName(bool show) { mShowCompleteName = show;}; + void setShowCompleteName(bool show, bool force = false) { mShowCompleteName = show; mForceCompleteName = force;}; const LLUUID& getAvatarId() const; std::string getAvatarName() const; @@ -220,6 +220,7 @@ private: bool mHovered; bool mShowCompleteName; + bool mForceCompleteName; std::string mGreyOutUsername; void fetchAvatarName(); diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 829b6380cd..76e308a966 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -504,7 +504,7 @@ void LLAvatarTracker::idleNotifyObservers() void LLAvatarTracker::notifyObservers() { - if (mIsNotifyObservers) + if (mIsNotifyObservers || (LLStartUp::getStartupState() <= STATE_INVENTORY_CALLBACKS)) { // Don't allow multiple calls. // new masks and ids will be processed later from idle. diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index a48e22bc73..1988e2072b 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -189,7 +189,14 @@ public: std::string url = "secondlife://" + mObjectData["slurl"].asString(); LLUrlAction::teleportToLocation(url); } - + else if (level == "obj_zoom_in") + { + LLUUID obj_id = mObjectData["object_id"]; + if (obj_id.notNull()) + { + handle_zoom_to_object(obj_id); + } + } } bool onObjectIconContextMenuItemVisible(const LLSD& userdata) @@ -203,6 +210,15 @@ public: { return !LLMuteList::getInstance()->isMuted(getAvatarId(), mFrom, LLMute::flagTextChat); } + else if (level == "obj_zoom_in") + { + LLUUID obj_id = mObjectData["object_id"]; + if (obj_id.notNull()) + { + return nullptr != gObjectList.findObject(mAvatarID); + } + return false; + } return false; } @@ -936,7 +952,7 @@ protected: menu->setItemEnabled("Voice Call", false); menu->setItemEnabled("Chat History", false); menu->setItemEnabled("Invite Group", false); - menu->setItemEnabled("Zoom In", false); + menu->setItemEnabled("Zoom In", true); menu->setItemEnabled("Share", false); menu->setItemEnabled("Pay", false); menu->setItemEnabled("Block Unblock", false); diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 550dfeb802..5ac4ce0d52 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -37,6 +37,8 @@ #include "lllocalcliprect.h" #include "lltrans.h" #include "llfloaterimnearbychat.h" +#include "llfloaterworldmap.h" +#include "llviewermenu.h" #include "llviewercontrol.h" #include "llagentdata.h" @@ -75,6 +77,23 @@ public: return true; } + if (verb == "zoomin") + { + if (!handle_zoom_to_object(object_id) && params.size() > 2) + { + // zoom faled, show location + // secondlife:///app/object/object_id/zoomin/{LOCATION}/{COORDS} SLapp + const std::string region_name = LLURI::unescape(params[0].asString()); + S32 x = (params.size() > 1) ? params[1].asInteger() : 128; + S32 y = (params.size() > 2) ? params[2].asInteger() : 128; + S32 z = (params.size() > 3) ? params[3].asInteger() : 0; + + LLFloaterWorldMap::getInstance()->trackURL(region_name, x, y, z); + LLFloaterReg::showInstance("world_map", "center"); + } + return true; + } + return false; } }; diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 9201241856..660fb1b41a 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -129,14 +129,14 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_ { LLVector3 pos_box_offset = point_to_box_offset(vol_pos, unshift_extents); F32 offset_dist = pos_box_offset.length(); - if (offset_dist > MAX_LEGAL_OFFSET && offset_dist > 0.f) + if (offset_dist > max_legal_offset && offset_dist > 0.f) { - F32 target_dist = (offset_dist - MAX_LEGAL_OFFSET); + F32 target_dist = (offset_dist - max_legal_offset); new_pos_fixup = (target_dist/offset_dist)*pos_box_offset; } if (new_pos_fixup != mPositionConstraintFixup) { - LL_DEBUGS("ConstraintFix") << getFullname() << " pos fix, offset_dist " << offset_dist << " pos fixup " + LL_DEBUGS("ConstraintFix") << getDebugName() << " pos fix, offset_dist " << offset_dist << " pos fixup " << new_pos_fixup << " was " << mPositionConstraintFixup << LL_ENDL; LL_DEBUGS("ConstraintFix") << "vol_pos " << vol_pos << LL_ENDL; LL_DEBUGS("ConstraintFix") << "extents " << extents[0] << " " << extents[1] << LL_ENDL; @@ -144,11 +144,11 @@ void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_ } } - if (box_size/mScaleConstraintFixup > MAX_LEGAL_SIZE) + if (box_size/mScaleConstraintFixup > max_legal_size) { - new_scale_fixup = mScaleConstraintFixup* MAX_LEGAL_SIZE /box_size; - LL_DEBUGS("ConstraintFix") << getFullname() << " scale fix, box_size " << box_size << " fixup " - << mScaleConstraintFixup << " max legal " << MAX_LEGAL_SIZE + new_scale_fixup = mScaleConstraintFixup*max_legal_size/box_size; + LL_DEBUGS("ConstraintFix") << getDebugName() << " scale fix, box_size " << box_size << " fixup " + << mScaleConstraintFixup << " max legal " << max_legal_size << " -> new scale " << new_scale_fixup << LL_ENDL; } } @@ -231,7 +231,7 @@ void LLControlAvatar::matchVolumeTransform() const LLMeshSkinInfo* skin_info = mRootVolp->getSkinInfo(); if (skin_info) { - LL_DEBUGS("BindShape") << getFullname() << " bind shape " << skin_info->mBindShapeMatrix << LL_ENDL; + LL_DEBUGS("BindShape") << getDebugName() << " bind shape " << skin_info->mBindShapeMatrix << LL_ENDL; bind_rot = LLSkinningUtil::getUnscaledQuaternion(LLMatrix4(skin_info->mBindShapeMatrix)); } #endif diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index e6a720e734..cea68c1779 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -663,7 +663,7 @@ void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD& { mConversations.clear(); notifyObservers(); - cache(); + saveToFile(getFileName()); deleteBackupLogs(); } } diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 5004055666..bb1daf4ec1 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -300,7 +300,7 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic for (auto itemp : mChildren) { - LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp); + LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp.get()); // Add the avatar uuid to the list (except if it's the own agent uuid) if (current_participant->getUUID() != gAgentID) { @@ -329,6 +329,7 @@ void LLConversationItemSession::updateName(LLConversationItemParticipant* partic void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant) { + LLPointer<LLFolderViewModelItem> holder(participant); removeChild(participant); mNeedsRefresh = true; updateName(participant); @@ -360,15 +361,10 @@ void LLConversationItemSession::clearAndDeparentModels() for (child_list_t::iterator it = mChildren.begin(); it != mChildren.end();) { LLFolderViewModelItem* child = *it; - if (child->getNumRefs() == 0) + // Note that model might still be assigned to some view/widget + // and have a different parent + if (child->getParent() == this) { - // LLConversationItemParticipant can be created but not assigned to any view, - // it was waiting for an "add_participant" event to be processed - delete child; - } - else - { - // Model is still assigned to some view/widget child->setParent(NULL); } it = mChildren.erase(it); @@ -383,7 +379,7 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const child_list_t::iterator iter; for (iter = mChildren.begin(); iter != mChildren.end(); iter++) { - participant = dynamic_cast<LLConversationItemParticipant*>(*iter); + participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get()); if (participant && participant->hasSameValue(participant_id)) { break; @@ -493,7 +489,7 @@ const bool LLConversationItemSession::getTime(F64& time) const child_list_t::const_iterator iter; for (iter = mChildren.begin(); iter != mChildren.end(); iter++) { - participant = dynamic_cast<LLConversationItemParticipant*>(*iter); + participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get()); F64 participant_time; if (participant && participant->getTime(participant_time)) { @@ -517,7 +513,7 @@ void LLConversationItemSession::dumpDebugData(bool dump_children) { for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++) { - LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter); + LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>((*iter).get()); if (participant) { participant->dumpDebugData(); diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index c1e48c63a9..d5486b9f4a 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -79,6 +79,9 @@ public: virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); } virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; } virtual std::string getLabelSuffix() const { return LLStringUtil::null; } + virtual bool isFavorite() const { return false; } + virtual bool isAgentInventory() const { return false; } + virtual bool isAgentInventoryRoot() const { return false; } virtual bool isItemRenameable() const { return true; } virtual bool renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return true; } virtual bool isItemMovable( void ) const { return false; } diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index a1f627c8cc..0e0ab236d6 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -86,7 +86,8 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes mHasArrow(true), mIsInActiveVoiceChannel(false), mFlashStateOn(false), - mFlashStarted(false) + mFlashStarted(false), + mIsAltFlashColor(false) { mFlashTimer = new LLFlashTimer(); mAreChildrenInited = true; // inventory only @@ -157,7 +158,7 @@ void LLConversationViewSession::destroyView() LLFolderViewFolder::destroyView(); } -void LLConversationViewSession::setFlashState(bool flash_state) +void LLConversationViewSession::setFlashState(bool flash_state, bool alternate_color) { if (flash_state && !mFlashStateOn) { @@ -170,6 +171,7 @@ void LLConversationViewSession::setFlashState(bool flash_state) mFlashStateOn = flash_state; mFlashStarted = false; + mIsAltFlashColor = mFlashStateOn && (alternate_color || mIsAltFlashColor); mFlashTimer->stopFlashing(); } @@ -288,7 +290,8 @@ void LLConversationViewSession::draw() startFlashing(); // draw highlight for selected items - drawHighlight(show_context, true, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); + static LLUIColor alt_color = LLUIColorTable::instance().getColor("MentionFlashBgColor", DEFAULT_WHITE); + drawHighlight(show_context, true, sHighlightBgColor, mIsAltFlashColor ? alt_color : sFlashBgColor, sFocusOutlineColor, sMouseOverColor); // Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap. bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen(); diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 8eb6392121..a6d240ed84 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -90,7 +90,7 @@ public: virtual void refresh(); - /*virtual*/ void setFlashState(bool flash_state); + /*virtual*/ void setFlashState(bool flash_state, bool alternate_color = false); void setHighlightState(bool hihglight_state); LLFloater* getSessionFloater(); @@ -111,6 +111,7 @@ private: LLFlashTimer* mFlashTimer; bool mFlashStateOn; bool mFlashStarted; + bool mIsAltFlashColor; bool mCollapsedMode; bool mHasArrow; diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 7d58511d41..cdf3244389 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -143,7 +143,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass) gGL.setColorMask(true, true); LLColor3 light_diffuse(0, 0, 0); - F32 light_exp = 0.0f; LLEnvironment& environment = LLEnvironment::instance(); LLSettingsWater::ptr_t pwater = environment.getCurrentWater(); @@ -170,7 +169,6 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass) // Apply magic numbers translating light direction into intensities light_dir.normalize(); F32 ground_proj_sq = light_dir.mV[0] * light_dir.mV[0] + light_dir.mV[1] * light_dir.mV[1]; - light_exp = llmax(32.f, 256.f * powf(ground_proj_sq, 16.0f)); if (0.f < light_diffuse.normalize()) // Normalizing a color? Puzzling... { light_diffuse *= (1.5f + (6.f * ground_proj_sq)); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 0017a724ea..875dac103c 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -2563,7 +2563,6 @@ void LLEnvironment::setSharedEnvironment() { clearEnvironment(LLEnvironment::ENV_LOCAL); setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - updateEnvironment(); } void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLUUID asset_id, F32 transition_time) diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index c05a7fef44..c6fea1ba82 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -101,10 +101,18 @@ namespace Details void LLEventPollImpl::handleMessage(const LLSD& content) { LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; - std::string msg_name = content["message"]; + std::string msg_name = content["message"].asString(); LLSD message; - message["sender"] = mSenderIp; - message["body"] = content["body"]; + try + { + message["sender"] = mSenderIp; + message["body"] = content["body"]; + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation on message: " << msg_name << LL_ENDL; + } LLMessageSystem::dispatch(msg_name, message); } diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 5eabed86a7..0e754c9561 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -59,7 +59,7 @@ LLFilePicker LLFilePicker::sInstance; #define XML_FILTER L"XML files (*.xml)\0*.xml\0" #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" -#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0" +#define MODEL_FILTER L"Model files (*.dae, *.gltf, *.glb)\0*.dae;*.gltf;*.glb\0" #define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0" #define HDRI_FILTER L"HDRI Files (*.exr)\0*.exr\0" #define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" @@ -217,6 +217,8 @@ bool LLFilePicker::setupFilter(ELoadFilter filter) break; case FFLOAD_MODEL: mOFN.lpstrFilter = MODEL_FILTER \ + COLLADA_FILTER \ + MATERIAL_FILTER \ L"\0"; break; case FFLOAD_MATERIAL: @@ -671,6 +673,8 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF case FFLOAD_HDRI: allowedv->push_back("exr"); case FFLOAD_MODEL: + allowedv->push_back("gltf"); + allowedv->push_back("glb"); case FFLOAD_COLLADA: allowedv->push_back("dae"); break; diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp index 99f24e161e..d93bd624f5 100644 --- a/indra/newview/llfloaterautoreplacesettings.cpp +++ b/indra/newview/llfloaterautoreplacesettings.cpp @@ -422,7 +422,13 @@ bool LLFloaterAutoReplaceSettings::callbackNewListName(const LLSD& notification, LLSD newList = notification["payload"]["list"]; - if ( response.has("listname") && response["listname"].isString() ) + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option != 1) // Must also match RenameAutoReplaceList + { + // user cancelled + return false; + } + else if (response.has("listname") && response["listname"].isString() ) { std::string newName = response["listname"].asString(); LLAutoReplaceSettings::setListName(newList, newName); @@ -508,12 +514,53 @@ bool LLFloaterAutoReplaceSettings::callbackListNameConflict(const LLSD& notifica return false; } +bool LLFloaterAutoReplaceSettings::callbackRemoveList(const LLSD& notification, const LLSD& response) +{ + std::string listName = notification["payload"]["list"]; + + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + switch (option) + { + case 1: + if (mSettings.removeReplacementList(listName)) + { + LL_INFOS("AutoReplace") << "deleted list '" << listName << "'" << LL_ENDL; + mReplacementsList->deleteSelectedItems(); // remove from the scrolling list + mSelectedListName.clear(); + updateListNames(); + updateListNamesControls(); + updateReplacementsList(); + } + break; + case 0: + break; + + default: + LL_ERRS("AutoReplace") << "invalid selected option " << option << LL_ENDL; + } + + return false; +} + void LLFloaterAutoReplaceSettings::onDeleteList() { std::string listName = mListNames->getSelectedValue().asString(); if ( ! listName.empty() ) { - if ( mSettings.removeReplacementList(listName) ) + const LLSD* mappings = mSettings.getListEntries(mSelectedListName); + if (mappings->size() > 0) + { + LLSD payload; + payload["list"] = listName; + + LLSD args; + args["MAP_SIZE"] = llformat("%d",mappings->size()); + args["LIST_NAME"] = listName; + + LLNotificationsUtil::add("RemoveAutoReplaceList", args, payload, + boost::bind(&LLFloaterAutoReplaceSettings::callbackRemoveList, this, _1, _2)); + } + else if ( mSettings.removeReplacementList(listName) ) { LL_INFOS("AutoReplace")<<"deleted list '"<<listName<<"'"<<LL_ENDL; mReplacementsList->deleteSelectedItems(); // remove from the scrolling list diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h index 94a7c00c15..1a8068ab7c 100644 --- a/indra/newview/llfloaterautoreplacesettings.h +++ b/indra/newview/llfloaterautoreplacesettings.h @@ -105,6 +105,8 @@ private: bool callbackNewListName(const LLSD& notification, const LLSD& response); /// called from the RenameAutoReplaceList notification dialog bool callbackListNameConflict(const LLSD& notification, const LLSD& response); + /// called from the RemoveAutoReplaceList notification dialog + bool callbackRemoveList(const LLSD& notification, const LLSD& response); bool selectedListIsFirst(); bool selectedListIsLast(); diff --git a/indra/newview/llfloateravatar.cpp b/indra/newview/llfloateravatarwelcomepack.cpp index 404316275d..82e44d1398 100644 --- a/indra/newview/llfloateravatar.cpp +++ b/indra/newview/llfloateravatarwelcomepack.cpp @@ -1,7 +1,7 @@ /** - * @file llfloateravatar.h - * @author Leyla Farazha - * @brief floater for the avatar changer + * @file llfloateravatarwelcomepack.cpp + * @author Callum Prentice (callum@lindenlab.com) + * @brief Floater container for the Avatar Welcome Pack we app * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code @@ -27,17 +27,16 @@ #include "llviewerprecompiledheaders.h" -#include "llfloateravatar.h" +#include "llfloateravatarwelcomepack.h" #include "lluictrlfactory.h" #include "llmediactrl.h" - -LLFloaterAvatar::LLFloaterAvatar(const LLSD& key) +LLFloaterAvatarWelcomePack::LLFloaterAvatarWelcomePack(const LLSD& key) : LLFloater(key) { } -LLFloaterAvatar::~LLFloaterAvatar() +LLFloaterAvatarWelcomePack::~LLFloaterAvatarWelcomePack() { if (mAvatarPicker) { @@ -47,15 +46,13 @@ LLFloaterAvatar::~LLFloaterAvatar() } } -bool LLFloaterAvatar::postBuild() +bool LLFloaterAvatarWelcomePack::postBuild() { mAvatarPicker = findChild<LLMediaCtrl>("avatar_picker_contents"); if (mAvatarPicker) { mAvatarPicker->clearCache(); } - enableResizeCtrls(true, true, false); + return true; } - - diff --git a/indra/newview/llfloateravatar.h b/indra/newview/llfloateravatarwelcomepack.h index fb591c8306..a332d46708 100644 --- a/indra/newview/llfloateravatar.h +++ b/indra/newview/llfloateravatarwelcomepack.h @@ -1,7 +1,7 @@ /** - * @file llfloateravatar.h - * @author Leyla Farazha - * @brief floater for the avatar changer + * @file llfloateravatarwelcomepack.h + * @author Callum Prentice (callum@lindenlab.com) + * @brief Floater container for the Avatar Welcome Pack we app * * $LicenseInfo:firstyear=2011&license=viewerlgpl$ * Second Life Viewer Source Code @@ -25,22 +25,21 @@ * $/LicenseInfo$ */ -#ifndef LL_FLOATER_AVATAR_H -#define LL_FLOATER_AVATAR_H +#pragma once #include "llfloater.h" + class LLMediaCtrl; -class LLFloaterAvatar: +class LLFloaterAvatarWelcomePack: public LLFloater { friend class LLFloaterReg; -private: - LLFloaterAvatar(const LLSD& key); - ~LLFloaterAvatar(); - bool postBuild() override; - LLMediaCtrl* mAvatarPicker; -}; + private: + LLFloaterAvatarWelcomePack(const LLSD& key); + ~LLFloaterAvatarWelcomePack(); + bool postBuild() override; -#endif + LLMediaCtrl* mAvatarPicker; +}; diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index c09c02d32b..74c5079268 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -89,9 +89,17 @@ bool LLFloaterBulkPermission::postBuild() { mBulkChangeNextOwnerTransfer = true; } + + mQueueOutputList = getChild<LLScrollListCtrl>("queue output"); return true; } +void LLFloaterBulkPermission::onClose(bool app_quitting) +{ + removeVOInventoryListener(); + LLFloater::onClose(app_quitting); +} + void LLFloaterBulkPermission::doApply() { // Inspects a stream of selected object contents and adds modifiable ones to the given array. @@ -216,7 +224,7 @@ void LLFloaterBulkPermission::onCommitCopy() bool LLFloaterBulkPermission::start() { // note: number of top-level objects to modify is mObjectIDs.size(). - getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("start_text")); + mQueueOutputList->setCommentText(getString("start_text")); return nextObject(); } @@ -239,7 +247,7 @@ bool LLFloaterBulkPermission::nextObject() if(isDone() && !mDone) { - getChild<LLScrollListCtrl>("queue output")->setCommentText(getString("done_text")); + mQueueOutputList->setCommentText(getString("done_text")); mDone = true; } return successful_start; @@ -294,8 +302,6 @@ void LLFloaterBulkPermission::doCheckUncheckAll(bool check) void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInventoryObject::object_list_t* inv) { - LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output"); - LLInventoryObject::object_list_t::const_iterator it = inv->begin(); LLInventoryObject::object_list_t::const_iterator end = inv->end(); for ( ; it != end; ++it) @@ -362,7 +368,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve status_text.setArg("[STATUS]", ""); } - list->setCommentText(status_text.getString()); + mQueueOutputList->setCommentText(status_text.getString()); //TODO if we are an object inside an object we should check a recuse flag and if set //open the inventory of the object and recurse - Michelle2 Zenovka diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h index 23ca45b611..0b61022e0c 100644 --- a/indra/newview/llfloaterbulkpermission.h +++ b/indra/newview/llfloaterbulkpermission.h @@ -41,7 +41,8 @@ class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener friend class LLFloaterReg; public: - bool postBuild(); + bool postBuild() override; + void onClose(bool app_quitting) override; private: @@ -57,7 +58,7 @@ private: /*virtual*/ void inventoryChanged(LLViewerObject* obj, LLInventoryObject::object_list_t* inv, S32 serial_num, - void* queue); + void* queue) override; // This is called by inventoryChanged void handleInventory(LLViewerObject* viewer_obj, @@ -85,7 +86,7 @@ private: private: // UI - LLScrollListCtrl* mMessages; + LLScrollListCtrl* mQueueOutputList = nullptr; LLButton* mCloseBtn; // Object Queue diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index b94c31ec04..392079efe4 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -118,8 +118,8 @@ std::string STATUS[] = //----------------------------------------------------------------------------- // LLFloaterBvhPreview() //----------------------------------------------------------------------------- -LLFloaterBvhPreview::LLFloaterBvhPreview(const std::string& filename) : - LLFloaterNameDesc(filename) +LLFloaterBvhPreview::LLFloaterBvhPreview(const LLSD& args) : + LLFloaterNameDesc(args) { mLastMouseX = 0; mLastMouseY = 0; @@ -179,7 +179,7 @@ void LLFloaterBvhPreview::setAnimCallbacks() getChild<LLUICtrl>("ease_out_time")->setValidateBeforeCommit( boost::bind(&LLFloaterBvhPreview::validateEaseOut, this, _1)); } -std::map <std::string, std::string> LLFloaterBvhPreview::getJointAliases() +std::map<std::string, std::string, std::less<>> LLFloaterBvhPreview::getJointAliases() { LLPointer<LLVOAvatar> av = (LLVOAvatar*)mAnimPreview->getDummyAvatar(); return av->getJointAliases(); @@ -252,7 +252,7 @@ bool LLFloaterBvhPreview::postBuild() ELoadStatus load_status = E_ST_OK; S32 line_number = 0; - std::map<std::string, std::string> joint_alias_map = getJointAliases(); + auto joint_alias_map = getJointAliases(); loaderp = new LLBVHLoader(file_buffer, load_status, line_number, joint_alias_map); std::string status = getString(STATUS[load_status]); @@ -1028,7 +1028,8 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata) LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost)); + expected_upload_cost, + floaterp->mDestinationFolderId)); upload_new_resource(assetUploadInfo); } diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h index ae64521492..1eb7f686fd 100644 --- a/indra/newview/llfloaterbvhpreview.h +++ b/indra/newview/llfloaterbvhpreview.h @@ -70,7 +70,7 @@ protected: class LLFloaterBvhPreview : public LLFloaterNameDesc { public: - LLFloaterBvhPreview(const std::string& filename); + LLFloaterBvhPreview(const LLSD& args); virtual ~LLFloaterBvhPreview(); bool postBuild(); @@ -108,7 +108,7 @@ public: S32 status, LLExtStat ext_status); private: void setAnimCallbacks() ; - std::map <std::string, std::string> getJointAliases(); + std::map<std::string, std::string, std::less<>> getJointAliases(); protected: diff --git a/indra/newview/llfloaterchatmentionpicker.cpp b/indra/newview/llfloaterchatmentionpicker.cpp new file mode 100644 index 0000000000..a3eb286375 --- /dev/null +++ b/indra/newview/llfloaterchatmentionpicker.cpp @@ -0,0 +1,184 @@ +/** + * @file llfloaterchatmentionpicker.cpp + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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 "llfloaterchatmentionpicker.h" + +#include "llavatarlist.h" +#include "llfloaterimcontainer.h" +#include "llchatmentionhelper.h" +#include "llparticipantlist.h" + +LLUUID LLFloaterChatMentionPicker::sSessionID(LLUUID::null); + +LLFloaterChatMentionPicker::LLFloaterChatMentionPicker(const LLSD& key) +: LLFloater(key), mAvatarList(NULL) +{ + // This floater should hover on top of our dependent (with the dependent having the focus) + setFocusStealsFrontmost(false); + setBackgroundVisible(false); + setAutoFocus(false); +} + +bool LLFloaterChatMentionPicker::postBuild() +{ + mAvatarList = getChild<LLAvatarList>("avatar_list"); + mAvatarList->setShowCompleteName(true, true); + mAvatarList->setFocusOnItemClicked(false); + mAvatarList->setItemClickedCallback([this](LLUICtrl* ctrl, S32 x, S32 y, MASK mask) + { + if (LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl)) + { + selectResident(item->getAvatarId()); + } + }); + mAvatarList->setRefreshCompleteCallback([this](LLUICtrl* ctrl, const LLSD& param) + { + if (mAvatarList->numSelected() == 0) + { + mAvatarList->selectFirstItem(); + } + }); + + return LLFloater::postBuild(); +} + +void LLFloaterChatMentionPicker::onOpen(const LLSD& key) +{ + buildAvatarList(); + mAvatarList->setNameFilter(key.has("av_name") ? key["av_name"].asString() : ""); + + gFloaterView->adjustToFitScreen(this, false); +} + +uuid_vec_t LLFloaterChatMentionPicker::getParticipantIds() +{ + LLParticipantList* item = dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(sSessionID)); + if (!item) + { + LL_WARNS() << "Participant list is missing" << LL_ENDL; + return {}; + } + + uuid_vec_t avatar_ids; + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); + while (current_participant_model != end_participant_model) + { + LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get()); + if (participant_model) + { + avatar_ids.push_back(participant_model->getUUID()); + } + current_participant_model++; + } + return avatar_ids; +} + +void LLFloaterChatMentionPicker::buildAvatarList() +{ + uuid_vec_t& avatar_ids = mAvatarList->getIDs(); + avatar_ids = getParticipantIds(); + updateAvatarList(avatar_ids); + mAvatarList->setDirty(); +} + +void LLFloaterChatMentionPicker::selectResident(const LLUUID& id) +{ + if (id.isNull()) + return; + + setValue(stringize("secondlife:///app/agent/", id.asString(), "/mention ")); + onCommit(); + LLChatMentionHelper::instance().hideHelper(); +} + +void LLFloaterChatMentionPicker::onClose(bool app_quitting) +{ + if (!app_quitting) + { + LLChatMentionHelper::instance().hideHelper(); + } +} + +bool LLFloaterChatMentionPicker::handleKey(KEY key, MASK mask, bool called_from_parent) +{ + if (mask == MASK_NONE) + { + switch (key) + { + case KEY_UP: + case KEY_DOWN: + return mAvatarList->handleKey(key, mask, called_from_parent); + case KEY_RETURN: + case KEY_TAB: + selectResident(mAvatarList->getSelectedUUID()); + return true; + case KEY_ESCAPE: + LLChatMentionHelper::instance().hideHelper(); + return true; + case KEY_LEFT: + case KEY_RIGHT: + return true; + default: + break; + } + } + return LLFloater::handleKey(key, mask, called_from_parent); +} + +void LLFloaterChatMentionPicker::goneFromFront() +{ + LLChatMentionHelper::instance().hideHelper(); +} + +void LLFloaterChatMentionPicker::updateSessionID(LLUUID session_id) +{ + sSessionID = session_id; + + LLParticipantList* item = dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(sSessionID)); + if (!item) + { + LL_WARNS() << "Participant list is missing" << LL_ENDL; + return; + } + + uuid_vec_t avatar_ids = getParticipantIds(); + updateAvatarList(avatar_ids); +} + +void LLFloaterChatMentionPicker::updateAvatarList(uuid_vec_t& avatar_ids) +{ + std::vector<std::string> av_names; + for (auto& id : avatar_ids) + { + LLAvatarName av_name; + LLAvatarNameCache::get(id, &av_name); + av_names.push_back(utf8str_tolower(av_name.getAccountName())); + av_names.push_back(utf8str_tolower(av_name.getDisplayName())); + } + LLChatMentionHelper::instance().updateAvatarList(av_names); +} diff --git a/indra/newview/llfloaterchatmentionpicker.h b/indra/newview/llfloaterchatmentionpicker.h new file mode 100644 index 0000000000..8d221d7a89 --- /dev/null +++ b/indra/newview/llfloaterchatmentionpicker.h @@ -0,0 +1,58 @@ +/** + * @file llfloaterchatmentionpicker.h + * + * $LicenseInfo:firstyear=2025&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2025, 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 LLFLOATERCHATMENTIONPICKER_H +#define LLFLOATERCHATMENTIONPICKER_H + +#include "llfloater.h" + +class LLAvatarList; + +class LLFloaterChatMentionPicker : public LLFloater +{ +public: + LLFloaterChatMentionPicker(const LLSD& key); + + virtual bool postBuild() override; + virtual void goneFromFront() override; + + void buildAvatarList(); + + static uuid_vec_t getParticipantIds(); + static void updateSessionID(LLUUID session_id); + static void updateAvatarList(uuid_vec_t& avatar_ids); + +private: + + void onOpen(const LLSD& key) override; + void onClose(bool app_quitting) override; + virtual bool handleKey(KEY key, MASK mask, bool called_from_parent) override; + void selectResident(const LLUUID& id); + + static LLUUID sSessionID; + LLAvatarList* mAvatarList; +}; + +#endif diff --git a/indra/newview/llfloatereditenvironmentbase.h b/indra/newview/llfloatereditenvironmentbase.h index 37fda5d33e..41192f3d30 100644 --- a/indra/newview/llfloatereditenvironmentbase.h +++ b/indra/newview/llfloatereditenvironmentbase.h @@ -133,7 +133,8 @@ protected: LLSettingsEditPanel() : LLPanel(), mIsDirty(false), - mOnDirtyChanged() + mOnDirtyChanged(), + mCanEdit(false) {} private: diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 42307dd3f8..0a8b8d321d 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -495,7 +495,6 @@ void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday) updateEditEnvironment(); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT); - LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); synchronizeTabs(); updateTabs(); refresh(); @@ -824,7 +823,6 @@ void LLFloaterEditExtDayCycle::onClearTrack() updateEditEnvironment(); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT); - LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT); synchronizeTabs(); updateTabs(); refresh(); diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp index 35f8340997..4825cbf7fb 100644 --- a/indra/newview/llfloaterenvironmentadjust.cpp +++ b/indra/newview/llfloaterenvironmentadjust.cpp @@ -242,9 +242,7 @@ void LLFloaterEnvironmentAdjust::captureCurrentEnvironment() environment.setEnvironment(LLEnvironment::ENV_LOCAL, mLiveSky, FLOATER_ENVIRONMENT_UPDATE); environment.setEnvironment(LLEnvironment::ENV_LOCAL, mLiveWater, FLOATER_ENVIRONMENT_UPDATE); } - environment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - environment.updateEnvironment(LLEnvironment::TRANSITION_INSTANT); - + environment.setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); } void LLFloaterEnvironmentAdjust::onButtonReset() @@ -258,7 +256,6 @@ void LLFloaterEnvironmentAdjust::onButtonReset() this->closeFloater(); LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL); LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); - LLEnvironment::instance().updateEnvironment(); } }); @@ -455,9 +452,29 @@ void LLFloaterEnvironmentAdjust::onMoonAzimElevChanged() void LLFloaterEnvironmentAdjust::onCloudMapChanged() { if (!mLiveSky) + { return; - mLiveSky->setCloudNoiseTextureId(getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->getValue().asUUID()); - mLiveSky->update(); + } + + LLTextureCtrl* picker_ctrl = getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP); + + LLUUID new_texture_id = picker_ctrl->getValue().asUUID(); + + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); + + LLSettingsSky::ptr_t sky_to_set = mLiveSky->buildClone(); + if (!sky_to_set) + { + return; + } + + sky_to_set->setCloudNoiseTextureId(new_texture_id); + + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, sky_to_set); + + LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true); + + picker_ctrl->setValue(new_texture_id); } void LLFloaterEnvironmentAdjust::onWaterMapChanged() diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 989e1d8d04..44e71e33f3 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -32,6 +32,7 @@ #include "llimagetga.h" #include "llimagejpeg.h" #include "llimagepng.h" +#include "llimagej2c.h" #include "llagent.h" #include "llagentbenefits.h" @@ -43,6 +44,10 @@ #include "llrender.h" #include "llface.h" #include "llfocusmgr.h" +#include "llfilesystem.h" +#include "llfloaterperms.h" +#include "llnotificationsutil.h" +#include "llstatusbar.h" // can_afford_transaction() #include "lltextbox.h" #include "lltoolmgr.h" #include "llui.h" @@ -52,6 +57,7 @@ #include "llvoavatar.h" #include "pipeline.h" #include "lluictrlfactory.h" +#include "llviewermenufile.h" // upload_new_resource() #include "llviewershadermgr.h" #include "llviewertexturelist.h" #include "llstring.h" @@ -72,8 +78,8 @@ const S32 PREVIEW_TEXTURE_HEIGHT = 320; //----------------------------------------------------------------------------- // LLFloaterImagePreview() //----------------------------------------------------------------------------- -LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) : - LLFloaterNameDesc(filename), +LLFloaterImagePreview::LLFloaterImagePreview(const LLSD& args) : + LLFloaterNameDesc(args), mAvatarPreview(NULL), mSculptedPreview(NULL), @@ -140,7 +146,7 @@ bool LLFloaterImagePreview::postBuild() } } - getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); + getChild<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnOK, this)); return true; } @@ -244,6 +250,61 @@ void LLFloaterImagePreview::clearAllPreviewTextures() } //----------------------------------------------------------------------------- +// onBtnOK() +//----------------------------------------------------------------------------- +void LLFloaterImagePreview::onBtnOK() +{ + getChildView("ok_btn")->setEnabled(false); // don't allow inadvertent extra uploads + + S32 expected_upload_cost = getExpectedUploadCost(); + if (can_afford_transaction(expected_upload_cost)) + { + LL_INFOS() << "saving texture: " << mRawImagep->getWidth() << "x" << mRawImagep->getHeight() << LL_ENDL; + // gen a new uuid for this asset + LLTransactionID tid; + tid.generate(); + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + + LLPointer<LLImageJ2C> formatted = new LLImageJ2C; + + if (formatted->encode(mRawImagep, 0.0f)) + { + LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE); + fmt_file.write(formatted->getData(), formatted->getDataSize()); + + LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( + tid, LLAssetType::AT_TEXTURE, + getChild<LLUICtrl>("name_form")->getValue().asString(), + getChild<LLUICtrl>("description_form")->getValue().asString(), + 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost + )); + + upload_new_resource(assetUploadInfo); + } + else + { + LLSD args; + args["REASON"] = LLImage::getLastThreadError(); + LLNotificationsUtil::add("ErrorEncodingImage", args); + LL_WARNS() << "Error encoding image" << LL_ENDL; + } + } + else + { + LLSD args; + args["COST"] = llformat("%d", expected_upload_cost); + LLNotificationsUtil::add("ErrorCannotAffordUpload", args); + } + + closeFloater(false); +} + +//----------------------------------------------------------------------------- // draw() //----------------------------------------------------------------------------- void LLFloaterImagePreview::draw() @@ -364,14 +425,13 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) return false; } - S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); - S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); + // raw image is limited to 256MB so need at least some upper limit that fits into that + constexpr S32 MAX_IMAGE_AREA = 8096 * 8096; - if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) + if (image_info.getWidth() * image_info.getHeight() > MAX_IMAGE_AREA) { LLStringUtil::format_map_t args; - args["WIDTH"] = llformat("%d", max_width); - args["HEIGHT"] = llformat("%d", max_height); + args["PIXELS"] = llformat("%dM", (S32)(MAX_IMAGE_AREA / 1000000)); mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); return false; @@ -399,6 +459,46 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) image->setLastError("Image files with less than 3 or more than 4 components are not supported."); return false; } + // Downscale images to fit the max_texture_dimensions_* + S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); + S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); + + S32 orig_width = raw_image->getWidth(); + S32 orig_height = raw_image->getHeight(); + + if (orig_width > max_width || orig_height > max_height) + { + // Calculate scale factors + F32 width_scale = (F32)max_width / (F32)orig_width; + F32 height_scale = (F32)max_height / (F32)orig_height; + F32 scale = llmin(width_scale, height_scale); + + // Calculate new dimensions, preserving aspect ratio + S32 new_width = LLImageRaw::contractDimToPowerOfTwo( + llclamp((S32)llroundf(orig_width * scale), 4, max_width) + ); + S32 new_height = LLImageRaw::contractDimToPowerOfTwo( + llclamp((S32)llroundf(orig_height * scale), 4, max_height) + ); + + if (!raw_image->scale(new_width, new_height)) + { + LL_WARNS() << "Failed to scale image from " + << orig_width << "x" << orig_height + << " to " << new_width << "x" << new_height << LL_ENDL; + return false; + } + + // Inform the resident about the resized image + LLSD subs; + subs["[ORIGINAL_WIDTH]"] = orig_width; + subs["[ORIGINAL_HEIGHT]"] = orig_height; + subs["[NEW_WIDTH]"] = new_width; + subs["[NEW_HEIGHT]"] = new_height; + subs["[MAX_WIDTH]"] = max_width; + subs["[MAX_HEIGHT]"] = max_height; + LLNotificationsUtil::add("ImageUploadResized", subs); + } raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); mRawImagep = raw_image; diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index ed395722de..5e5f4932c2 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -110,7 +110,7 @@ protected: class LLFloaterImagePreview : public LLFloaterNameDesc { public: - LLFloaterImagePreview(const std::string& filename); + LLFloaterImagePreview(const LLSD& args); virtual ~LLFloaterImagePreview(); bool postBuild() override; @@ -126,6 +126,8 @@ public: void clearAllPreviewTextures(); + void onBtnOK(); + protected: static void onPreviewTypeCommit(LLUICtrl*,void*); void draw() override; diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index e4b14d8df6..d821d9a4a5 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -460,7 +460,7 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate() LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd(); while (current_participant_model != end_participant_model) { - LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); + LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get()); if (participant_model) { // Get the avatar name for this participant id from the cache and update the model @@ -511,7 +511,7 @@ void LLFloaterIMContainer::idleUpdate() bool can_ban = haveAbilityToBan(); while (current_participant_model != end_participant_model) { - LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); + LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get()); if (participant_model) { participant_model->setModeratorOptionsVisible(is_moderator); @@ -1540,6 +1540,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v // Beyond that point, if only the user agent is selected, everything is disabled if (is_single_select && (single_id == gAgentID)) { + if ("can_zoom_in" == item) + { + return true; + } if (is_moderator_option) { return enableModerateContextMenuItem(item, true); @@ -1874,7 +1878,7 @@ LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); while (current_participant_model != end_participant_model) { - LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model); + LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get()); LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model); participant_view->addToFolder(widget); current_participant_model++; @@ -2302,14 +2306,14 @@ bool LLFloaterIMContainer::isConversationLoggingAllowed() return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0; } -void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes) +void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes, bool alternate_color) { //Finds the conversation line item to flash using the session_id LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id)); if (widget) { - widget->setFlashState(is_flashes); + widget->setFlashState(is_flashes, alternate_color); } } diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index e5486e67da..30eed8be36 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -208,7 +208,7 @@ public: void reSelectConversation(); void updateSpeakBtnState(); static bool isConversationLoggingAllowed(); - void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes); + void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes, bool alternate_color = false); void highlightConversationItemWidget(const LLUUID& session_id, bool is_highlighted); bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget); boost::signals2::connection mMicroChangedSignal; diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index db6f9ac22a..b649514bff 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -586,7 +586,7 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type ) { if (mInputEditor) { - LLWString text = mInputEditor->getWText(); + LLWString text = mInputEditor->getConvertedText(); LLWStringUtil::trim(text); LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines. if (!text.empty()) diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 185274981b..84a9fad708 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -251,7 +251,7 @@ void LLFloaterIMSession::sendMsgFromInputEditor() { if (mInputEditor) { - LLWString text = mInputEditor->getWText(); + LLWString text = mInputEditor->getConvertedText(); LLWStringUtil::trim(text); LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines. if(!text.empty()) diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 50e765c236..e03422780a 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -35,6 +35,7 @@ #include "llavatariconctrl.h" #include "llchatentry.h" #include "llchathistory.h" +#include "llfloaterchatmentionpicker.h" #include "llchiclet.h" #include "llchicletbar.h" #include "lldraghandle.h" @@ -105,26 +106,7 @@ LLFloaterIMSessionTab::~LLFloaterIMSessionTab() { delete mRefreshTimer; LLIMMgr::instance().removeSessionObserver(this); - - LLFloaterIMContainer* im_container = LLFloaterIMContainer::findInstance(); - if (im_container) - { - LLParticipantList* session = dynamic_cast<LLParticipantList*>(im_container->getSessionModel(mSessionID)); - if (session) - { - for (const conversations_widgets_map::value_type& widget_pair : mConversationsWidgets) - { - LLFolderViewItem* widget = widget_pair.second; - LLFolderViewModelItem* item_vmi = widget->getViewModelItem(); - if (item_vmi && item_vmi->getNumRefs() == 1) - { - // This is the last pointer, remove participant from session - // before participant gets deleted on destroyView. - session->removeChild(item_vmi); - } - } - } - } + mEmojiCloseConn.disconnect(); } // static @@ -485,6 +467,7 @@ void LLFloaterIMSessionTab::onFocusReceived() LLIMModel::instance().sendNoUnreadMessages(mSessionID); } + LLFloaterChatMentionPicker::updateSessionID(mSessionID); super::onFocusReceived(); } @@ -727,7 +710,7 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant() LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd(); while (current_participant_model != end_participant_model) { - LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model); + LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>((*current_participant_model).get()); if (participant_model) { addConversationViewParticipant(participant_model); @@ -771,27 +754,6 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id); if (widget) { - LLFolderViewModelItem* item_vmi = widget->getViewModelItem(); - if (item_vmi && item_vmi->getNumRefs() == 1) - { - // This is the last pointer, remove participant from session - // before participant gets deleted on destroyView. - // - // Floater (widget) and participant's view can simultaneously - // co-own the model, in which case view is responsible for - // the deletion and floater is free to clear and recreate - // the list, yet there are cases where only widget owns - // the pointer so it should do the cleanup. - // See "add_participant". - // - // Todo: If it keeps causing issues turn participants - // into LLPointers in the session - LLParticipantList* session = getParticipantList(); - if (session) - { - session->removeChild(item_vmi); - } - } widget->destroyView(); } mConversationsWidgets.erase(participant_id); @@ -857,7 +819,7 @@ void LLFloaterIMSessionTab::refreshConversation() LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID); while (current_participant_model != end_participant_model) { - LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); + LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>((*current_participant_model).get()); if (speaker_mgr && participant_model) { LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID()); diff --git a/indra/newview/llfloaterinventorysettings.cpp b/indra/newview/llfloaterinventorysettings.cpp index e5ee69f240..aab632bcb8 100644 --- a/indra/newview/llfloaterinventorysettings.cpp +++ b/indra/newview/llfloaterinventorysettings.cpp @@ -28,9 +28,14 @@ #include "llfloaterinventorysettings.h" +#include "llcolorswatch.h" +#include "llviewercontrol.h" + LLFloaterInventorySettings::LLFloaterInventorySettings(const LLSD& key) : LLFloater(key) { + mCommitCallbackRegistrar.add("ScriptPref.applyUIColor", boost::bind(&LLFloaterInventorySettings::applyUIColor, this, _1, _2)); + mCommitCallbackRegistrar.add("ScriptPref.getUIColor", boost::bind(&LLFloaterInventorySettings::getUIColor, this, _1, _2)); } LLFloaterInventorySettings::~LLFloaterInventorySettings() @@ -39,6 +44,29 @@ LLFloaterInventorySettings::~LLFloaterInventorySettings() bool LLFloaterInventorySettings::postBuild() { getChild<LLButton>("ok_btn")->setCommitCallback(boost::bind(&LLFloater::closeFloater, this, false)); + + getChild<LLUICtrl>("favorites_color")->setCommitCallback(boost::bind(&LLFloaterInventorySettings::updateColorSwatch, this)); + + bool enable_color = gSavedSettings.getBOOL("InventoryFavoritesColorText"); + getChild<LLUICtrl>("favorites_swatch")->setEnabled(enable_color); + return true; } +void LLFloaterInventorySettings::updateColorSwatch() +{ + bool val = getChild<LLUICtrl>("favorites_color")->getValue(); + getChild<LLUICtrl>("favorites_swatch")->setEnabled(val); +} + +void LLFloaterInventorySettings::applyUIColor(LLUICtrl* ctrl, const LLSD& param) +{ + LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue())); +} + +void LLFloaterInventorySettings::getUIColor(LLUICtrl* ctrl, const LLSD& param) +{ + LLColorSwatchCtrl* color_swatch = (LLColorSwatchCtrl*)ctrl; + color_swatch->setOriginal(LLUIColorTable::instance().getColor(param.asString())); +} + diff --git a/indra/newview/llfloaterinventorysettings.h b/indra/newview/llfloaterinventorysettings.h index 3fe3a001b9..c27d5d2e1b 100644 --- a/indra/newview/llfloaterinventorysettings.h +++ b/indra/newview/llfloaterinventorysettings.h @@ -40,6 +40,11 @@ public: private: LLFloaterInventorySettings(const LLSD& key); ~LLFloaterInventorySettings(); + + void updateColorSwatch(); + + void applyUIColor(LLUICtrl* ctrl, const LLSD& param); + void getUIColor(LLUICtrl* ctrl, const LLSD& param); }; #endif diff --git a/indra/newview/llfloatermediasettings.cpp b/indra/newview/llfloatermediasettings.cpp index 2496887c9d..81eab52e6c 100644 --- a/indra/newview/llfloatermediasettings.cpp +++ b/indra/newview/llfloatermediasettings.cpp @@ -180,8 +180,15 @@ void LLFloaterMediaSettings::onClose(bool app_quitting) //////////////////////////////////////////////////////////////////////////////// //static -void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable ) +void LLFloaterMediaSettings::initValues( const LLSD& media_settings, bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media) { + if (!sInstance) + { + return; + } + sInstance->mIdenticalHasMediaInfo = has_media_info; + sInstance->mMultipleMedia = multiple_media; + sInstance->mMultipleValidMedia = multiple_valid_media; if (sInstance->hasFocus()) return; // Clear values diff --git a/indra/newview/llfloatermediasettings.h b/indra/newview/llfloatermediasettings.h index 38730ddc98..7ed7ab246f 100644 --- a/indra/newview/llfloatermediasettings.h +++ b/indra/newview/llfloatermediasettings.h @@ -48,7 +48,7 @@ public: static LLFloaterMediaSettings* getInstance(); static bool instanceExists(); static void apply(); - static void initValues( const LLSD& media_settings , bool editable); + static void initValues( const LLSD& media_settings , bool editable, bool has_media_info, bool multiple_media, bool multiple_valid_media); static void clearValues( bool editable); LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;}; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 8332a430e6..6a6766fb3f 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -64,6 +64,7 @@ #include "llcallbacklist.h" #include "llviewertexteditor.h" #include "llviewernetwork.h" +#include "llmaterialeditor.h" //static @@ -349,14 +350,14 @@ void LLFloaterModelPreview::initModelPreview() } //static -bool LLFloaterModelPreview::showModelPreview() +void LLFloaterModelPreview::showModelPreview(const LLUUID& dest_folder) { LLFloaterModelPreview* fmp = (LLFloaterModelPreview*)LLFloaterReg::getInstance("upload_model"); if (fmp && !fmp->isModelLoading()) { + fmp->setUploadDestination(dest_folder); fmp->loadHighLodModel(); } - return true; } void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl) @@ -505,7 +506,7 @@ void LLFloaterModelPreview::onClickCalculateBtn() gMeshRepo.uploadModel(mModelPreview->mUploadData, mModelPreview->mPreviewScale, childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, - mUploadModelUrl, false, + mUploadModelUrl, mDestinationFolderId, false, getWholeModelFeeObserverHandle()); toggleCalculateButton(false); @@ -619,11 +620,9 @@ void LLFloaterModelPreview::onJointListSelection() LLPanel *panel = mTabContainer->getPanelByName("rigging_panel"); LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list"); LLScrollListCtrl *joints_pos = panel->getChild<LLScrollListCtrl>("pos_overrides_list"); - LLScrollListCtrl *joints_scale = panel->getChild<LLScrollListCtrl>("scale_overrides_list"); LLTextBox *joint_pos_descr = panel->getChild<LLTextBox>("pos_overrides_descr"); joints_pos->deleteAllItems(); - joints_scale->deleteAllItems(); LLScrollListItem *selected = joints_list->getFirstSelected(); if (selected) @@ -1341,26 +1340,26 @@ void LLFloaterModelPreview::addStringToLog(const std::string& message, const LLS { std::string str; switch (lod) -{ + { case LLModel::LOD_IMPOSTOR: str = "LOD0 "; break; case LLModel::LOD_LOW: str = "LOD1 "; break; case LLModel::LOD_MEDIUM: str = "LOD2 "; break; case LLModel::LOD_PHYSICS: str = "PHYS "; break; case LLModel::LOD_HIGH: str = "LOD3 "; break; default: break; -} + } LLStringUtil::format_map_t args_msg; LLSD::map_const_iterator iter = args.beginMap(); LLSD::map_const_iterator end = args.endMap(); for (; iter != end; ++iter) -{ + { args_msg[iter->first] = iter->second.asString(); } str += sInstance->getString(message, args_msg); sInstance->addStringToLogTab(str, flash); } - } +} // static void LLFloaterModelPreview::addStringToLog(const std::string& str, bool flash) @@ -1488,7 +1487,7 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides) { // Populate table - std::map<std::string, std::string> joint_alias_map; + std::map<std::string, std::string, std::less<>> joint_alias_map; mModelPreview->getJointAliases(joint_alias_map); S32 conflicts = 0; @@ -1660,7 +1659,7 @@ void LLFloaterModelPreview::onUpload(void* user_data) gMeshRepo.uploadModel(mp->mModelPreview->mUploadData, mp->mModelPreview->mPreviewScale, mp->childGetValue("upload_textures").asBoolean(), upload_skinweights, upload_joint_positions, lock_scale_if_joint_position, - mp->mUploadModelUrl, + mp->mUploadModelUrl, mp->mDestinationFolderId, true, LLHandle<LLWholeModelFeeObserver>(), mp->getWholeModelUploadObserverHandle()); } @@ -1770,9 +1769,15 @@ void LLFloaterModelPreview::onLoDSourceCommit(S32 lod) if (index == LLModelPreview::MESH_OPTIMIZER_AUTO || index == LLModelPreview::MESH_OPTIMIZER_SLOPPY || index == LLModelPreview::MESH_OPTIMIZER_PRECISE) - { //rebuild LoD to update triangle counts + { + // rebuild LoD to update triangle counts onLODParamCommit(lod, true); } + if (index == LLModelPreview::USE_LOD_ABOVE) + { + // refresh to pick triangle counts + mModelPreview->mDirty = true; + } } void LLFloaterModelPreview::resetDisplayOptions() diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 6adc084fe8..7b652a3613 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -73,7 +73,8 @@ public: /*virtual*/ void reshape(S32 width, S32 height, bool called_from_parent = true); void initModelPreview(); - static bool showModelPreview(); + void setUploadDestination(const LLUUID& dest_folder) { mDestinationFolderId = dest_folder; } + static void showModelPreview(const LLUUID& dest_folder = LLUUID::null); bool handleMouseDown(S32 x, S32 y, MASK mask); bool handleMouseUp(S32 x, S32 y, MASK mask); @@ -164,9 +165,6 @@ protected: static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata); - static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata); - static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata); - static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata); void draw(); @@ -225,6 +223,7 @@ private: void createSmoothComboBox(LLComboBox* combo_box, float min, float max); + LLUUID mDestinationFolderId; LLButton* mUploadBtn; LLButton* mCalculateBtn; LLViewerTextEditor* mUploadLogText; diff --git a/indra/newview/llfloatermyenvironment.cpp b/indra/newview/llfloatermyenvironment.cpp index 891e16a8ef..c0405c106e 100644 --- a/indra/newview/llfloatermyenvironment.cpp +++ b/indra/newview/llfloatermyenvironment.cpp @@ -38,7 +38,9 @@ #include "llcheckboxctrl.h" #include "llviewerinventory.h" #include "llenvironment.h" +#include "llnotificationsutil.h" #include "llparcel.h" +#include "lltrans.h" #include "llviewerparcelmgr.h" //========================================================================= @@ -223,16 +225,13 @@ void LLFloaterMyEnvironment::onFilterEdit(const std::string& search_string) mInventoryList->setFilterSubString(search_string); } -void LLFloaterMyEnvironment::onDeleteSelected() +void LLFloaterMyEnvironment::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, uuid_vec_t item_ids) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + if (option == 0) { - uuid_vec_t selected; - - getSelectedIds(selected); - if (selected.empty()) - return; - const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); - for (const LLUUID& itemid: selected) + for (const LLUUID& itemid : item_ids) { LLInventoryItem* inv_item = gInventory.getItem(itemid); @@ -253,6 +252,27 @@ void LLFloaterMyEnvironment::onDeleteSelected() } gInventory.notifyObservers(); } +} + +void LLFloaterMyEnvironment::onDeleteSelected() +{ + uuid_vec_t selected; + + getSelectedIds(selected); + if (selected.empty()) + return; + + LLSD args; + args["QUESTION"] = LLTrans::getString(selected.size() > 1 ? "DeleteItems" : "DeleteItem"); + LLNotificationsUtil::add( + "DeleteItems", + args, + LLSD(), + [this, selected](const LLSD& notification, const LLSD& response) + { + onItemsRemovalConfirmation(notification, response, selected); + }); +} void LLFloaterMyEnvironment::onDoCreate(const LLSD &data) @@ -318,13 +338,13 @@ bool LLFloaterMyEnvironment::canAction(const std::string &context) if (context == PARAMETER_EDIT) { - return (selected.size() == 1) && isSettingSelected(selected.front()); + return (selected.size() == 1) && isSettingId(selected.front()); } else if (context == PARAMETER_COPY) { for (std::vector<LLUUID>::iterator it = selected.begin(); it != selected.end(); it++) { - if(!isSettingSelected(*it)) + if(!isSettingId(*it)) { return false; } @@ -342,7 +362,7 @@ bool LLFloaterMyEnvironment::canAction(const std::string &context) LLClipboard::instance().pasteFromClipboard(ids); for (std::vector<LLUUID>::iterator it = ids.begin(); it != ids.end(); it++) { - if (!isSettingSelected(*it)) + if (!isSettingId(*it)) { return false; } @@ -351,7 +371,7 @@ bool LLFloaterMyEnvironment::canAction(const std::string &context) } else if (context == PARAMETER_COPYUUID) { - return (selected.size() == 1) && isSettingSelected(selected.front()); + return (selected.size() == 1) && isSettingId(selected.front()); } return false; @@ -367,16 +387,42 @@ bool LLFloaterMyEnvironment::canApply(const std::string &context) if (context == PARAMETER_REGION) { - return LLEnvironment::instance().canAgentUpdateRegionEnvironment(); + return isSettingId(selected.front()) && LLEnvironment::instance().canAgentUpdateRegionEnvironment(); } else if (context == PARAMETER_PARCEL) { - return LLEnvironment::instance().canAgentUpdateParcelEnvironment(); + return isSettingId(selected.front()) && LLEnvironment::instance().canAgentUpdateParcelEnvironment(); } - else + else if (context == PARAMETER_LOCAL) { - return (context == PARAMETER_LOCAL); + return isSettingId(selected.front()); } + + return false; +} + +bool can_delete(const LLUUID& id) +{ + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + if (id == trash_id || gInventory.isObjectDescendentOf(id, trash_id)) + { + return false; + } + + LLViewerInventoryCategory* cat = gInventory.getCategory(id); + if (cat) + { + if (!get_is_category_removable(&gInventory, id)) + { + return false; + } + } + else if (!get_is_item_removable(&gInventory, id, false)) + { + return false; + } + + return true; } //------------------------------------------------------------------------- @@ -389,7 +435,14 @@ void LLFloaterMyEnvironment::refreshButtonStates() getChild<LLUICtrl>(BUTTON_GEAR)->setEnabled(settings_ok); getChild<LLUICtrl>(BUTTON_NEWSETTINGS)->setEnabled(true); - getChild<LLUICtrl>(BUTTON_DELETE)->setEnabled(settings_ok && !selected.empty()); + + bool enable_delete = false; + if(settings_ok && !selected.empty()) + { + enable_delete = can_delete(selected.front()); + } + + getChild<LLUICtrl>(BUTTON_DELETE)->setEnabled(enable_delete); } //------------------------------------------------------------------------- @@ -438,7 +491,7 @@ LLUUID LLFloaterMyEnvironment::findItemByAssetId(LLUUID asset_id, bool copyable_ return LLUUID::null; } -bool LLFloaterMyEnvironment::isSettingSelected(LLUUID item_id) +bool LLFloaterMyEnvironment::isSettingId(const LLUUID& item_id) { LLInventoryItem* itemp = gInventory.getItem(item_id); diff --git a/indra/newview/llfloatermyenvironment.h b/indra/newview/llfloatermyenvironment.h index 8e81b8e5e2..c5d521d207 100644 --- a/indra/newview/llfloatermyenvironment.h +++ b/indra/newview/llfloatermyenvironment.h @@ -60,6 +60,7 @@ private: void onFilterCheckChange(); void onFilterEdit(const std::string& search_string); void onSelectionChange(); + void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, uuid_vec_t item_ids); void onDeleteSelected(); void onDoCreate(const LLSD &data); void onDoApply(const std::string &context); @@ -69,7 +70,7 @@ private: void getSelectedIds(uuid_vec_t& ids) const; void refreshButtonStates(); - bool isSettingSelected(LLUUID item_id); + static bool isSettingId(const LLUUID &item_id); static LLUUID findItemByAssetId(LLUUID asset_id, bool copyable_only, bool ignore_library); }; diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp index 01c50d89c5..569b41cfa9 100644 --- a/indra/newview/llfloaternamedesc.cpp +++ b/indra/newview/llfloaternamedesc.cpp @@ -62,11 +62,20 @@ const S32 PREVIEW_HPAD = PREVIEW_RESIZE_HANDLE_SIZE; //----------------------------------------------------------------------------- // LLFloaterNameDesc() //----------------------------------------------------------------------------- -LLFloaterNameDesc::LLFloaterNameDesc(const LLSD& filename ) - : LLFloater(filename), - mIsAudio(false) +LLFloaterNameDesc::LLFloaterNameDesc(const LLSD& args) + : LLFloater(args) + , mIsAudio(false) + , mIsText(false) { - mFilenameAndPath = filename.asString(); + if (args.isString()) + { + mFilenameAndPath = args.asString(); + } + else + { + mFilenameAndPath = args["filename"].asString(); + mDestinationFolderId = args["dest"].asUUID(); + } mFilename = gDirUtilp->getBaseFileName(mFilenameAndPath, false); } @@ -203,7 +212,8 @@ void LLFloaterNameDesc::onBtnOK( ) LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost)); + expected_upload_cost, + mDestinationFolderId)); upload_new_resource(uploadInfo, callback, nruserdata); } @@ -230,8 +240,8 @@ void LLFloaterNameDesc::onBtnCancel() // LLFloaterSoundPreview() //----------------------------------------------------------------------------- -LLFloaterSoundPreview::LLFloaterSoundPreview(const LLSD& filename ) - : LLFloaterNameDesc(filename) +LLFloaterSoundPreview::LLFloaterSoundPreview(const LLSD& args ) + : LLFloaterNameDesc(args) { mIsAudio = true; } @@ -251,8 +261,8 @@ bool LLFloaterSoundPreview::postBuild() // LLFloaterAnimPreview() //----------------------------------------------------------------------------- -LLFloaterAnimPreview::LLFloaterAnimPreview(const LLSD& filename ) - : LLFloaterNameDesc(filename) +LLFloaterAnimPreview::LLFloaterAnimPreview(const LLSD& args ) + : LLFloaterNameDesc(args) { } @@ -270,8 +280,8 @@ bool LLFloaterAnimPreview::postBuild() // LLFloaterScriptPreview() //----------------------------------------------------------------------------- -LLFloaterScriptPreview::LLFloaterScriptPreview(const LLSD& filename ) - : LLFloaterNameDesc(filename) +LLFloaterScriptPreview::LLFloaterScriptPreview(const LLSD& args ) + : LLFloaterNameDesc(args) { mIsText = true; } diff --git a/indra/newview/llfloaternamedesc.h b/indra/newview/llfloaternamedesc.h index aa5571ccc0..8c8ec49a8e 100644 --- a/indra/newview/llfloaternamedesc.h +++ b/indra/newview/llfloaternamedesc.h @@ -39,7 +39,7 @@ class LLRadioGroup; class LLFloaterNameDesc : public LLFloater { public: - LLFloaterNameDesc(const LLSD& filename); + LLFloaterNameDesc(const LLSD& args); virtual ~LLFloaterNameDesc(); bool postBuild() override; @@ -58,6 +58,7 @@ protected: std::string mFilenameAndPath; std::string mFilename; + LLUUID mDestinationFolderId; }; class LLFloaterSoundPreview : public LLFloaterNameDesc diff --git a/indra/newview/llfloaternewfeaturenotification.cpp b/indra/newview/llfloaternewfeaturenotification.cpp index 369727ff1e..1badcdd3d9 100644 --- a/indra/newview/llfloaternewfeaturenotification.cpp +++ b/indra/newview/llfloaternewfeaturenotification.cpp @@ -43,12 +43,28 @@ bool LLFloaterNewFeatureNotification::postBuild() setCanDrag(false); getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterNewFeatureNotification::onCloseBtn, this)); - const std::string title_txt = "title_txt"; - const std::string dsc_txt = "description_txt"; - std::string feature = "_" + getKey().asString(); + if (getKey().isString()) + { + const std::string title_txt = "title_txt"; + const std::string dsc_txt = "description_txt"; - getChild<LLUICtrl>(title_txt)->setValue(getString(title_txt + feature)); - getChild<LLUICtrl>(dsc_txt)->setValue(getString(dsc_txt + feature)); + std::string feature = "_" + getKey().asString(); + if (hasString(title_txt + feature)) + { + getChild<LLUICtrl>(title_txt)->setValue(getString(title_txt + feature)); + getChild<LLUICtrl>(dsc_txt)->setValue(getString(dsc_txt + feature)); + } + else + { + // Show blank + LL_WARNS() << "Feature \"" << getKey().asString() << "\" not found for feature notification" << LL_ENDL; + } + } + else + { + // Show blank + LL_WARNS() << "Feature notification without a feature" << LL_ENDL; + } if (getKey().asString() == "gltf") { diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp index 26b7304b9a..fa491a4b27 100644 --- a/indra/newview/llfloaterobjectweights.cpp +++ b/indra/newview/llfloaterobjectweights.cpp @@ -36,6 +36,14 @@ #include "llviewerparcelmgr.h" #include "llviewerregion.h" +static const std::string lod_strings[4] = +{ + "lowest_lod", + "low_lod", + "medium_lod", + "high_lod", +}; + // virtual bool LLCrossParcelFunctor::apply(LLViewerObject* obj) { @@ -75,7 +83,10 @@ LLFloaterObjectWeights::LLFloaterObjectWeights(const LLSD& key) mSelectedOnLand(NULL), mRezzedOnLand(NULL), mRemainingCapacity(NULL), - mTotalCapacity(NULL) + mTotalCapacity(NULL), + mLodLevel(nullptr), + mTrianglesShown(nullptr), + mPixelArea(nullptr) { } @@ -99,6 +110,10 @@ bool LLFloaterObjectWeights::postBuild() mRemainingCapacity = getChild<LLTextBox>("remaining_capacity"); mTotalCapacity = getChild<LLTextBox>("total_capacity"); + mLodLevel = getChild<LLTextBox>("lod_level"); + mTrianglesShown = getChild<LLTextBox>("triangles_shown"); + mPixelArea = getChild<LLTextBox>("pixel_area"); + return true; } @@ -135,6 +150,69 @@ void LLFloaterObjectWeights::setErrorStatus(S32 status, const std::string& reaso toggleWeightsLoadingIndicators(false); } +void LLFloaterObjectWeights::draw() +{ + // Normally it's a bad idea to set text and visibility inside draw + // since it can cause rect updates go to different, already drawn elements, + // but floater is very simple and these elements are supposed to be isolated + LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); + if (selection->isEmpty()) + { + const std::string text = getString("nothing_selected"); + mLodLevel->setText(text); + mTrianglesShown->setText(text); + mPixelArea->setText(text); + + toggleRenderLoadingIndicators(false); + } + else + { + S32 object_lod = -1; + bool multiple_lods = false; + S32 total_tris = 0; + F32 pixel_area = 0; + for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin(); + iter != selection->valid_root_end(); ++iter) + { + LLViewerObject* object = (*iter)->getObject(); + S32 lod = object->getLOD(); + if (object_lod < 0) + { + object_lod = lod; + } + else if (object_lod != lod) + { + multiple_lods = true; + } + + if (object->isRootEdit()) + { + total_tris += object->recursiveGetTriangleCount(); + pixel_area += object->getPixelArea(); + } + } + + if (multiple_lods) + { + mLodLevel->setText(getString("multiple_lods")); + toggleRenderLoadingIndicators(false); + } + else if (object_lod < 0) + { + // nodes are waiting for data + toggleRenderLoadingIndicators(true); + } + else + { + mLodLevel->setText(getString(lod_strings[object_lod])); + toggleRenderLoadingIndicators(false); + } + mTrianglesShown->setText(llformat("%d", total_tris)); + mPixelArea->setText(llformat("%d", pixel_area)); + } + LLFloater::draw(); +} + void LLFloaterObjectWeights::updateLandImpacts(const LLParcel* parcel) { if (!parcel || LLSelectMgr::getInstance()->getSelection()->isEmpty()) @@ -252,6 +330,17 @@ void LLFloaterObjectWeights::toggleLandImpactsLoadingIndicators(bool visible) mTotalCapacity->setVisible(!visible); } +void LLFloaterObjectWeights::toggleRenderLoadingIndicators(bool visible) +{ + childSetVisible("lod_level_loading_indicator", visible); + childSetVisible("triangles_shown_loading_indicator", visible); + childSetVisible("pixel_area_loading_indicator", visible); + + mLodLevel->setVisible(!visible); + mTrianglesShown->setVisible(!visible); + mPixelArea->setVisible(!visible); +} + void LLFloaterObjectWeights::updateIfNothingSelected() { const std::string text = getString("nothing_selected"); @@ -269,6 +358,11 @@ void LLFloaterObjectWeights::updateIfNothingSelected() mRemainingCapacity->setText(text); mTotalCapacity->setText(text); + mLodLevel->setText(text); + mTrianglesShown->setText(text); + mPixelArea->setText(text); + toggleWeightsLoadingIndicators(false); toggleLandImpactsLoadingIndicators(false); + toggleRenderLoadingIndicators(false); } diff --git a/indra/newview/llfloaterobjectweights.h b/indra/newview/llfloaterobjectweights.h index 3b999f6b9b..bda625564b 100644 --- a/indra/newview/llfloaterobjectweights.h +++ b/indra/newview/llfloaterobjectweights.h @@ -58,21 +58,24 @@ public: LLFloaterObjectWeights(const LLSD& key); ~LLFloaterObjectWeights(); - /*virtual*/ bool postBuild(); + bool postBuild() override; - /*virtual*/ void onOpen(const LLSD& key); + void onOpen(const LLSD& key) override; - /*virtual*/ void onWeightsUpdate(const SelectionCost& selection_cost); - /*virtual*/ void setErrorStatus(S32 status, const std::string& reason); + void onWeightsUpdate(const SelectionCost& selection_cost) override; + void setErrorStatus(S32 status, const std::string& reason) override; + + void draw() override; void updateLandImpacts(const LLParcel* parcel); - void refresh(); + void refresh() override; private: - /*virtual*/ void generateTransactionID(); + void generateTransactionID() override; void toggleWeightsLoadingIndicators(bool visible); void toggleLandImpactsLoadingIndicators(bool visible); + void toggleRenderLoadingIndicators(bool visible); void updateIfNothingSelected(); @@ -88,6 +91,10 @@ private: LLTextBox *mRezzedOnLand; LLTextBox *mRemainingCapacity; LLTextBox *mTotalCapacity; + + LLTextBox *mLodLevel; + LLTextBox *mTrianglesShown; + LLTextBox *mPixelArea; }; #endif //LL_LLFLOATEROBJECTWEIGHTS_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index fdac390e8a..b74736a39d 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -366,6 +366,11 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance())); mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this)); mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering +#ifdef LL_DISCORD + gSavedSettings.getControl("EnableDiscord")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); + gSavedSettings.getControl("ShowDiscordActivityDetails")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); + gSavedSettings.getControl("ShowDiscordActivityState")->getCommitSignal()->connect(boost::bind(&LLAppViewer::updateDiscordActivity)); +#endif } void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type ) @@ -523,6 +528,11 @@ bool LLFloaterPreference::postBuild() getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true); } +#ifndef LL_DISCORD + LLPanel* panel = getChild<LLPanel>("privacy_preferences_discord"); + getChild<LLTabContainer>("privacy_tab_container")->removeTabPanel(panel); +#endif + return true; } @@ -1968,7 +1978,21 @@ void LLFloaterPreference::selectChatPanel() void LLFloaterPreference::changed() { + if (LLConversationLog::instance().getIsLoggingEnabled()) + { getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0); + } + else + { + // onClearLog clears list, then notifies changed() and only then clears file, + // so check presence of conversations before checking file, file will cleared later. + llstat st; + bool has_logs = LLConversationLog::instance().getConversations().size() > 0 + && LLFile::stat(LLConversationLog::instance().getFileName(), &st) == 0 + && S_ISREG(st.st_mode) + && st.st_size > 0; + getChild<LLButton>("clear_log")->setEnabled(has_logs); + } // set 'enable' property for 'Delete transcripts...' button updateDeleteTranscriptsButton(); diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 8cc01f6dc6..01108b5cfa 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -207,14 +207,14 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) mSettingNameText->setToolTip(controlp->getName()); mComment->setVisible(true); - std::string old_text = mComment->getText(); std::string new_text = controlp->getComment(); // Don't setText if not nessesary, it will reset scroll // This is a debug UI that reads from xml, there might // be use cases where comment changes, but not the name - if (old_text != new_text) + if (mOldText != new_text) { mComment->setText(controlp->getComment()); + mOldText = new_text; } mValSpinner1->setMaxValue(F32_MAX); @@ -467,6 +467,7 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) } default: mComment->setText(std::string("unknown")); + mOldText = "unknown"; break; } } diff --git a/indra/newview/llfloatersettingsdebug.h b/indra/newview/llfloatersettingsdebug.h index b813cf4a74..8781cd3b67 100644 --- a/indra/newview/llfloatersettingsdebug.h +++ b/indra/newview/llfloatersettingsdebug.h @@ -82,6 +82,7 @@ protected: LLColorSwatchCtrl* mColorSwatch = nullptr; std::string mSearchFilter; + std::string mOldText; }; #endif //LLFLOATERDEBUGSETTINGS_H diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index abffba8ffa..c3bc24c6b9 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -1042,7 +1042,9 @@ void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filen { CFStringRef executable_cfstr = (CFStringRef)CFDictionaryGetValue(bundleInfoDict, CFSTR("CFBundleExecutable")); // get the name of the actual executable (e.g. TextEdit or firefox-bin) int max_file_length = 256; // (max file name length is 255 in OSX) - char* executable_buf = (char*)malloc(sizeof(char) * max_file_length); + + // Xcode 26: VLAs are a clang extension. Just create the buffer and delete it after. + char *executable_buf = new char [max_file_length]; if(CFStringGetCString(executable_cfstr, executable_buf, max_file_length, kCFStringEncodingMacRoman)) // convert CFStringRef to char* { executable_path += std::string("/Contents/MacOS/") + std::string(executable_buf); // append path to executable directory and then executable name to exec path @@ -1052,7 +1054,7 @@ void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filen std::string warning = "Unable to get CString from CFString for executable path"; popupAndPrintWarning(warning); } - free(executable_buf); + delete [] executable_buf; } else { diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index a798ba31ee..03979edbc1 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -169,6 +169,52 @@ public: }; LLWorldMapHandler gWorldMapHandler; +// handle secondlife:///app/worldmap_global/{GLOBAL_COORDS} URLs +class LLWorldMapGlobalHandler : public LLCommandHandler +{ +public: + LLWorldMapGlobalHandler() : LLCommandHandler("worldmap_global", UNTRUSTED_THROTTLE) + {} + + virtual bool canHandleUntrusted( + const LLSD& params, + const LLSD& query_map, + LLMediaCtrl* web, + const std::string& nav_type) + { + if (nav_type == NAV_TYPE_CLICKED + || nav_type == NAV_TYPE_EXTERNAL) + { + // NAV_TYPE_EXTERNAL will be throttled + return true; + } + + return false; + } + + bool handle(const LLSD& params, + const LLSD& query_map, + const std::string& grid, + LLMediaCtrl* web) + { + if (params.size() < 3) + { + LL_WARNS() << "Correct global coordinates are not provided." << LL_ENDL; + return true; + } + + LLVector3d parcel_global_pos = LLVector3d(params[0].asInteger(), params[1].asInteger(), params[2].asInteger()); + LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance(); + if (!parcel_global_pos.isExactlyZero() && worldmap_instance) + { + worldmap_instance->trackLocation(parcel_global_pos); + LLFloaterReg::showInstance("world_map", "center"); + } + return true; + } +}; +LLWorldMapGlobalHandler gWorldMapGlobalHandler; + // SocialMap handler secondlife:///app/maptrackavatar/id class LLMapTrackAvatarHandler : public LLCommandHandler { @@ -325,11 +371,9 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key) mWaitingForTracker(false), mIsClosing(false), mSetToUserPosition(true), + mProcessingSearchUpdate(false), mTrackedLocation(0.0,0.0,0.0), mTrackedStatus(LLTracker::TRACKING_NOTHING), - mListFriendCombo(nullptr), - mListLandmarkCombo(nullptr), - mListSearchResults(nullptr), mParcelInfoObserver(nullptr), mShowParcelInfo(false) { @@ -341,7 +385,7 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key) mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this)); mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this)); mCommitCallbackRegistrar.add("WMap.Landmark", boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this)); - mCommitCallbackRegistrar.add("WMap.SearchResult", boost::bind(&LLFloaterWorldMap::onCommitSearchResult, this)); + mCommitCallbackRegistrar.add("WMap.SearchResult", [this](LLUICtrl* ctrl, const LLSD& data) { LLFloaterWorldMap::onCommitSearchResult(false); }); mCommitCallbackRegistrar.add("WMap.GoHome", boost::bind(&LLFloaterWorldMap::onGoHome, this)); mCommitCallbackRegistrar.add("WMap.Teleport", boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this)); mCommitCallbackRegistrar.add("WMap.ShowTarget", boost::bind(&LLFloaterWorldMap::onShowTargetBtn, this)); @@ -383,32 +427,33 @@ bool LLFloaterWorldMap::postBuild() mTeleportCoordSpinY = getChild<LLUICtrl>("teleport_coordinate_y"); mTeleportCoordSpinZ = getChild<LLUICtrl>("teleport_coordinate_z"); - LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo"); - avatar_combo->selectFirstItem(); - avatar_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboPrearrange, this) ); - avatar_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); - mListFriendCombo = dynamic_cast<LLCtrlListInterface *>(avatar_combo); + mFriendCombo = getChild<LLComboBox>("friend combo"); + mFriendCombo->selectFirstItem(); + mFriendCombo->setPrearrangeCallback(boost::bind(&LLFloaterWorldMap::onAvatarComboPrearrange, this)); + mFriendCombo->setTextChangedCallback(boost::bind(&LLFloaterWorldMap::onComboTextEntry, this)); mLocationEditor = getChild<LLSearchEditor>("location"); mLocationEditor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1)); - mLocationEditor->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this)); + mLocationEditor->setTextChangedCallback(boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this)); - getChild<LLScrollListCtrl>("search_results")->setDoubleClickCallback( boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this)); - mListSearchResults = childGetListInterface("search_results"); + mSearchResults = getChild<LLScrollListCtrl>("search_results"); + mSearchResults->setDoubleClickCallback(boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this)); - LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo"); - landmark_combo->selectFirstItem(); - landmark_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboPrearrange, this) ); - landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); - mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo); + mLandmarkCombo = getChild<LLComboBox>("landmark combo"); + mLandmarkCombo->selectFirstItem(); + mLandmarkCombo->setPrearrangeCallback(boost::bind(&LLFloaterWorldMap::onLandmarkComboPrearrange, this)); + mLandmarkCombo->setTextChangedCallback(boost::bind(&LLFloaterWorldMap::onComboTextEntry, this)); mZoomSlider = getChild<LLSliderCtrl>("zoom slider"); F32 slider_zoom = mMapView->getZoom(); mZoomSlider->setValue(slider_zoom); + mTrackCtrlsPanel = getChild<LLPanel>("layout_panel_4"); + mSearchButton = getChild<LLButton>("DoSearch"); + getChild<LLPanel>("expand_btn_panel")->setMouseDownCallback(boost::bind(&LLFloaterWorldMap::onExpandCollapseBtn, this)); - setDefaultBtn(NULL); + mTrackCtrlsPanel->setDefaultBtn(nullptr); onChangeMaturity(); @@ -608,7 +653,6 @@ void LLFloaterWorldMap::draw() } mTeleportButton->setEnabled((bool)tracking_status); - // getChildView("Clear")->setEnabled((bool)tracking_status); mShowDestinationButton->setEnabled((bool)tracking_status || LLWorldMap::getInstance()->isTracking()); mCopySlurlButton->setEnabled((mSLURL.isValid()) ); @@ -700,26 +744,24 @@ void LLFloaterWorldMap::requestParcelInfo(const LLVector3d& pos_global, const LL } } -void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string& name ) +void LLFloaterWorldMap::trackAvatar(const LLUUID& avatar_id, const std::string& name) { mShowParcelInfo = false; - LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo"); - if (!iface) return; buildAvatarIDList(); - if(iface->setCurrentByID(avatar_id) || gAgent.isGodlike()) + if (mFriendCombo->setCurrentByID(avatar_id) || gAgent.isGodlike()) { // *HACK: Adjust Z values automatically for liaisons & gods so // they swoop down when they click on the map. Requested // convenience. - if(gAgent.isGodlike()) + if (gAgent.isGodlike()) { mTeleportCoordSpinZ->setValue(LLSD(200.f)); } // Don't re-request info if we already have it or we won't have it in time to teleport if (mTrackedStatus != LLTracker::TRACKING_AVATAR || avatar_id != mTrackedAvatarID) { - mTrackedStatus = LLTracker::TRACKING_AVATAR; + mTrackedStatus = LLTracker::TRACKING_AVATAR; mTrackedAvatarID = avatar_id; LLTracker::trackAvatar(avatar_id, name); } @@ -728,52 +770,45 @@ void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string& { LLTracker::stopTracking(false); } - setDefaultBtn("Teleport"); + mTrackCtrlsPanel->setDefaultBtn(mTeleportButton); } -void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id ) +void LLFloaterWorldMap::trackLandmark(const LLUUID& landmark_item_id) { mShowParcelInfo = false; - LLCtrlSelectionInterface *iface = childGetSelectionInterface("landmark combo"); - if (!iface) return; buildLandmarkIDLists(); bool found = false; - S32 idx; + S32 idx; for (idx = 0; idx < mLandmarkItemIDList.size(); idx++) { - if ( mLandmarkItemIDList.at(idx) == landmark_item_id) + if (mLandmarkItemIDList.at(idx) == landmark_item_id) { found = true; break; } } - if (found && iface->setCurrentByID( landmark_item_id ) ) + if (found && mLandmarkCombo->setCurrentByID(landmark_item_id)) { - LLUUID asset_id = mLandmarkAssetIDList.at( idx ); - std::string name; - LLComboBox* combo = getChild<LLComboBox>( "landmark combo"); - if (combo) name = combo->getSimple(); - mTrackedStatus = LLTracker::TRACKING_LANDMARK; - LLTracker::trackLandmark(mLandmarkAssetIDList.at( idx ), // assetID - mLandmarkItemIDList.at( idx ), // itemID - name); // name + LLUUID asset_id = mLandmarkAssetIDList.at(idx); + std::string name = mLandmarkCombo->getSimple(); + mTrackedStatus = LLTracker::TRACKING_LANDMARK; + LLTracker::trackLandmark(mLandmarkAssetIDList.at(idx), // assetID + mLandmarkItemIDList.at(idx), // itemID + name); // name - if( asset_id != sHomeID ) + if (asset_id != sHomeID) { // start the download process - gLandmarkList.getAsset( asset_id); + gLandmarkList.getAsset(asset_id); } - - // We have to download both region info and landmark data, so set busy. JC - // getWindow()->incBusyCount(); } else { LLTracker::stopTracking(false); } - setDefaultBtn("Teleport"); + mTrackCtrlsPanel->setDefaultBtn(mTeleportButton); } @@ -782,7 +817,7 @@ void LLFloaterWorldMap::trackEvent(const LLItemInfo &event_info) mShowParcelInfo = false; mTrackedStatus = LLTracker::TRACKING_LOCATION; LLTracker::trackLocation(event_info.getGlobalPosition(), event_info.getName(), event_info.getToolTip(), LLTracker::LOCATION_EVENT); - setDefaultBtn("Teleport"); + mTrackCtrlsPanel->setDefaultBtn(mTeleportButton); } void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item) @@ -790,11 +825,12 @@ void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item) mShowParcelInfo = false; mTrackedStatus = LLTracker::TRACKING_LOCATION; LLTracker::trackLocation(item.getGlobalPosition(), item.getName(), item.getToolTip(), LLTracker::LOCATION_ITEM); - setDefaultBtn("Teleport"); + mTrackCtrlsPanel->setDefaultBtn(mTeleportButton); } void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) { + mProcessingSearchUpdate = false; LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); if (!sim_info) { @@ -804,7 +840,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) S32 world_x = S32(pos_global.mdV[0] / 256); S32 world_y = S32(pos_global.mdV[1] / 256); LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true); - setDefaultBtn(""); + mTrackCtrlsPanel->setDefaultBtn(nullptr); // clicked on a non-region - turn off coord display enableTeleportCoordsDisplay( false ); @@ -818,7 +854,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) LLTracker::stopTracking(false); LLWorldMap::getInstance()->setTracking(pos_global); LLWorldMap::getInstance()->setTrackingInvalid(); - setDefaultBtn(""); + mTrackCtrlsPanel->setDefaultBtn(nullptr); // clicked on a down region - turn off coord display enableTeleportCoordsDisplay( false ); @@ -849,7 +885,7 @@ void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global) // we have a valid region - turn on coord display enableTeleportCoordsDisplay( true ); - setDefaultBtn("Teleport"); + mTrackCtrlsPanel->setDefaultBtn(mTeleportButton); } // enable/disable teleport destination coordinates @@ -934,7 +970,10 @@ void LLFloaterWorldMap::updateLocation() } } - mLocationEditor->setValue(sim_name); + if (!mProcessingSearchUpdate) + { + mLocationEditor->setValue(sim_name); + } // refresh coordinate display to reflect where user clicked. LLVector3d coord_pos = LLTracker::getTrackedPositionGlobal(); @@ -964,7 +1003,7 @@ void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S3 local_pos.mV[VZ] = (F32)z_coord; LLVector3d global_pos = sim_info->getGlobalPos(local_pos); trackLocation(global_pos); - setDefaultBtn("Teleport"); + mTrackCtrlsPanel->setDefaultBtn(mTeleportButton); } else { @@ -1025,17 +1064,14 @@ void LLFloaterWorldMap::observeFriends() void LLFloaterWorldMap::friendsChanged() { - LLAvatarTracker& t = LLAvatarTracker::instance(); - const LLUUID& avatar_id = t.getAvatarID(); + LLAvatarTracker& t = LLAvatarTracker::instance(); + const LLUUID& avatar_id = t.getAvatarID(); buildAvatarIDList(); - if(avatar_id.notNull()) + if (avatar_id.notNull()) { - LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo"); const LLRelationship* buddy_info = t.getBuddyInfo(avatar_id); - if(!iface || - !iface->setCurrentByID(avatar_id) || - (buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) || - gAgent.isGodlike()) + if (!mFriendCombo->setCurrentByID(avatar_id) || + (buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) || gAgent.isGodlike()) { LLTracker::stopTracking(false); } @@ -1045,15 +1081,12 @@ void LLFloaterWorldMap::friendsChanged() // No longer really builds a list. Instead, just updates mAvatarCombo. void LLFloaterWorldMap::buildAvatarIDList() { - LLCtrlListInterface *list = mListFriendCombo; - if (!list) return; - // Delete all but the "None" entry - S32 list_size = list->getItemCount(); + S32 list_size = mFriendCombo->getItemCount(); if (list_size > 1) { - list->selectItemRange(1, -1); - list->operateOnSelection(LLCtrlListInterface::OP_DELETE); + mFriendCombo->selectItemRange(1, -1); + mFriendCombo->operateOnSelection(LLCtrlListInterface::OP_DELETE); } // Get all of the calling cards for avatar that are currently online @@ -1061,29 +1094,26 @@ void LLFloaterWorldMap::buildAvatarIDList() LLAvatarTracker::instance().applyFunctor(collector); LLCollectMappableBuddies::buddy_map_t::iterator it; LLCollectMappableBuddies::buddy_map_t::iterator end; - it = collector.mMappable.begin(); + it = collector.mMappable.begin(); end = collector.mMappable.end(); - for( ; it != end; ++it) + for (; it != end; ++it) { - list->addSimpleElement((*it).second, ADD_BOTTOM, (*it).first); + mFriendCombo->addSimpleElement((*it).second, ADD_BOTTOM, (*it).first); } - list->setCurrentByID( LLAvatarTracker::instance().getAvatarID() ); - list->selectFirstItem(); + mFriendCombo->setCurrentByID(LLAvatarTracker::instance().getAvatarID()); + mFriendCombo->selectFirstItem(); } void LLFloaterWorldMap::buildLandmarkIDLists() { - LLCtrlListInterface *list = mListLandmarkCombo; - if (!list) return; - // Delete all but the "None" entry - S32 list_size = list->getItemCount(); + S32 list_size = mLandmarkCombo->getItemCount(); if (list_size > 1) { - list->selectItemRange(1, -1); - list->operateOnSelection(LLCtrlListInterface::OP_DELETE); + mLandmarkCombo->selectItemRange(1, -1); + mLandmarkCombo->operateOnSelection(LLCtrlListInterface::OP_DELETE); } mLandmarkItemIDList.clear(); @@ -1115,13 +1145,13 @@ void LLFloaterWorldMap::buildLandmarkIDLists() { LLInventoryItem* item = items.at(i); - list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID()); + mLandmarkCombo->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID()); mLandmarkAssetIDList.push_back( item->getAssetUUID() ); mLandmarkItemIDList.push_back( item->getUUID() ); } - list->selectFirstItem(); + mLandmarkCombo->selectFirstItem(); } @@ -1139,10 +1169,9 @@ F32 LLFloaterWorldMap::getDistanceToDestination(const LLVector3d &destination, void LLFloaterWorldMap::clearLocationSelection(bool clear_ui, bool dest_reached) { - LLCtrlListInterface *list = mListSearchResults; - if (list && (!dest_reached || (list->getItemCount() == 1))) + if (!dest_reached || (mSearchResults->getItemCount() == 1)) { - list->operateOnAll(LLCtrlListInterface::OP_DELETE); + mSearchResults->operateOnAll(LLCtrlListInterface::OP_DELETE); } LLWorldMap::getInstance()->cancelTracking(); mCompletingRegionName = ""; @@ -1153,11 +1182,7 @@ void LLFloaterWorldMap::clearLandmarkSelection(bool clear_ui) { if (clear_ui || !childHasKeyboardFocus("landmark combo")) { - LLCtrlListInterface *list = mListLandmarkCombo; - if (list) - { - list->selectByValue( "None" ); - } + mLandmarkCombo->selectByValue("None"); } } @@ -1167,10 +1192,9 @@ void LLFloaterWorldMap::clearAvatarSelection(bool clear_ui) if (clear_ui || !childHasKeyboardFocus("friend combo")) { mTrackedStatus = LLTracker::TRACKING_NOTHING; - LLCtrlListInterface *list = mListFriendCombo; - if (list && list->getSelectedValue().asString() != "None") + if (mFriendCombo->getSelectedValue().asString() != "None") { - list->selectByValue( "None" ); + mFriendCombo->selectByValue("None"); } } } @@ -1223,28 +1247,25 @@ void LLFloaterWorldMap::onGoHome() { gAgent.teleportHome(); closeFloater(); + mProcessingSearchUpdate = false; } -void LLFloaterWorldMap::onLandmarkComboPrearrange( ) +void LLFloaterWorldMap::onLandmarkComboPrearrange() { - if( mIsClosing ) + if (mIsClosing) { return; } - LLCtrlListInterface *list = mListLandmarkCombo; - if (!list) return; - - LLUUID current_choice = list->getCurrentID(); + LLUUID current_choice = mLandmarkCombo->getCurrentID(); buildLandmarkIDLists(); - if( current_choice.isNull() || !list->setCurrentByID( current_choice ) ) + if (current_choice.isNull() || !mLandmarkCombo->setCurrentByID(current_choice)) { LLTracker::stopTracking(false); } - } void LLFloaterWorldMap::onComboTextEntry() @@ -1264,33 +1285,28 @@ void LLFloaterWorldMap::onSearchTextEntry( ) void LLFloaterWorldMap::onLandmarkComboCommit() { - if( mIsClosing ) + if (mIsClosing) { return; } - LLCtrlListInterface *list = mListLandmarkCombo; - if (!list) return; - LLUUID asset_id; - LLUUID item_id = list->getCurrentID(); + LLUUID item_id = mLandmarkCombo->getCurrentID(); LLTracker::stopTracking(false); - //RN: stopTracking() clears current combobox selection, need to reassert it here - list->setCurrentByID(item_id); + // RN: stopTracking() clears current combobox selection, need to reassert it here + mLandmarkCombo->setCurrentByID(item_id); - if( item_id.isNull() ) - { - } - else if( item_id == sHomeID ) + if (item_id.isNull()) {} + else if (item_id == sHomeID) { asset_id = sHomeID; } else { - LLInventoryItem* item = gInventory.getItem( item_id ); - if( item ) + LLInventoryItem* item = gInventory.getItem(item_id); + if (item) { asset_id = item->getAssetUUID(); } @@ -1301,34 +1317,31 @@ void LLFloaterWorldMap::onLandmarkComboCommit() } } - trackLandmark( item_id); + trackLandmark(item_id); onShowTargetBtn(); // Reset to user postion if nothing is tracked - mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + mSetToUserPosition = (LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING); } // static -void LLFloaterWorldMap::onAvatarComboPrearrange( ) +void LLFloaterWorldMap::onAvatarComboPrearrange() { - if( mIsClosing ) + if (mIsClosing) { return; } - LLCtrlListInterface *list = mListFriendCombo; - if (!list) return; - LLUUID current_choice; - if( LLAvatarTracker::instance().haveTrackingInfo() ) + if (LLAvatarTracker::instance().haveTrackingInfo()) { current_choice = LLAvatarTracker::instance().getAvatarID(); } buildAvatarIDList(); - if( !list->setCurrentByID( current_choice ) || current_choice.isNull() ) + if (!mFriendCombo->setCurrentByID(current_choice) || current_choice.isNull()) { LLTracker::stopTracking(false); } @@ -1336,26 +1349,21 @@ void LLFloaterWorldMap::onAvatarComboPrearrange( ) void LLFloaterWorldMap::onAvatarComboCommit() { - if( mIsClosing ) + if (mIsClosing) { return; } - LLCtrlListInterface *list = mListFriendCombo; - if (!list) return; - - const LLUUID& new_avatar_id = list->getCurrentID(); + const LLUUID& new_avatar_id = mFriendCombo->getCurrentID(); if (new_avatar_id.notNull()) { - std::string name; - LLComboBox* combo = getChild<LLComboBox>("friend combo"); - if (combo) name = combo->getSimple(); + std::string name = mFriendCombo->getSimple(); trackAvatar(new_avatar_id, name); onShowTargetBtn(); } else - { // Reset to user postion if nothing is tracked - mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING ); + { // Reset to user postion if nothing is tracked + mSetToUserPosition = (LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING); } } @@ -1375,11 +1383,11 @@ void LLFloaterWorldMap::updateSearchEnabled() if (childHasKeyboardFocus("location") && mLocationEditor->getValue().asString().length() > 0) { - setDefaultBtn("DoSearch"); + mTrackCtrlsPanel->setDefaultBtn(mSearchButton); } else { - setDefaultBtn(NULL); + mTrackCtrlsPanel->setDefaultBtn(nullptr); } } @@ -1409,6 +1417,7 @@ void LLFloaterWorldMap::onLocationCommit() { return; } + mProcessingSearchUpdate = true; LLStringUtil::toLower(str); mCompletingRegionName = str; @@ -1430,6 +1439,7 @@ void LLFloaterWorldMap::onCoordinatesCommit() { return; } + mProcessingSearchUpdate = false; S32 x_coord = (S32)mTeleportCoordSpinX->getValue().asReal(); S32 y_coord = (S32)mTeleportCoordSpinY->getValue().asReal(); @@ -1443,6 +1453,7 @@ void LLFloaterWorldMap::onCoordinatesCommit() void LLFloaterWorldMap::onClearBtn() { mTrackedStatus = LLTracker::TRACKING_NOTHING; + mProcessingSearchUpdate = false; LLTracker::stopTracking(true); LLWorldMap::getInstance()->cancelTracking(); mSLURL = LLSLURL(); // Clear the SLURL since it's invalid @@ -1459,6 +1470,7 @@ void LLFloaterWorldMap::onShowAgentBtn() mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate // Set flag so user's location will be displayed if not tracking anything else mSetToUserPosition = true; + mProcessingSearchUpdate = false; } void LLFloaterWorldMap::onClickTeleportBtn() @@ -1487,8 +1499,9 @@ void LLFloaterWorldMap::onExpandCollapseBtn() std::string image_name = getString(toggle_collapse ? "expand_icon" : "collapse_icon"); std::string tooltip = getString(toggle_collapse ? "expand_tooltip" : "collapse_tooltip"); - getChild<LLIconCtrl>("expand_collapse_icon")->setImage(LLUI::getUIImage(image_name)); - getChild<LLIconCtrl>("expand_collapse_icon")->setToolTip(tooltip); + LLIconCtrl* expandCollapseIcon = getChild<LLIconCtrl>("expand_collapse_icon"); + expandCollapseIcon->setImage(LLUI::getUIImage(image_name)); + expandCollapseIcon->setToolTip(tooltip); getChild<LLPanel>("expand_btn_panel")->setToolTip(tooltip); } @@ -1613,6 +1626,12 @@ void LLFloaterWorldMap::teleport() gAgent.teleportViaLocation( pos_global ); } } + + if (mProcessingSearchUpdate) + { + mProcessingSearchUpdate = false; + mTrackedSimName.clear(); + } } void LLFloaterWorldMap::flyToLandmark() @@ -1680,9 +1699,9 @@ void LLFloaterWorldMap::teleportToAvatar() void LLFloaterWorldMap::flyToAvatar() { - if( LLAvatarTracker::instance().haveTrackingInfo() ) + if (LLAvatarTracker::instance().haveTrackingInfo()) { - gAgent.startAutoPilotGlobal( LLAvatarTracker::instance().getGlobalPos() ); + gAgent.startAutoPilotGlobal(LLAvatarTracker::instance().getGlobalPos()); } } @@ -1693,8 +1712,7 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) return; } - LLScrollListCtrl *list = getChild<LLScrollListCtrl>("search_results"); - list->operateOnAll(LLCtrlListInterface::OP_DELETE); + mSearchResults->operateOnAll(LLCtrlListInterface::OP_DELETE); auto name_length = mCompletingRegionName.length(); @@ -1722,7 +1740,7 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) value["id"] = info->getName(); value["columns"][0]["column"] = "sim_name"; value["columns"][0]["value"] = info->getName(); - list->addElement(value); + mSearchResults->addElement(value); num_results++; } } @@ -1737,21 +1755,24 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) // if match found, highlight it and go if (!match.isUndefined()) { - list->selectByValue(match); + mSearchResults->selectByValue(match); + mSearchResults->setFocus(true); + onCommitSearchResult(false /*fully commit the only option*/); } - // else select first found item + // else let user decide else { - list->selectFirstItem(); + mSearchResults->selectFirstItem(); + mSearchResults->setFocus(true); + onCommitSearchResult(true /*don't update text field*/); } - getChild<LLUICtrl>("search_results")->setFocus(true); - onCommitSearchResult(); } else { // if we found nothing, say "none" - list->setCommentText(LLTrans::getString("worldmap_results_none_found")); - list->operateOnAll(LLCtrlListInterface::OP_DESELECT); + mProcessingSearchUpdate = false; + mSearchResults->setCommentText(LLTrans::getString("worldmap_results_none_found")); + mSearchResults->operateOnAll(LLCtrlListInterface::OP_DESELECT); } } @@ -1763,13 +1784,9 @@ void LLFloaterWorldMap::onTeleportFinished() } } -void LLFloaterWorldMap::onCommitSearchResult() +void LLFloaterWorldMap::onCommitSearchResult(bool from_search) { - LLCtrlListInterface *list = mListSearchResults; - if (!list) return; - - LLSD selected_value = list->getSelectedValue(); - std::string sim_name = selected_value.asString(); + std::string sim_name = mSearchResults->getSelectedValue().asString(); if (sim_name.empty()) { return; @@ -1785,7 +1802,7 @@ void LLFloaterWorldMap::onCommitSearchResult() { LLVector3d pos_global = info->getGlobalOrigin(); - const F64 SIM_COORD_DEFAULT = 128.0; + constexpr F64 SIM_COORD_DEFAULT = 128.0; LLVector3 pos_local(SIM_COORD_DEFAULT, SIM_COORD_DEFAULT, 0.0f); // Did this value come from a trackURL() request? @@ -1798,9 +1815,15 @@ void LLFloaterWorldMap::onCommitSearchResult() pos_global.mdV[VY] += (F64)pos_local.mV[VY]; pos_global.mdV[VZ] = (F64)pos_local.mV[VZ]; - mLocationEditor->setValue(sim_name); + // Commiting search string automatically selects first item in the search list, + // in such case onCommitSearchResult shouldn't modify search string + if (!from_search) + { + mLocationEditor->setValue(sim_name); + } trackLocation(pos_global); - setDefaultBtn("Teleport"); + mProcessingSearchUpdate = from_search; + mTrackCtrlsPanel->setDefaultBtn(mTeleportButton); break; } } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 2f2b2b7a0d..9558ca2615 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -51,6 +51,8 @@ class LLCheckBoxCtrl; class LLSliderCtrl; class LLSpinCtrl; class LLSearchEditor; +class LLComboBox; +class LLScrollListCtrl; class LLWorldMapParcelInfoObserver : public LLRemoteParcelInfoObserver { @@ -174,7 +176,7 @@ protected: void onLocationFocusChanged( LLFocusableElement* ctrl ); void onLocationCommit(); void onCoordinatesCommit(); - void onCommitSearchResult(); + void onCommitSearchResult(bool from_search); void onTeleportFinished(); @@ -211,6 +213,7 @@ private: bool mIsClosing; bool mSetToUserPosition; + bool mProcessingSearchUpdate; // Don't update search string from what user set it to LLVector3d mTrackedLocation; LLTracker::ETrackingStatus mTrackedStatus; @@ -218,14 +221,11 @@ private: LLUUID mTrackedAvatarID; LLSLURL mSLURL; - LLCtrlListInterface * mListFriendCombo; - LLCtrlListInterface * mListLandmarkCombo; - LLCtrlListInterface * mListSearchResults; - LLButton* mTeleportButton = nullptr; LLButton* mShowDestinationButton = nullptr; LLButton* mCopySlurlButton = nullptr; LLButton* mGoHomeButton = nullptr; + LLButton* mSearchButton = nullptr; LLCheckBoxCtrl* mPeopleCheck = nullptr; LLCheckBoxCtrl* mInfohubCheck = nullptr; @@ -245,6 +245,13 @@ private: LLSliderCtrl* mZoomSlider = nullptr; + LLComboBox* mLandmarkCombo = nullptr; + LLComboBox* mFriendCombo = nullptr; + + LLScrollListCtrl* mSearchResults = nullptr; + + LLPanel* mTrackCtrlsPanel = nullptr; + boost::signals2::connection mTeleportFinishConnection; }; diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index c668d414d3..a0621bb015 100644 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -68,9 +68,10 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) if (!folder->areChildrenInited() || !needsSort(folder->getViewModelItem())) return; - LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem()); - if (modelp->getUUID().isNull()) return; + LLFolderViewModelItemInventory* sort_modelp = static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem()); + if (!sort_modelp->canSortContent()) return; + bool has_favorites = false; for (std::list<LLFolderViewFolder*>::iterator it = folder->getFoldersBegin(), end_it = folder->getFoldersEnd(); it != end_it; ++it) @@ -79,11 +80,14 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) LLFolderViewFolder* child_folderp = *it; sort(child_folderp); + LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); + has_favorites |= child_folderp->isFavorite() || child_folderp->hasFavorites(); + if (child_folderp->getFoldersCount() > 0) { - time_t most_recent_folder_time = - static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate(); - LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); + LLFolderViewModelItemInventory* folderp = static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem()); + time_t most_recent_folder_time = folderp->getCreationDate(); + if (most_recent_folder_time > modelp->getCreationDate()) { modelp->setCreationDate(most_recent_folder_time); @@ -91,16 +95,26 @@ void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) } if (child_folderp->getItemsCount() > 0) { - time_t most_recent_item_time = - static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate(); + LLFolderViewModelItemInventory* itemp = static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem()); + time_t most_recent_item_time = itemp->getCreationDate(); - LLFolderViewModelItemInventory* modelp = static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem()); if (most_recent_item_time > modelp->getCreationDate()) { modelp->setCreationDate(most_recent_item_time); } } } + for (std::list<LLFolderViewItem*>::const_iterator it = folder->getItemsBegin(), end_it = folder->getItemsEnd(); + it != end_it && !has_favorites; + ++it) + { + LLFolderViewItem* child_itemp = *it; + has_favorites |= child_itemp->isFavorite(); + } + if (has_favorites) + { + folder->updateHasFavorites(true); + } base_t::sort(folder); } diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h index 48b4ee5fd9..74645a19e0 100644 --- a/indra/newview/llfolderviewmodelinventory.h +++ b/indra/newview/llfolderviewmodelinventory.h @@ -48,6 +48,7 @@ public: virtual bool isItemInTrash( void) const { return false; } // TODO: make into pure virtual. virtual bool isItemInOutfits() const { return false; } virtual bool isAgentInventory() const { return false; } + virtual bool isAgentInventoryRoot() const { return false; } virtual bool isUpToDate() const = 0; virtual void addChild(LLFolderViewModelItem* child); virtual bool hasChildren() const = 0; @@ -58,6 +59,7 @@ public: virtual EInventorySortGroup getSortGroup() const = 0; virtual LLInventoryObject* getInventoryObject() const = 0; virtual void requestSort(); + virtual bool canSortContent() const { return getUUID().notNull(); } virtual void setPassedFilter(bool filtered, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0); virtual bool filter( LLFolderViewFilter& filter); virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter); diff --git a/indra/newview/llgltffolderitem.h b/indra/newview/llgltffolderitem.h index 89d90c81cc..40a4c6fef1 100644 --- a/indra/newview/llgltffolderitem.h +++ b/indra/newview/llgltffolderitem.h @@ -114,6 +114,11 @@ public: EType getType() const { return mItemType; } S32 getItemId() const { return mItemId; } + bool isFavorite() const override { return false; } + bool isItemInTrash() const override { return false; } + bool isAgentInventory() const override { return false; } + bool isAgentInventoryRoot() const override { return false; } + private: LLUIImagePtr pIcon; std::string mName; diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp index d0d2ee191a..776d2dd31e 100644 --- a/indra/newview/llhudeffectlookat.cpp +++ b/indra/newview/llhudeffectlookat.cpp @@ -37,6 +37,7 @@ #include "lldrawable.h" #include "llviewerobjectlist.h" #include "llviewercontrol.h" +#include "llvoavatarself.h" #include "llrendersphere.h" #include "llselectmgr.h" #include "llglheaders.h" @@ -397,6 +398,21 @@ bool LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec return false; } + static LLCachedControl<bool> enable_lookat_hints(gSavedSettings, "EnableLookAtTarget", true); + if (!enable_lookat_hints) + { + // Clear the effect so it doesn't linger around if it gets disabled + if (mTargetType != LOOKAT_TARGET_IDLE) + { + mTargetObject = gAgentAvatarp; + mTargetType = LOOKAT_TARGET_IDLE; + mTargetOffsetGlobal.set(2.f, 0.f, 0.f); + setDuration(3.f); + setNeedsSendToSim(true); + } + return false; + } + if (target_type >= LOOKAT_NUM_TARGETS) { LL_WARNS() << "Bad target_type " << (int)target_type << " - ignoring." << LL_ENDL; @@ -409,6 +425,29 @@ bool LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec return false; } + static LLCachedControl<bool> limit_lookat_hints(gSavedSettings, "LimitLookAtTarget", true); + // Don't affect the look at if object is gAgentAvatarp (cursor head follow) + if (limit_lookat_hints && object != gAgentAvatarp) + { + // If it is a object + if (object) + { + position += object->getRenderPosition(); + object = NULL; + } + + LLVector3 agentHeadPosition = gAgentAvatarp->mHeadp->getWorldPosition(); + float dist = (float)dist_vec(agentHeadPosition, position); + + static LLCachedControl<F32> limit_lookat_hints_distance(gSavedSettings, "LimitLookAtTargetDistance", 2.0f); + if (dist > limit_lookat_hints_distance) + { + LLVector3 headOffset = position - agentHeadPosition; + headOffset *= limit_lookat_hints_distance / dist; + position.setVec(agentHeadPosition + headOffset); + } + } + F32 current_time = mTimer.getElapsedTimeF32(); // type of lookat behavior or target object has changed diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp index eeb38cd6aa..c600010f6b 100644 --- a/indra/newview/llhudeffectpointat.cpp +++ b/indra/newview/llhudeffectpointat.cpp @@ -34,6 +34,7 @@ #include "llagent.h" #include "llagentcamera.h" #include "lldrawable.h" +#include "llviewercontrol.h" #include "llviewerobjectlist.h" #include "llvoavatar.h" #include "message.h" @@ -226,6 +227,19 @@ bool LLHUDEffectPointAt::setPointAt(EPointAtType target_type, LLViewerObject *ob return false; } + static LLCachedControl<bool> enable_selection_hints(gSavedSettings, "EnableSelectionHints", true); + if (!enable_selection_hints) + { + // Clear the effect so it doesn't linger around if it gets disabled + if (mTargetType != POINTAT_TARGET_NONE) + { + clearPointAtTarget(); + setDuration(1.f); + setNeedsSendToSim(true); + } + return false; + } + if (target_type >= POINTAT_NUM_TARGETS) { LL_WARNS() << "Bad target_type " << (int)target_type << " - ignoring." << LL_ENDL; diff --git a/indra/newview/llhudeffectresetskeleton.cpp b/indra/newview/llhudeffectresetskeleton.cpp new file mode 100644 index 0000000000..31065a3e76 --- /dev/null +++ b/indra/newview/llhudeffectresetskeleton.cpp @@ -0,0 +1,211 @@ +/** + * @file llhudeffectresetskeleton.cpp + * @brief LLHUDEffectResetSkeleton class implementation + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, 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 "llhudeffectresetskeleton.h" + +#include "llagent.h" +#include "llviewerobjectlist.h" +#include "llvoavatar.h" +#include "message.h" + +// packet layout +const S32 TARGET_OBJECT = 0; // This is to allow for targetting owned animesh +const S32 RESET_ANIMATIONS = 16; //This can also be a flags if needed +const S32 PKT_SIZE = 17; + +//----------------------------------------------------------------------------- +// LLHUDEffectResetSkeleton() +//----------------------------------------------------------------------------- +LLHUDEffectResetSkeleton::LLHUDEffectResetSkeleton(const U8 type) : + LLHUDEffect(type) +{ +} + +//----------------------------------------------------------------------------- +// ~LLHUDEffectResetSkeleton() +//----------------------------------------------------------------------------- +LLHUDEffectResetSkeleton::~LLHUDEffectResetSkeleton() +{ +} + +//----------------------------------------------------------------------------- +// packData() +//----------------------------------------------------------------------------- +void LLHUDEffectResetSkeleton::packData(LLMessageSystem *mesgsys) +{ + // Pack the default data + LLHUDEffect::packData(mesgsys); + + // Pack the type-specific data. Uses a fun packed binary format. Whee! + U8 packed_data[PKT_SIZE]; + memset(packed_data, 0, PKT_SIZE); + + // pack both target object and position + // position interpreted as offset if target object is non-null + if (mTargetObject) + { + htolememcpy(&(packed_data[TARGET_OBJECT]), mTargetObject->mID.mData, MVT_LLUUID, 16); + } + else + { + htolememcpy(&(packed_data[TARGET_OBJECT]), LLUUID::null.mData, MVT_LLUUID, 16); + } + + U8 resetAnimations = (U8)mResetAnimations; + htolememcpy(&(packed_data[RESET_ANIMATIONS]), &resetAnimations, MVT_U8, 1); + + mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, PKT_SIZE); +} + +//----------------------------------------------------------------------------- +// unpackData() +//----------------------------------------------------------------------------- +void LLHUDEffectResetSkeleton::unpackData(LLMessageSystem *mesgsys, S32 blocknum) +{ + LLVector3d new_target; + U8 packed_data[PKT_SIZE]; + + + LLHUDEffect::unpackData(mesgsys, blocknum); + + LLUUID source_id; + mesgsys->getUUIDFast(_PREHASH_Effect, _PREHASH_AgentID, source_id, blocknum); + + LLViewerObject *objp = gObjectList.findObject(source_id); + if (objp && objp->isAvatar()) + { + setSourceObject(objp); + } + else + { + //LL_WARNS() << "Could not find source avatar for ResetSkeleton effect" << LL_ENDL; + return; + } + + S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData); + if (size != PKT_SIZE) + { + LL_WARNS() << "ResetSkeleton effect with bad size " << size << LL_ENDL; + return; + } + + mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, PKT_SIZE, blocknum); + + LLUUID target_id; + htolememcpy(target_id.mData, &(packed_data[TARGET_OBJECT]), MVT_LLUUID, 16); + + // The purpose for having a target ID is if we want to reset animesh, or + // other things in the future. + // I implemented this, but due to issues regarding various permission + // checks, I scrapped it for now. --Chaser Zaks + // See https://github.com/secondlife/viewer/pull/1212 for additional info + + if (target_id.isNull()) + { + target_id = source_id; + } + + objp = gObjectList.findObject(target_id); + + if (objp) + { + setTargetObject(objp); + } + + U8 resetAnimations = 0; + htolememcpy(&resetAnimations, &(packed_data[RESET_ANIMATIONS]), MVT_U8, 1); + + // Pre-emptively assume this is going to be flags in the future. + // It isn't needed now, but this will assure that only bit 1 is set + mResetAnimations = resetAnimations & 1; + + update(); +} + +//----------------------------------------------------------------------------- +// setTargetObjectAndOffset() +//----------------------------------------------------------------------------- +void LLHUDEffectResetSkeleton::setTargetObject(LLViewerObject *objp) +{ + mTargetObject = objp; +} + + +//----------------------------------------------------------------------------- +// markDead() +//----------------------------------------------------------------------------- +void LLHUDEffectResetSkeleton::markDead() +{ + LLHUDEffect::markDead(); +} + +void LLHUDEffectResetSkeleton::setSourceObject(LLViewerObject* objectp) +{ + // restrict source objects to avatars + if (objectp && objectp->isAvatar()) + { + LLHUDEffect::setSourceObject(objectp); + } +} + +//----------------------------------------------------------------------------- +// update() +//----------------------------------------------------------------------------- +void LLHUDEffectResetSkeleton::update() +{ + // If the target object is dead, set the target object to NULL + if (mTargetObject.isNull() || mTargetObject->isDead()) + { + markDead(); + return; + } + + if (mSourceObject.isNull() || mSourceObject->isDead()) + { + markDead(); + return; + } + + if (mTargetObject->isAvatar()) + { + // Only the owner of a avatar can reset their skeleton like this + // Also allow reset if we created the effect (Local resetting) + if (mSourceObject->getID() == mTargetObject->getID() || getOriginatedHere()) + { + LLVOAvatar* avatar = mTargetObject->asAvatar(); + avatar->resetSkeleton(mResetAnimations); + } + } + else + { + LL_WARNS() << mSourceObject->getID() << " attempted to reset skeleton on " + << mTargetObject->getID() << ", but it is not a avatar!" << LL_ENDL; + } + + markDead(); +} diff --git a/indra/newview/llhudeffectresetskeleton.h b/indra/newview/llhudeffectresetskeleton.h new file mode 100644 index 0000000000..39a6137054 --- /dev/null +++ b/indra/newview/llhudeffectresetskeleton.h @@ -0,0 +1,59 @@ +/** + * @file llhudeffectresetskeleton.h + * @brief LLHUDEffectResetSkeleton class definition + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLHUDEFFECTRESETSKELETON_H +#define LL_LLHUDEFFECTRESETSKELETON_H + +#include "llhudeffect.h" + +class LLViewerObject; +class LLVOAvatar; + + +class LLHUDEffectResetSkeleton final : public LLHUDEffect +{ +public: + friend class LLHUDObject; + + /*virtual*/ void markDead(); + /*virtual*/ void setSourceObject(LLViewerObject* objectp); + + void setTargetObject(LLViewerObject *objp); + void setResetAnimations(bool enable){ mResetAnimations = enable; }; + +protected: + LLHUDEffectResetSkeleton(const U8 type); + ~LLHUDEffectResetSkeleton(); + + /*virtual*/ void packData(LLMessageSystem *mesgsys); + /*virtual*/ void unpackData(LLMessageSystem *mesgsys, S32 blocknum); + + void update(); +private: + bool mResetAnimations; +}; + +#endif // LL_LLHUDEFFECTRESETSKELETON_H diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp index e6fbfbfb38..04e9e2dff2 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -36,6 +36,7 @@ #include "llhudeffecttrail.h" #include "llhudeffectlookat.h" #include "llhudeffectpointat.h" +#include "llhudeffectresetskeleton.h" #include "llhudnametag.h" #include "llvoicevisualizer.h" @@ -241,6 +242,9 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type) case LL_HUD_EFFECT_BLOB: hud_objectp = new LLHUDEffectBlob(type); break; + case LL_HUD_EFFECT_RESET_SKELETON: + hud_objectp = new LLHUDEffectResetSkeleton(type); + break; default: LL_WARNS() << "Unknown type of hud effect:" << (U32) type << LL_ENDL; } diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h index 8c628e3f92..f683f21e96 100644 --- a/indra/newview/llhudobject.h +++ b/indra/newview/llhudobject.h @@ -96,7 +96,8 @@ public: LL_HUD_EFFECT_POINTAT, LL_HUD_EFFECT_VOICE_VISUALIZER, // Ventrella LL_HUD_NAME_TAG, - LL_HUD_EFFECT_BLOB + LL_HUD_EFFECT_BLOB, + LL_HUD_EFFECT_RESET_SKELETON }; protected: static void sortObjects(); diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index fd0d8b696f..c092b4c91a 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -225,10 +225,6 @@ void LLHUDText::renderText() } text_color = segment_iter->mColor; - if (mOnHUDAttachment) - { - text_color = linearColor4(text_color); - } text_color.mV[VALPHA] *= alpha_factor; hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, mOnHUDAttachment); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 4e8bcc4f7a..7cd0171a37 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -422,6 +422,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, U8 *binary_bucket, S32 binary_bucket_size, LLHost &sender, + LLSD metadata, LLUUID aux_id) { LLChat chat; @@ -451,6 +452,28 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, bool is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && LLMuteList::isLinden(name); + /*** + * The simulator may have flagged this sender as a bot, if the viewer would like to display + * the chat text in a different color or font, the below code is how the viewer can + * tell if the sender is a bot. + *----------------------------------------------------- + bool is_bot = false; + if (metadata.has("sender")) + { // The server has identified this sender as a bot. + is_bot = metadata["sender"]["bot"].asBoolean(); + } + *----------------------------------------------------- + */ + + std::string notice_name; + LLSD notice_args; + if (metadata.has("notice")) + { // The server has injected a notice into the IM conversation. + // These will be things like bot notifications, etc. + notice_name = metadata["notice"]["id"].asString(); + notice_args = metadata["notice"]["data"]; + } + chat.mMuted = is_muted; chat.mFromID = from_id; chat.mFromName = name; @@ -544,7 +567,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, } else { - // standard message, not from system + // standard message, server may have injected a notice into the conversation. std::string saved; if (offline == IM_OFFLINE) { @@ -579,8 +602,17 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, region_message = true; } } - gIMMgr->addMessage( - session_id, + + std::string real_name; + + if (!notice_name.empty()) + { // The simulator has injected some sort of notice into the conversation. + // findString will only replace the contents of buffer if the notice_id is found. + LLTrans::findString(buffer, notice_name, notice_args); + real_name = SYSTEM_FROM; + } + + gIMMgr->addMessage(session_id, from_id, name, buffer, @@ -591,7 +623,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, region_id, position, region_message, - timestamp); + timestamp, + LLUUID::null, + real_name); } else { @@ -1486,10 +1520,10 @@ void LLIMProcessing::requestOfflineMessages() if (!requested && gMessageSystem && !gDisconnected - && LLMuteList::getInstance()->isLoaded() && isAgentAvatarValid() && gAgent.getRegion() - && gAgent.getRegion()->capabilitiesReceived()) + && gAgent.getRegion()->capabilitiesReceived() + && (LLMuteList::getInstance()->isLoaded() || LLMuteList::getInstance()->getLoadFailed())) { std::string cap_url = gAgent.getRegionCapability("ReadOfflineMsgs"); @@ -1619,6 +1653,12 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) from_group = message_data["from_group"].asString() == "Y"; } + LLSD metadata; + if (message_data.has("metadata")) + { + metadata = message_data["metadata"]; + } + EInstantMessage dialog = static_cast<EInstantMessage>(message_data["dialog"].asInteger()); LLUUID session_id = message_data["transaction-id"].asUUID(); if (session_id.isNull() && dialog == IM_FROM_TASK) @@ -1646,6 +1686,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) local_bin_bucket.data(), S32(local_bin_bucket.size()), local_sender, + metadata, message_data["asset_id"].asUUID()); }); diff --git a/indra/newview/llimprocessing.h b/indra/newview/llimprocessing.h index 030d28b198..66ffc59ae0 100644 --- a/indra/newview/llimprocessing.h +++ b/indra/newview/llimprocessing.h @@ -48,6 +48,7 @@ public: U8 *binary_bucket, S32 binary_bucket_size, LLHost &sender, + LLSD metadata, LLUUID aux_id = LLUUID::null); // Either receives list of offline messages from 'ReadOfflineMsgs' capability diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 04e8a26008..c1e80ba4f1 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -71,6 +71,7 @@ #include "llviewerregion.h" #include "llcorehttputil.h" #include "lluiusage.h" +#include "llurlregistry.h" #include <array> @@ -197,6 +198,9 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id); bool store_dnd_message = false; // flag storage of a dnd message bool is_session_focused = session_floater->isTornOff() && session_floater->hasFocus(); + bool contains_mention = LLUrlRegistry::getInstance()->containsAgentMention(msg["message"].asString()); + static LLCachedControl<bool> play_snd_mention_pref(gSavedSettings, "PlaySoundChatMention", false); + bool play_snd_mention = contains_mention && play_snd_mention_pref && (msg["source_type"].asInteger() != CHAT_SOURCE_OBJECT); if (!LLFloater::isVisible(im_box) || im_box->isMinimized()) { conversations_floater_status = CLOSED; @@ -230,7 +234,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) else { user_preferences = gSavedSettings.getString("NotificationNearbyChatOptions"); - if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNearbyChatIM"))) + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNearbyChatIM")) && !play_snd_mention) { make_ui_sound("UISndNewIncomingIMSession"); } @@ -241,7 +245,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) if (LLAvatarTracker::instance().isBuddy(participant_id)) { user_preferences = gSavedSettings.getString("NotificationFriendIMOptions"); - if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundFriendIM"))) + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundFriendIM")) && !play_snd_mention) { make_ui_sound("UISndNewIncomingIMSession"); } @@ -249,7 +253,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) else { user_preferences = gSavedSettings.getString("NotificationNonFriendIMOptions"); - if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNonFriendIM"))) + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNonFriendIM")) && !play_snd_mention) { make_ui_sound("UISndNewIncomingIMSession"); } @@ -258,7 +262,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) else if (session->isAdHocSessionType()) { user_preferences = gSavedSettings.getString("NotificationConferenceIMOptions"); - if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundConferenceIM"))) + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundConferenceIM")) && !play_snd_mention) { make_ui_sound("UISndNewIncomingIMSession"); } @@ -266,11 +270,18 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) else if(session->isGroupSessionType()) { user_preferences = gSavedSettings.getString("NotificationGroupChatOptions"); - if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundGroupChatIM"))) + if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundGroupChatIM")) && !play_snd_mention) { make_ui_sound("UISndNewIncomingIMSession"); } } + if (play_snd_mention) + { + if (!gAgent.isDoNotDisturb()) + { + make_ui_sound("UISndChatMention"); + } + } // actions: @@ -323,7 +334,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) if ("openconversations" == user_preferences || ON_TOP == conversations_floater_status || ("toast" == user_preferences && ON_TOP != conversations_floater_status) - || ("flash" == user_preferences && (CLOSED == conversations_floater_status + || (("flash" == user_preferences || contains_mention) && (CLOSED == conversations_floater_status || NOT_ON_TOP == conversations_floater_status)) || is_dnd_msg) { @@ -343,7 +354,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg) } else { - im_box->flashConversationItemWidget(session_id, true); + im_box->flashConversationItemWidget(session_id, true, contains_mention); } } } @@ -1689,6 +1700,8 @@ bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, } else { + // will check KeepConversationLogTranscripts on its own + LLConversationLog::instance().cache(); return false; } } @@ -3142,9 +3155,16 @@ void LLIMMgr::addMessage( const LLUUID& region_id, const LLVector3& position, bool is_region_msg, - U32 timestamp) // May be zero + U32 timestamp, // May be zero + LLUUID display_id, + std::string_view display_name) { LLUUID other_participant_id = target_id; + std::string message_display_name = (display_name.empty()) ? from : std::string(display_name); + if (display_id.isNull() && (display_name.empty())) + { + display_id = other_participant_id; + } LLUUID new_session_id = session_id; if (new_session_id.isNull()) @@ -3240,9 +3260,13 @@ void LLIMMgr::addMessage( } //Play sound for new conversations - if (!skip_message & !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation"))) + if (!skip_message && !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation"))) { - make_ui_sound("UISndNewIncomingIMSession"); + static LLCachedControl<bool> play_snd_mention_pref(gSavedSettings, "PlaySoundChatMention", false); + if (!play_snd_mention_pref || !LLUrlRegistry::getInstance()->containsAgentMention(msg)) + { + make_ui_sound("UISndNewIncomingIMSession"); + } } } else @@ -3254,7 +3278,7 @@ void LLIMMgr::addMessage( if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) { - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg, timestamp); + LLIMModel::instance().addMessage(new_session_id, message_display_name, display_id, msg, true, is_region_msg, timestamp); } // Open conversation floater if offline messages are present @@ -3262,7 +3286,7 @@ void LLIMMgr::addMessage( { LLFloaterReg::showInstance("im_container"); LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")-> - flashConversationItemWidget(new_session_id, true); + flashConversationItemWidget(new_session_id, true, LLUrlRegistry::getInstance()->containsAgentMention(msg)); } } diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 61776860e3..23f90ca795 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -368,7 +368,9 @@ public: const LLUUID& region_id = LLUUID::null, const LLVector3& position = LLVector3::zero, bool is_region_msg = false, - U32 timestamp = 0); + U32 timestamp = 0, + LLUUID display_id = LLUUID::null, + std::string_view display_name = ""); void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args); diff --git a/indra/newview/llinspecttexture.cpp b/indra/newview/llinspecttexture.cpp index 24dbe61bad..9f0d236826 100644 --- a/indra/newview/llinspecttexture.cpp +++ b/indra/newview/llinspecttexture.cpp @@ -115,7 +115,6 @@ public: protected: LLPointer<LLViewerFetchedTexture> m_Image; - S32 mImageBoostLevel = LLGLTexture::BOOST_NONE; std::string mLoadingText; }; @@ -128,12 +127,8 @@ LLTexturePreviewView::LLTexturePreviewView(const LLView::Params& p) LLTexturePreviewView::~LLTexturePreviewView() { - if (m_Image) - { - m_Image->setBoostLevel(mImageBoostLevel); m_Image = nullptr; } -} void LLTexturePreviewView::draw() { @@ -153,18 +148,18 @@ void LLTexturePreviewView::draw() bool isLoading = (!m_Image->isFullyLoaded()) && (m_Image->getDiscardLevel() > 0); if (isLoading) LLFontGL::getFontSansSerif()->renderUTF8(mLoadingText, 0, rctClient.mLeft + 3, rctClient.mTop - 25, LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::DROP_SHADOW); - m_Image->addTextureStats((isLoading) ? MAX_IMAGE_AREA : (F32)(rctClient.getWidth() * rctClient.getHeight())); + + m_Image->setKnownDrawSize(MAX_IMAGE_SIZE, MAX_IMAGE_SIZE); } } void LLTexturePreviewView::setImageFromAssetId(const LLUUID& idAsset) { - m_Image = LLViewerTextureManager::getFetchedTexture(idAsset, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + m_Image = LLViewerTextureManager::getFetchedTexture(idAsset, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_THUMBNAIL); if (m_Image) { - mImageBoostLevel = m_Image->getBoostLevel(); - m_Image->setBoostLevel(LLGLTexture::BOOST_PREVIEW); m_Image->forceToSaveRawImage(0); + m_Image->setKnownDrawSize(MAX_IMAGE_SIZE, MAX_IMAGE_SIZE); if ( (!m_Image->isFullyLoaded()) && (!m_Image->hasFetcher()) ) { if (m_Image->isInFastCacheList()) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 5bd17d4d5b..331754d009 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -829,6 +829,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { const LLInventoryObject *obj = getInventoryObject(); bool single_folder_root = (mRoot == NULL); + bool is_cof = isCOFFolder(); + bool is_inbox = isInboxFolder(); if (obj) { @@ -843,7 +845,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Copy")); } - if (isAgentInventory() && !single_folder_root && !isMarketplaceListingsFolder()) + bool is_agent_inventory = isAgentInventory(); + if (is_agent_inventory && !single_folder_root && !is_cof && !is_inbox) { items.push_back(std::string("New folder from selected")); items.push_back(std::string("Subfolder Separator")); @@ -856,6 +859,19 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } + if (isFavorite()) + { + items.push_back(std::string("Remove from Favorites")); + } + else if (is_agent_inventory && !gInventory.isObjectDescendentOf(mUUID, gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH))) + { + items.push_back(std::string("Add to Favorites")); + if (gInventory.getRootFolderID() == mUUID) + { + disabled_items.push_back(std::string("Add to Favorites")); + } + } + if (obj->getIsLinkType()) { items.push_back(std::string("Find Original")); @@ -868,6 +884,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (!isItemMovable() || !canMenuCut()) { disabled_items.push_back(std::string("Cut")); + disabled_items.push_back(std::string("New folder from selected")); } } else @@ -877,7 +894,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, items.push_back(std::string("Find Links")); } - if (!isInboxFolder() && !single_folder_root) + if (!is_inbox && !single_folder_root) { items.push_back(std::string("Rename")); if (!isItemRenameable() || ((flags & FIRST_SELECTED_ITEM) == 0)) @@ -917,6 +934,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, if (!isItemMovable() || !canMenuCut()) { disabled_items.push_back(std::string("Cut")); + disabled_items.push_back(std::string("New folder from selected")); } if (canListOnMarketplace() && !isMarketplaceListingsFolder() && !isInboxFolder()) @@ -939,7 +957,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } // Don't allow items to be pasted directly into the COF or the inbox - if (!isCOFFolder() && !isInboxFolder()) + if (!is_cof && !is_inbox) { items.push_back(std::string("Paste")); } @@ -1333,6 +1351,13 @@ bool LLInvFVBridge::isAgentInventory() const return model->isObjectDescendentOf(mUUID, gInventory.getRootFolderID()); } +bool LLInvFVBridge::isAgentInventoryRoot() const +{ + const LLInventoryModel* model = getInventoryModel(); + if(!model) return false; + return gInventory.getRootFolderID() == mUUID; +} + bool LLInvFVBridge::isCOFFolder() const { return LLAppearanceMgr::instance().getIsInCOF(mUUID); @@ -2280,7 +2305,21 @@ const LLUUID& LLItemBridge::getThumbnailUUID() const return LLUUID::null; } -// virtual +bool LLItemBridge::isFavorite() const +{ + LLViewerInventoryItem* item = NULL; + LLInventoryModel* model = getInventoryModel(); + if (model) + { + item = model->getItem(mUUID); + } + if (item) + { + return get_is_favorite(item); + } + return false; +} + bool LLItemBridge::isItemPermissive() const { if (LLViewerInventoryItem* item = getItem()) @@ -2425,6 +2464,16 @@ const LLUUID& LLFolderBridge::getThumbnailUUID() const return LLUUID::null; } +bool LLFolderBridge::isFavorite() const +{ + LLViewerInventoryCategory* cat = getCategory(); + if (cat) + { + return cat->getIsFavorite(); + } + return false; +} + void LLFolderBridge::update() { // we know we have children but haven't fetched them (doesn't obey filter) @@ -2664,6 +2713,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, // bool is_movable = true; + bool create_outfit = false; if (is_movable && (marketplacelistings_id == cat_id)) { @@ -2708,7 +2758,12 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, tooltip_msg = LLTrans::getString("TooltipOutfitNotInInventory"); is_movable = false; } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -2732,7 +2787,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantMoveOutfitIntoOutfit"); } - else if ((dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) && inv_res == MY_OUTFITS_SUBFOLDER) + else if (dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) { is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); @@ -2742,7 +2797,12 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -2943,7 +3003,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, if (mUUID == my_outifts_id) { EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); - if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT) + if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT || !create_outfit) { LLInvFVBridge::changeCategoryParent( model, @@ -2967,15 +3027,19 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat, { case MY_OUTFITS_NO: // Moning from outside outfits into outfits - if (dest_res == MY_OUTFITS_SUBFOLDER) + if (dest_res == MY_OUTFITS_SUBFOLDER && create_outfit) { // turn it into outfit - dropToMyOutfitsSubfolder(inv_cat, mUUID, LLFolderType::FT_OUTFIT, cb); + dropToMyOutfitsSubfolder(inv_cat, mUUID, cb); } else { - // or link it? - dropToMyOutfitsSubfolder(inv_cat, mUUID, LLFolderType::FT_NONE, cb); + LLInvFVBridge::changeCategoryParent( + model, + (LLViewerInventoryCategory*)inv_cat, + mUUID, + move_is_into_trash); + if (cb) cb->fire(inv_cat->getUUID()); } break; case MY_OUTFITS_SUBFOLDER: @@ -4094,7 +4158,6 @@ void LLFolderBridge::perform_pasteFromClipboard() LLInventoryObject *obj = model->getObject(item_id); if (obj) { - if (move_is_into_lost_and_found) { if (LLAssetType::AT_CATEGORY == obj->getType()) @@ -4104,41 +4167,57 @@ void LLFolderBridge::perform_pasteFromClipboard() } if (move_is_into_outfit) { - if (!move_is_into_my_outfits && item && can_move_to_outfit(item, move_is_into_current_outfit)) + bool handled = false; + if (mUUID != my_outifts_id + && dest_folder->getPreferredType() == LLFolderType::FT_OUTFIT + && item + && can_move_to_outfit(item, move_is_into_current_outfit)) { - // todo: this is going to create dupplicate folders? dropToOutfit(item, move_is_into_current_outfit, cb); + handled = true; } else if (move_is_into_my_outfits && LLAssetType::AT_CATEGORY == obj->getType()) { - LLInventoryCategory* cat = model->getCategory(item_id); + LLViewerInventoryCategory* cat = model->getCategory(item_id); U32 max_items_to_wear = gSavedSettings.getU32("WearFolderLimit"); - if (cat && can_move_to_my_outfits(model, cat, max_items_to_wear)) + if (cat && can_move_to_my_outfits_as_outfit(model, cat, max_items_to_wear)) { if (mUUID == my_outifts_id) { dropToMyOutfits(cat, cb); + handled = true; } - else if (move_is_into_my_outfits) + else { - EMyOutfitsSubfolderType res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id); - if (res == MY_OUTFITS_SUBFOLDER) + EMyOutfitsSubfolderType dest_res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id); + if (dest_res == MY_OUTFITS_SUBFOLDER) { // turn it into outfit - dropToMyOutfitsSubfolder(cat, mUUID, LLFolderType::FT_OUTFIT, cb); + dropToMyOutfitsSubfolder(cat, mUUID, cb); + handled = true; + } + } + } + if (!handled && cat && can_move_to_my_outfits_as_subfolder(model, cat)) + { + EMyOutfitsSubfolderType dest_res = myoutfit_object_subfolder_type(model, mUUID, my_outifts_id); + if (dest_res == MY_OUTFITS_SUBFOLDER || mUUID == my_outifts_id) + { + if (LLClipboard::instance().isCutMode()) + { + changeCategoryParent(model, cat, parent_id, false); } else { - dropToMyOutfitsSubfolder(cat, mUUID, LLFolderType::FT_NONE, cb); + copy_inventory_category(model, cat, parent_id); } + if (cb) cb->fire(item_id); + handled = true; } } - else - { - LLNotificationsUtil::add("MyOutfitsPasteFailed"); - } } - else + + if (!handled) { LLNotificationsUtil::add("MyOutfitsPasteFailed"); } @@ -4181,7 +4260,7 @@ void LLFolderBridge::perform_pasteFromClipboard() // move_inventory_item() is not enough, as we have to update inventory locally too if (LLAssetType::AT_CATEGORY == obj->getType()) { - LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id); + LLViewerInventoryCategory* vicat = model->getCategory(item_id); llassert(vicat); if (vicat) { @@ -4390,6 +4469,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items } disabled_items.push_back(std::string("New Folder")); + disabled_items.push_back(std::string("upload_options")); disabled_items.push_back(std::string("upload_def")); disabled_items.push_back(std::string("create_new")); } @@ -4415,6 +4495,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items { disabled_items.push_back(std::string("New Folder")); disabled_items.push_back(std::string("New Listing Folder")); + disabled_items.push_back(std::string("upload_options")); disabled_items.push_back(std::string("upload_def")); disabled_items.push_back(std::string("create_new")); } @@ -4471,10 +4552,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items if (cat->getPreferredType() == LLFolderType::FT_OUTFIT) { // Want some but not all of the items from getClipboardEntries for outfits. - items.push_back(std::string("New Outfit Folder")); items.push_back(std::string("Rename")); items.push_back(std::string("thumbnail")); + addInventoryFavoritesMenuOptions(items); addDeleteContextMenuOptions(items, disabled_items); // EXT-4030: disallow deletion of currently worn outfit const LLViewerInventoryItem* base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink(); @@ -4492,16 +4573,17 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items EMyOutfitsSubfolderType in_my_outfits = myoutfit_object_subfolder_type(model, mUUID, outfits_id); if (in_my_outfits != MY_OUTFITS_NO) { + // Either an outfit or a subfolder inside MY_OUTFITS if (in_my_outfits == MY_OUTFITS_SUBFOLDER) { // Not inside an outfit, but inside 'my outfits' items.push_back(std::string("New Outfit")); + items.push_back(std::string("New Outfit Folder")); } - - items.push_back(std::string("New Outfit Folder")); items.push_back(std::string("Rename")); items.push_back(std::string("thumbnail")); + addInventoryFavoritesMenuOptions(items); addDeleteContextMenuOptions(items, disabled_items); } else @@ -4518,6 +4600,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items } if (!isMarketplaceListingsFolder()) { + items.push_back(std::string("upload_options")); items.push_back(std::string("upload_def")); items.push_back(std::string("create_new")); items.push_back(std::string("New Script")); @@ -4549,6 +4632,8 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items if (model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT) == mUUID) { items.push_back(std::string("Copy outfit list to clipboard")); + addInventoryFavoritesMenuOptions(items); + addOpenFolderMenuOptions(flags, items); } @@ -4807,6 +4892,18 @@ void LLFolderBridge::addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items) } } +void LLFolderBridge::addInventoryFavoritesMenuOptions(menuentry_vec_t& items) +{ + if (isFavorite()) + { + items.push_back(std::string("Remove from Favorites")); + } + else + { + items.push_back(std::string("Add to Favorites")); + } +} + bool LLFolderBridge::hasChildren() const { LLInventoryModel* model = getInventoryModel(); @@ -5480,12 +5577,11 @@ void LLFolderBridge::dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLI inv_cat->getThumbnailUUID()); } -void LLFolderBridge::dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLFolderType::EType preferred_type, LLPointer<LLInventoryCallback> cb) +void LLFolderBridge::dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLPointer<LLInventoryCallback> cb) { - const LLUUID outfits_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); inventory_func_type func = boost::bind(outfitFolderCreatedCallback, inv_cat->getUUID(), _1, cb, mInventoryPanel); getInventoryModel()->createNewCategory(dest_id, - preferred_type, + LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID()); @@ -7062,12 +7158,13 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) item = (LLViewerInventoryItem*)gInventory.getItem(object_id); if(item && gInventory.isObjectDescendentOf(object_id, gInventory.getRootFolderID())) { - rez_attachment(item, NULL, true); // Replace if "Wear"ing. + static LLCachedControl<bool> replace_item(gSavedSettings, "InventoryAddAttachmentBehavior", false); + rez_attachment(item, NULL, ("attach" == action) ? replace_item() : true); // Replace if "Wear"ing. } else if(item && item->isFinished()) { // must be in library. copy it to our inventory and put it on. - LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0)); + LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, true)); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), @@ -8192,7 +8289,8 @@ void LLObjectBridgeAction::attachOrDetach() } else { - LLAppearanceMgr::instance().wearItemOnAvatar(mUUID, true, false); // Don't replace if adding. + static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryAddAttachmentBehavior", false); + LLAppearanceMgr::instance().wearItemOnAvatar(mUUID, true, inventory_linking()); // Don't replace if adding. } } @@ -8383,6 +8481,7 @@ void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) buildContextMenuOptions(flags, items, disabled_items); items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end()); + items.erase(std::remove(items.begin(), items.end(), std::string("New folder from selected")), items.end()); hide_context_entries(menu, items, disabled_items); } @@ -8417,6 +8516,51 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge( return new_listener; } +/************************************************************************/ +/* Favorites Inventory Panel related classes */ +/************************************************************************/ +void LLFavoritesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) +{ + // todo: consider things that should be disabled + menuentry_vec_t disabled_items, items; + buildContextMenuOptions(flags, items, disabled_items); + + items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end()); + items.erase(std::remove(items.begin(), items.end(), std::string("New folder from selected")), items.end()); + + hide_context_entries(menu, items, disabled_items); +} + +LLInvFVBridge* LLFavoritesInventoryBridgeBuilder::createBridge( + LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, + LLInventoryType::EType inv_type, + LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, + LLFolderView* root, + const LLUUID& uuid, + U32 flags /*= 0x00*/) const +{ + LLInvFVBridge* new_listener = NULL; + if (asset_type == LLAssetType::AT_CATEGORY + && actual_asset_type != LLAssetType::AT_LINK_FOLDER) + { + new_listener = new LLFavoritesFolderBridge(inv_type, inventory, root, uuid); + } + else + { + new_listener = LLInventoryFolderViewModelBuilder::createBridge(asset_type, + actual_asset_type, + inv_type, + inventory, + view_model, + root, + uuid, + flags); + } + return new_listener; +} + LLFolderViewGroupedItemBridge::LLFolderViewGroupedItemBridge() { } @@ -8427,7 +8571,7 @@ void LLFolderViewGroupedItemBridge::groupFilterContextMenu(folder_view_item_dequ menuentry_vec_t disabled_items; if (get_selection_item_uuids(selected_items, ids)) { - if (!LLAppearanceMgr::instance().canAddWearables(ids) && canWearSelected(ids)) + if (!LLAppearanceMgr::instance().canAddWearables(ids, false) && canWearSelected(ids)) { disabled_items.push_back(std::string("Wearable And Object Wear")); disabled_items.push_back(std::string("Wearable Add")); diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index a101c7368a..d96adbd1d2 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -86,6 +86,7 @@ public: //-------------------------------------------------------------------- virtual const LLUUID& getUUID() const { return mUUID; } virtual const LLUUID& getThumbnailUUID() const { return LLUUID::null; } + virtual bool isFavorite() const { return false; } virtual void clearDisplayName() { mDisplayName.clear(); } virtual void restoreItem() {} virtual void restoreToWorld() {} @@ -175,6 +176,7 @@ protected: bool isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory? bool isAgentInventory() const; // false if lost or in the inventory library + bool isAgentInventoryRoot() const; // true if worn by agent bool isCOFFolder() const; // true if COF or descendant of bool isInboxFolder() const; // true if COF or descendant of marketplace inbox @@ -259,6 +261,7 @@ public: LLViewerInventoryItem* getItem() const; virtual const LLUUID& getThumbnailUUID() const; + virtual bool isFavorite() const; protected: bool confirmRemoveItem(const LLSD& notification, const LLSD& response); @@ -301,6 +304,7 @@ public: virtual std::string getLabelSuffix() const; virtual LLFontGL::StyleFlags getLabelStyle() const; virtual const LLUUID& getThumbnailUUID() const; + virtual bool isFavorite() const; void setShowDescendantsCount(bool show_count) {mShowDescendantsCount = show_count;} @@ -341,6 +345,7 @@ protected: void buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items); void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items); void addOpenFolderMenuOptions(U32 flags, menuentry_vec_t& items); + void addInventoryFavoritesMenuOptions(menuentry_vec_t& items); // Inventory favorites, not toolbar favorites //-------------------------------------------------------------------- // Menu callbacks @@ -369,7 +374,7 @@ protected: void dropToFavorites(LLInventoryItem* inv_item, LLPointer<LLInventoryCallback> cb = NULL); void dropToOutfit(LLInventoryItem* inv_item, bool move_is_into_current_outfit, LLPointer<LLInventoryCallback> cb = NULL); void dropToMyOutfits(LLInventoryCategory* inv_cat, LLPointer<LLInventoryCallback> cb = NULL); - void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest, LLFolderType::EType preferred_type, LLPointer<LLInventoryCallback> cb = NULL); + void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest, LLPointer<LLInventoryCallback> cb = NULL); //-------------------------------------------------------------------- // Messy hacks for handling folder options @@ -755,6 +760,46 @@ public: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Favorites Inventory Panel related classes +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +// Overridden version of the Inventory-Folder-View-Bridge for Folders +class LLFavoritesFolderBridge : public LLFolderBridge +{ + friend class LLInvFVBridgeAction; +public: + // Creates context menu for Folders related to Recent Inventory Panel. + // Uses base logic and than removes from visible items "New..." menu items. + LLFavoritesFolderBridge(LLInventoryType::EType type, + LLInventoryPanel* inventory, + LLFolderView* root, + const LLUUID& uuid) : + LLFolderBridge(inventory, root, uuid) + { + mInvType = type; + } + /*virtual*/ void buildContextMenu(LLMenuGL& menu, U32 flags); + /*virtual*/ bool canSortContent() const { return true; } +}; + +// Bridge builder to create Inventory-Folder-View-Bridge for Recent Inventory Panel +class LLFavoritesInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder +{ +public: + LLFavoritesInventoryBridgeBuilder() {} + // Overrides FolderBridge for Recent Inventory Panel. + // It use base functionality for bridges other than FolderBridge. + virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type, + LLAssetType::EType actual_asset_type, + LLInventoryType::EType inv_type, + LLInventoryPanel* inventory, + LLFolderViewModelInventory* view_model, + LLFolderView* root, + const LLUUID& uuid, + U32 flags = 0x00) const; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Marketplace Inventory Panel related classes //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -781,7 +826,7 @@ private: void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment, - bool replace = false); + bool replace); // Move items from an in-world object's "Contents" folder to a specified // folder in agent inventory. diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 5c0905af3c..99c2d6e410 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -64,6 +64,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p) mFilterUUID(p.uuid), mFilterLinks(p.links), mFilterThumbnails(p.thumbnails), + mFilterFavorites(p.favorites), mSearchVisibility(p.search_visibility) { } @@ -159,6 +160,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item) passed = passed && checkAgainstCreator(listener); passed = passed && checkAgainstSearchVisibility(listener); + passed = passed && checkAgainstFilterFavorites(listener->getUUID()); passed = passed && checkAgainstFilterThumbnails(listener->getUUID()); return passed; @@ -221,6 +223,19 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const return false; } + const LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id); + if (cat && cat->getIsFavorite()) + { + if (mFilterOps.mFilterFavorites == FILTER_ONLY_FAVORITES) + { + return true; + } + if (mFilterOps.mFilterFavorites == FILTER_EXCLUDE_FAVORITES) + { + return false; + } + } + // Marketplace folder filtering const U32 filterTypes = mFilterOps.mFilterTypes; const U32 marketplace_filter = FILTERTYPE_MARKETPLACE_ACTIVE | FILTERTYPE_MARKETPLACE_INACTIVE | @@ -273,6 +288,16 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const } } + if (filterTypes & FILTERTYPE_NO_TRASH_ITEMS) + { + const LLUUID trash_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + // If not a descendant of the marketplace listings root, then the nesting depth is -1 by definition + if (gInventory.isObjectDescendentOf(folder_id, trash_uuid)) + { + return false; + } + } + // show folder links LLViewerInventoryItem* item = gInventory.getItem(folder_id); if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER) @@ -611,6 +636,24 @@ bool LLInventoryFilter::checkAgainstFilterThumbnails(const LLUUID& object_id) co return true; } +bool LLInventoryFilter::checkAgainstFilterFavorites(const LLUUID& object_id) const +{ + const LLInventoryObject* object = gInventory.getObject(object_id); + if (!object) return true; + + + if (mFilterOps.mFilterFavorites != FILTER_INCLUDE_FAVORITES) + { + bool is_favorite = get_is_favorite(object); + if (is_favorite && (mFilterOps.mFilterFavorites == FILTER_EXCLUDE_FAVORITES)) + return false; + if (!is_favorite && (mFilterOps.mFilterFavorites == FILTER_ONLY_FAVORITES)) + return false; + } + + return true; +} + bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory* listener) const { if (!listener) @@ -811,6 +854,32 @@ void LLInventoryFilter::setFilterThumbnails(U64 filter_thumbnails) mFilterOps.mFilterThumbnails = filter_thumbnails; } +void LLInventoryFilter::setFilterFavorites(U64 filter_favorites) +{ + if (mFilterOps.mFilterFavorites != filter_favorites) + { + if (mFilterOps.mFilterFavorites == FILTER_EXCLUDE_FAVORITES + && filter_favorites == FILTER_ONLY_FAVORITES) + { + setModified(FILTER_RESTART); + } + else if (mFilterOps.mFilterFavorites == FILTER_ONLY_FAVORITES + && filter_favorites == FILTER_EXCLUDE_FAVORITES) + { + setModified(FILTER_RESTART); + } + else if (mFilterOps.mFilterFavorites == FILTER_INCLUDE_FAVORITES) + { + setModified(FILTER_MORE_RESTRICTIVE); + } + else + { + setModified(FILTER_LESS_RESTRICTIVE); + } + } + mFilterOps.mFilterFavorites = filter_favorites; +} + void LLInventoryFilter::setFilterEmptySystemFolders() { mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS; @@ -923,6 +992,11 @@ void LLInventoryFilter::toggleSearchVisibilityLibrary() } } +void LLInventoryFilter::setFilterNoTrashFolder() +{ + mFilterOps.mFilterTypes |= FILTERTYPE_NO_TRASH_ITEMS; +} + void LLInventoryFilter::setFilterNoMarketplaceFolder() { mFilterOps.mFilterTypes |= FILTERTYPE_NO_MARKETPLACE_ITEMS; @@ -959,7 +1033,7 @@ void LLInventoryFilter::setFilterSubString(const std::string& string) boost::char_separator<char> sep("+"); tokenizer tokens(filter_sub_string_new, sep); - for (auto token_iter : tokens) + for (const auto& token_iter : tokens) { mFilterTokens.push_back(token_iter); } @@ -1025,7 +1099,7 @@ void LLInventoryFilter::setFilterSubString(const std::string& string) } // Cancel out UUID once the search string is modified - if (mFilterOps.mFilterTypes == FILTERTYPE_UUID) + if (mFilterOps.mFilterTypes & FILTERTYPE_UUID) { mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID; mFilterOps.mFilterUUID = LLUUID::null; @@ -1615,6 +1689,11 @@ U64 LLInventoryFilter::getFilterThumbnails() const return mFilterOps.mFilterThumbnails; } +U64 LLInventoryFilter::getFilterFavorites() const +{ + return mFilterOps.mFilterFavorites; +} + bool LLInventoryFilter::hasFilterString() const { return mFilterSubString.size() > 0; @@ -1707,7 +1786,7 @@ std::string LLInventoryFilter::getEmptyLookupMessage(bool is_empty_folder) const } } -bool LLInventoryFilter::areDateLimitsSet() +bool LLInventoryFilter::areDateLimitsSet() const { return mFilterOps.mMinDate != time_min() || mFilterOps.mMaxDate != time_max() diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 7e64a03e73..c0164e04e4 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -61,6 +61,7 @@ public: FILTERTYPE_NO_MARKETPLACE_ITEMS = 0x1 << 10, // pass iff folder is not under the marketplace FILTERTYPE_WORN = 0x1 << 11, // pass if item is worn FILTERTYPE_SETTINGS = 0x1 << 12, // pass if the item is a settings object + FILTERTYPE_NO_TRASH_ITEMS = 0x1 << 13, // pass iff folder is not under the marketplace }; enum EFilterDateDirection @@ -83,6 +84,13 @@ public: FILTER_ONLY_THUMBNAILS }; + enum EFilterFavorite + { + FILTER_INCLUDE_FAVORITES, + FILTER_EXCLUDE_FAVORITES, + FILTER_ONLY_FAVORITES + }; + enum ESortOrderType { SO_NAME = 0, // Sort inventory by name @@ -149,6 +157,7 @@ public: Optional<PermissionMask> permissions; Optional<EFilterCreatorType> creator_type; Optional<EFilterThumbnail> thumbnails; + Optional<EFilterFavorite> favorites; Params() : types("filter_types", FILTERTYPE_OBJECT), @@ -156,6 +165,7 @@ public: wearable_types("wearable_types", 0xffffFFFFffffFFFFULL), settings_types("settings_types", 0xffffFFFFffffFFFFULL), thumbnails("thumbnails", FILTER_INCLUDE_THUMBNAILS), + favorites("favorites", FILTER_INCLUDE_FAVORITES), category_types("category_types", 0xffffFFFFffffFFFFULL), links("links", FILTERLINK_INCLUDE_LINKS), search_visibility("search_visibility", 0xFFFFFFFF), @@ -177,6 +187,7 @@ public: mFilterWearableTypes, mFilterSettingsTypes, // for _SETTINGS mFilterThumbnails, + mFilterFavorites, mFilterLinks, mFilterCategoryTypes; // For _CATEGORY LLUUID mFilterUUID; // for UUID @@ -220,6 +231,7 @@ public: U64 getFilterSettingsTypes() const; U64 getSearchVisibilityTypes() const; U64 getFilterThumbnails() const; + U64 getFilterFavorites() const; bool isFilterObjectTypesWith(LLInventoryType::EType t) const; void setFilterObjectTypes(U64 types); @@ -233,8 +245,10 @@ public: void setFilterMarketplaceInactiveFolders(); void setFilterMarketplaceUnassociatedFolders(); void setFilterMarketplaceListingFolders(bool select_only_listing_folders); + void setFilterNoTrashFolder(); void setFilterNoMarketplaceFolder(); void setFilterThumbnails(U64 filter_thumbnails); + void setFilterFavorites(U64 filter_favorites); void updateFilterTypes(U64 types, U64& current_types); void setSearchType(ESearchType type); ESearchType getSearchType() { return mSearchType; } @@ -339,9 +353,10 @@ public: LLInventoryFilter& operator =(const LLInventoryFilter& other); bool checkAgainstFilterThumbnails(const LLUUID& object_id) const; + bool checkAgainstFilterFavorites(const LLUUID& object_id) const; private: - bool areDateLimitsSet(); + bool areDateLimitsSet() const; bool checkAgainstFilterSubString(const std::string& desc) const; bool checkAgainstFilterType(const class LLFolderViewModelItemInventory* listener) const; bool checkAgainstFilterType(const LLInventoryItem* item) const; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 7fff88fba7..d1fd82a7f1 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -51,6 +51,7 @@ #include "lldirpicker.h" #include "lldonotdisturbnotificationstorage.h" #include "llfloatermarketplacelistings.h" +#include "llfloatermodelpreview.h" #include "llfloatersidepanelcontainer.h" #include "llfocusmgr.h" #include "llfolderview.h" @@ -62,6 +63,7 @@ #include "llinventorymodel.h" #include "llinventorypanel.h" #include "lllineeditor.h" +#include "llmaterialeditor.h" #include "llmarketplacenotifications.h" #include "llmarketplacefunctions.h" #include "llmenugl.h" @@ -86,6 +88,7 @@ #include "llviewermessage.h" #include "llviewerfoldertype.h" #include "llviewerobjectlist.h" +#include "llviewermenufile.h" #include "llviewerregion.h" #include "llviewerwindow.h" #include "llvoavatarself.h" @@ -438,7 +441,13 @@ void copy_inventory_category(LLInventoryModel* model, { copy_inventory_category_content(new_id, model, cat, root_copy_id, move_no_copy_items); }; - gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName(), func, cat->getThumbnailUUID()); + LLFolderType::EType type = LLFolderType::FT_NONE; + if (cat->getPreferredType() == LLFolderType::FT_OUTFIT) + { + // at the moment only permitting copy of outfits and normal folders + type = LLFolderType::FT_OUTFIT; + } + gInventory.createNewCategory(parent_id, type, cat->getName(), func, cat->getThumbnailUUID()); } void copy_inventory_category(LLInventoryModel* model, @@ -460,6 +469,25 @@ void copy_inventory_category(LLInventoryModel* model, gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName(), func, cat->getThumbnailUUID()); } +void copy_inventory_category(LLInventoryModel* model, + LLViewerInventoryCategory* cat, + const LLUUID& parent_id, + const LLUUID& root_copy_id, + bool move_no_copy_items, + LLPointer<LLInventoryCallback> callback) +{ + // Create the initial folder + inventory_func_type func = [model, cat, root_copy_id, move_no_copy_items, callback](const LLUUID& new_id) + { + copy_inventory_category_content(new_id, model, cat, root_copy_id, move_no_copy_items); + if (callback) + { + callback.get()->fire(new_id); + } + }; + gInventory.createNewCategory(parent_id, LLFolderType::FT_NONE, cat->getName(), func, cat->getThumbnailUUID()); +} + void copy_cb(const LLUUID& dest_folder, const LLUUID& root_id) { // Decrement the count in root_id since that one item won't be copied over @@ -2147,21 +2175,10 @@ void validate_marketplacelistings( void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id) { - LLInventoryItem* inv_item = gInventory.getItem(item_id); + LLViewerInventoryItem* inv_item = gInventory.getItem(item_id); if (inv_item) { - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item); - new_item->setParent(new_parent_id); - new_item->updateParentOnServer(false); - gInventory.updateItem(new_item); - gInventory.notifyObservers(); + gInventory.changeItemParent(inv_item, new_parent_id, false); } } @@ -2169,17 +2186,17 @@ void move_items_to_folder(const LLUUID& new_cat_uuid, const uuid_vec_t& selected { for (uuid_vec_t::const_iterator it = selected_uuids.begin(); it != selected_uuids.end(); ++it) { - LLInventoryItem* inv_item = gInventory.getItem(*it); + LLViewerInventoryItem* inv_item = gInventory.getItem(*it); if (inv_item) { - change_item_parent(*it, new_cat_uuid); + gInventory.changeItemParent(inv_item, new_cat_uuid, false); } else { - LLInventoryCategory* inv_cat = gInventory.getCategory(*it); + LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it); if (inv_cat && !LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType())) { - gInventory.changeCategoryParent((LLViewerInventoryCategory*)inv_cat, new_cat_uuid, false); + gInventory.changeCategoryParent(inv_cat, new_cat_uuid, false); } } } @@ -2314,7 +2331,7 @@ bool can_move_to_landmarks(LLInventoryItem* inv_item) } // Returns true if folder's content can be moved to Current Outfit or any outfit folder. -bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit) +bool can_move_to_my_outfits_as_outfit(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit) { LLInventoryModel::cat_array_t *cats; LLInventoryModel::item_array_t *items; @@ -2325,9 +2342,9 @@ bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_ca return false; } - if (items->size() == 0) + if (items->size() == 0 && inv_cat->getPreferredType() != LLFolderType::FT_OUTFIT) { - // Nothing to move(create) + // Nothing to create an outfit folder from return false; } @@ -2353,6 +2370,51 @@ bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_ca return true; } +bool can_move_to_my_outfits_as_subfolder(LLInventoryModel* model, LLInventoryCategory* inv_cat, S32 depth) +{ + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + model->getDirectDescendentsOf(inv_cat->getUUID(), cats, items); + + if (items->size() > 0) + { + // subfolders don't allow items + return false; + } + + if (inv_cat->getPreferredType() != LLFolderType::FT_NONE) + { + // only normal folders can become subfodlers + return false; + } + + constexpr size_t MAX_CONTENT = 255; + if (cats->size() > MAX_CONTENT) + { + // don't allow massive folders + return false; + } + + for (LLPointer<LLViewerInventoryCategory>& cat : *cats) + { + // outfits are valid to move, check non-outfit folders + if (cat->getPreferredType() != LLFolderType::FT_OUTFIT) + { + if (depth == 3) + { + // don't allow massive folders + return false; + } + if (!can_move_to_my_outfits_as_subfolder(model, cat, depth + 1)) + { + return false; + } + } + } + + return true; +} + std::string get_localized_folder_name(LLUUID cat_uuid) { std::string localized_root_name; @@ -2418,6 +2480,143 @@ void ungroup_folder_items(const LLUUID& folder_id) gInventory.notifyObservers(); } +class LLUpdateFavorite : public LLInventoryCallback +{ +public: + LLUpdateFavorite(const LLUUID& inv_item_id) + : mInvItemID(inv_item_id) + {} + /* virtual */ void fire(const LLUUID& inv_item_id) override + { + gInventory.addChangedMask(LLInventoryObserver::UPDATE_FAVORITE, mInvItemID); + + LLInventoryModel::item_array_t items; + LLInventoryModel::cat_array_t cat_array; + LLLinkedItemIDMatches matches(mInvItemID); + gInventory.collectDescendentsIf(gInventory.getRootFolderID(), + cat_array, + items, + LLInventoryModel::INCLUDE_TRASH, + matches); + + std::set<LLUUID> link_ids; + for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) + { + LLPointer<LLViewerInventoryItem> item = *it; + + gInventory.addChangedMask(LLInventoryObserver::UPDATE_FAVORITE, item->getUUID()); + } + + gInventory.notifyObservers(); + } +private: + LLUUID mInvItemID; +}; + +void favorite_send(LLInventoryObject* obj, const LLUUID& obj_id, bool favorite) +{ + LLSD updates; + if (favorite) + { + updates["favorite"] = LLSD().with("toggled", true); + } + else + { + updates["favorite"] = LLSD(); + } + + LLPointer<LLInventoryCallback> cb = new LLUpdateFavorite(obj_id); + + LLViewerInventoryCategory* view_folder = dynamic_cast<LLViewerInventoryCategory*>(obj); + if (view_folder) + { + update_inventory_category(obj_id, updates, cb); + } + LLViewerInventoryItem* view_item = dynamic_cast<LLViewerInventoryItem*>(obj); + if (view_item) + { + update_inventory_item(obj_id, updates, cb); + } +} + +bool get_is_favorite(const LLInventoryObject* object) +{ + if (object->getIsLinkType()) + { + LLInventoryObject* obj = gInventory.getObject(object->getLinkedUUID()); + return obj && obj->getIsFavorite(); + } + + return object->getIsFavorite(); +} + +bool get_is_favorite(const LLUUID& obj_id) +{ + LLInventoryObject* object = gInventory.getObject(obj_id); + if (object && object->getIsLinkType()) + { + LLInventoryObject* obj = gInventory.getObject(object->getLinkedUUID()); + return obj && obj->getIsFavorite(); + } + + return object->getIsFavorite(); +} + +void set_favorite(const LLUUID& obj_id, bool favorite) +{ + LLInventoryObject* obj = gInventory.getObject(obj_id); + + if (obj && obj->getIsLinkType()) + { + if (!favorite && obj->getIsFavorite()) + { + // Links currently aren't supposed to be favorites, + // instead should show state of the original + LL_INFOS("Inventory") << "Recovering proper 'favorites' state of a link " << obj_id << LL_ENDL; + favorite_send(obj, obj_id, false); + } + obj = gInventory.getObject(obj->getLinkedUUID()); + } + + if (obj && obj->getIsFavorite() != favorite) + { + favorite_send(obj, obj->getUUID(), favorite); + } +} + +void toggle_favorite(const LLUUID& obj_id) +{ + LLInventoryObject* obj = gInventory.getObject(obj_id); + if (obj && obj->getIsLinkType()) + { + obj = gInventory.getObject(obj->getLinkedUUID()); + } + + if (obj) + { + favorite_send(obj, obj->getUUID(), !obj->getIsFavorite()); + } +} + +void toggle_favorites(const uuid_vec_t& ids) +{ + if (ids.size() == 0) + { + return; + } + if (ids.size() == 1) + { + toggle_favorite(ids[0]); + return; + } + + bool new_val = !get_is_favorite(ids.front()); + for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) + { + set_favorite(*it, new_val); + } +} + std::string get_searchable_description(LLInventoryModel* model, const LLUUID& item_id) { if (model) @@ -2752,6 +2951,20 @@ bool LLIsTypeWithPermissions::operator()(LLInventoryCategory* cat, LLInventoryIt return false; } +bool LLFavoritesCollector::operator()(LLInventoryCategory* cat, + LLInventoryItem* item) +{ + if (item && item->getIsFavorite()) + { + return true; + } + if (cat && cat->getIsFavorite()) + { + return true; + } + return false; +} + bool LLBuddyCollector::operator()(LLInventoryCategory* cat, LLInventoryItem* item) { @@ -3236,7 +3449,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root for (LLInventoryModel::item_array_t::value_type& item : items) { - if (get_is_item_worn(item)) + if (!item->getIsLinkType() && get_is_item_worn(item)) { has_worn = true; LLWearableType::EType type = item->getWearableType(); @@ -3256,7 +3469,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } } LLViewerInventoryItem* item = gInventory.getItem(obj_id); - if (item && get_is_item_worn(item)) + if (item && !item->getIsLinkType() && get_is_item_worn(item)) { has_worn = true; LLWearableType::EType type = item->getWearableType(); @@ -3462,7 +3675,6 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } else if ("new_folder_from_selected" == action) { - LLInventoryObject* first_item = gInventory.getObject(*ids.begin()); if (!first_item) { @@ -3506,6 +3718,20 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root ungroup_folder_items(*ids.begin()); } } + else if ("add_to_favorites" == action) + { + for (const LLUUID& id : ids) + { + set_favorite(id, true); + } + } + else if ("remove_from_favorites" == action) + { + for (const LLUUID& id : ids) + { + set_favorite(id, false); + } + } else if ("thumbnail" == action) { if (selected_items.size() > 0) @@ -3616,6 +3842,54 @@ void LLInventoryAction::removeItemFromDND(LLFolderView* root) } } +void LLInventoryAction::fileUploadLocation(const LLUUID& dest_id, const std::string& action) +{ + if (action == "def_model") + { + gSavedPerAccountSettings.setString("ModelUploadFolder", dest_id.asString()); + } + else if (action == "def_texture") + { + gSavedPerAccountSettings.setString("TextureUploadFolder", dest_id.asString()); + } + else if (action == "def_sound") + { + gSavedPerAccountSettings.setString("SoundUploadFolder", dest_id.asString()); + } + else if (action == "def_animation") + { + gSavedPerAccountSettings.setString("AnimationUploadFolder", dest_id.asString()); + } + else if (action == "def_pbr_material") + { + gSavedPerAccountSettings.setString("PBRUploadFolder", dest_id.asString()); + } + else if (action == "upload_texture") + { + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2, dest_id), LLFilePicker::FFLOAD_IMAGE, false); + } + else if (action == "upload_sound") + { + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2, dest_id), LLFilePicker::FFLOAD_WAV, false); + } + else if (action == "upload_animation") + { + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2, dest_id), LLFilePicker::FFLOAD_ANIM, false); + } + else if (action == "upload_model") + { + LLFloaterModelPreview::showModelPreview(dest_id); + } + else if (action == "upload_pbr_material") + { + LLMaterialEditor::importMaterial(dest_id); + } + else if (action == "upload_bulk") + { + LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2, true, dest_id), LLFilePicker::FFLOAD_ALL, true); + } +} + void LLInventoryAction::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -3724,15 +3998,17 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root) for (; set_iter != selected_items.end(); ++set_iter) { viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*set_iter)->getViewModelItem()); - if (!viewModel || !viewModel->getInventoryObject()) continue; - if (gInventory.isObjectDescendentOf(viewModel->getInventoryObject()->getParentUUID(), marketplacelistings_id)) + if (!viewModel) continue; + LLInventoryObject* inv_obj = viewModel->getInventoryObject(); + if (!inv_obj) continue; + if (gInventory.isObjectDescendentOf(inv_obj->getParentUUID(), marketplacelistings_id)) { - const LLUUID &parent_id = viewModel->getInventoryObject()->getParentUUID(); + const LLUUID &parent_id = inv_obj->getParentUUID(); if (parent_id != marketplacelistings_id) { sMarketplaceFolders.push_back(parent_id); } - const LLUUID &curr_id = viewModel->getInventoryObject()->getUUID(); + const LLUUID &curr_id = inv_obj->getUUID(); if (curr_id != marketplacelistings_id) { sMarketplaceFolders.push_back(curr_id); diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index 0ab045f2a0..ae7bb8770d 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -78,6 +78,7 @@ void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::s void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id = LLUUID::null, bool move_no_copy_items = false); void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id, bool move_no_copy_items, inventory_func_type callback); +void copy_inventory_category(LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& parent_id, const LLUUID& root_copy_id, bool move_no_copy_items, LLPointer<LLInventoryCallback> callback); void copy_inventory_category_content(const LLUUID& new_cat_uuid, LLInventoryModel* model, LLViewerInventoryCategory* cat, const LLUUID& root_copy_id, bool move_no_copy_items); @@ -112,10 +113,16 @@ std::string get_category_path(LLUUID cat_id); bool can_move_to_outfit(LLInventoryItem* inv_item, bool move_is_into_current_outfit); bool can_move_to_landmarks(LLInventoryItem* inv_item); -bool can_move_to_my_outfits(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit); +bool can_move_to_my_outfits_as_outfit(LLInventoryModel* model, LLInventoryCategory* inv_cat, U32 wear_limit); +bool can_move_to_my_outfits_as_subfolder(LLInventoryModel* model, LLInventoryCategory* inv_cat, S32 depth = 0); std::string get_localized_folder_name(LLUUID cat_uuid); void new_folder_window(const LLUUID& folder_id); void ungroup_folder_items(const LLUUID& folder_id); +bool get_is_favorite(const LLInventoryObject* object); +bool get_is_favorite(const LLUUID& obj_id); +void set_favorite(const LLUUID& obj_id, bool favorite); +void toggle_favorite(const LLUUID& obj_id); +void toggle_favorites(const uuid_vec_t& ids); std::string get_searchable_description(LLInventoryModel* model, const LLUUID& item_id); std::string get_searchable_creator_name(LLInventoryModel* model, const LLUUID& item_id); std::string get_searchable_UUID(LLInventoryModel* model, const LLUUID& item_id); @@ -199,7 +206,9 @@ class LLInventoryCollectFunctor { public: virtual ~LLInventoryCollectFunctor(){}; - virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) = 0; + virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) = 0; + + virtual bool exceedsLimit() { return false; } static bool itemTransferCommonlyAllowed(const LLInventoryItem* item); }; @@ -374,6 +383,18 @@ protected: }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFavoritesCollector +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFavoritesCollector : public LLInventoryCollectFunctor +{ +public: + LLFavoritesCollector() {} + virtual ~LLFavoritesCollector() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLBuddyCollector // // Simple class that collects calling cards that are not null, and not @@ -631,6 +652,7 @@ struct LLInventoryAction static void callback_copySelected(const LLSD& notification, const LLSD& response, class LLInventoryModel* model, class LLFolderView* root, const std::string& action); static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLHandle<LLFolderView> root); static void removeItemFromDND(LLFolderView* root); + static void fileUploadLocation(const LLUUID& dest_id, const std::string& action); static void saveMultipleTextures(const std::vector<std::string>& filenames, std::set<LLFolderViewItem*> selected_items, LLInventoryModel* model); diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp index 713d87787e..a4cb6ea65d 100644 --- a/indra/newview/llinventorygallery.cpp +++ b/indra/newview/llinventorygallery.cpp @@ -65,7 +65,7 @@ const S32 FAST_LOAD_THUMBNAIL_TRSHOLD = 50; // load folders below this value imm bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, bool drop, std::string& tooltip_msg, bool is_link); bool dragItemIntoFolder(LLUUID folder_id, LLInventoryItem* inv_item, bool drop, std::string& tooltip_msg, bool user_confirm); void dropToMyOutfits(LLInventoryCategory* inv_cat); -void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id, LLFolderType::EType preferred_type); +void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID& dest_id); class LLGalleryPanel: public LLPanel { @@ -636,7 +636,7 @@ void LLInventoryGallery::removeFromLastRow(LLInventoryGalleryItem* item) mItemPanels.pop_back(); } -LLInventoryGalleryItem* LLInventoryGallery::buildGalleryItem(std::string name, LLUUID item_id, LLAssetType::EType type, LLUUID thumbnail_id, LLInventoryType::EType inventory_type, U32 flags, time_t creation_date, bool is_link, bool is_worn) +LLInventoryGalleryItem* LLInventoryGallery::buildGalleryItem(std::string name, LLUUID item_id, LLAssetType::EType type, LLUUID thumbnail_id, LLInventoryType::EType inventory_type, U32 flags, time_t creation_date, bool is_link, bool is_worn, bool is_favorite) { LLInventoryGalleryItem::Params giparams; giparams.visible = true; @@ -647,6 +647,7 @@ LLInventoryGalleryItem* LLInventoryGallery::buildGalleryItem(std::string name, L gitem->setUUID(item_id); gitem->setGallery(this); gitem->setType(type, inventory_type, flags, is_link); + gitem->setFavorite(is_favorite); gitem->setLoadImmediately(mLoadThumbnailsImmediately); gitem->setThumbnail(thumbnail_id); gitem->setWorn(is_worn); @@ -939,8 +940,19 @@ bool LLInventoryGallery::updateAddedItem(LLUUID item_id) } bool res = false; - - LLInventoryGalleryItem* item = buildGalleryItem(name, item_id, obj->getType(), thumbnail_id, inventory_type, misc_flags, obj->getCreationDate(), obj->getIsLinkType(), is_worn); + bool is_favorite = get_is_favorite(obj); + + LLInventoryGalleryItem* item = buildGalleryItem( + name, + item_id, + obj->getType(), + thumbnail_id, + inventory_type, + misc_flags, + obj->getCreationDate(), + obj->getIsLinkType(), + is_worn, + is_favorite); mItemMap.insert(LLInventoryGallery::gallery_item_map_t::value_type(item_id, item)); if (mGalleryCreated) { @@ -977,7 +989,7 @@ void LLInventoryGallery::updateRemovedItem(LLUUID item_id) mItemBuildQuery.erase(item_id); } -void LLInventoryGallery::updateChangedItemName(LLUUID item_id, std::string name) +void LLInventoryGallery::updateChangedItemData(LLUUID item_id, std::string name, bool is_favorite) { gallery_item_map_t::iterator iter = mItemMap.find(item_id); if (iter != mItemMap.end()) @@ -986,6 +998,7 @@ void LLInventoryGallery::updateChangedItemName(LLUUID item_id, std::string name) if (item) { item->setItemName(name); + item->setFavorite(is_favorite); } } } @@ -2001,7 +2014,7 @@ void LLInventoryGallery::deleteSelection() for (LLInventoryModel::item_array_t::value_type& item : items) { - if (get_is_item_worn(item)) + if (!item->getIsLinkType() && get_is_item_worn(item)) { has_worn = true; LLWearableType::EType type = item->getWearableType(); @@ -2022,7 +2035,7 @@ void LLInventoryGallery::deleteSelection() } LLViewerInventoryItem* item = gInventory.getItem(id); - if (item && get_is_item_worn(item)) + if (item && !item->getIsLinkType() && get_is_item_worn(item)) { has_worn = true; LLWearableType::EType type = item->getWearableType(); @@ -2335,7 +2348,7 @@ void LLInventoryGallery::refreshList(const LLUUID& category_id) return; } - updateChangedItemName(*items_iter, obj->getName()); + updateChangedItemData(*items_iter, obj->getName(), get_is_favorite(obj)); mNeedsArrange = true; } @@ -2851,6 +2864,14 @@ void LLInventoryGalleryItem::setType(LLAssetType::EType type, LLInventoryType::E getChild<LLIconCtrl>("link_overlay")->setVisible(is_link); } +void LLInventoryGalleryItem::setFavorite(bool is_favorite) +{ + getChild<LLIconCtrl>("fav_icon")->setVisible(is_favorite); + static const LLUIColor text_color = LLUIColorTable::instance().getColor("LabelTextColor", LLColor4::white); + static const LLUIColor favorite_color = LLUIColorTable::instance().getColor("InventoryFavoriteColor", LLColor4::white); + mNameText->setReadOnlyColor(is_favorite ? favorite_color : text_color); +} + void LLInventoryGalleryItem::setThumbnail(LLUUID id) { mDefaultImage = id.isNull(); @@ -3714,6 +3735,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, // bool is_movable = true; + bool create_outfit = false; if (is_movable && (marketplacelistings_id == cat_id)) { @@ -3759,7 +3781,12 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, tooltip_msg = LLTrans::getString("TooltipOutfitNotInInventory"); is_movable = false; } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -3783,7 +3810,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantMoveOutfitIntoOutfit"); } - else if ((dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) && inv_res == MY_OUTFITS_SUBFOLDER) + else if (dest_res == MY_OUTFITS_OUTFIT || dest_res == MY_OUTFITS_SUBOUTFIT) { is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); @@ -3793,7 +3820,12 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, is_movable = false; tooltip_msg = LLTrans::getString("TooltipCantCreateOutfit"); } - else if (can_move_to_my_outfits(model, inv_cat, max_items_to_wear)) + else if (can_move_to_my_outfits_as_outfit(model, inv_cat, max_items_to_wear)) + { + is_movable = true; + create_outfit = true; + } + else if (can_move_to_my_outfits_as_subfolder(model, inv_cat)) { is_movable = true; } @@ -3928,7 +3960,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, if (dest_id == my_outifts_id) { EMyOutfitsSubfolderType inv_res = myoutfit_object_subfolder_type(model, cat_id, my_outifts_id); - if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT) + if (inv_res == MY_OUTFITS_SUBFOLDER || inv_res == MY_OUTFITS_OUTFIT || !create_outfit) { gInventory.changeCategoryParent( (LLViewerInventoryCategory*)inv_cat, @@ -3950,14 +3982,17 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, { case MY_OUTFITS_NO: // Moning from outside outfits into outfits - if (dest_res == MY_OUTFITS_SUBFOLDER) + if (dest_res == MY_OUTFITS_SUBFOLDER && create_outfit) { // turn it into outfit - dropToMyOutfitsSubfolder(inv_cat, dest_id, LLFolderType::FT_OUTFIT); + dropToMyOutfitsSubfolder(inv_cat, dest_id); } else { - dropToMyOutfitsSubfolder(inv_cat, dest_id, LLFolderType::FT_NONE); + gInventory.changeCategoryParent( + (LLViewerInventoryCategory*)inv_cat, + dest_id, + move_is_into_trash); } break; case MY_OUTFITS_SUBFOLDER: @@ -4136,10 +4171,10 @@ void dropToMyOutfits(LLInventoryCategory* inv_cat) gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID()); } -void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID &dest_id, LLFolderType::EType preferred_type) +void dropToMyOutfitsSubfolder(LLInventoryCategory* inv_cat, const LLUUID &dest_id) { // Note: creation will take time, so passing folder id to callback is slightly unreliable, // but so is collecting and passing descendants' ids inventory_func_type func = boost::bind(&outfitFolderCreatedCallback, inv_cat->getUUID(), _1); - gInventory.createNewCategory(dest_id, preferred_type, inv_cat->getName(), func, inv_cat->getThumbnailUUID()); + gInventory.createNewCategory(dest_id, LLFolderType::FT_OUTFIT, inv_cat->getName(), func, inv_cat->getThumbnailUUID()); } diff --git a/indra/newview/llinventorygallery.h b/indra/newview/llinventorygallery.h index 59d08d19ed..7f53f9998d 100644 --- a/indra/newview/llinventorygallery.h +++ b/indra/newview/llinventorygallery.h @@ -102,7 +102,7 @@ public: void getCurrentCategories(uuid_vec_t& vcur); bool updateAddedItem(LLUUID item_id); // returns true if added item is visible void updateRemovedItem(LLUUID item_id); - void updateChangedItemName(LLUUID item_id, std::string name); + void updateChangedItemData(LLUUID item_id, std::string name, bool is_favorite); void updateItemThumbnail(LLUUID item_id); void updateWornItem(LLUUID item_id, bool is_worn); @@ -227,7 +227,7 @@ private: bool updateRowsIfNeeded(); void updateGalleryWidth(); - LLInventoryGalleryItem* buildGalleryItem(std::string name, LLUUID item_id, LLAssetType::EType type, LLUUID thumbnail_id, LLInventoryType::EType inventory_type, U32 flags, time_t creation_date, bool is_link, bool is_worn); + LLInventoryGalleryItem* buildGalleryItem(std::string name, LLUUID item_id, LLAssetType::EType type, LLUUID thumbnail_id, LLInventoryType::EType inventory_type, U32 flags, time_t creation_date, bool is_link, bool is_worn, bool is_favorite); LLInventoryGalleryItem* getItem(const LLUUID& id) const; void buildGalleryPanel(int row_count); @@ -343,6 +343,7 @@ public: void setHidden(bool hidden) {mHidden = hidden;} void setType(LLAssetType::EType type, LLInventoryType::EType inventory_type, U32 flags, bool is_link); + void setFavorite(bool is_favorite); LLAssetType::EType getAssetType() { return mType; } void setThumbnail(LLUUID id); void setGallery(LLInventoryGallery* gallery) { mGallery = gallery; } diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp index 7acd3b90a2..7212c4dedb 100644 --- a/indra/newview/llinventorygallerymenu.cpp +++ b/indra/newview/llinventorygallerymenu.cpp @@ -250,6 +250,20 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata) { ungroup_folder_items(mUUIDs.front()); } + else if ("add_to_favorites" == action) + { + for (const LLUUID& id : mUUIDs) + { + set_favorite(id, true); + } + } + else if ("remove_from_favorites" == action) + { + for (const LLUUID& id : mUUIDs) + { + set_favorite(id, false); + } + } else if ("replaceoutfit" == action) { modify_outfit(false, mUUIDs.front(), &gInventory); @@ -472,22 +486,7 @@ void LLInventoryGalleryContextMenu::onRename(const LLSD& notification, const LLS void LLInventoryGalleryContextMenu::fileUploadLocation(const LLSD& userdata) { const std::string param = userdata.asString(); - if (param == "model") - { - gSavedPerAccountSettings.setString("ModelUploadFolder", mUUIDs.front().asString()); - } - else if (param == "texture") - { - gSavedPerAccountSettings.setString("TextureUploadFolder", mUUIDs.front().asString()); - } - else if (param == "sound") - { - gSavedPerAccountSettings.setString("SoundUploadFolder", mUUIDs.front().asString()); - } - else if (param == "animation") - { - gSavedPerAccountSettings.setString("AnimationUploadFolder", mUUIDs.front().asString()); - } + LLInventoryAction::fileUploadLocation(mUUIDs.front(), param); } bool LLInventoryGalleryContextMenu::canSetUploadLocation(const LLSD& userdata) @@ -768,6 +767,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men { items.push_back(std::string("New Folder")); } + items.push_back(std::string("upload_options")); items.push_back(std::string("upload_def")); } @@ -777,8 +777,8 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men if (res != MY_OUTFITS_OUTFIT && res != MY_OUTFITS_SUBOUTFIT) { items.push_back(std::string("New Outfit")); + items.push_back(std::string("New Outfit Folder")); } - items.push_back(std::string("New Outfit Folder")); items.push_back(std::string("Delete")); items.push_back(std::string("Rename")); if (!get_is_category_and_children_removable(&gInventory, selected_id, false)) @@ -787,6 +787,18 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } } + if (!is_trash && !is_in_trash && gInventory.getRootFolderID() != selected_id) + { + if (get_is_favorite(obj)) + { + items.push_back(std::string("Remove from Favorites")); + } + else + { + items.push_back(std::string("Add to Favorites")); + } + } + items.push_back(std::string("Subfolder Separator")); if (!is_system_folder && !isRootFolder() && !is_outfits) { @@ -832,6 +844,17 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men if(is_agent_inventory) { items.push_back(std::string("Cut")); + if (!is_in_trash) + { + if (get_is_favorite(obj)) + { + items.push_back(std::string("Remove from Favorites")); + } + else + { + items.push_back(std::string("Add to Favorites")); + } + } if (!is_link || !is_cof || !get_is_item_worn(selected_id)) { items.push_back(std::string("Delete")); @@ -968,6 +991,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men } disabled_items.push_back(std::string("New Folder")); + disabled_items.push_back(std::string("upload_options")); disabled_items.push_back(std::string("upload_def")); disabled_items.push_back(std::string("create_new")); } @@ -1018,6 +1042,15 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men disabled_items.push_back(std::string("Marketplace Move")); } } + + if (get_is_favorite(obj)) + { + items.push_back(std::string("Remove from Favorites")); + } + else if (is_agent_inventory) + { + items.push_back(std::string("Add to Favorites")); + } } hide_context_entries(*menu, items, disabled_items); diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index 2e0669fc38..cfa37cc3ee 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -115,7 +115,7 @@ void LLInventoryItemsList::doIdle() { if (mRefreshState == REFRESH_COMPLETE) return; - if (isInVisibleChain() || mForceRefresh ) + if (isInVisibleChain() || mForceRefresh || !getFilterSubString().empty()) { refresh(); diff --git a/indra/newview/llinventorylistener.cpp b/indra/newview/llinventorylistener.cpp new file mode 100644 index 0000000000..028483e134 --- /dev/null +++ b/indra/newview/llinventorylistener.cpp @@ -0,0 +1,309 @@ +/** + * @file llinventorylistener.cpp + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, 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 "llinventorylistener.h" + +#include "llappearancemgr.h" +#include "llinventoryfunctions.h" +#include "lltransutil.h" +#include "llwearableitemslist.h" +#include "stringize.h" + +LLInventoryListener::LLInventoryListener() + : LLEventAPI("LLInventory", + "API for interactions with viewer Inventory items") +{ + add("getItemsInfo", + "Return information about items or folders defined in [\"item_ids\"]:\n" + "reply will contain [\"items\"] and [\"categories\"] result set keys", + &LLInventoryListener::getItemsInfo, + llsd::map("item_ids", LLSD(), "reply", LLSD())); + + add("getFolderTypeNames", + "Return the table of folder type names, contained in [\"names\"]\n", + &LLInventoryListener::getFolderTypeNames, + llsd::map("reply", LLSD())); + + add("getAssetTypeNames", + "Return the table of asset type names, contained in [\"names\"]\n", + &LLInventoryListener::getAssetTypeNames, + llsd::map("reply", LLSD())); + + add("getBasicFolderID", + "Return the UUID of the folder by specified folder type name, for example:\n" + "\"Textures\", \"My outfits\", \"Sounds\" and other basic folders which have associated type", + &LLInventoryListener::getBasicFolderID, + llsd::map("ft_name", LLSD(), "reply", LLSD())); + + add("getDirectDescendants", + "Return result set keys [\"categories\"] and [\"items\"] for the direct\n" + "descendants of the [\"folder_id\"]", + &LLInventoryListener::getDirectDescendants, + llsd::map("folder_id", LLSD(), "reply", LLSD())); + + add("collectDescendantsIf", + "Return result set keys [\"categories\"] and [\"items\"] for the descendants\n" + "of the [\"folder_id\"], if it passes specified filters:\n" + "[\"name\"] is a substring of object's name,\n" + "[\"desc\"] is a substring of object's description,\n" + "asset [\"type\"] corresponds to the string name of the object's asset type\n" + "[\"limit\"] sets item count limit in result set (default unlimited)\n" + "[\"filter_links\"]: EXCLUDE_LINKS - don't show links, ONLY_LINKS - only show links, INCLUDE_LINKS - show links too (default)", + &LLInventoryListener::collectDescendantsIf, + llsd::map("folder_id", LLSD(), "reply", LLSD())); +} + +void add_cat_info(LLEventAPI::Response& response, LLViewerInventoryCategory* cat) +{ + response["categories"].insert(cat->getUUID().asString(), + llsd::map("id", cat->getUUID(), + "name", cat->getName(), + "parent_id", cat->getParentUUID(), + "type", LLFolderType::lookup(cat->getPreferredType()))); + +}; + +void add_item_info(LLEventAPI::Response& response, LLViewerInventoryItem* item) +{ + response["items"].insert(item->getUUID().asString(), + llsd::map("id", item->getUUID(), + "name", item->getName(), + "parent_id", item->getParentUUID(), + "desc", item->getDescription(), + "inv_type", LLInventoryType::lookup(item->getInventoryType()), + "asset_type", LLAssetType::lookup(item->getType()), + "creation_date", LLSD::Integer(item->getCreationDate()), + "asset_id", item->getAssetUUID(), + "is_link", item->getIsLinkType(), + "linked_id", item->getLinkedUUID())); +} + +void add_objects_info(LLEventAPI::Response& response, LLInventoryModel::cat_array_t cat_array, LLInventoryModel::item_array_t item_array) +{ + for (auto& p : item_array) + { + add_item_info(response, p); + } + for (auto& p : cat_array) + { + add_cat_info(response, p); + } +} + +void LLInventoryListener::getItemsInfo(LLSD const &data) +{ + Response response(LLSD(), data); + uuid_vec_t ids = LLSDParam<uuid_vec_t>(data["item_ids"]); + for (auto &it : ids) + { + LLViewerInventoryItem* item = gInventory.getItem(it); + if (item) + { + add_item_info(response, item); + } + else + { + LLViewerInventoryCategory *cat = gInventory.getCategory(it); + if (cat) + { + add_cat_info(response, cat); + } + } + } +} + +void LLInventoryListener::getFolderTypeNames(LLSD const &data) +{ + Response response(llsd::map("names", LLFolderType::getTypeNames()), data); +} + +void LLInventoryListener::getAssetTypeNames(LLSD const &data) +{ + Response response(llsd::map("names", LLAssetType::getTypeNames()), data); +} + +void LLInventoryListener::getBasicFolderID(LLSD const &data) +{ + Response response(llsd::map("id", gInventory.findCategoryUUIDForType(LLFolderType::lookup(data["ft_name"].asString()))), data); +} + + +void LLInventoryListener::getDirectDescendants(LLSD const &data) +{ + Response response(LLSD(), data); + LLUUID folder_id(data["folder_id"].asUUID()); + LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id); + if (!cat) + { + return response.error(stringize("Folder ", std::quoted(data["folder_id"].asString()), " was not found")); + } + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(folder_id, cats, items); + + add_objects_info(response, *cats, *items); +} + +struct LLFilteredCollector : public LLInventoryCollectFunctor +{ + enum EFilterLink + { + INCLUDE_LINKS, // show links too + EXCLUDE_LINKS, // don't show links + ONLY_LINKS // only show links + }; + + LLFilteredCollector(LLSD const &data); + virtual ~LLFilteredCollector() {} + virtual bool operator()(LLInventoryCategory *cat, LLInventoryItem *item) override; + virtual bool exceedsLimit() override + { + // mItemLimit == 0 means unlimited + return (mItemLimit && mItemLimit <= mItemCount); + } + + protected: + bool checkagainstType(LLInventoryCategory *cat, LLInventoryItem *item); + bool checkagainstNameDesc(LLInventoryCategory *cat, LLInventoryItem *item); + bool checkagainstLinks(LLInventoryCategory *cat, LLInventoryItem *item); + + LLAssetType::EType mType; + std::string mName; + std::string mDesc; + EFilterLink mLinkFilter; + + S32 mItemLimit; + S32 mItemCount; +}; + +void LLInventoryListener::collectDescendantsIf(LLSD const &data) +{ + Response response(LLSD(), data); + LLUUID folder_id(data["folder_id"].asUUID()); + LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id); + if (!cat) + { + return response.error(stringize("Folder ", std::quoted(data["folder_id"].asString()), " was not found")); + } + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + + LLFilteredCollector collector = LLFilteredCollector(data); + + gInventory.collectDescendentsIf(folder_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, collector); + + add_objects_info(response, cat_array, item_array); +} + +LLFilteredCollector::LLFilteredCollector(LLSD const &data) : + mType(LLAssetType::EType::AT_UNKNOWN), + mLinkFilter(INCLUDE_LINKS), + mItemLimit(0), + mItemCount(0) +{ + + mName = data["name"].asString(); + mDesc = data["desc"].asString(); + + if (data.has("type")) + { + mType = LLAssetType::lookup(data["type"]); + } + if (data.has("filter_links")) + { + if (data["filter_links"] == "EXCLUDE_LINKS") + { + mLinkFilter = EXCLUDE_LINKS; + } + else if (data["filter_links"] == "ONLY_LINKS") + { + mLinkFilter = ONLY_LINKS; + } + } + if (data["limit"].isInteger()) + { + mItemLimit = std::max(data["limit"].asInteger(), 1); + } +} + +bool LLFilteredCollector::operator()(LLInventoryCategory *cat, LLInventoryItem *item) +{ + bool passed = checkagainstType(cat, item); + passed = passed && checkagainstNameDesc(cat, item); + passed = passed && checkagainstLinks(cat, item); + + if (passed) + { + ++mItemCount; + } + return passed; +} + +bool LLFilteredCollector::checkagainstNameDesc(LLInventoryCategory *cat, LLInventoryItem *item) +{ + std::string name, desc; + bool passed(true); + if (cat) + { + if (!mDesc.empty()) return false; + name = cat->getName(); + } + if (item) + { + name = item->getName(); + passed = (mDesc.empty() || (item->getDescription().find(mDesc) != std::string::npos)); + } + + return passed && (mName.empty() || name.find(mName) != std::string::npos); +} + +bool LLFilteredCollector::checkagainstType(LLInventoryCategory *cat, LLInventoryItem *item) +{ + if (mType == LLAssetType::AT_UNKNOWN) + { + return true; + } + if (cat && (mType == LLAssetType::AT_CATEGORY)) + { + return true; + } + if (item && item->getType() == mType) + { + return true; + } + return false; +} + +bool LLFilteredCollector::checkagainstLinks(LLInventoryCategory *cat, LLInventoryItem *item) +{ + bool is_link = cat ? cat->getIsLinkType() : item->getIsLinkType(); + if (is_link && (mLinkFilter == EXCLUDE_LINKS)) + return false; + if (!is_link && (mLinkFilter == ONLY_LINKS)) + return false; + return true; +} diff --git a/indra/newview/llinventorylistener.h b/indra/newview/llinventorylistener.h new file mode 100644 index 0000000000..d50397730c --- /dev/null +++ b/indra/newview/llinventorylistener.h @@ -0,0 +1,48 @@ +/** + * @file llinventorylistener.h + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#ifndef LL_LLINVENTORYLISTENER_H +#define LL_LLINVENTORYLISTENER_H + +#include "lleventapi.h" +#include "llinventoryfunctions.h" + +class LLInventoryListener : public LLEventAPI +{ +public: + LLInventoryListener(); + +private: + void getItemsInfo(LLSD const &data); + void getFolderTypeNames(LLSD const &data); + void getAssetTypeNames(LLSD const &data); + void getBasicFolderID(LLSD const &data); + void getDirectDescendants(LLSD const &data); + void collectDescendantsIf(LLSD const &data); +}; + +#endif // LL_LLINVENTORYLISTENER_H + diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp index e210975a5a..5fb5b0f23f 100644 --- a/indra/newview/llinventorylistitem.cpp +++ b/indra/newview/llinventorylistitem.cpp @@ -43,7 +43,19 @@ static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelInventoryListItemBaseParams(&typeid(LLPanelInventoryListItemBase::Params), "inventory_list_item"); -static const S32 WIDGET_SPACING = 3; +constexpr S32 WIDGET_SPACING = 3; +constexpr S32 FAVORITE_IMAGE_SIZE = 14; +constexpr S32 FAVORITE_IMAGE_PAD = 3; + +bool get_is_item_favorite(const LLViewerInventoryItem* inv) +{ + if (inv->getIsLinkType()) + { + LLInventoryObject* obj = gInventory.getObject(inv->getLinkedUUID()); + return obj && obj->getIsFavorite(); + } + return inv->getIsFavorite(); +} LLPanelInventoryListItemBase::Params::Params() : default_style("default_style"), @@ -75,19 +87,30 @@ void LLPanelInventoryListItemBase::draw() LLViewerInventoryItem* inv_item = getItem(); if (inv_item) { - updateItem(inv_item->getName()); + updateItem(inv_item->getName(), get_is_item_favorite(inv_item)); } setNeedsRefresh(false); } + static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true); + + LLRect local_rect = getLocalRect(); if (mHovered && mHoverImage) { - mHoverImage->draw(getLocalRect()); + mHoverImage->draw(local_rect); + } + else if (mIsFavorite && draw_star()) + { + + static LLPointer<LLUIImage> fav_img = LLRender2D::getInstance()->getUIImage("Inv_Favorite_Star_Full"); + gl_draw_scaled_image( + local_rect.getWidth() - FAVORITE_IMAGE_SIZE - FAVORITE_IMAGE_PAD, FAVORITE_IMAGE_PAD, + FAVORITE_IMAGE_SIZE, FAVORITE_IMAGE_SIZE, fav_img->getImage()); } if (mSelected && mSelectedImage) { - mSelectedImage->draw(getLocalRect()); + mSelectedImage->draw(local_rect); } if (mSeparatorVisible && mSeparatorImage) @@ -95,7 +118,7 @@ void LLPanelInventoryListItemBase::draw() // place under bottom of listitem, using image height // item_pad in list using the item should be >= image height // to avoid cropping of top of the next item. - LLRect separator_rect = getLocalRect(); + LLRect separator_rect = local_rect; separator_rect.mTop = separator_rect.mBottom; separator_rect.mBottom -= mSeparatorImage->getHeight(); F32 alpha = getCurrentTransparency(); @@ -107,9 +130,15 @@ void LLPanelInventoryListItemBase::draw() // virtual void LLPanelInventoryListItemBase::updateItem(const std::string& name, + bool favorite, EItemState item_state) { setIconImage(mIconImage); + if (mIsFavorite != favorite) + { + mIsFavorite = favorite; + reshapeMiddleWidgets(); + } setTitle(name, mHighlightedText, item_state); } @@ -164,7 +193,7 @@ bool LLPanelInventoryListItemBase::postBuild() if (inv_item) { mIconImage = LLInventoryIcon::getIcon(inv_item->getType(), inv_item->getInventoryType(), inv_item->getFlags(), false); - updateItem(inv_item->getName()); + updateItem(inv_item->getName(), get_is_item_favorite(inv_item)); } setNeedsRefresh(true); @@ -290,6 +319,7 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem mHovered(false), mSelected(false), mSeparatorVisible(false), + mIsFavorite(false), mHoverImage(params.hover_image), mSelectedImage(params.selected_image), mSeparatorImage(params.separator_image) @@ -392,6 +422,16 @@ void LLPanelInventoryListItemBase::setTitle(const std::string& title, default:; } + if (mIsFavorite) + { + static LLUICachedControl<bool> use_color("InventoryFavoritesColorText", true); + if (use_color) + { + static const LLUIColor favorite_color = LLUIColorTable::instance().getColor("InventoryFavoriteColor", LLColor4::white); + style_params.color = favorite_color; + } + } + LLTextUtil::textboxSetHighlightedVal( mTitleCtrl, style_params, @@ -466,6 +506,10 @@ void LLPanelInventoryListItemBase::reshapeMiddleWidgets() S32 name_left = icon_rect.mRight + getWidgetSpacing(); S32 name_right = getLocalRect().getWidth() - mRightWidgetsWidth - getWidgetSpacing(); + if (mIsFavorite) + { + name_right -= FAVORITE_IMAGE_SIZE + FAVORITE_IMAGE_PAD; + } LLRect name_rect(mTitleCtrl->getRect()); name_rect.set(name_left, name_rect.mTop, name_right, name_rect.mBottom); mTitleCtrl->setShape(name_rect); diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h index 21540a380b..40a86001a4 100644 --- a/indra/newview/llinventorylistitem.h +++ b/indra/newview/llinventorylistitem.h @@ -167,6 +167,7 @@ protected: * Called after inventory item was updated, update panel widgets to reflect inventory changes. */ virtual void updateItem(const std::string& name, + bool favorite, EItemState item_state = IS_DEFAULT); void setLeftWidgetsWidth(S32 width) { mLeftWidgetsWidth = width; } @@ -222,8 +223,9 @@ private: LLUIImagePtr mSelectedImage; LLUIImagePtr mSeparatorImage; - bool mSelected; - bool mSeparatorVisible; + bool mSelected = false; + bool mSeparatorVisible = false; + bool mIsFavorite = false; // note that any setter needs to update tittle std::string mHighlightedText; diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 0a2d938bd0..2dfc3b014f 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -78,7 +78,7 @@ // Increment this if the inventory contents change in a non-backwards-compatible way. // For viewer 2, the addition of link items makes a pre-viewer-2 cache incorrect. -const S32 LLInventoryModel::sCurrentInvCacheVersion = 3; +const S32 LLInventoryModel::sCurrentInvCacheVersion = 5; bool LLInventoryModel::sFirstTimeInViewer2 = true; S32 LLInventoryModel::sPendingSystemFolders = 0; @@ -1283,6 +1283,10 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, { for (auto& cat : *cat_array) { + if (add.exceedsLimit()) + { + break; + } if(add(cat,NULL)) { cats.push_back(cat); @@ -1298,6 +1302,10 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id, { for (auto& item : *item_array) { + if (add.exceedsLimit()) + { + break; + } if(add(NULL, item)) { items.push_back(item); @@ -2682,6 +2690,7 @@ bool LLInventoryModel::loadSkeleton( LL_PROFILE_ZONE_SCOPED; LL_DEBUGS(LOG_INV) << "importing inventory skeleton for " << owner_id << LL_ENDL; + LLTimer timer; typedef std::set<LLPointer<LLViewerInventoryCategory>, InventoryIDPtrLess> cat_set_t; cat_set_t temp_cats; bool rv = true; @@ -2768,6 +2777,7 @@ bool LLInventoryModel::loadSkeleton( bool is_cache_obsolete = false; if (loadFromFile(inventory_filename, categories, items, categories_to_update, is_cache_obsolete)) { + LL_PROFILE_ZONE_NAMED("loadFromFile"); // We were able to find a cache of files. So, use what we // found to generate a set of categories we should add. We // will go through each category loaded and if the version @@ -2807,8 +2817,9 @@ bool LLInventoryModel::loadSkeleton( cached_ids.insert(tcat->getUUID()); // At the moment download does not provide a thumbnail - // uuid, use the one from cache + // uuid or favorite, use values from cache tcat->setThumbnailUUID(cat->getThumbnailUUID()); + tcat->setFavorite(cat->getIsFavorite()); } } @@ -2965,7 +2976,8 @@ bool LLInventoryModel::loadSkeleton( } LL_INFOS(LOG_INV) << "Successfully loaded " << cached_category_count - << " categories and " << cached_item_count << " items from cache." + << " categories and " << cached_item_count << " items from cache" + << " after " << timer.getElapsedTimeF32() << " seconds." << LL_ENDL; return rv; @@ -3372,7 +3384,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, } LL_INFOS(LOG_INV) << "loading inventory from: (" << filename << ")" << LL_ENDL; - llifstream file(filename.c_str()); + llifstream file(filename.c_str(), std::ifstream::in | std::ifstream::binary); if (!file.is_open()) { @@ -3381,80 +3393,92 @@ bool LLInventoryModel::loadFromFile(const std::string& filename, } is_cache_obsolete = true; // Obsolete until proven current - - //U64 lines_count = 0U; - std::string line; - LLPointer<LLSDParser> parser = new LLSDNotationParser(); - while (std::getline(file, line)) + U32 value_nbo = 0; + file.read((char*)&value_nbo, sizeof(U32)); + if (file.fail()) { - LLSD s_item; - std::istringstream iss(line); - if (parser->parse(iss, s_item, line.length()) == LLSDParser::PARSE_FAILURE) + LL_WARNS(LOG_INV) << "Failed to read cache version. Unable to load inventory from: " << filename << LL_ENDL; + } + else + { + S32 version = (S32)ntohl(value_nbo); + if (version == sCurrentInvCacheVersion) { - LL_WARNS(LOG_INV)<< "Parsing inventory cache failed" << LL_ENDL; - break; + // Cache is up to date + is_cache_obsolete = false; } - - if (s_item.has("inv_cache_version")) + else { - S32 version = s_item["inv_cache_version"].asInteger(); - if (version == sCurrentInvCacheVersion) - { - // Cache is up to date - is_cache_obsolete = false; - continue; - } - else - { - LL_WARNS(LOG_INV)<< "Inventory cache is out of date" << LL_ENDL; - break; - } + LL_WARNS(LOG_INV) << "Inventory cache is out of date" << LL_ENDL; } - else if (s_item.has("cat_id")) + } + + LLSD inventory; + if (!is_cache_obsolete) + { + LLPointer<LLSDParser> parser = new LLSDBinaryParser(); + + if (parser->parse(file, inventory, LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE) { - if (is_cache_obsolete) - break; + is_cache_obsolete = true; + LL_WARNS(LOG_INV) << "Parsing inventory cache failed" << LL_ENDL; + } + } - LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null); - if(inv_cat->importLLSD(s_item)) + if (!is_cache_obsolete) + { + const LLSD& llsd_cats = inventory["categories"]; + if (llsd_cats.isArray()) + { + LLSD::array_const_iterator iter = llsd_cats.beginArray(); + LLSD::array_const_iterator end = llsd_cats.endArray(); + for (; iter != end; ++iter) { - categories.push_back(inv_cat); + LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null); + if (inv_cat->importLLSDMap(*iter)) + { + categories.push_back(inv_cat); + } } } - else if (s_item.has("item_id")) - { - if (is_cache_obsolete) - break; - LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem; - if( inv_item->fromLLSD(s_item) ) + const LLSD& llsd_items = inventory["items"]; + if (llsd_items.isArray()) + { + LLSD::array_const_iterator iter = llsd_items.beginArray(); + LLSD::array_const_iterator end = llsd_items.endArray(); + for (; iter != end; ++iter) { - if(inv_item->getUUID().isNull()) - { - LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: " - << inv_item->getName() << LL_ENDL; - } - else + LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem; + if (inv_item->fromLLSD(*iter)) { - if (inv_item->getType() == LLAssetType::AT_UNKNOWN) + if (inv_item->getUUID().isNull()) { - cats_to_update.insert(inv_item->getParentUUID()); + LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: " + << inv_item->getName() << LL_ENDL; } else { - items.push_back(inv_item); + if (inv_item->getType() == LLAssetType::AT_UNKNOWN) + { + cats_to_update.insert(inv_item->getParentUUID()); + } + else + { + items.push_back(inv_item); + } } } + + // TODO(brad) - figure out how to reenable this without breaking everything else + // static constexpr U64 BATCH_SIZE = 512U; + // if ((++lines_count % BATCH_SIZE) == 0) + // { + // // SL-19968 - make sure message system code gets a chance to run every so often + // pump_idle_startup_network(); + // } } } - -// TODO(brad) - figure out how to reenable this without breaking everything else -// static constexpr U64 BATCH_SIZE = 512U; -// if ((++lines_count % BATCH_SIZE) == 0) -// { -// // SL-19968 - make sure message system code gets a chance to run every so often -// pump_idle_startup_network(); -// } } file.close(); @@ -3477,54 +3501,54 @@ bool LLInventoryModel::saveToFile(const std::string& filename, try { - llofstream fileXML(filename.c_str()); - if (!fileXML.is_open()) + llofstream fileSD(filename.c_str(), std::ios_base::out | std::ios_base::binary); + if (!fileSD.is_open()) { LL_WARNS(LOG_INV) << "Failed to open file. Unable to save inventory to: " << filename << LL_ENDL; return false; } - - LLSD cache_ver; - cache_ver["inv_cache_version"] = sCurrentInvCacheVersion; - - if (fileXML.fail()) + U32 value_nbo = htonl(sCurrentInvCacheVersion); + fileSD.write((const char*)(&value_nbo), sizeof(U32)); + if (fileSD.fail()) { - LL_WARNS(LOG_INV) << "Failed to write cache version to file. Unable to save inventory to: " << filename << LL_ENDL; + LL_WARNS(LOG_INV) << "Failed to write cache. Unable to save inventory to: " << filename << LL_ENDL; return false; } - fileXML << LLSDOStreamer<LLSDNotationFormatter>(cache_ver) << std::endl; + LLSD inventory; + inventory["categories"] = LLSD::emptyArray(); + LLSD& cat_array = inventory["categories"]; S32 cat_count = 0; for (auto& cat : categories) { if (cat->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN) { - fileXML << LLSDOStreamer<LLSDNotationFormatter>(cat->exportLLSD()) << std::endl; + LLSD sd; + cat->exportLLSD(sd); + cat_array.append(sd); cat_count++; } - - if (fileXML.fail()) - { - LL_WARNS(LOG_INV) << "Failed to write a folder to file. Unable to save inventory to: " << filename << LL_ENDL; - return false; - } } + inventory["items"] = LLSD::emptyArray(); + LLSD& item_array = inventory["items"]; auto it_count = items.size(); for (auto& item : items) { - fileXML << LLSDOStreamer<LLSDNotationFormatter>(item->asLLSD()) << std::endl; - - if (fileXML.fail()) - { - LL_WARNS(LOG_INV) << "Failed to write an item to file. Unable to save inventory to: " << filename << LL_ENDL; - return false; - } + LLSD sd; + item->asLLSD(sd); + item_array.append(sd); + } + fileSD << LLSDOStreamer<LLSDBinaryFormatter>(inventory) << std::endl; + if (fileSD.fail()) + { + LL_WARNS(LOG_INV) << "Failed to write cache. Unable to save inventory to: " << filename << LL_ENDL; + return false; } - fileXML.flush(); + fileSD.flush(); - fileXML.close(); + fileSD.close(); LL_INFOS(LOG_INV) << "Inventory saved: " << (S32)cat_count << " categories, " << (S32)it_count << " items." << LL_ENDL; } diff --git a/indra/newview/llinventoryobserver.cpp b/indra/newview/llinventoryobserver.cpp index ac791e224e..ac22be9d5a 100644 --- a/indra/newview/llinventoryobserver.cpp +++ b/indra/newview/llinventoryobserver.cpp @@ -749,6 +749,13 @@ void LLInventoryCategoriesObserver::changed(U32 mask) cat_changed = true; } + bool is_favorite = category->getIsFavorite(); + if (cat_data.mIsFavorite != is_favorite) + { + cat_data.mIsFavorite = is_favorite; + cat_changed = true; + } + // If anything has changed above, fire the callback. if (cat_changed) cat_data.mCallback(); @@ -766,6 +773,7 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t S32 version = LLViewerInventoryCategory::VERSION_UNKNOWN; S32 current_num_known_descendents = LLViewerInventoryCategory::DESCENDENT_COUNT_UNKNOWN; bool can_be_added = true; + bool favorite = false; LLUUID thumbnail_id; LLViewerInventoryCategory* category = gInventory.getCategory(cat_id); @@ -779,6 +787,7 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t // to a category have been made. version = category->getVersion(); thumbnail_id = category->getThumbnailUUID(); + favorite = category->getIsFavorite(); LLInventoryModel::cat_array_t* cats; LLInventoryModel::item_array_t* items; @@ -804,11 +813,11 @@ bool LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t if(init_name_hash) { digest_t item_name_hash = gInventory.hashDirectDescendentNames(cat_id); - mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, thumbnail_id, cb, version, current_num_known_descendents,item_name_hash))); + mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, thumbnail_id, favorite, cb, version, current_num_known_descendents,item_name_hash))); } else { - mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, thumbnail_id, cb, version, current_num_known_descendents))); + mCategoryMap.insert(category_map_value_t(cat_id,LLCategoryData(cat_id, thumbnail_id, favorite, cb, version, current_num_known_descendents))); } } @@ -821,25 +830,37 @@ void LLInventoryCategoriesObserver::removeCategory(const LLUUID& cat_id) } LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData( - const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents) + const LLUUID& cat_id, + const LLUUID& thumbnail_id, + bool is_favorite, + callback_t cb, + S32 version, + S32 num_descendents) : mCatID(cat_id) , mCallback(cb) , mVersion(version) , mDescendentsCount(num_descendents) , mThumbnailId(thumbnail_id) + , mIsFavorite(is_favorite) , mIsNameHashInitialized(false) { } LLInventoryCategoriesObserver::LLCategoryData::LLCategoryData( - const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents, const digest_t& name_hash) + const LLUUID& cat_id, + const LLUUID& thumbnail_id, + bool is_favorite, + callback_t cb, S32 version, + S32 num_descendents, + const digest_t& name_hash) : mCatID(cat_id) , mCallback(cb) , mVersion(version) , mDescendentsCount(num_descendents) , mThumbnailId(thumbnail_id) + , mIsFavorite(is_favorite) , mIsNameHashInitialized(true) , mItemNameHash(name_hash) { diff --git a/indra/newview/llinventoryobserver.h b/indra/newview/llinventoryobserver.h index 950b02d3cf..12d6c44521 100644 --- a/indra/newview/llinventoryobserver.h +++ b/indra/newview/llinventoryobserver.h @@ -60,6 +60,7 @@ public: CREATE = 512, // With ADD, item has just been created. // unfortunately a particular message is still associated with some unique semantics. UPDATE_CREATE = 1024, // With ADD, item added via UpdateCreateInventoryItem + UPDATE_FAVORITE = 2048, // With ADD, item added via UpdateCreateInventoryItem ALL = 0xffffffff }; LLInventoryObserver(); @@ -276,12 +277,26 @@ protected: typedef LLUUID digest_t; // To clarify the actual usage of this "UUID" struct LLCategoryData { - LLCategoryData(const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents); - LLCategoryData(const LLUUID& cat_id, const LLUUID& thumbnail_id, callback_t cb, S32 version, S32 num_descendents, const digest_t& name_hash); + LLCategoryData( + const LLUUID& cat_id, + const LLUUID& thumbnail_id, + bool is_favorite, + callback_t cb, + S32 version, + S32 num_descendents); + LLCategoryData( + const LLUUID& cat_id, + const LLUUID& thumbnail_id, + bool is_favorite, + callback_t cb, + S32 version, + S32 num_descendents, + const digest_t& name_hash); callback_t mCallback; S32 mVersion; S32 mDescendentsCount; digest_t mItemNameHash; + bool mIsFavorite; bool mIsNameHashInitialized; LLUUID mCatID; LLUUID mThumbnailId; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 5a067ba454..b540e9c5bb 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -55,11 +55,13 @@ #include "llviewerfoldertype.h" #include "llvoavatarself.h" +class LLInventoryFavoritesItemsPanel; class LLInventoryRecentItemsPanel; class LLAssetFilteredInventoryPanel; static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel"); static LLDefaultChildRegistry::Register<LLInventoryRecentItemsPanel> t_recent_inventory_panel("recent_inventory_panel"); +static LLDefaultChildRegistry::Register<LLInventoryFavoritesItemsPanel> t_favorites_inventory_panel("favorites_inventory_panel"); static LLDefaultChildRegistry::Register<LLAssetFilteredInventoryPanel> t_asset_filtered_inv_panel("asset_filtered_inv_panel"); const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder"); @@ -364,9 +366,28 @@ void LLInventoryPanel::initializeViewBuilding() if (mInventory->isInventoryUsable() && LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT) { + LLTimer timer; // Usually this happens on login, so we have less time constraits, but too long and we can cause a disconnect const F64 max_time = 20.f; initializeViews(max_time); + + if (mViewsInitialized == VIEWS_INITIALIZED) + { + LL_INFOS("Inventory") + << "Fully initialized inventory panel " << getName() + << " with " << (S32)mItemMap.size() + << " views in " << timer.getElapsedTimeF32() << " seconds." + << LL_ENDL; + } + else + { + LL_INFOS("Inventory") + << "Partially initialized inventory panel " << getName() + << " with " << (S32)mItemMap.size() + << " views in " << timer.getElapsedTimeF32() + << " seconds. Pending known views: " << (S32)mBuildViewsQueue.size() + << LL_ENDL; + } } else { @@ -622,6 +643,19 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve } } + if (mask & LLInventoryObserver::UPDATE_FAVORITE) + { + if (view_item) + { + view_item->refresh(); + LLFolderViewFolder* parent = view_item->getParentFolder(); + if (parent) + { + parent->updateHasFavorites(get_is_favorite(model_item)); + } + } + } + // We don't typically care which of these masks the item is actually flagged with, since the masks // may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into // Landmarks; this is a STRUCTURE change for that panel but is an ADD change for the Landmarks @@ -650,6 +684,16 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve setSelection(item_id, false); } updateFolderLabel(model_item->getParentUUID()); + + if (get_is_favorite(model_item)) + { + LLFolderViewFolder* new_parent = getFolderByID(model_item->getParentUUID()); + if (new_parent) + { + new_parent->updateHasFavorites(true); + } + } + } ////////////////////////////// @@ -663,9 +707,11 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve { LLFolderViewModelItem* old_parent_vmi = old_parent->getViewModelItem(); LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(old_parent_vmi); - LLFolderViewFolder* new_parent = (LLFolderViewFolder*)getItemByID(model_item->getParentUUID()); - // Item has been moved. - if (old_parent != new_parent) + LLFolderViewFolder* new_parent = getFolderByID(model_item->getParentUUID()); + + if (old_parent != new_parent // Item has been moved. + && (new_parent != NULL || !isInRootContent(item_id, view_item)) // item is not or shouldn't be in root content + ) { if (new_parent != NULL) { @@ -700,9 +746,21 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve { old_parent_vmi->dirtyDescendantsFilter(); } + + if (view_item->isFavorite()) + { + if (old_parent) + { + old_parent->updateHasFavorites(false); // favorite was removed + } + if (new_parent) + { + new_parent->updateHasFavorites(true); // favorite was added + } } } } + } ////////////////////////////// // REMOVE Operation @@ -725,6 +783,10 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve updateFolderLabel(viewmodel_folder->getUUID()); } } + if (view_item->isFavorite()) + { + parent->updateHasFavorites(false); // favorite was removed + } } } } @@ -735,7 +797,7 @@ void LLInventoryPanel::modelChanged(U32 mask) { LL_PROFILE_ZONE_SCOPED; - if (mViewsInitialized != VIEWS_INITIALIZED) return; + if (mViewsInitialized != VIEWS_INITIALIZED) return; // todo: Store changes if building? const LLInventoryModel* model = getModel(); if (!model) return; @@ -842,7 +904,23 @@ void LLInventoryPanel::idle(void* user_data) bool in_visible_chain = panel->isInVisibleChain(); - if (!panel->mBuildViewsQueue.empty()) + if (!panel->mBuildRootQueue.empty()) + { + const F64 max_time = in_visible_chain ? 0.006f : 0.001f; // 6 ms + F64 curent_time = LLTimer::getTotalSeconds(); + panel->mBuildViewsEndTime = curent_time + max_time; + + while (curent_time < panel->mBuildViewsEndTime + && !panel->mBuildRootQueue.empty()) + { + LLUUID item_id = panel->mBuildRootQueue.back(); + panel->mBuildRootQueue.pop_back(); + panel->findAndInitRootContent(item_id); + + curent_time = LLTimer::getTotalSeconds(); + } + } + else if (!panel->mBuildViewsQueue.empty()) { const F64 max_time = in_visible_chain ? 0.006f : 0.001f; // 6 ms F64 curent_time = LLTimer::getTotalSeconds(); @@ -882,6 +960,11 @@ void LLInventoryPanel::idle(void* user_data) panel->mViewsInitialized = VIEWS_INITIALIZED; } } + // in case panel is empty or only has 'roots' + else if (panel->mViewsInitialized == VIEWS_BUILDING) + { + panel->mViewsInitialized = VIEWS_INITIALIZED; + } // Take into account the fact that the root folder might be invalidated if (panel->mFolderRoot.get()) @@ -924,20 +1007,9 @@ void LLInventoryPanel::initializeViews(F64 max_time) mBuildViewsEndTime = curent_time + max_time; // init everything - LLUUID root_id = getRootFolderID(); - if (root_id.notNull()) - { - buildNewViews(getRootFolderID()); - } - else - { - // Default case: always add "My Inventory" root first, "Library" root second - // If we run out of time, this still should create root folders - buildNewViews(gInventory.getRootFolderID()); // My Inventory - buildNewViews(gInventory.getLibraryRootFolderID()); // Library - } + initRootContent(); - if (mBuildViewsQueue.empty()) + if (mBuildViewsQueue.empty() && mBuildRootQueue.empty()) { mViewsInitialized = VIEWS_INITIALIZED; } @@ -968,6 +1040,22 @@ void LLInventoryPanel::initializeViews(F64 max_time) } } +void LLInventoryPanel::initRootContent() +{ + LLUUID root_id = getRootFolderID(); + if (root_id.notNull()) + { + buildNewViews(getRootFolderID()); + } + else + { + // Default case: always add "My Inventory" root first, "Library" root second + // If we run out of time, this still should create root folders + buildNewViews(gInventory.getRootFolderID()); // My Inventory + buildNewViews(gInventory.getLibraryRootFolderID()); // Library + } +} + LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge, bool allow_drop) { @@ -1739,26 +1827,8 @@ bool LLInventoryPanel::beginIMSession() void LLInventoryPanel::fileUploadLocation(const LLSD& userdata) { const std::string param = userdata.asString(); - if (param == "model") - { - gSavedPerAccountSettings.setString("ModelUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); - } - else if (param == "texture") - { - gSavedPerAccountSettings.setString("TextureUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); - } - else if (param == "sound") - { - gSavedPerAccountSettings.setString("SoundUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); - } - else if (param == "animation") - { - gSavedPerAccountSettings.setString("AnimationUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); - } - else if (param == "pbr_material") - { - gSavedPerAccountSettings.setString("PBRUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); - } + const LLUUID dest = LLFolderBridge::sSelf.get()->getUUID(); + LLInventoryAction::fileUploadLocation(dest, param); } void LLInventoryPanel::openSingleViewInventory(LLUUID folder_id) @@ -2206,6 +2276,274 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params) mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER; } +/************************************************************************/ +/* Favorites Inventory Panel related class */ +/************************************************************************/ +static const LLFavoritesInventoryBridgeBuilder FAVORITES_BUILDER; +class LLInventoryFavoritesItemsPanel : public LLInventoryPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> + {}; + + void initFromParams(const Params& p) + { + LLInventoryPanel::initFromParams(p); + // turn off trash + getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() | (1ULL << LLFolderType::FT_TRASH)); + getFilter().setFilterNoTrashFolder(); + // turn off marketplace for favorites + getFilter().setFilterNoMarketplaceFolder(); + } + + void removeItemID(const LLUUID& id) override; + bool isInRootContent(const LLUUID& id, LLFolderViewItem* view_item) override; + +protected: + LLInventoryFavoritesItemsPanel(const Params&); + friend class LLUICtrlFactory; + + void findAndInitRootContent(const LLUUID& folder_id) override; + void initRootContent() override; + + // removeFavorite removes item from root, does not readd favorited children if present + bool removeFavorite(const LLUUID& id, const LLInventoryObject* model_item); + void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override; + + std::set<LLUUID> mRootContentIDs; +}; + +LLInventoryFavoritesItemsPanel::LLInventoryFavoritesItemsPanel(const Params& params) + : LLInventoryPanel(params) +{ + // replace bridge builder to have necessary View bridges. + mInvFVBridgeBuilder = &FAVORITES_BUILDER; +} + +void LLInventoryFavoritesItemsPanel::removeItemID(const LLUUID& id) +{ + std::set<LLUUID>::iterator found = mRootContentIDs.find(id); + if (found != mRootContentIDs.end()) + { + mRootContentIDs.erase(found); + // check content for favorites + mBuildRootQueue.emplace_back(id); + } + + LLInventoryPanel::removeItemID(id); +} + +bool LLInventoryFavoritesItemsPanel::isInRootContent(const LLUUID& id, LLFolderViewItem* view_item) +{ + if (!view_item->isFavorite()) + { + return false; + } + + std::set<LLUUID>::iterator found = mRootContentIDs.find(id); + return found != mRootContentIDs.end(); +} + +void LLInventoryFavoritesItemsPanel::findAndInitRootContent(const LLUUID& id) +{ + F64 curent_time = LLTimer::getTotalSeconds(); + if (mBuildViewsEndTime < curent_time) + { + mBuildRootQueue.emplace_back(id); + return; + } + LLViewerInventoryCategory::cat_array_t* categories; + LLViewerInventoryItem::item_array_t* items; + mInventory->lockDirectDescendentArrays(id, categories, items); + + if (categories) + { + S32 count = static_cast<S32>(categories->size()); + for (S32 i = 0; i < count; ++i) + { + LLViewerInventoryCategory* cat = categories->at(i); + if (cat->getPreferredType() == LLFolderType::FT_TRASH) + { + continue; + } + else if (cat->getIsFavorite()) + { + LLFolderViewItem* folder_view_item = getItemByID(cat->getUUID()); + if (!folder_view_item) + { + const LLUUID& parent_id = cat->getParentUUID(); + mRootContentIDs.emplace(cat->getUUID()); + + buildViewsTree(cat->getUUID(), parent_id, cat, folder_view_item, mFolderRoot.get(), BUILD_TIMELIMIT); + } + } + else + { + findAndInitRootContent(cat->getUUID()); + } + } + } + + if (items) + { + S32 count = static_cast<S32>(items->size()); + for (S32 i = 0; i < count; ++i) + { + LLViewerInventoryItem* item = items->at(i); + const LLUUID item_id = item->getUUID(); + if (item->getIsFavorite() && typedViewsFilter(item_id, item)) + { + LLFolderViewItem* folder_view_item = getItemByID(id); + if (!folder_view_item) + { + const LLUUID& parent_id = item->getParentUUID(); + mRootContentIDs.emplace(item_id); + + buildViewsTree(item_id, parent_id, item, folder_view_item, mFolderRoot.get(), BUILD_TIMELIMIT); + } + } + } + } + + mInventory->unlockDirectDescendentArrays(id); +} + +void LLInventoryFavoritesItemsPanel::initRootContent() +{ + findAndInitRootContent(gInventory.getRootFolderID()); // My Inventory +} + +bool LLInventoryFavoritesItemsPanel::removeFavorite(const LLUUID& id, const LLInventoryObject* model_item) +{ + std::set<LLUUID>::iterator found = mRootContentIDs.find(id); + if (found == mRootContentIDs.end()) + { + return false; + } + + mRootContentIDs.erase(found); + + // This item is in root's content, remove item's UI. + LLFolderViewItem* view_item = getItemByID(id); + if (view_item) + { + LLFolderViewFolder* parent = view_item->getParentFolder(); + LLFolderViewModelItemInventory* viewmodel_item = static_cast<LLFolderViewModelItemInventory*>(view_item->getViewModelItem()); + if (viewmodel_item) + { + removeItemID(viewmodel_item->getUUID()); + } + view_item->destroyView(); + if (parent) + { + parent->getViewModelItem()->dirtyDescendantsFilter(); + LLFolderViewModelItemInventory* viewmodel_folder = static_cast<LLFolderViewModelItemInventory*>(parent->getViewModelItem()); + if (viewmodel_folder) + { + updateFolderLabel(viewmodel_folder->getUUID()); + } + if (view_item->isFavorite()) + { + parent->updateHasFavorites(false); // favorite was removed + } + } + } + + return true; +} + +void LLInventoryFavoritesItemsPanel::itemChanged(const LLUUID& id, U32 mask, const LLInventoryObject* model_item) +{ + LLFolderViewItem* view_item = getItemByID(id); + if (!model_item && !view_item) + { + // remove operation, but item is not in panel already + return; + } + + bool handled = false; + + if (mask & (LLInventoryObserver::UPDATE_FAVORITE | + LLInventoryObserver::STRUCTURE | + LLInventoryObserver::ADD | + LLInventoryObserver::REMOVE)) + { + // specifically exlude links and not get_is_favorite(model_item) + if (model_item && model_item->getIsFavorite()) + { + if (!view_item) + { + const LLViewerInventoryCategory* cat = dynamic_cast<const LLViewerInventoryCategory*>(model_item); + if (cat) + { + // New favorite folder + if (cat->getPreferredType() != LLFolderType::FT_TRASH) + { + // If any descendants were in the list, remove them + // Todo: Consider implementing and checking hasFavorites to save on search + LLFavoritesCollector is_favorite; + LLInventoryModel::cat_array_t cat_array; + LLInventoryModel::item_array_t item_array; + gInventory.collectDescendentsIf(id, cat_array, item_array, false, is_favorite); + for (LLInventoryModel::cat_array_t::const_iterator it = cat_array.begin(); it != cat_array.end(); ++it) + { + removeFavorite((*it)->getUUID(), *it); + } + for (LLInventoryModel::item_array_t::const_iterator it = item_array.begin(); it != item_array.end(); ++it) + { + removeFavorite((*it)->getUUID(), *it); + } + + LLFolderViewItem* folder_view_item = getItemByID(cat->getUUID()); + if (!folder_view_item) + { + const LLUUID& parent_id = cat->getParentUUID(); + mRootContentIDs.emplace(cat->getUUID()); + + buildViewsTree(cat->getUUID(), parent_id, cat, folder_view_item, mFolderRoot.get(), BUILD_ONE_FOLDER); + } + } + } + else + { + // New favorite item + if (model_item->getIsFavorite() && typedViewsFilter(id, model_item)) + { + const LLUUID& parent_id = model_item->getParentUUID(); + mRootContentIDs.emplace(id); + + buildViewsTree(id, parent_id, model_item, NULL, mFolderRoot.get(), BUILD_ONE_FOLDER); + } + } + handled = true; + } + } + else + { + handled = removeFavorite(id, model_item); + if (handled) + { + const LLViewerInventoryCategory* cat = dynamic_cast<const LLViewerInventoryCategory*>(model_item); + // Todo: Consider implementing and checking hasFavorites to save on search + if (cat) + { + // re-add any favorited children + mBuildRootQueue.emplace_back(id); + } + } + } + } + + if (!handled + && (!model_item || model_item->getParentUUID().notNull())) // filter out 'My inventory' + { + LLInventoryPanel::itemChanged(id, mask, model_item); + } +} +/************************************************************************/ +/* LLInventorySingleFolderPanel */ +/************************************************************************/ + static LLDefaultChildRegistry::Register<LLInventorySingleFolderPanel> t_single_folder_inventory_panel("single_folder_inventory_panel"); LLInventorySingleFolderPanel::LLInventorySingleFolderPanel(const Params& params) diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 56909c8d98..473283352f 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -251,7 +251,8 @@ public: bool reset_filter = false); static void setSFViewAndOpenFolder(const LLInventoryPanel* panel, const LLUUID& folder_id); void addItemID(const LLUUID& id, LLFolderViewItem* itemp); - void removeItemID(const LLUUID& id); + virtual void removeItemID(const LLUUID& id); + virtual bool isInRootContent(const LLUUID& id, LLFolderViewItem* view_item) { return false; } LLFolderViewItem* getItemByID(const LLUUID& id); LLFolderViewFolder* getFolderByID(const LLUUID& id); void setSelectionByID(const LLUUID& obj_id, bool take_keyboard_focus); @@ -334,6 +335,8 @@ public: protected: // Builds the UI. Call this once the inventory is usable. void initializeViews(F64 max_time); + virtual void initRootContent(); + virtual void findAndInitRootContent(const LLUUID& root_id) {}; // Specific inventory colors static bool sColorSetInitialized; @@ -371,7 +374,7 @@ protected: virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge); boost::function<void(const std::deque<LLFolderViewItem*>& items, bool user_action)> mSelectionCallback; -private: + // buildViewsTree does not include some checks and is meant // for recursive use, use buildNewViews() for first call LLFolderViewItem* buildViewsTree(const LLUUID& id, @@ -394,6 +397,8 @@ private: EViewsInitializationState mViewsInitialized; // Whether views have been generated F64 mBuildViewsEndTime; // Stop building views past this timestamp std::deque<LLUUID> mBuildViewsQueue; + std::deque<LLUUID> mBuildRootQueue; + }; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index fbf4a7d1dd..fa1f650113 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -32,6 +32,8 @@ #include "lllogchat.h" #include "llregex.h" #include "lltrans.h" +#include "llurlaction.h" +#include "llurlentry.h" #include "llviewercontrol.h" #include "lldiriterator.h" @@ -358,13 +360,29 @@ void LLLogChat::saveHistory(const std::string& filename, return; } + std::string altered_line = line; + + // avoid costly regex calls + if (line.find("/mention") != std::string::npos) + { + static const boost::regex mention_regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/mention", boost::regex::perl | boost::regex::icase); + + // replace mention URL with [@username](URL) + altered_line = boost::regex_replace(line, mention_regex, [](const boost::smatch& match) -> std::string + { + std::string url = match[0].str(); + std::string username = LLUrlAction::getURLLabel(url); + return "[" + username + "](" + url + ")"; + }); + } + LLSD item; if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) item["time"] = LLLogChat::timestamp2LogString(0, gSavedPerAccountSettings.getBOOL("LogTimestampDate")); item["from_id"] = from_id; - item["message"] = line; + item["message"] = altered_line; //adding "Second Life:" for all system messages to make chat log history parsing more reliable if (from.empty() && from_id.isNull()) @@ -432,8 +450,8 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m } // If we got here, we managed to stat the file. - // Open the file to read - LLFILE* fptr = LLFile::fopen(log_file_name, "r"); /*Flawfinder: ignore*/ + // Open the file to read in binary mode to prevent interpreting other characters as EOF + LLFILE* fptr = LLFile::fopen(log_file_name, "rb"); /*Flawfinder: ignore*/ if (!fptr) { // Ok, this is strange but not really tragic in the big picture of things LL_WARNS("ChatHistory") << "Unable to read file " << log_file_name << " after stat was successful" << LL_ENDL; @@ -470,6 +488,19 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m std::string line(remove_utf8_bom(buffer)); + + // fast heuristic test for a mention URL in a string + // this is used to avoid costly regex calls + if (line.find("/mention)") != std::string::npos) + { + // restore original mention URL from [@username](URL) format + static const boost::regex altered_mention_regex("\\[@([^\\]]+)\\]\\((" APP_HEADER_REGEX "/agent/[\\da-f-]+/mention)\\)", + boost::regex::perl | boost::regex::icase); + + // $2 captures the URL part + line = boost::regex_replace(line, altered_mention_regex, "$2"); + } + //updated 1.23 plain text log format requires a space added before subsequent lines in a multilined message if (' ' == line[0]) { @@ -1150,7 +1181,7 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL } bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false; - LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/ + LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "rb");/*Flawfinder: ignore*/ if (!fptr) { @@ -1159,17 +1190,17 @@ void LLLoadHistoryThread::loadHistory(const std::string& file_name, std::list<LL { std::string old_name(file_name); old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size()); - fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r"); + fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "rb"); if (fptr) { fclose(fptr); LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name)); } - fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r"); + fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "rb"); } if (!fptr) { - fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/ + fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "rb");/*Flawfinder: ignore*/ if (!fptr) { mNewLoad = false; diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index cbc3744aa3..4bffe7feac 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -329,6 +329,15 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) LL_DEBUGS("LLLogin") << "reason " << reason_response << " message " << message_response << LL_ENDL; + + if (response.has("mfa_hash")) + { + mRequestData["params"]["mfa_hash"] = response["mfa_hash"]; + mRequestData["params"]["token"] = ""; + + saveMFAHash(response); + } + // For the cases of critical message or TOS agreement, // start the TOS dialog. The dialog response will be handled // by the LLLoginInstance::handleTOSResponse() callback. @@ -593,6 +602,24 @@ bool LLLoginInstance::handleMFAChallenge(LLSD const & notif, LLSD const & respon return true; } +void LLLoginInstance::saveMFAHash(LLSD const& response) +{ + std::string grid(LLGridManager::getInstance()->getGridId()); + std::string user_id(LLStartUp::getUserId()); + + // Only save mfa_hash for future logins if the user wants their info remembered. + if (response.has("mfa_hash") && gSavedSettings.getBOOL("RememberUser") && LLLoginInstance::getInstance()->saveMFA()) + { + gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]); + } + else if (!LLLoginInstance::getInstance()->saveMFA()) + { + gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id); + } + // TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically + gSecAPIHandler->syncProtectedMap(); +} + std::string construct_start_string() { std::string start; diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index 748909c069..941b378b14 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -70,6 +70,8 @@ public: void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; } LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; } + void saveMFAHash(LLSD const& response); + private: typedef std::shared_ptr<LLEventAPI::Response> ResponsePtr; void constructAuthParams(LLPointer<LLCredential> user_credentials); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 46d4c70f87..cac72bb085 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -138,7 +138,8 @@ LLFloaterComboOptions* LLFloaterComboOptions::showUI( { combo_picker->mComboOptions->addSimpleElement(*iter); } - combo_picker->mComboOptions->selectFirstItem(); + // select 'Bulk Upload All' option + combo_picker->mComboOptions->selectNthItem((S32)options.size() - 1); combo_picker->openFloater(LLSD(title)); combo_picker->setFocus(true); @@ -1333,15 +1334,6 @@ const std::string LLMaterialEditor::buildMaterialDescription() desc << mNormalName; } - // trim last char if it's a ',' in case there is no normal texture - // present and the code above inserts one - // (no need to check for string length - always has initial string) - std::string::iterator iter = desc.str().end() - 1; - if (*iter == ',') - { - desc.str().erase(iter); - } - // sanitize the material description so that it's compatible with the inventory // note: split this up because clang doesn't like operating directly on the // str() - error: lvalue reference to type 'basic_string<...>' cannot bind to a @@ -1349,6 +1341,15 @@ const std::string LLMaterialEditor::buildMaterialDescription() std::string inv_desc = desc.str(); LLInventoryObject::correctInventoryName(inv_desc); + // trim last char if it's a ',' in case there is no normal texture + // present and the code above inserts one + // (no need to check for string length - always has initial string) + std::string::iterator iter = inv_desc.end() - 1; + if (*iter == ',') + { + inv_desc.erase(iter); + } + return inv_desc; } @@ -1415,7 +1416,7 @@ bool LLMaterialEditor::saveIfNeeded() } std::string res_desc = buildMaterialDescription(); - createInventoryItem(buffer, mMaterialName, res_desc, local_permissions); + createInventoryItem(buffer, mMaterialName, res_desc, local_permissions, mUploadFolder); // We do not update floater with uploaded asset yet, so just close it. closeFloater(); @@ -1585,12 +1586,12 @@ private: std::string mNewName; }; -void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& permissions) +void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& permissions, const LLUUID& upload_folder) { // gen a new uuid for this asset LLTransactionID tid; tid.generate(); // timestamp-based randomization + uniquification - LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); + LLUUID parent = upload_folder.isNull() ? gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL) : upload_folder; const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? LLPointer<LLObjectsMaterialItemCallback> cb = new LLObjectsMaterialItemCallback(permissions, buffer, name); @@ -1904,7 +1905,11 @@ static void pack_textures( } } -void LLMaterialEditor::uploadMaterialFromModel(const std::string& filename, tinygltf::Model& model_in, S32 index) +void LLMaterialEditor::uploadMaterialFromModel( + const std::string& filename, + tinygltf::Model& model_in, + S32 index, + const LLUUID& dest) { if (index < 0 || !LLMaterialEditor::capabilitiesAvailable()) { @@ -1927,12 +1932,13 @@ void LLMaterialEditor::uploadMaterialFromModel(const std::string& filename, tiny // This uses 'filename' to make sure multiple bulk uploads work // instead of fighting for a single instance. LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD().with("filename", filename).with("index", LLSD::Integer(index))); + me->mUploadFolder = dest; me->loadMaterial(model_in, filename, index, false); me->saveIfNeeded(); } -void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index) +void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index, const LLUUID& dest_folder) { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; @@ -2432,17 +2438,17 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati return; } - createInventoryItem(str.str(), new_name, std::string(), permissions); + createInventoryItem(str.str(), new_name, std::string(), permissions, LLUUID::null); } -const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type, bool allow_2k); +void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type, bool allow_2k, const LLUUID& dest); void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename, S32 index, bool open_floater) { if (index == model_in.materials.size()) { // bulk upload all the things - upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true); + upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true, LLUUID::null); return; } @@ -2479,6 +2485,42 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: pack_textures(base_color_img, normal_img, mr_img, emissive_img, occlusion_img, mBaseColorJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C); + if (open_floater) + { + bool textures_scaled = false; + if (mBaseColorFetched && mBaseColorJ2C + && (mBaseColorFetched->getWidth() != mBaseColorJ2C->getWidth() + || mBaseColorFetched->getHeight() != mBaseColorJ2C->getHeight())) + { + textures_scaled = true; + } + else if (mNormalFetched && mNormalJ2C + && (mNormalFetched->getWidth() != mNormalJ2C->getWidth() + || mNormalFetched->getHeight() != mNormalJ2C->getHeight())) + { + textures_scaled = true; + } + else if (mMetallicRoughnessFetched && mMetallicRoughnessJ2C + && (mMetallicRoughnessFetched->getWidth() != mMetallicRoughnessJ2C->getWidth() + || mMetallicRoughnessFetched->getHeight() != mMetallicRoughnessJ2C->getHeight())) + { + textures_scaled = true; + } + else if (mEmissiveFetched && mEmissiveJ2C + && (mEmissiveFetched->getWidth() != mEmissiveJ2C->getWidth() + || mEmissiveFetched->getHeight() != mEmissiveJ2C->getHeight())) + { + textures_scaled = true; + } + + if (textures_scaled) + { + LLSD args; + args["MAX_SIZE"] = LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT; + LLNotificationsUtil::add("MaterialImagesWereScaled", args); + } + } + LLUUID base_color_id; if (mBaseColorFetched.notNull()) { @@ -2685,10 +2727,8 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c // so we can include everything if (stripped_uri.length() > 0) { - // example "DamagedHelmet: base layer" + // example "base layer" return STRINGIZE( - mMaterialNameShort << - ": " << stripped_uri << " (" << texture_type << @@ -2697,28 +2737,17 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c } else // uri doesn't include the type (because the uri is empty) - // so we must reorganize the string a bit to include the name - // and an explicit name type + // include an explicit name type { - // example "DamagedHelmet: (Emissive)" - return STRINGIZE( - mMaterialNameShort << - " (" << - texture_type << - ")" - ); + // example "Emissive" + return texture_type; } } else - // uri includes the type so just use it directly with the - // name of the material + // uri includes the type so just use it directly { - return STRINGIZE( - // example: AlienBust: normal_layer - mMaterialNameShort << - ": " << - stripped_uri - ); + // example: "normal_layer" + return stripped_uri; } } @@ -2849,10 +2878,10 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const ti } } -void LLMaterialEditor::importMaterial() +void LLMaterialEditor::importMaterial(const LLUUID dest_folder) { LLFilePickerReplyThread::startPicker( - [](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter) + [dest_folder](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter) { if (LLAppViewer::instance()->quitRequested()) { @@ -2862,7 +2891,7 @@ void LLMaterialEditor::importMaterial() { if (filenames.size() > 0) { - LLMaterialEditor::loadMaterialFromFile(filenames[0], -1); + LLMaterialEditor::loadMaterialFromFile(filenames[0], -1, dest_folder); } } catch (std::bad_alloc&) @@ -3550,6 +3579,7 @@ void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, con LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), expected_upload_cost, + mUploadFolder, false, cb, failed_upload)); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 232467460e..1abdd7f84c 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -94,7 +94,7 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener void setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index); // open a file dialog and select a gltf/glb file for import - static void importMaterial(); + static void importMaterial(const LLUUID dest_folder = LLUUID::null); // for live preview, apply current material to currently selected object void applyToSelection(); @@ -105,8 +105,11 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener void loadAsset() override; // @index if -1 and file contains more than one material, // will promt to select specific one - static void uploadMaterialFromModel(const std::string& filename, tinygltf::Model& model, S32 index); - static void loadMaterialFromFile(const std::string& filename, S32 index = -1); + static void uploadMaterialFromModel(const std::string& filename, + tinygltf::Model& model, + S32 index, + const LLUUID& dest_folder_id = LLUUID::null); + static void loadMaterialFromFile(const std::string& filename, S32 index = -1, const LLUUID& dest_folder = LLUUID::null); void onSelectionChanged(); // live overrides selection changes @@ -134,8 +137,6 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener void onClickSave(); - void getGLTFModel(tinygltf::Model& model); - std::string getEncodedAsset(); bool decodeAsset(const std::vector<char>& buffer); @@ -239,7 +240,7 @@ private: static void saveObjectsMaterialAs(const LLGLTFMaterial *render_material, const LLLocalGLTFMaterial *local_material, const LLPermissions& permissions, const LLUUID& object_id /* = LLUUID::null */, const LLUUID& item /* = LLUUID::null */); static bool updateInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id); - static void createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& permissions); + static void createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& permissions, const LLUUID& upload_folder); void setFromGLTFMaterial(LLGLTFMaterial* mat); bool setFromSelection(); @@ -249,6 +250,7 @@ private: friend class LLMaterialFilePicker; LLUUID mAssetID; + LLUUID mUploadFolder; LLTextureCtrl* mBaseColorTextureCtrl; LLTextureCtrl* mMetallicTextureCtrl; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 48c80842b9..07d68fc3ec 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -544,6 +544,66 @@ bool RequestStats::isDelayed() const return mTimer.getStarted() && !mTimer.hasExpired(); } +F32 calculate_score(LLVOVolume* object) +{ + if (!object) + { + return -1.f; + } + LLDrawable* drawable = object->mDrawable; + if (!drawable) + { + return -1; + } + if (drawable->isState(LLDrawable::RIGGED) || object->isAttachment()) + { + LLVOAvatar* avatar = object->getAvatar(); + LLDrawable* av_drawable = avatar ? avatar->mDrawable : nullptr; + if (avatar && av_drawable) + { + // See LLVOVolume::calcLOD() + F32 radius; + if (avatar->isControlAvatar()) + { + const LLVector3* box = avatar->getLastAnimExtents(); + LLVector3 diag = box[1] - box[0]; + radius = diag.magVec() * 0.5f; + } + else + { + // Volume in a rigged mesh attached to a regular avatar. + const LLVector3* box = avatar->getLastAnimExtents(); + LLVector3 diag = box[1] - box[0]; + radius = diag.magVec(); + + if (!avatar->isSelf() && !avatar->hasFirstFullAttachmentData()) + { + // slightly deprioritize avatars that are still receiving data + radius *= 0.9f; + } + } + return radius / llmax(av_drawable->mDistanceWRTCamera, 1.f); + } + } + return drawable->getRadius() / llmax(drawable->mDistanceWRTCamera, 1.f); +} + +void PendingRequestBase::updateScore() +{ + mScore = 0; + if (mTrackedData) + { + for (LLVOVolume* volume : mTrackedData->mVolumes) + { + F32 cur_score = calculate_score(volume); + if (cur_score > 0) + { + mScore = llmax(mScore, cur_score); + } + } + } +} + LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMaterial& material) { LLPointer< LLViewerFetchedTexture > * ppTex = static_cast< LLPointer< LLViewerFetchedTexture > * >(material.mOpaqueData); @@ -756,8 +816,12 @@ public: }; -void log_upload_error(LLCore::HttpStatus status, const LLSD& content, - const char * const stage, const std::string & model_name) +void log_upload_error( + LLCore::HttpStatus status, + const LLSD& content, + const char * const stage, + const std::string & model_name, + const std::vector<std::string> & texture_filenames) { // Add notification popup. LLSD args; @@ -815,6 +879,20 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content, error_num++; } } + + if (err.has("TextureIndex")) + { + S32 texture_index = err["TextureIndex"].asInteger(); + if (texture_index < texture_filenames.size()) + { + args["MESSAGE"] = message + "\n" + texture_filenames[texture_index]; + } + else + { + llassert(false); // figure out why or how texture wasn't in the list + args["MESSAGE"] = message + llformat("\nTexture index: %d", texture_index); + } + } } else { @@ -1809,42 +1887,36 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) //static void LLMeshRepoThread::incActiveLODRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); ++LLMeshRepoThread::sActiveLODRequests; } //static void LLMeshRepoThread::decActiveLODRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); --LLMeshRepoThread::sActiveLODRequests; } //static void LLMeshRepoThread::incActiveHeaderRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); ++LLMeshRepoThread::sActiveHeaderRequests; } //static void LLMeshRepoThread::decActiveHeaderRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); --LLMeshRepoThread::sActiveHeaderRequests; } //static void LLMeshRepoThread::incActiveSkinRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); ++LLMeshRepoThread::sActiveSkinRequests; } //static void LLMeshRepoThread::decActiveSkinRequests() { - LLMutexLock lock(gMeshRepo.mThread->mMutex); --LLMeshRepoThread::sActiveSkinRequests; } @@ -2226,7 +2298,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes if (gMeshRepo.mLoadingSkins.find(mesh_id) == gMeshRepo.mLoadingSkins.end()) { - gMeshRepo.mLoadingSkins[mesh_id] = {}; // add an empty vector to indicate to main thread that we are loading skin info + gMeshRepo.mLoadingSkins[mesh_id]; // add an empty vector to indicate to main thread that we are loading skin info } } @@ -2308,7 +2380,13 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); if (volume->unpackVolumeFaces(data, data_size)) { - if (volume->getNumFaces() > 0) + // Use LLVolume::getNumVolumeFaces() here and not LLVolume::getNumFaces(), + // because setMeshAssetLoaded() has not yet been called for this volume + // (it is set later in LLMeshRepository::notifyMeshLoaded()), and + // getNumFaces() would return the number of faces in the LLProfile + // instead. HB + S32 num_faces = volume->getNumVolumeFaces(); + if (num_faces > 0) { // if we have a valid SkinInfo, cache per-joint bounding boxes for this LOD LLPointer<LLMeshSkinInfo> skin_info = nullptr; @@ -2322,7 +2400,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p } if (skin_info.notNull() && isAgentAvatarValid()) { - for (S32 i = 0; i < volume->getNumFaces(); ++i) + for (S32 i = 0; i < num_faces; ++i) { // NOTE: no need to lock gAgentAvatarp as the state being checked is not changed after initialization LLVolumeFace& face = volume->getVolumeFace(i); @@ -2341,6 +2419,11 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p // might be good idea to turn mesh into pointer to avoid making a copy mesh.mVolume = NULL; } + { + // make sure skin info is not removed from list while we are decreasing reference count + LLMutexLock lock(mSkinMapMutex); + skin_info = nullptr; + } return MESH_OK; } } @@ -2488,7 +2571,7 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, - const std::string & upload_url, bool do_upload, + const std::string & upload_url, LLUUID destination_folder_id, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer) : LLThread("mesh upload"), @@ -2496,6 +2579,7 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, mDiscarded(false), mDoUpload(do_upload), mWholeModelUploadURL(upload_url), + mDestinationFolderId(destination_folder_id), mFeeObserverHandle(fee_observer), mUploadObserverHandle(upload_observer) { @@ -2612,13 +2696,21 @@ LLSD llsd_from_file(std::string filename) return result; } -void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) +void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, std::vector<std::string>& texture_list_dest, bool include_textures) { LLSD result; LLSD res; + if (mDestinationFolderId.isNull()) + { result["folder_id"] = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_OBJECT); result["texture_folder_id"] = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_TEXTURE); + } + else + { + result["folder_id"] = mDestinationFolderId; + result["texture_folder_id"] = mDestinationFolderId; + } result["asset_type"] = "mesh"; result["inventory_type"] = "object"; result["description"] = "(No Description)"; @@ -2640,10 +2732,14 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) S32 instance_num = 0; - for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) + // Handle models, ignore submodels for now. + // Probably should pre-sort by mSubmodelID instead of running twice. + // Note: mInstance should be sorted by model name for the sake of + // deterministic order. + for (auto& iter : mInstance) { LLMeshUploadData data; - data.mBaseModel = iter->first; + data.mBaseModel = iter.first; if (data.mBaseModel->mSubmodelID) { @@ -2652,7 +2748,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) continue; } - LLModelInstance& first_instance = *(iter->second.begin()); + LLModelInstance& first_instance = *(iter.second.begin()); for (S32 i = 0; i < 5; i++) { data.mModel[i] = first_instance.mLOD[i]; @@ -2686,7 +2782,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) mUploadSkin, mUploadJoints, mLockScaleIfJointPosition, - false, + LLModel::WRITE_BINARY, false, data.mBaseModel->mSubmodelID); @@ -2699,8 +2795,8 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) } // For all instances that use this model - for (instance_list::iterator instance_iter = iter->second.begin(); - instance_iter != iter->second.end(); + for (instance_list::iterator instance_iter = iter.second.begin(); + instance_iter != iter.second.end(); ++instance_iter) { @@ -2761,7 +2857,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) LLPointer<LLImageJ2C> upload_file = LLViewerTextureList::convertToUploadFile(texture->getSavedRawImage()); - if (!upload_file.isNull() && upload_file->getDataSize()) + if (!upload_file.isNull() && upload_file->getDataSize() && !upload_file->isBufferInvalid()) { texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize()); } @@ -2775,6 +2871,8 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) texture_index[texture] = texture_num; std::string str = texture_str.str(); res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end()); + // store indexes for error handling; + texture_list_dest.push_back(material.mDiffuseMapFilename); texture_num++; } @@ -2798,10 +2896,11 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) } } - for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter) + // Now handle the submodels. + for (auto& iter : mInstance) { LLMeshUploadData data; - data.mBaseModel = iter->first; + data.mBaseModel = iter.first; if (!data.mBaseModel->mSubmodelID) { @@ -2810,7 +2909,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) continue; } - LLModelInstance& first_instance = *(iter->second.begin()); + LLModelInstance& first_instance = *(iter.second.begin()); for (S32 i = 0; i < 5; i++) { data.mModel[i] = first_instance.mLOD[i]; @@ -2844,7 +2943,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) mUploadSkin, mUploadJoints, mLockScaleIfJointPosition, - false, + LLModel::WRITE_BINARY, false, data.mBaseModel->mSubmodelID); @@ -2857,8 +2956,8 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) } // For all instances that use this model - for (instance_list::iterator instance_iter = iter->second.begin(); - instance_iter != iter->second.end(); + for (instance_list::iterator instance_iter = iter.second.begin(); + instance_iter != iter.second.end(); ++instance_iter) { @@ -3039,7 +3138,8 @@ void LLMeshUploadThread::doWholeModelUpload() LL_DEBUGS(LOG_MESH) << "Hull generation completed." << LL_ENDL; mModelData = LLSD::emptyMap(); - wholeModelToLLSD(mModelData, true); + mTextureFiles.clear(); + wholeModelToLLSD(mModelData, mTextureFiles, true); LLSD body = mModelData["asset_resources"]; dump_llsd_to_file(body, make_dump_name("whole_model_body_", dump_num)); @@ -3092,7 +3192,8 @@ void LLMeshUploadThread::requestWholeModelFee() generateHulls(); mModelData = LLSD::emptyMap(); - wholeModelToLLSD(mModelData, false); + mTextureFiles.clear(); + wholeModelToLLSD(mModelData, mTextureFiles, false); dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num)); LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicyClass, @@ -3158,7 +3259,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp body["error"] = LLSD::emptyMap(); body["error"]["message"] = reason; body["error"]["identifier"] = "NetworkError"; // from asset-upload/upload_util.py - log_upload_error(status, body, "upload", mModelData["name"].asString()); + log_upload_error(status, body, "upload", mModelData["name"].asString(), mTextureFiles); if (observer) { @@ -3193,7 +3294,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp else { LL_WARNS(LOG_MESH) << "Upload failed. Not in expected 'complete' state." << LL_ENDL; - log_upload_error(status, body, "upload", mModelData["name"].asString()); + log_upload_error(status, body, "upload", mModelData["name"].asString(), mTextureFiles); if (observer) { @@ -3218,7 +3319,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp body["error"] = LLSD::emptyMap(); body["error"]["message"] = reason; body["error"]["identifier"] = "NetworkError"; // from asset-upload/upload_util.py - log_upload_error(status, body, "fee", mModelData["name"].asString()); + log_upload_error(status, body, "fee", mModelData["name"].asString(), mTextureFiles); if (observer) { @@ -3251,7 +3352,7 @@ void LLMeshUploadThread::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResp else { LL_WARNS(LOG_MESH) << "Fee request failed. Not in expected 'upload' state." << LL_ENDL; - log_upload_error(status, body, "fee", mModelData["name"].asString()); + log_upload_error(status, body, "fee", mModelData["name"].asString(), mTextureFiles); if (observer) { @@ -4218,13 +4319,13 @@ void LLMeshRepository::unregisterMesh(LLVOVolume* vobj) { for (auto& param : lod) { - vector_replace_with_last(param.second, vobj); + vector_replace_with_last(param.second.mVolumes, vobj); } } for (auto& skin_pair : mLoadingSkins) { - vector_replace_with_last(skin_pair.second, vobj); + vector_replace_with_last(skin_pair.second.mVolumes, vobj); } } @@ -4247,16 +4348,17 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para mesh_load_map::iterator iter = mLoadingMeshes[new_lod].find(mesh_id); if (iter != mLoadingMeshes[new_lod].end()) { //request pending for this mesh, append volume id to list - auto it = std::find(iter->second.begin(), iter->second.end(), vobj); - if (it == iter->second.end()) { - iter->second.push_back(vobj); + auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), vobj); + if (it == iter->second.mVolumes.end()) { + iter->second.addVolume(vobj); } } else { //first request for this mesh - mLoadingMeshes[new_lod][mesh_id].push_back(vobj); - mPendingRequests.emplace_back(new PendingRequestLOD(mesh_params, new_lod)); + std::shared_ptr<PendingRequestBase> request(new PendingRequestLOD(mesh_params, new_lod)); + mPendingRequests.emplace_back(request); + mLoadingMeshes[new_lod][mesh_id].initData(vobj, request); LLMeshRepository::sLODPending++; } } @@ -4315,50 +4417,6 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para return new_lod; } -F32 calculate_score(LLVOVolume* object) -{ - if (!object) - { - return -1.f; - } - LLDrawable* drawable = object->mDrawable; - if (!drawable) - { - return -1; - } - if (drawable->isState(LLDrawable::RIGGED) || object->isAttachment()) - { - LLVOAvatar* avatar = object->getAvatar(); - LLDrawable* av_drawable = avatar ? avatar->mDrawable : nullptr; - if (avatar && av_drawable) - { - // See LLVOVolume::calcLOD() - F32 radius; - if (avatar->isControlAvatar()) - { - const LLVector3* box = avatar->getLastAnimExtents(); - LLVector3 diag = box[1] - box[0]; - radius = diag.magVec() * 0.5f; - } - else - { - // Volume in a rigged mesh attached to a regular avatar. - const LLVector3* box = avatar->getLastAnimExtents(); - LLVector3 diag = box[1] - box[0]; - radius = diag.magVec(); - - if (!avatar->isSelf() && !avatar->hasFirstFullAttachmentData()) - { - // slightly deprioritize avatars that are still receiving data - radius *= 0.9f; - } - } - return radius / llmax(av_drawable->mDistanceWRTCamera, 1.f); - } - } - return drawable->getRadius() / llmax(drawable->mDistanceWRTCamera, 1.f); -} - void LLMeshRepository::notifyLoadedMeshes() { //called from main thread LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); @@ -4495,13 +4553,20 @@ void LLMeshRepository::notifyLoadedMeshes() { LLMutexTrylock lock1(mMeshMutex); LLMutexTrylock lock2(mThread->mMutex); + LLMutexTrylock lock3(mThread->mHeaderMutex); + LLMutexTrylock lock4(mThread->mPendingMutex); static U32 hold_offs(0); - if (! lock1.isLocked() || ! lock2.isLocked()) + if (! lock1.isLocked() || ! lock2.isLocked() || ! lock3.isLocked() || ! lock4.isLocked()) { // If we can't get the locks, skip and pick this up later. + // Eventually thread queue will be free enough ++hold_offs; sMaxLockHoldoffs = llmax(sMaxLockHoldoffs, hold_offs); + if (hold_offs > 4) + { + LL_WARNS_ONCE() << "High mesh thread holdoff" << LL_ENDL; + } return; } hold_offs = 0; @@ -4548,61 +4613,25 @@ void LLMeshRepository::notifyLoadedMeshes() if (mPendingRequests.size() > push_count) { + LL_PROFILE_ZONE_NAMED("Mesh score update"); // More requests than the high-water limit allows so // sort and forward the most important. - //calculate "score" for pending requests - - //create score map - std::map<LLUUID, F32> score_map; - - for (U32 i = 0; i < LLVolumeLODGroup::NUM_LODS; ++i) - { - for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) - { - F32 max_score = 0.f; - for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) - { - F32 cur_score = calculate_score(*obj_iter); - if (cur_score >= 0.f) - { - max_score = llmax(max_score, cur_score); - } - } - - score_map[iter->first] = max_score; - } - } - for (mesh_load_map::iterator iter = mLoadingSkins.begin(); iter != mLoadingSkins.end(); ++iter) - { - F32 max_score = 0.f; - for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) - { - F32 cur_score = calculate_score(*obj_iter); - if (cur_score >= 0.f) - { - max_score = llmax(max_score, cur_score); - } - } - - score_map[iter->first] = max_score; - } - - //set "score" for pending requests - for (std::unique_ptr<PendingRequestBase>& req_p : mPendingRequests) + // update "score" for pending requests + for (std::shared_ptr<PendingRequestBase>& req_p : mPendingRequests) { - req_p->setScore(score_map[req_p->getId()]); + req_p->checkScore(); } //sort by "score" std::partial_sort(mPendingRequests.begin(), mPendingRequests.begin() + push_count, mPendingRequests.end(), PendingRequestBase::CompareScoreGreater()); } - LLMutexTrylock lock3(mThread->mHeaderMutex); - LLMutexTrylock lock4(mThread->mPendingMutex); while (!mPendingRequests.empty() && push_count > 0) { - std::unique_ptr<PendingRequestBase>& req_p = mPendingRequests.front(); + std::shared_ptr<PendingRequestBase>& req_p = mPendingRequests.front(); + // todo: check hasTrackedData here and erase request if none + // since this is supposed to mean that request was removed switch (req_p->getRequestType()) { case MESH_REQUEST_LOD: @@ -4657,7 +4686,7 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID); if (iter != mLoadingSkins.end()) { - for (LLVOVolume* vobj : iter->second) + for (LLVOVolume* vobj : iter->second.mVolumes) { if (vobj) { @@ -4673,7 +4702,7 @@ void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id) skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); if (iter != mLoadingSkins.end()) { - for (LLVOVolume* vobj : iter->second) + for (LLVOVolume* vobj : iter->second.mVolumes) { if (vobj) { @@ -4737,7 +4766,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } //notify waiting LLVOVolume instances that their requested mesh is available - for (LLVOVolume* vobj : obj_iter->second) + for (LLVOVolume* vobj : obj_iter->second.mVolumes) { if (vobj) { @@ -4767,7 +4796,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, LLPrimitive::getVolumeManager()->unrefVolume(sys_volume); } - for (LLVOVolume* vobj : obj_iter->second) + for (LLVOVolume* vobj : obj_iter->second.mVolumes) { if (vobj) { @@ -4810,16 +4839,17 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOV skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); if (iter != mLoadingSkins.end()) { //request pending for this mesh, append volume id to list - auto it = std::find(iter->second.begin(), iter->second.end(), requesting_obj); - if (it == iter->second.end()) { - iter->second.push_back(requesting_obj); + auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), requesting_obj); + if (it == iter->second.mVolumes.end()) { + iter->second.addVolume(requesting_obj); } } else { //first request for this mesh - mLoadingSkins[mesh_id].push_back(requesting_obj); - mPendingRequests.emplace_back(new PendingRequestUUID(mesh_id, MESH_REQUEST_SKIN)); + std::shared_ptr<PendingRequestBase> request(new PendingRequestUUID(mesh_id, MESH_REQUEST_SKIN)); + mLoadingSkins[mesh_id].initData(requesting_obj, request); + mPendingRequests.emplace_back(request); } } } @@ -4998,12 +5028,12 @@ bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id) const void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, - std::string upload_url, bool do_upload, + std::string upload_url, const LLUUID& destination_folder_id, bool do_upload, LLHandle<LLWholeModelFeeObserver> fee_observer, LLHandle<LLWholeModelUploadObserver> upload_observer) { LLMeshUploadThread* thread = new LLMeshUploadThread(data, scale, upload_textures, upload_skin, upload_joints, lock_scale_if_joint_position, - upload_url, do_upload, fee_observer, upload_observer); + upload_url, destination_folder_id, do_upload, fee_observer, upload_observer); mUploadWaitList.push_back(thread); } @@ -5993,13 +6023,7 @@ bool LLMeshRepository::meshUploadEnabled() bool LLMeshRepository::meshRezEnabled() { static LLCachedControl<bool> mesh_enabled(gSavedSettings, "MeshEnabled"); - LLViewerRegion *region = gAgent.getRegion(); - if(mesh_enabled && - region) - { - return region->meshRezEnabled(); - } - return false; + return mesh_enabled; } // Threading: main thread only diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index b9acb3573f..2b772f7803 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -168,7 +168,6 @@ public: void submitRequest(Request* request); static S32 llcdCallback(const char*, S32, S32); - void cancel(); void setMeshData(LLCDMeshData& mesh, bool vertex_based); void doDecomposition(); @@ -206,19 +205,19 @@ private: LLFrameTimer mTimer; }; - +class MeshLoadData; class PendingRequestBase { public: struct CompareScoreGreater { - bool operator()(const std::unique_ptr<PendingRequestBase>& lhs, const std::unique_ptr<PendingRequestBase>& rhs) + bool operator()(const std::shared_ptr<PendingRequestBase>& lhs, const std::shared_ptr<PendingRequestBase>& rhs) { return lhs->mScore > rhs->mScore; // greatest = first } }; - PendingRequestBase() : mScore(0.f) {}; + PendingRequestBase() : mScore(0.f), mTrackedData(nullptr), mScoreDirty(true) {}; virtual ~PendingRequestBase() {} bool operator<(const PendingRequestBase& rhs) const @@ -226,14 +225,34 @@ public: return mId < rhs.mId; } - void setScore(F32 score) { mScore = score; } F32 getScore() const { return mScore; } + void checkScore() + { + constexpr F32 EXPIRE_TIME_SECS = 8.f; + if (mScoreTimer.getElapsedTimeF32() > EXPIRE_TIME_SECS || mScoreDirty) + { + updateScore(); + mScoreDirty = false; + mScoreTimer.reset(); + } + }; + LLUUID getId() const { return mId; } virtual EMeshRequestType getRequestType() const = 0; + void trackData(MeshLoadData* data) { mTrackedData = data; mScoreDirty = true; } + void untrackData() { mTrackedData = nullptr; } + bool hasTrackedData() { return mTrackedData != nullptr; } + void setScoreDirty() { mScoreDirty = true; } + protected: - F32 mScore; + void updateScore(); + LLUUID mId; + F32 mScore; + bool mScoreDirty; + LLTimer mScoreTimer; + MeshLoadData* mTrackedData; }; class PendingRequestLOD : public PendingRequestBase @@ -267,6 +286,37 @@ private: EMeshRequestType mRequestType; }; + +class MeshLoadData +{ +public: + MeshLoadData() {} + ~MeshLoadData() + { + if (std::shared_ptr<PendingRequestBase> request = mRequest.lock()) + { + request->untrackData(); + } + } + void initData(LLVOVolume* vol, std::shared_ptr<PendingRequestBase>& request) + { + mVolumes.push_back(vol); + request->trackData(this); + mRequest = request; + } + void addVolume(LLVOVolume* vol) + { + mVolumes.push_back(vol); + if (std::shared_ptr<PendingRequestBase> request = mRequest.lock()) + { + request->setScoreDirty(); + } + } + std::vector<LLVOVolume*> mVolumes; +private: + std::weak_ptr<PendingRequestBase> mRequest; +}; + class LLMeshHeader { public: @@ -624,7 +674,22 @@ public: typedef std::vector<LLModelInstance> instance_list; instance_list mInstanceList; - typedef std::map<LLPointer<LLModel>, instance_list> instance_map; + // Upload should happen in deterministic order, so sort instances by model name. + struct LLUploadModelInstanceLess + { + inline bool operator()(const LLPointer<LLModel>& a, const LLPointer<LLModel>& b) const + { + if (a.isNull() || b.isNull()) + { + llassert(false); // We are uploading these models, they shouldn't be null. + return true; + } + // Note: probably can sort by mBaseModel->mSubmodelID here as well to avoid + // running over the list twice in wholeModelToLLSD. + return a->mLabel < b->mLabel; + } + }; + typedef std::map<LLPointer<LLModel>, instance_list, LLUploadModelInstanceLess> instance_map; instance_map mInstance; LLMutex* mMutex; @@ -640,10 +705,13 @@ public: LLHost mHost; std::string mWholeModelFeeCapability; std::string mWholeModelUploadURL; + LLUUID mDestinationFolderId; LLMeshUploadThread(instance_list& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, - const std::string & upload_url, bool do_upload = true, + const std::string & upload_url, + const LLUUID destination_folder_id = LLUUID::null, + bool do_upload = true, LLHandle<LLWholeModelFeeObserver> fee_observer = (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); ~LLMeshUploadThread(); @@ -659,7 +727,7 @@ public: void doWholeModelUpload(); void requestWholeModelFee(); - void wholeModelToLLSD(LLSD& dest, bool include_textures); + void wholeModelToLLSD(LLSD& dest, std::vector<std::string>& texture_list_dest, bool include_textures); void decomposeMeshMatrix(LLMatrix4& transformation, LLVector3& result_pos, @@ -680,6 +748,7 @@ private: bool mDoUpload; // if false only model data will be requested, otherwise the model will be uploaded LLSD mModelData; + std::vector<std::string> mTextureFiles; // llcorehttp library interface objects. LLCore::HttpStatus mHttpStatus; @@ -802,7 +871,9 @@ public: void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position, - std::string upload_url, bool do_upload = true, + std::string upload_url, + const LLUUID& destination_folder_id = LLUUID::null, + bool do_upload = true, LLHandle<LLWholeModelFeeObserver> fee_observer= (LLHandle<LLWholeModelFeeObserver>()), LLHandle<LLWholeModelUploadObserver> upload_observer = (LLHandle<LLWholeModelUploadObserver>())); @@ -814,7 +885,7 @@ public: static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > mesh_load_map; + typedef std::unordered_map<LLUUID, MeshLoadData> mesh_load_map; mesh_load_map mLoadingMeshes[4]; typedef std::unordered_map<LLUUID, LLPointer<LLMeshSkinInfo>> skin_map; @@ -825,11 +896,11 @@ public: LLMutex* mMeshMutex; - typedef std::vector <std::unique_ptr<PendingRequestBase> > pending_requests_vec; + typedef std::vector <std::shared_ptr<PendingRequestBase> > pending_requests_vec; pending_requests_vec mPendingRequests; //list of mesh ids awaiting skin info - typedef std::unordered_map<LLUUID, std::vector<LLVOVolume*> > skin_load_map; + typedef std::unordered_map<LLUUID, MeshLoadData > skin_load_map; skin_load_map mLoadingSkins; //list of mesh ids awaiting decompositions diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 5a8fd299bf..e0649e1d88 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -30,7 +30,7 @@ #include "llmodelloader.h" #include "lldaeloader.h" -#include "llgltfloader.h" +#include "gltf/llgltfloader.h" #include "llfloatermodelpreview.h" #include "llagent.h" @@ -40,6 +40,7 @@ #include "lldrawable.h" #include "llface.h" #include "lliconctrl.h" +#include "lljointdata.h" #include "llmatrix4a.h" #include "llmeshrepository.h" #include "llmeshoptimizer.h" @@ -163,10 +164,14 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) , mPhysicsSearchLOD(LLModel::LOD_PHYSICS) , mResetJoints(false) , mModelNoErrors(true) + , mLoading(false) + , mModelLoader(nullptr) , mLastJointUpdate(false) , mFirstSkinUpdate(true) , mHasDegenerate(false) - , mImporterDebug(LLCachedControl<bool>(gSavedSettings, "ImporterDebug", false)) + , mNumOfFetchingTextures(0) + , mTexturesNeedScaling(false) + , mImporterDebug(LLCachedControl<bool>(gSavedSettings, "ImporterDebugVerboseLogging", false)) { mNeedsUpdate = true; mCameraDistance = 0.f; @@ -175,11 +180,9 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) mCameraZoom = 1.f; mTextureName = 0; mPreviewLOD = 0; - mModelLoader = NULL; mMaxTriangleLimit = 0; mDirty = false; mGenLOD = false; - mLoading = false; mLookUpLodFiles = false; mLoadState = LLModelLoader::STARTING; mGroup = 0; @@ -211,6 +214,7 @@ LLModelPreview::~LLModelPreview() { mModelLoader->shutdown(); mModelLoader = NULL; + mLoading = false; } if (mPreviewAvatar) @@ -557,10 +561,7 @@ void LLModelPreview::rebuildUploadData() texture->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, true, false, new LLHandle<LLModelPreview>(getHandle()), &mCallbackTextureList, false); texture->forceToSaveRawImage(0, F32_MAX); texture->updateFetch(); - if (mModelLoader) - { - mModelLoader->mNumOfFetchingTextures++; - } + mNumOfFetchingTextures++; } } } @@ -691,7 +692,7 @@ void LLModelPreview::saveUploadData(const std::string& filename, save_skinweights, save_joint_positions, lock_scale_if_joint_position, - false, true, instance.mModel->mSubmodelID); + LLModel::WRITE_BINARY, true, instance.mModel->mSubmodelID); data["mesh"][instance.mModel->mLocalID] = str.str(); } @@ -753,6 +754,10 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, true); assert(lod >= LLModel::LOD_IMPOSTOR && lod < LLModel::NUM_LODS); + if (mModelLoader == nullptr) + { + mLoading = false; + } return; } @@ -780,7 +785,7 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable mLODFile[lod] = filename; - std::map<std::string, std::string> joint_alias_map; + std::map<std::string, std::string, std::less<>> joint_alias_map; getJointAliases(joint_alias_map); LLHandle<LLModelPreview> preview_handle = getHandle(); @@ -806,10 +811,14 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable joint_alias_map, LLSkinningUtil::getMaxJointCount(), gSavedSettings.getU32("ImporterModelLimit"), + gSavedSettings.getU32("ImporterDebugMode"), gSavedSettings.getBOOL("ImporterPreprocessDAE")); } else { + LLVOAvatar* av = getPreviewAvatar(); + std::vector<LLJointData> viewer_skeleton; + av->getJointMatricesAndHierarhy(viewer_skeleton); mModelLoader = new LLGLTFLoader( filename, lod, @@ -822,7 +831,9 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable mJointsFromNode, joint_alias_map, LLSkinningUtil::getMaxJointCount(), - gSavedSettings.getU32("ImporterModelLimit")); + gSavedSettings.getU32("ImporterModelLimit"), + gSavedSettings.getU32("ImporterDebugMode"), + viewer_skeleton); } if (force_disable_slm) @@ -985,7 +996,9 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) setRigValidForJointPositionUpload(mModelLoader->isRigValidForJointPositionUpload()); setLegacyRigFlags(mModelLoader->getLegacyRigFlags()); + mTexturesNeedScaling |= mModelLoader->mTexturesNeedScaling; mModelLoader->loadTextures(); + warnTextureScaling(); if (loaded_lod == -1) { //populate all LoDs from model loader scene @@ -1807,7 +1820,7 @@ F32 LLModelPreview::genMeshOptimizerPerFace(LLModel *base_model, LLModel *target void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 decimation, bool enforce_tri_limit) { - LL_INFOS() << "Generating lod " << which_lod << " using meshoptimizer" << LL_ENDL; + LL_DEBUGS("Upload") << "Generating lod " << which_lod << " using meshoptimizer" << LL_ENDL; // Allow LoD from -1 to LLModel::LOD_PHYSICS if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1) { @@ -1884,6 +1897,12 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d mMaxTriangleLimit = base_triangle_count; + // For logging purposes + S32 meshes_processed = 0; + S32 meshes_simplified = 0; + S32 meshes_sloppy_simplified = 0; + S32 meshes_fail_count = 0; + // Build models S32 start = LLModel::LOD_HIGH; @@ -1893,7 +1912,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d { start = which_lod; end = which_lod; - } + }; for (S32 lod = start; lod >= end; --lod) { @@ -1956,6 +1975,11 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d const LLVolumeFace &face = base->getVolumeFace(face_idx); LLVolumeFace &new_face = target_model->getVolumeFace(face_idx); new_face = face; + meshes_fail_count++; + } + else + { + meshes_simplified++; } } } @@ -1968,7 +1992,18 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_NO_TOPOLOGY) < 0) { // Sloppy failed and returned an invalid model - genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL); + if (genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL) < 0) + { + meshes_fail_count++; + } + else + { + meshes_simplified++; + } + } + else + { + meshes_sloppy_simplified++; } } } @@ -2068,25 +2103,28 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, MESH_OPTIMIZER_FULL); } - LL_INFOS() << "Model " << target_model->getName() + LL_DEBUGS("Upload") << "Model " << target_model->getName() << " lod " << which_lod << " resulting ratio " << precise_ratio << " simplified using per model method." << LL_ENDL; + meshes_simplified++; } else { - LL_INFOS() << "Model " << target_model->getName() + LL_DEBUGS("Upload") << "Model " << target_model->getName() << " lod " << which_lod << " resulting ratio " << sloppy_ratio << " sloppily simplified using per model method." << LL_ENDL; + meshes_sloppy_simplified++; } } else { - LL_INFOS() << "Model " << target_model->getName() + LL_DEBUGS("Upload") << "Model " << target_model->getName() << " lod " << which_lod << " resulting ratio " << precise_ratio << " simplified using per model method." << LL_ENDL; + meshes_simplified++; } } @@ -2100,6 +2138,8 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d //copy material list target_model->mMaterialList = base->mMaterialList; + meshes_processed++; + if (!validate_model(target_model)) { LL_ERRS() << "Invalid model generated when creating LODs" << LL_ENDL; @@ -2129,6 +2169,11 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d } } } + + LL_INFOS("Upload") << "LOD " << which_lod << ", Mesh optimizer processed meshes : " << meshes_processed + <<" simplified: " << meshes_simplified + << ", slopily simplified: " << meshes_sloppy_simplified + << ", failures: " << meshes_fail_count << LL_ENDL; } void LLModelPreview::updateStatusMessages() @@ -2348,7 +2393,7 @@ void LLModelPreview::updateStatusMessages() if (lod != lod_high) { - if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high]) + if (total_submeshes[lod] && total_submeshes[lod] > total_submeshes[lod_high]) { //number of submeshes is different message = "mesh_status_submesh_mismatch"; upload_status[lod] = 2; @@ -2466,7 +2511,7 @@ void LLModelPreview::updateStatusMessages() LLMutexLock lock(this); if (mModelLoader) { - if (!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean()) + if (!areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean()) { // Some textures are still loading, prevent upload until they are done mModelNoErrors = false; @@ -2498,6 +2543,8 @@ void LLModelPreview::updateStatusMessages() S32 phys_tris = 0; S32 phys_hulls = 0; S32 phys_points = 0; + S32 which_mode = 0; + S32 file_mode = 1; //get the triangle count for the whole scene for (LLModelLoader::scene::iterator iter = mScene[LLModel::LOD_PHYSICS].begin(), endIter = mScene[LLModel::LOD_PHYSICS].end(); iter != endIter; ++iter) @@ -2619,18 +2666,16 @@ void LLModelPreview::updateStatusMessages() fmp->childEnable("simplify_cancel"); fmp->childEnable("decompose_cancel"); } - } - - LLCtrlSelectionInterface* iface = fmp->childGetSelectionInterface("physics_lod_combo"); - S32 which_mode = 0; - S32 file_mode = 1; - if (iface) - { - which_mode = iface->getFirstSelectedIndex(); - file_mode = iface->getItemCount() - 1; + LLCtrlSelectionInterface* iface = fmp->childGetSelectionInterface("physics_lod_combo"); + if (iface) + { + which_mode = iface->getFirstSelectedIndex(); + file_mode = iface->getItemCount() - 1; + } } + if (which_mode == file_mode) { mFMP->childEnable("physics_file"); @@ -3039,9 +3084,12 @@ void LLModelPreview::loadedCallback( S32 lod, void* opaque) { + if(LLModelPreview::sIgnoreLoadedCallback) + return; + LLModelPreview* pPreview = static_cast<LLModelPreview*>(opaque); LLMutexLock lock(pPreview); - if (pPreview && pPreview->mModelLoader && !LLModelPreview::sIgnoreLoadedCallback) + if (pPreview && pPreview->mModelLoader) { // Load loader's warnings into floater's log tab const LLSD out = pPreview->mModelLoader->logOut(); @@ -3090,25 +3138,48 @@ void LLModelPreview::lookupLODModelFiles(S32 lod) S32 next_lod = (lod - 1 >= LLModel::LOD_IMPOSTOR) ? lod - 1 : LLModel::LOD_PHYSICS; std::string lod_filename = mLODFile[LLModel::LOD_HIGH]; - std::string ext = ".dae"; std::string lod_filename_lower(lod_filename); LLStringUtil::toLower(lod_filename_lower); - std::string::size_type i = lod_filename_lower.rfind(ext); - if (i != std::string::npos) + + // Check for each supported file extension + std::vector<std::string> supported_exts = { ".dae", ".gltf", ".glb" }; + std::string found_ext; + std::string::size_type ext_pos = std::string::npos; + + for (const auto& ext : supported_exts) { - lod_filename.replace(i, lod_filename.size() - ext.size(), getLodSuffix(next_lod) + ext); + std::string::size_type i = lod_filename_lower.rfind(ext); + if (i != std::string::npos) + { + ext_pos = i; + found_ext = ext; + break; + } } - if (gDirUtilp->fileExists(lod_filename)) + + if (ext_pos != std::string::npos) { - LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; - if (fmp) + // Replace extension with LOD suffix + original extension + std::string lod_file_to_check = lod_filename; + lod_file_to_check.replace(ext_pos, found_ext.size(), getLodSuffix(next_lod) + found_ext); + + if (gDirUtilp->fileExists(lod_file_to_check)) + { + LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance; + if (fmp) + { + fmp->setCtrlLoadFromFile(next_lod); + } + loadModel(lod_file_to_check, next_lod); + } + else { - fmp->setCtrlLoadFromFile(next_lod); + lookupLODModelFiles(next_lod); } - loadModel(lod_filename, next_lod); } else { + // No recognized extension found, continue with next LOD lookupLODModelFiles(next_lod); } } @@ -3149,6 +3220,7 @@ U32 LLModelPreview::loadTextures(LLImportMaterial& material, LLHandle<LLModelPre tex->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, true, false, new LLHandle<LLModelPreview>(handle), &preview->mCallbackTextureList, false); tex->forceToSaveRawImage(0, F32_MAX); material.setDiffuseMap(tex->getID()); // record tex ID + preview->mNumOfFetchingTextures++; return 1; } @@ -3323,7 +3395,6 @@ bool LLModelPreview::render() fmp->setViewOptionEnabled("show_skin_weight", show_skin_weight); } } - //if (this) return TRUE; if (upload_skin && !has_skin_weights) { //can't upload skin weights if model has no skin weights @@ -3993,6 +4064,18 @@ void LLModelPreview::setPreviewLOD(S32 lod) updateStatusMessages(); } +void LLModelPreview::warnTextureScaling() +{ + if (areTexturesReady() && mTexturesNeedScaling) + { + std::ostringstream out; + out << "One or more textures in this model were scaled to be within the allowed limits."; + LL_INFOS() << out.str() << LL_ENDL; + LLSD args; + LLFloaterModelPreview::addStringToLog("ModelTextureScaling", args, true, -1); + } +} + //static void LLModelPreview::textureLoadedCallback( bool success, @@ -4013,11 +4096,19 @@ void LLModelPreview::textureLoadedCallback( LLModelPreview* preview = static_cast<LLModelPreview*>(handle->get()); preview->refresh(); - if (final && preview->mModelLoader) + if (final) { - if (preview->mModelLoader->mNumOfFetchingTextures > 0) + if (src_vi + && (src_vi->getOriginalWidth() > LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT + || src_vi->getOriginalHeight() > LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT)) + { + preview->mTexturesNeedScaling = true; + } + + if (preview->mNumOfFetchingTextures > 0) { - preview->mModelLoader->mNumOfFetchingTextures--; + preview->mNumOfFetchingTextures--; + preview->warnTextureScaling(); } } } diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 0873263587..7b3b699b33 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -204,6 +204,7 @@ public: std::vector<S32> mLodsQuery; std::vector<S32> mLodsWithParsingError; bool mHasDegenerate; + bool areTexturesReady() { return !mNumOfFetchingTextures; } protected: @@ -213,6 +214,7 @@ protected: static LLJoint* lookupJointByName(const std::string&, void* opaque); static U32 loadTextures(LLImportMaterial& material, LLHandle<LLModelPreview> handle); + void warnTextureScaling(); void lookupLODModelFiles(S32 lod); private: @@ -242,6 +244,9 @@ private: /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true. LLPointer<LLModel> mDefaultPhysicsShapeP; + S32 mNumOfFetchingTextures; + bool mTexturesNeedScaling; + typedef enum { MESH_OPTIMIZER_FULL, diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 2d51acc063..f6d635f51f 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -154,7 +154,8 @@ std::string LLMute::getDisplayType() const // LLMuteList() //----------------------------------------------------------------------------- LLMuteList::LLMuteList() : - mIsLoaded(false) + mLoadState(ML_INITIAL), + mRequestStartTime(0.f) { gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList); @@ -209,6 +210,23 @@ bool LLMuteList::isLinden(const std::string& name) return last_name == "linden"; } +bool LLMuteList::getLoadFailed() const +{ + if (mLoadState == ML_FAILED) + { + return true; + } + if (mLoadState == ML_REQUESTED) + { + constexpr F64 WAIT_SECONDS = 30; + if (mRequestStartTime + WAIT_SECONDS < LLTimer::getTotalSeconds()) + { + return true; + } + } + return false; +} + static LLVOAvatar* find_avatar(const LLUUID& id) { LLViewerObject *obj = gObjectList.findObject(id); @@ -371,11 +389,14 @@ void LLMuteList::updateAdd(const LLMute& mute) msg->addU32("MuteFlags", mute.mFlags); gAgent.sendReliableMessage(); - if (!mIsLoaded) + if (!isLoaded()) { LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL; } - mIsLoaded = true; // why is this here? -MG + // Based of logs and testing, if file doesn't exist server side, + // viewer will not receive any callback and won't know to set + // ML_LOADED. As a workaround, set it regardless of current state. + mLoadState = ML_LOADED; } @@ -564,6 +585,7 @@ bool LLMuteList::loadFromFile(const std::string& filename) if(!filename.size()) { LL_WARNS() << "Mute List Filename is Empty!" << LL_ENDL; + mLoadState = ML_FAILED; return false; } @@ -571,6 +593,7 @@ bool LLMuteList::loadFromFile(const std::string& filename) if (!fp) { LL_WARNS() << "Couldn't open mute list " << filename << LL_ENDL; + mLoadState = ML_FAILED; return false; } @@ -730,13 +753,17 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id) if (gDisconnected) { LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL; + mLoadState = ML_FAILED; return; } if (!gAgent.getRegion()) { LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL; + mLoadState = ML_FAILED; return; } + mLoadState = ML_REQUESTED; + mRequestStartTime = LLTimer::getElapsedSeconds(); // Double amount of retries due to this request happening during busy stage // Ideally this should be turned into a capability gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, true, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL); @@ -749,7 +776,7 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id) void LLMuteList::cache(const LLUUID& agent_id) { // Write to disk even if empty. - if(mIsLoaded) + if(isLoaded()) { std::string agent_id_string; std::string filename; @@ -777,6 +804,13 @@ void LLMuteList::processMuteListUpdate(LLMessageSystem* msg, void**) msg->getStringFast(_PREHASH_MuteData, _PREHASH_Filename, unclean_filename); std::string filename = LLDir::getScrubbedFileName(unclean_filename); + LLMuteList* mute_list = getInstance(); + mute_list->mLoadState = ML_REQUESTED; + mute_list->mRequestStartTime = LLTimer::getElapsedSeconds(); + + // Todo: Based of logs and testing, there is no callback + // from server if file doesn't exist server side. + // Once server side gets fixed make sure it gets handled right. std::string *local_filename_and_path = new std::string(gDirUtilp->getExpandedFilename( LL_PATH_CACHE, filename )); gXferManager->requestFile(*local_filename_and_path, filename, @@ -809,12 +843,16 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_ LLMuteList::getInstance()->loadFromFile(*local_filename_and_path); LLFile::remove(*local_filename_and_path); } + else + { + LLMuteList::getInstance()->mLoadState = ML_FAILED; + } delete local_filename_and_path; } void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username) { - if (mIsLoaded) + if (isLoaded()) { LLMute mute(id, username, LLMute::AGENT); mute_set_t::iterator mute_it = mMutes.find(mute); @@ -866,7 +904,7 @@ void LLMuteList::removeObserver(LLMuteListObserver* observer) void LLMuteList::setLoaded() { - mIsLoaded = true; + mLoadState = ML_LOADED; notifyObservers(); } diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index 13d579c61f..b65fd61fcc 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -74,6 +74,14 @@ class LLMuteList : public LLSingleton<LLMuteList> LLSINGLETON(LLMuteList); ~LLMuteList(); /*virtual*/ void cleanupSingleton() override; + + enum EMuteListState + { + ML_INITIAL, + ML_REQUESTED, + ML_LOADED, + ML_FAILED, + }; public: // reasons for auto-unmuting a resident enum EAutoReason @@ -107,7 +115,8 @@ public: static bool isLinden(const std::string& name); - bool isLoaded() const { return mIsLoaded; } + bool isLoaded() const { return mLoadState == ML_LOADED; } + bool getLoadFailed() const; std::vector<LLMute> getMutes() const; @@ -167,7 +176,8 @@ private: typedef std::set<LLMuteListObserver*> observer_set_t; observer_set_t mObservers; - bool mIsLoaded; + EMuteListState mLoadState; + F64 mRequestStartTime; friend class LLDispatchEmptyMuteList; }; diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index b1d5cd9e16..3adee9fa16 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -69,7 +69,6 @@ const S32 GALLERY_ITEMS_PER_ROW_MIN = 2; LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p) : LLOutfitListBase(), - mOutfitsObserver(NULL), mScrollPanel(NULL), mGalleryPanel(NULL), mLastRowPanel(NULL), @@ -88,9 +87,16 @@ LLOutfitGallery::LLOutfitGallery(const LLOutfitGallery::Params& p) mItemsInRow(p.items_in_row), mRowPanWidthFactor(p.row_panel_width_factor), mGalleryWidthFactor(p.gallery_width_factor), - mTextureSelected(NULL) + mTextureSelected(NULL), + mSortMenu(nullptr) { updateGalleryWidth(); + + LLControlVariable* ctrl = gSavedSettings.getControl("InventoryFavoritesColorText"); + if (ctrl) + { + mSavedSettingInvFavColor = ctrl->getSignal()->connect(boost::bind(&LLOutfitGallery::handleInvFavColorChange, this)); + } } LLOutfitGallery::Params::Params() @@ -421,19 +427,32 @@ void LLOutfitGallery::updateRowsIfNeeded() bool compareGalleryItem(LLOutfitGalleryItem* item1, LLOutfitGalleryItem* item2) { - static LLCachedControl<bool> outfit_gallery_sort_by_name(gSavedSettings, "OutfitGallerySortByName"); - if(outfit_gallery_sort_by_name || - ((item1->isDefaultImage() && item2->isDefaultImage()) || (!item1->isDefaultImage() && !item2->isDefaultImage()))) - { - std::string name1 = item1->getItemName(); - std::string name2 = item2->getItemName(); - - return (LLStringUtil::compareDict(name1, name2) < 0); - } - else + static LLCachedControl<S32> sort_by_name(gSavedSettings, "OutfitGallerySortOrder", 0); + switch (sort_by_name()) { - return item2->isDefaultImage(); + case 2: + // Sort by favorites - favorite items first, then alphabetically + if (item1->isFavorite() != item2->isFavorite()) + { + return item1->isFavorite(); + } + break; + case 1: + // Sort by images - items with non-default images first, then alphabetically + if (item1->isDefaultImage() != item2->isDefaultImage()) + { + return item2->isDefaultImage(); + } + break; + default: + // Sort alphabetically only + break; } + + // Final comparison is always alphabetical by name + std::string name1 = item1->getItemName(); + std::string name2 = item2->getItemName(); + return (LLStringUtil::compareDict(name1, name2) < 0); } void LLOutfitGallery::reArrangeRows(S32 row_diff) @@ -476,6 +495,20 @@ void LLOutfitGallery::updateGalleryWidth() mGalleryWidth = mGalleryWidthFactor * mItemsInRow - mItemHorizontalGap; } +void LLOutfitGallery::handleInvFavColorChange() +{ + for (outfit_map_t::iterator iter = mOutfitMap.begin(); + iter != mOutfitMap.end(); + ++iter) + { + if (!iter->second) continue; + LLOutfitGalleryItem* item = (LLOutfitGalleryItem*)iter->second; + + // refresh font color + item->setOutfitFavorite(item->isFavorite()); + } +} + LLPanel* LLOutfitGallery::addLastRow() { mRowCount++; @@ -627,7 +660,7 @@ void LLOutfitGallery::removeFromLastRow(LLOutfitGalleryItem* item) mItemPanels.pop_back(); } -LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name, LLUUID outfit_id) +LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name, LLUUID outfit_id, bool is_favorite) { LLOutfitGalleryItem::Params giparams; LLOutfitGalleryItem* gitem = LLUICtrlFactory::create<LLOutfitGalleryItem>(giparams); @@ -636,6 +669,7 @@ LLOutfitGalleryItem* LLOutfitGallery::buildGalleryItem(std::string name, LLUUID gitem->setFollowsLeft(); gitem->setFollowsTop(); gitem->setOutfitName(name); + gitem->setOutfitFavorite(is_favorite); gitem->setUUID(outfit_id); gitem->setGallery(this); return gitem; @@ -730,12 +764,6 @@ LLOutfitGallery::~LLOutfitGallery() { delete mOutfitGalleryMenu; - if (gInventory.containsObserver(mOutfitsObserver)) - { - gInventory.removeObserver(mOutfitsObserver); - } - delete mOutfitsObserver; - while (!mUnusedRowPanels.empty()) { LLPanel* panelp = mUnusedRowPanels.back(); @@ -793,8 +821,18 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id) LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); if (!cat) return; - std::string name = cat->getName(); - LLOutfitGalleryItem* item = buildGalleryItem(name, cat_id); + if (!isOutfitFolder(cat)) + { + // Assume a subfolder that contains or will contain outfits, track it + const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + mCategoriesObserver->addCategory(cat_id, [this, outfits]() + { + observerCallback(outfits); + }); + return; + } + + LLOutfitGalleryItem* item = buildGalleryItem(cat->getName(), cat_id, cat->getIsFavorite()); mOutfitMap.insert(LLOutfitGallery::outfit_map_value_t(cat_id, item)); item->setRightMouseDownCallback(boost::bind(&LLOutfitListBase::outfitRightClickCallBack, this, _1, _2, _3, cat_id)); @@ -809,14 +847,8 @@ void LLOutfitGallery::updateAddedCategory(LLUUID cat_id) if (!outfit_category) return; - if (mOutfitsObserver == NULL) - { - mOutfitsObserver = new LLInventoryCategoriesObserver(); - gInventory.addObserver(mOutfitsObserver); - } - // Start observing changes in "My Outfits" category. - mOutfitsObserver->addCategory(cat_id, + mCategoriesObserver->addCategory(cat_id, boost::bind(&LLOutfitGallery::refreshOutfit, this, cat_id), true); outfit_category->fetch(); @@ -829,7 +861,7 @@ void LLOutfitGallery::updateRemovedCategory(LLUUID cat_id) if (outfits_iter != mOutfitMap.end()) { // 0. Remove category from observer. - mOutfitsObserver->removeCategory(cat_id); + mCategoriesObserver->removeCategory(cat_id); //const LLUUID& outfit_id = outfits_iter->first; LLOutfitGalleryItem* item = outfits_iter->second; @@ -863,6 +895,7 @@ void LLOutfitGallery::updateChangedCategoryName(LLViewerInventoryCategory *cat, if (item) { item->setOutfitName(name); + item->setOutfitFavorite(cat->getIsFavorite()); } } } @@ -943,6 +976,10 @@ LLOutfitListGearMenuBase* LLOutfitGallery::createGearMenu() static LLDefaultChildRegistry::Register<LLOutfitGalleryItem> r("outfit_gallery_item"); +bool LLOutfitGalleryItem::sColorSetInitialized = false; +LLUIColor LLOutfitGalleryItem::sDefaultTextColor; +LLUIColor LLOutfitGalleryItem::sDefaultFavoriteColor; + LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p) : LLPanel(p), mGallery(nullptr), @@ -954,6 +991,12 @@ LLOutfitGalleryItem::LLOutfitGalleryItem(const Params& p) mUUID(LLUUID()) { buildFromFile("panel_outfit_gallery_item.xml"); + if (!sColorSetInitialized) + { + sDefaultTextColor = LLUIColorTable::instance().getColor("White", LLColor4::white); + sDefaultFavoriteColor = LLUIColorTable::instance().getColor("InventoryFavoriteColor", LLColor4::white); + sColorSetInitialized = true; + } } LLOutfitGalleryItem::~LLOutfitGalleryItem() @@ -1000,6 +1043,19 @@ void LLOutfitGalleryItem::draw() gl_draw_scaled_image(interior.mLeft - 1, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha); } + static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true); + if(mFavorite && draw_star()) + { + const S32 HPAD = 3; + const S32 VPAD = 6; // includes padding for text and for the image + const S32 image_size = 14; + static LLPointer<LLUIImage> fav_img = LLRender2D::getInstance()->getUIImage("Inv_Favorite_Star_Full"); + + const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + gl_draw_scaled_image( + border.getWidth() - image_size - HPAD, image_size + VPAD + mOutfitNameText->getRect().getHeight(), + image_size, image_size, fav_img->getImage(), UI_VERTEX_COLOR % alpha); + } } void LLOutfitGalleryItem::setOutfitName(std::string name) @@ -1009,18 +1065,28 @@ void LLOutfitGalleryItem::setOutfitName(std::string name) mOutfitName = name; } +void LLOutfitGalleryItem::setOutfitFavorite(bool is_favorite) +{ + mFavorite = is_favorite; + + static LLCachedControl<bool> use_color(gSavedSettings, "InventoryFavoritesColorText"); + mOutfitNameText->setReadOnlyColor((mFavorite && use_color()) ? sDefaultFavoriteColor : sDefaultTextColor); +} + void LLOutfitGalleryItem::setOutfitWorn(bool value) { mWorn = value; LLStringUtil::format_map_t worn_string_args; std::string worn_string = getString("worn_string", worn_string_args); - LLUIColor text_color = LLUIColorTable::instance().getColor("White", LLColor4::white); - mOutfitWornText->setReadOnlyColor(text_color); - mOutfitNameText->setReadOnlyColor(text_color); + mOutfitWornText->setReadOnlyColor(sDefaultTextColor.get()); + mOutfitNameText->setReadOnlyColor(sDefaultTextColor.get()); mOutfitWornText->setFont(value ? LLFontGL::getFontSansSerifBold() : LLFontGL::getFontSansSerifSmall()); mOutfitNameText->setFont(value ? LLFontGL::getFontSansSerifBold() : LLFontGL::getFontSansSerifSmall()); mOutfitWornText->setValue(value ? worn_string : ""); mOutfitNameText->setText(mOutfitName); // refresh LLTextViewModel to pick up font changes + + static LLCachedControl<bool> use_color(gSavedSettings, "InventoryFavoritesColorText"); + mOutfitNameText->setReadOnlyColor((mFavorite && use_color()) ? sDefaultFavoriteColor : sDefaultTextColor); } void LLOutfitGalleryItem::setSelected(bool value) @@ -1172,6 +1238,7 @@ LLContextMenu* LLOutfitGalleryContextMenu::createMenu() registrar.add("Outfit.Delete", boost::bind(LLOutfitGallery::onRemoveOutfit, selected_id)); registrar.add("Outfit.Create", boost::bind(&LLOutfitGalleryContextMenu::onCreate, this, _2)); registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitGalleryContextMenu::onThumbnail, this, selected_id)); + registrar.add("Outfit.Favorite", boost::bind(&LLOutfitGalleryContextMenu::onFavorite, this, selected_id)); registrar.add("Outfit.Save", boost::bind(&LLOutfitGalleryContextMenu::onSave, this, selected_id)); enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitGalleryContextMenu::onEnable, this, _2)); enable_registrar.add("Outfit.OnVisible", boost::bind(&LLOutfitGalleryContextMenu::onVisible, this, _2)); @@ -1210,25 +1277,12 @@ void LLOutfitGalleryGearMenu::onUpdateItemsVisibility() { if (!mMenu) return; bool have_selection = getSelectedOutfitID().notNull(); - mMenu->setItemVisible("expand", false); - mMenu->setItemVisible("collapse", false); mMenu->setItemVisible("thumbnail", have_selection); mMenu->setItemVisible("sepatator3", true); mMenu->setItemVisible("sort_folders_by_name", true); LLOutfitListGearMenuBase::onUpdateItemsVisibility(); } -void LLOutfitGalleryGearMenu::onChangeSortOrder() -{ - bool sort_by_name = !gSavedSettings.getBOOL("OutfitGallerySortByName"); - gSavedSettings.setBOOL("OutfitGallerySortByName", sort_by_name); - LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); - if (gallery) - { - gallery->reArrangeRows(); - } -} - bool LLOutfitGalleryGearMenu::hasDefaultImage() { LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mOutfitList); @@ -1345,6 +1399,15 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) } } +LLToggleableMenu* LLOutfitGallery::getSortMenu() +{ + if (!mSortMenu) + { + mSortMenu = new LLOutfitGallerySortMenu(this); + } + return mSortMenu->getMenu(); +} + LLUUID LLOutfitGallery::getPhotoAssetId(const LLUUID& outfit_id) { outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id); @@ -1360,3 +1423,84 @@ LLUUID LLOutfitGallery::getDefaultPhoto() return LLUUID(); } + +//////////////////// LLOutfitGallerySortMenu //////////////////// + +LLOutfitGallerySortMenu::LLOutfitGallerySortMenu(LLOutfitListBase* parent_panel) + : mPanelHandle(parent_panel->getHandle()) +{ + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add("Sort.OnSort", boost::bind(&LLOutfitGallerySortMenu::onSort, this, _2)); + enable_registrar.add("Sort.OnEnable", boost::bind(&LLOutfitGallerySortMenu::onEnable, this, _2)); + + mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( + "menu_outfit_gallery_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(mMenu); +} + + +LLToggleableMenu* LLOutfitGallerySortMenu::getMenu() +{ + return mMenu; +} + +void LLOutfitGallerySortMenu::updateItemsVisibility() +{ + onUpdateItemsVisibility(); +} + +void LLOutfitGallerySortMenu::onUpdateItemsVisibility() +{ + if (!mMenu) return; +} + +bool LLOutfitGallerySortMenu::onEnable(LLSD::String param) +{ + static LLCachedControl<S32> sort_order(gSavedSettings, "OutfitGallerySortOrder", 0); + if ("favorites_to_top" == param) + { + return sort_order == 2; + } + else if ("images_to_top" == param) + { + return sort_order == 1; + } + else if ("by_name" == param) + { + return sort_order == 0; + } + + return false; +} + +void LLOutfitGallerySortMenu::onSort(LLSD::String param) +{ + S32 sort_order = gSavedSettings.getS32("OutfitGallerySortOrder"); + S32 new_sort_order = 0; + if ("favorites_to_top" == param) + { + new_sort_order = 2; + } + else if ("images_to_top" == param) + { + new_sort_order = 1; + } + else if ("by_name" == param) + { + new_sort_order = 0; + } + if (sort_order == new_sort_order) + { + new_sort_order = sort_order ? 0 : 1; + } + gSavedSettings.setS32("OutfitGallerySortOrder", new_sort_order); + + LLOutfitGallery* gallery = dynamic_cast<LLOutfitGallery*>(mPanelHandle.get()); + if (gallery) + { + gallery->reArrangeRows(); + } +} + diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h index 541ea2f9d4..5801a32a39 100644 --- a/indra/newview/lloutfitgallery.h +++ b/indra/newview/lloutfitgallery.h @@ -42,11 +42,13 @@ class LLOutfitGalleryItem; class LLOutfitListGearMenuBase; class LLOutfitGalleryGearMenu; class LLOutfitGalleryContextMenu; +class LLOutfitGallerySortMenu; class LLOutfitGallery : public LLOutfitListBase { public: friend class LLOutfitGalleryGearMenu; + friend class LLOutfitGallerySortMenu; friend class LLOutfitGalleryContextMenu; friend class LLUpdateGalleryOnPhotoLinked; @@ -102,10 +104,12 @@ public: /*virtual*/ bool getHasExpandableFolders() { return false; } + /*virtual*/ void onChangeSortOrder(const LLSD& userdata) {}; void updateMessageVisibility(); bool hasDefaultImage(const LLUUID& outfit_cat_id); void refreshOutfit(const LLUUID& category_id); + virtual LLToggleableMenu* getSortMenu(); protected: /*virtual*/ void onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id); @@ -133,8 +137,9 @@ private: void reArrangeRows(S32 row_diff = 0); void updateRowsIfNeeded(); void updateGalleryWidth(); + void handleInvFavColorChange(); - LLOutfitGalleryItem* buildGalleryItem(std::string name, LLUUID outfit_id); + LLOutfitGalleryItem* buildGalleryItem(std::string name, LLUUID outfit_id, bool is_favorite); LLOutfitGalleryItem* getSelectedItem() const; LLOutfitGalleryItem* getItem(const LLUUID& id) const; @@ -176,6 +181,7 @@ private: int mGalleryWidthFactor; LLListContextMenu* mOutfitGalleryMenu; + LLOutfitGallerySortMenu* mSortMenu; typedef std::map<LLUUID, LLOutfitGalleryItem*> outfit_map_t; typedef outfit_map_t::value_type outfit_map_value_t; @@ -187,6 +193,8 @@ private: LLInventoryCategoriesObserver* mOutfitsObserver; + + boost::signals2::connection mSavedSettingInvFavColor; }; class LLOutfitGalleryContextMenu : public LLOutfitContextMenu { @@ -213,8 +221,6 @@ public: protected: /*virtual*/ void onUpdateItemsVisibility(); private: - /*virtual*/ void onChangeSortOrder(); - bool hasDefaultImage(); }; @@ -243,6 +249,7 @@ public: bool setImageAssetId(LLUUID asset_id); LLUUID getImageAssetId(); void setOutfitName(std::string name); + void setOutfitFavorite(bool is_favorite); void setOutfitWorn(bool value); void setSelected(bool value); void setUUID(const LLUUID &outfit_id) {mUUID = outfit_id;} @@ -250,6 +257,7 @@ public: std::string getItemName() {return mOutfitName;} bool isDefaultImage() {return mDefaultImage;} + bool isFavorite() { return mFavorite; } bool isHidden() {return mHidden;} void setHidden(bool hidden) {mHidden = hidden;} @@ -267,7 +275,29 @@ private: bool mWorn; bool mDefaultImage; bool mHidden; + bool mFavorite; std::string mOutfitName; + + static bool sColorSetInitialized; + static LLUIColor sDefaultTextColor; + static LLUIColor sDefaultFavoriteColor; +}; + +class LLOutfitGallerySortMenu +{ +public: + LLOutfitGallerySortMenu(LLOutfitListBase* parent_panel); + + LLToggleableMenu* getMenu(); + void updateItemsVisibility(); + +private: + void onUpdateItemsVisibility(); + bool onEnable(LLSD::String param); + void onSort(LLSD::String param); + + LLToggleableMenu* mMenu; + LLHandle<LLPanel> mPanelHandle; }; #endif // LL_LLOUTFITGALLERYCTRL_H diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 9d8493549d..cb2a6191fa 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -34,10 +34,13 @@ #include "llaccordionctrl.h" #include "llaccordionctrltab.h" #include "llagentwearables.h" +#include "llaisapi.h" #include "llappearancemgr.h" +#include "llappviewer.h" #include "llfloaterreg.h" #include "llfloatersidepanelcontainer.h" #include "llinspecttexture.h" +#include "llinventorymodelbackgroundfetch.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" #include "llmenubutton.h" @@ -45,6 +48,7 @@ #include "lloutfitobserver.h" #include "lltoggleablemenu.h" #include "lltransutil.h" +#include "llviewercontrol.h" #include "llviewermenu.h" #include "llvoavatar.h" #include "llvoavatarself.h" @@ -53,14 +57,24 @@ static bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y); static const LLOutfitTabNameComparator OUTFIT_TAB_NAME_COMPARATOR; +static const LLOutfitTabFavComparator OUTFIT_TAB_FAV_COMPARATOR; /*virtual*/ bool LLOutfitTabNameComparator::compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const { - std::string name1 = tab1->getTitle(); - std::string name2 = tab2->getTitle(); + return (LLStringUtil::compareDict(tab1->getTitle(), tab2->getTitle()) < 0); +} - return (LLStringUtil::compareDict(name1, name2) < 0); +bool LLOutfitTabFavComparator::compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const +{ + LLOutfitAccordionCtrlTab* taba = (LLOutfitAccordionCtrlTab*)tab1; + LLOutfitAccordionCtrlTab* tabb = (LLOutfitAccordionCtrlTab*)tab2; + if (taba->getFavorite() != tabb->getFavorite()) + { + return taba->getFavorite(); + } + + return (LLStringUtil::compareDict(tab1->getTitle(), tab2->getTitle()) < 0); } struct outfit_accordion_tab_params : public LLInitParam::Block<outfit_accordion_tab_params, LLOutfitAccordionCtrlTab::Params> @@ -80,6 +94,9 @@ const outfit_accordion_tab_params& get_accordion_tab_params() { initialized = true; + LLOutfitAccordionCtrlTab::sFavoriteIcon = LLUI::getUIImage("Inv_Favorite_Star_Full"); + LLOutfitAccordionCtrlTab::sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", LLColor4U(255, 255, 255)); + LLXMLNodePtr xmlNode; if (LLUICtrlFactory::getLayeredXMLNode("outfit_accordion_tab.xml", xmlNode)) { @@ -103,11 +120,20 @@ LLOutfitsList::LLOutfitsList() , mAccordion(NULL) , mListCommands(NULL) , mItemSelected(false) + , mSortMenu(nullptr) { + LLControlVariable* ctrl = gSavedSettings.getControl("InventoryFavoritesColorText"); + if (ctrl) + { + mSavedSettingInvFavColor = ctrl->getSignal()->connect(boost::bind(&LLOutfitsList::handleInvFavColorChange, this)); + } } LLOutfitsList::~LLOutfitsList() { + delete mSortMenu; + mSavedSettingInvFavColor.disconnect(); + mGearMenuConnection.disconnect(); } bool LLOutfitsList::postBuild() @@ -115,9 +141,25 @@ bool LLOutfitsList::postBuild() mAccordion = getChild<LLAccordionCtrl>("outfits_accordion"); mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR); + initComparator(); + return LLOutfitListBase::postBuild(); } +void LLOutfitsList::initComparator() +{ + S32 mode = gSavedSettings.getS32("OutfitListSortOrder"); + if (mode == 0) + { + mAccordion->setComparator(&OUTFIT_TAB_NAME_COMPARATOR); + } + else + { + mAccordion->setComparator(&OUTFIT_TAB_FAV_COMPARATOR); + } + sortOutfits(); +} + //virtual void LLOutfitsList::onOpen(const LLSD& info) { @@ -142,6 +184,17 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id); if (!cat) return; + if (!isOutfitFolder(cat)) + { + // Assume a subfolder that contains or will contain outfits, track it + const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + mCategoriesObserver->addCategory(cat_id, [this, outfits]() + { + observerCallback(outfits); + }); + return; + } + std::string name = cat->getName(); outfit_accordion_tab_params tab_params(get_accordion_tab_params()); @@ -154,6 +207,7 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) tab->setName(name); tab->setTitle(name); + tab->setFavorite(cat->getIsFavorite()); // *TODO: LLUICtrlFactory::defaultBuilder does not use "display_children" from xml. Should be investigated. tab->setDisplayChildren(false); @@ -183,8 +237,9 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) // Setting callback to reset items selection inside outfit on accordion collapsing and expanding (EXT-7875) tab->setDropDownStateChangedCallback(boost::bind(&LLOutfitsList::resetItemSelection, this, list, cat_id)); - // force showing list items that don't match current filter(EXT-7158) - list->setForceShowingUnmatchedItems(true); + // Depending on settings, force showing list items that don't match current filter(EXT-7158) + static LLCachedControl<bool> list_filter(gSavedSettings, "OutfitListFilterFullList"); + list->setForceShowingUnmatchedItems(list_filter(), false); // Setting list commit callback to monitor currently selected wearable item. list->setCommitCallback(boost::bind(&LLOutfitsList::onListSelectionChange, this, _1)); @@ -194,12 +249,22 @@ void LLOutfitsList::updateAddedCategory(LLUUID cat_id) list->setRightMouseDownCallback(boost::bind(&LLOutfitsList::onWearableItemsListRightClick, this, _1, _2, _3)); - // Fetch the new outfit contents. - cat->fetch(); - - // Refresh the list of outfit items after fetch(). - // Further list updates will be triggered by the category observer. - list->updateList(cat_id); + if (AISAPI::isAvailable() && LLInventoryModelBackgroundFetch::instance().folderFetchActive()) + { + // for reliability just fetch it whole, linked items included + LLInventoryModelBackgroundFetch::instance().fetchFolderAndLinks(cat_id, [cat_id, list] + { + if (list) list->updateList(cat_id); + }); + } + else + { + // Fetch the new outfit contents. + cat->fetch(); + // Refresh the list of outfit items after fetch(). + // Further list updates will be triggered by the category observer. + list->updateList(cat_id); + } // If filter is currently applied we store the initial tab state. if (!getFilterSubString().empty()) @@ -249,13 +314,11 @@ void LLOutfitsList::onHighlightBaseOutfit(LLUUID base_id, LLUUID prev_id) { if (mOutfitsMap[prev_id]) { - mOutfitsMap[prev_id]->setTitleFontStyle("NORMAL"); - mOutfitsMap[prev_id]->setTitleColor(LLUIColorTable::instance().getColor("AccordionHeaderTextColor")); + ((LLOutfitAccordionCtrlTab*)mOutfitsMap[prev_id])->setOutfitSelected(false); } if (mOutfitsMap[base_id]) { - mOutfitsMap[base_id]->setTitleFontStyle("BOLD"); - mOutfitsMap[base_id]->setTitleColor(LLUIColorTable::instance().getColor("SelectedOutfitTextColor")); + ((LLOutfitAccordionCtrlTab*)mOutfitsMap[base_id])->setOutfitSelected(true); } } @@ -313,6 +376,11 @@ void LLOutfitsList::onSetSelectedOutfitByUUID(const LLUUID& outfit_uuid) } } +void LLOutfitListBase::onAction(const LLSD& userdata) +{ + performAction(userdata.asString()); +} + // virtual bool LLOutfitListBase::isActionEnabled(const LLSD& userdata) { @@ -425,11 +493,12 @@ void LLOutfitsList::updateChangedCategoryName(LLViewerInventoryCategory *cat, st if (outfits_iter != mOutfitsMap.end()) { // Update tab name with the new category name. - LLAccordionCtrlTab* tab = outfits_iter->second; + LLOutfitAccordionCtrlTab* tab = (LLOutfitAccordionCtrlTab*) outfits_iter->second; if (tab) { tab->setName(name); tab->setTitle(name); + tab->setFavorite(cat->getIsFavorite()); } } } @@ -521,7 +590,7 @@ void LLOutfitsList::onFilterSubStringChanged(const std::string& new_string, cons LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); if (list) { - list->setFilterSubString(new_string, tab->getDisplayChildren()); + list->setFilterSubString(new_string, true); } if (old_string.empty()) @@ -738,6 +807,75 @@ void LLOutfitsList::onOutfitRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUI } } +void LLOutfitsList::handleInvFavColorChange() +{ + for (outfits_map_t::iterator iter = mOutfitsMap.begin(); + iter != mOutfitsMap.end(); + ++iter) + { + if (!iter->second) continue; + LLOutfitAccordionCtrlTab* tab = (LLOutfitAccordionCtrlTab*)iter->second; + + // refresh font color + tab->setFavorite(tab->getFavorite()); + } +} + +void LLOutfitsList::onChangeSortOrder(const LLSD& userdata) +{ + std::string sort_data = userdata.asString(); + if (sort_data == "favorites_to_top") + { + // at the moment this is a toggle + S32 val = gSavedSettings.getS32("OutfitListSortOrder"); + gSavedSettings.setS32("OutfitListSortOrder", (val ? 0 : 1)); + + initComparator(); + } + else if (sort_data == "show_entire_outfit") + { + bool new_val = !gSavedSettings.getBOOL("OutfitListFilterFullList"); + gSavedSettings.setBOOL("OutfitListFilterFullList", new_val); + + if (!getFilterSubString().empty()) + { + for (outfits_map_t::value_type& outfit : mOutfitsMap) + { + LLAccordionCtrlTab* tab = outfit.second; + const LLUUID& category_id = outfit.first; + if (!tab) continue; + + LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); + if (list) + { + list->setForceRefresh(true); + list->setForceShowingUnmatchedItems(new_val, tab->getDisplayChildren()); + } + applyFilterToTab(category_id, tab, getFilterSubString()); + } + mAccordion->arrange(); + } + } +} + +LLToggleableMenu* LLOutfitsList::getSortMenu() +{ + if (!mSortMenu) + { + mSortMenu = new LLOutfitListSortMenu(this); + } + return mSortMenu->getMenu(); +} + +void LLOutfitsList::updateMenuItemsVisibility() +{ + if (mSortMenu) + { + mSortMenu->updateItemsVisibility(); + } + LLOutfitListBase::updateMenuItemsVisibility(); +} + LLOutfitListGearMenuBase* LLOutfitsList::createGearMenu() { return new LLOutfitListGearMenu(this); @@ -755,10 +893,10 @@ bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y) LLOutfitListBase::LLOutfitListBase() : LLPanelAppearanceTab() , mIsInitialized(false) + , mGearMenu(nullptr) { mCategoriesObserver = new LLInventoryCategoriesObserver(); mOutfitMenu = new LLOutfitContextMenu(this); - //mGearMenu = createGearMenu(); } LLOutfitListBase::~LLOutfitListBase() @@ -819,52 +957,45 @@ void LLOutfitListBase::observerCallback(const LLUUID& category_id) refreshList(category_id); } -class LLIsOutfitListFolder : public LLInventoryCollectFunctor +bool LLOutfitListBase::isOutfitFolder(LLViewerInventoryCategory* cat) const { -public: - LLIsOutfitListFolder() + if (!cat) { - mOutfitsId = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS); + return false; } - virtual ~LLIsOutfitListFolder() {} - - bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) override + if (cat->getPreferredType() == LLFolderType::FT_OUTFIT) { - if (cat) + return true; + } + // assumes that folder is somewhere inside MyOutfits + if (cat->getPreferredType() == LLFolderType::FT_NONE) + { + LLViewerInventoryCategory* inv_cat = dynamic_cast<LLViewerInventoryCategory*>(cat); + if (inv_cat && inv_cat->getDescendentCount() > 3) { - if (cat->getPreferredType() == LLFolderType::FT_OUTFIT) + LLInventoryModel::cat_array_t* cats; + LLInventoryModel::item_array_t* items; + gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items); + if (cats->empty() // protection against outfits inside + && items->size() > 3) // arbitrary, if doesn't have at least base parts, not an outfit { + // For now assume this to be an old style outfit, not a subfolder + // but ideally no such 'outfits' should be left in My Outfits + // Todo: stop counting FT_NONE as outfits, + // convert obvious outfits into FT_OUTFIT return true; } - if (cat->getPreferredType() == LLFolderType::FT_NONE - && cat->getParentUUID() == mOutfitsId) - { - LLViewerInventoryCategory* inv_cat = dynamic_cast<LLViewerInventoryCategory*>(cat); - if (inv_cat && inv_cat->getDescendentCount() > 3) - { - LLInventoryModel::cat_array_t* cats; - LLInventoryModel::item_array_t* items; - gInventory.getDirectDescendentsOf(inv_cat->getUUID(), cats, items); - if (cats->empty() // protection against outfits inside - && items->size() > 3) // eyes, skin, hair and shape are required - { - // For now assume this to be an old style outfit, not a subfolder - // but ideally no such 'outfits' should be left in My Outfits - // Todo: stop counting FT_NONE as outfits, - // convert obvious outfits into FT_OUTFIT - return true; - } - } - } } - return false; } -protected: - LLUUID mOutfitsId; -}; + return false; +} void LLOutfitListBase::refreshList(const LLUUID& category_id) { + if (LLAppViewer::instance()->quitRequested()) + { + return; + } bool wasNull = mRefreshListState.CategoryUUID.isNull(); mRefreshListState.CategoryUUID.setNull(); @@ -872,13 +1003,13 @@ void LLOutfitListBase::refreshList(const LLUUID& category_id) LLInventoryModel::item_array_t item_array; // Collect all sub-categories of a given category. - LLIsOutfitListFolder is_outfit; + LLIsType is_category(LLAssetType::AT_CATEGORY); gInventory.collectDescendentsIf( category_id, cat_array, item_array, LLInventoryModel::EXCLUDE_TRASH, - is_outfit); + is_category); // Memorize item names for each UUID std::map<LLUUID, std::string> names; @@ -923,8 +1054,18 @@ void LLOutfitListBase::onIdle(void* userdata) void LLOutfitListBase::onIdleRefreshList() { + if (LLAppViewer::instance()->quitRequested()) + { + mRefreshListState.CategoryUUID.setNull(); + gIdleCallbacks.deleteFunction(onIdle, this); + return; + } if (mRefreshListState.CategoryUUID.isNull()) + { + LL_WARNS() << "Called onIdleRefreshList without id" << LL_ENDL; + gIdleCallbacks.deleteFunction(onIdle, this); return; + } const F64 MAX_TIME = 0.05f; F64 curent_time = LLTimer::getTotalSeconds(); @@ -1066,12 +1207,6 @@ void LLOutfitListBase::ChangeOutfitSelection(LLWearableItemsList* list, const LL bool LLOutfitListBase::postBuild() { - mGearMenu = createGearMenu(); - - LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); - - menu_gear_btn->setMouseDownCallback(boost::bind(&LLOutfitListGearMenuBase::updateItemsVisibility, mGearMenu)); - menu_gear_btn->setMenu(mGearMenu->getMenu()); return true; } @@ -1085,6 +1220,20 @@ void LLOutfitListBase::expandAllFolders() onExpandAllFolders(); } +void LLOutfitListBase::updateMenuItemsVisibility() +{ + mGearMenu->updateItemsVisibility(); +} + +LLToggleableMenu* LLOutfitListBase::getGearMenu() +{ + if (!mGearMenu) + { + mGearMenu = createGearMenu(); + } + return mGearMenu->getMenu(); +}; + void LLOutfitListBase::deselectOutfit(const LLUUID& category_id) { // Reset selection if the outfit is selected. @@ -1111,6 +1260,7 @@ LLContextMenu* LLOutfitContextMenu::createMenu() registrar.add("Outfit.Rename", boost::bind(renameOutfit, selected_id)); registrar.add("Outfit.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList)); registrar.add("Outfit.Thumbnail", boost::bind(&LLOutfitContextMenu::onThumbnail, this, selected_id)); + registrar.add("Outfit.Favorite", boost::bind(&LLOutfitContextMenu::onFavorite, this, selected_id)); registrar.add("Outfit.Save", boost::bind(&LLOutfitContextMenu::onSave, this, selected_id)); enable_registrar.add("Outfit.OnEnable", boost::bind(&LLOutfitContextMenu::onEnable, this, _2)); @@ -1161,6 +1311,16 @@ bool LLOutfitContextMenu::onVisible(LLSD::String param) { return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); } + else if ("favorites_add" == param) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(outfit_cat_id); + return cat && !cat->getIsFavorite(); + } + else if ("favorites_remove" == param) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(outfit_cat_id); + return cat && cat->getIsFavorite(); + } return true; } @@ -1185,6 +1345,14 @@ void LLOutfitContextMenu::onThumbnail(const LLUUID &outfit_cat_id) } } +void LLOutfitContextMenu::onFavorite(const LLUUID& outfit_cat_id) +{ + if (outfit_cat_id.notNull()) + { + toggle_favorite(outfit_cat_id); + } +} + void LLOutfitContextMenu::onSave(const LLUUID &outfit_cat_id) { if (outfit_cat_id.notNull()) @@ -1215,14 +1383,13 @@ LLOutfitListGearMenuBase::LLOutfitListGearMenuBase(LLOutfitListBase* olist) registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenuBase::onRename, this)); registrar.add("Gear.Delete", boost::bind(&LLOutfitListBase::removeSelected, mOutfitList)); registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenuBase::onCreate, this, _2)); - registrar.add("Gear.Collapse", boost::bind(&LLOutfitListBase::onCollapseAllFolders, mOutfitList)); - registrar.add("Gear.Expand", boost::bind(&LLOutfitListBase::onExpandAllFolders, mOutfitList)); registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenuBase::onAdd, this)); registrar.add("Gear.Save", boost::bind(&LLOutfitListGearMenuBase::onSave, this)); registrar.add("Gear.Thumbnail", boost::bind(&LLOutfitListGearMenuBase::onThumbnail, this)); - registrar.add("Gear.SortByName", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this)); + registrar.add("Gear.Favorite", boost::bind(&LLOutfitListGearMenuBase::onFavorite, this)); + registrar.add("Gear.SortByImage", boost::bind(&LLOutfitListGearMenuBase::onChangeSortOrder, this)); enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenuBase::onEnable, this, _2)); enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenuBase::onVisible, this, _2)); @@ -1356,6 +1523,16 @@ bool LLOutfitListGearMenuBase::onVisible(LLSD::String param) { return false; } + else if ("favorites_add" == param) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id); + return cat && !cat->getIsFavorite(); + } + else if ("favorites_remove" == param) + { + LLViewerInventoryCategory* cat = gInventory.getCategory(selected_outfit_id); + return cat && cat->getIsFavorite(); + } return true; } @@ -1367,6 +1544,12 @@ void LLOutfitListGearMenuBase::onThumbnail() LLFloaterReg::showInstance("change_item_thumbnail", data); } +void LLOutfitListGearMenuBase::onFavorite() +{ + const LLUUID& selected_outfit_id = getSelectedOutfitID(); + toggle_favorite(selected_outfit_id); +} + void LLOutfitListGearMenuBase::onChangeSortOrder() { @@ -1382,21 +1565,91 @@ LLOutfitListGearMenu::~LLOutfitListGearMenu() void LLOutfitListGearMenu::onUpdateItemsVisibility() { if (!mMenu) return; - mMenu->setItemVisible("expand", true); - mMenu->setItemVisible("collapse", true); mMenu->setItemVisible("thumbnail", getSelectedOutfitID().notNull()); + mMenu->setItemVisible("favorite", getSelectedOutfitID().notNull()); mMenu->setItemVisible("sepatator3", false); mMenu->setItemVisible("sort_folders_by_name", false); LLOutfitListGearMenuBase::onUpdateItemsVisibility(); } +//////////////////// LLOutfitListSortMenu //////////////////// + +LLOutfitListSortMenu::LLOutfitListSortMenu(LLOutfitListBase* parent_panel) + : mPanelHandle(parent_panel->getHandle()) +{ + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; + + registrar.add("Sort.Collapse", boost::bind(&LLOutfitListBase::onCollapseAllFolders, parent_panel)); + registrar.add("Sort.Expand", boost::bind(&LLOutfitListBase::onExpandAllFolders, parent_panel)); + registrar.add("Sort.OnSort", boost::bind(&LLOutfitListBase::onChangeSortOrder, parent_panel, _2)); + enable_registrar.add("Sort.OnEnable", boost::bind(&LLOutfitListSortMenu::onEnable, this, _2)); + + mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>( + "menu_outfit_list_sort.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + llassert(mMenu); +} + + +LLToggleableMenu* LLOutfitListSortMenu::getMenu() +{ + return mMenu; +} + +void LLOutfitListSortMenu::updateItemsVisibility() +{ + onUpdateItemsVisibility(); +} + +void LLOutfitListSortMenu::onUpdateItemsVisibility() +{ + if (!mMenu) return; + mMenu->setItemVisible("expand", true); + mMenu->setItemVisible("collapse", true); + mMenu->setItemVisible("sort_favorites_to_top", true); + mMenu->setItemVisible("show_entire_outfit_in_search", true); +} + +bool LLOutfitListSortMenu::onEnable(LLSD::String param) +{ + if ("favorites_to_top" == param) + { + static LLCachedControl<S32> sort_order(gSavedSettings, "OutfitListSortOrder", 0); + return sort_order == 1; + } + else if ("show_entire_outfit" == param) + { + static LLCachedControl<bool> filter_mode(gSavedSettings, "OutfitListFilterFullList", 0); + return filter_mode; + } + + return false; +} + + +//////////////////// LLOutfitAccordionCtrlTab //////////////////// + +LLUIImage* LLOutfitAccordionCtrlTab::sFavoriteIcon; +LLUIColor LLOutfitAccordionCtrlTab::sFgColor; + +void LLOutfitAccordionCtrlTab::draw() +{ + LLAccordionCtrlTab::draw(); + drawFavoriteIcon(); +} + bool LLOutfitAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask) { if (y >= getLocalRect().getHeight() - getHeaderHeight()) { LLSD params; params["inv_type"] = LLInventoryType::IT_CATEGORY; - params["thumbnail_id"] = gInventory.getCategory(mFolderID)->getThumbnailUUID(); + LLViewerInventoryCategory* cat = gInventory.getCategory(mFolderID); + if (cat) + { + params["thumbnail_id"] = cat->getThumbnailUUID(); + } + // else consider returning params["item_id"] = mFolderID; LLToolTipMgr::instance().show(LLToolTip::Params() @@ -1410,4 +1663,54 @@ bool LLOutfitAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask) return LLAccordionCtrlTab::handleToolTip(x, y, mask); } + +void LLOutfitAccordionCtrlTab::setFavorite(bool is_favorite) +{ + mIsFavorite = is_favorite; + updateTitleColor(); +} + +void LLOutfitAccordionCtrlTab::setOutfitSelected(bool val) +{ + mIsSelected = val; + setTitleFontStyle(mIsSelected ? "BOLD" : "NORMAL"); + updateTitleColor(); + } + +void LLOutfitAccordionCtrlTab::updateTitleColor() + { + static LLUICachedControl<bool> highlight_color("InventoryFavoritesColorText", true); + if (mIsFavorite && highlight_color()) + { + setTitleColor(LLUIColorTable::instance().getColor("InventoryFavoriteColor")); + } + else if (mIsSelected) + { + setTitleColor(LLUIColorTable::instance().getColor("SelectedOutfitTextColor")); + } + else + { + setTitleColor(LLUIColorTable::instance().getColor("AccordionHeaderTextColor")); + } + } + +void LLOutfitAccordionCtrlTab::drawFavoriteIcon() +{ + if (!mIsFavorite) + { + return; + } + static LLUICachedControl<bool> draw_star("InventoryFavoritesUseStar", true); + if (!draw_star) + { + return; + } + + const S32 PAD = 2; + const S32 image_size = 18; + + gl_draw_scaled_image( + getRect().getWidth() - image_size - PAD, getRect().getHeight() - image_size - PAD, + image_size, image_size, sFavoriteIcon->getImage(), sFgColor); +} // EOF diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index f581b419d9..0bf5becb05 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -41,6 +41,7 @@ class LLAccordionCtrlTab; class LLInventoryCategoriesObserver; class LLOutfitListGearMenuBase; +class LLOutfitListSortMenuBase; class LLWearableItemsList; class LLListContextMenu; @@ -61,6 +62,17 @@ public: /*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const; }; +class LLOutfitTabFavComparator : public LLAccordionCtrl::LLTabComparator +{ + LOG_CLASS(LLOutfitTabFavComparator); + +public: + LLOutfitTabFavComparator() {}; + virtual ~LLOutfitTabFavComparator() {}; + + /*virtual*/ bool compare(const LLAccordionCtrlTab* tab1, const LLAccordionCtrlTab* tab2) const; +}; + class LLOutfitListBase : public LLPanelAppearanceTab { public: @@ -92,6 +104,7 @@ public: boost::signals2::connection setSelectionChangeCallback(selection_change_callback_t cb); void outfitRightClickCallBack(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id); + void onAction(const LLSD& userdata); virtual bool isActionEnabled(const LLSD& userdata); virtual void performAction(std::string action); virtual bool hasItemSelected() = 0; @@ -109,6 +122,12 @@ public: virtual bool getHasExpandableFolders() = 0; + virtual void onChangeSortOrder(const LLSD& userdata) = 0; + + virtual void updateMenuItemsVisibility(); + virtual LLToggleableMenu* getGearMenu(); + virtual bool getTrashMenuVisible() { return true; }; + protected: void observerCallback(const LLUUID& category_id); virtual LLOutfitListGearMenuBase* createGearMenu() = 0; @@ -118,6 +137,8 @@ protected: void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response); virtual void onChangeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id) = 0; + bool isOutfitFolder(LLViewerInventoryCategory* cat) const; + static void onIdle(void* userdata); void onIdleRefreshList(); @@ -139,6 +160,7 @@ protected: selection_change_signal_t mSelectionChangeSignal; LLListContextMenu* mOutfitMenu; LLOutfitListGearMenuBase* mGearMenu; + boost::signals2::connection mGearMenuConnection; }; ////////////////////////////////////////////////////////////////////////// @@ -155,7 +177,6 @@ protected: /* virtual */ LLContextMenu* createMenu(); bool onEnable(LLSD::String param); - bool onVisible(LLSD::String param); static void editOutfit(); @@ -163,6 +184,7 @@ protected: static void renameOutfit(const LLUUID& outfit_cat_id); void onThumbnail(const LLUUID &outfit_cat_id); + void onFavorite(const LLUUID& outfit_cat_id); void onSave(const LLUUID &outfit_cat_id); private: @@ -182,6 +204,7 @@ public: protected: virtual void onUpdateItemsVisibility(); virtual void onThumbnail(); + virtual void onFavorite(); virtual void onChangeSortOrder(); const LLUUID& getSelectedOutfitID(); @@ -202,6 +225,23 @@ private: bool onVisible(LLSD::String param); }; +class LLOutfitListSortMenu +{ +public: + LLOutfitListSortMenu(LLOutfitListBase* parent_panel); + + LLToggleableMenu* getMenu(); + void updateItemsVisibility(); + +private: + void onUpdateItemsVisibility(); + bool onEnable(LLSD::String param); + + LLToggleableMenu* mMenu; + LLHandle<LLPanel> mPanelHandle; +}; + + class LLOutfitListGearMenu : public LLOutfitListGearMenuBase { public: @@ -221,8 +261,16 @@ public: Params() : cat_id("cat_id") {} }; + virtual void draw(); virtual bool handleToolTip(S32 x, S32 y, MASK mask); + void setFavorite(bool is_favorite); + bool getFavorite() const { return mIsFavorite; } + void setOutfitSelected(bool val); + + static LLUIImage* sFavoriteIcon; + static LLUIColor sFgColor; + protected: LLOutfitAccordionCtrlTab(const LLOutfitAccordionCtrlTab::Params &p) : LLAccordionCtrlTab(p), @@ -230,7 +278,12 @@ public: {} friend class LLUICtrlFactory; + void updateTitleColor(); + void drawFavoriteIcon(); + LLUUID mFolderID; + bool mIsFavorite = false; + bool mIsSelected = false; }; /** * @class LLOutfitsList @@ -249,6 +302,7 @@ public: virtual ~LLOutfitsList(); /*virtual*/ bool postBuild(); + void initComparator(); /*virtual*/ void onOpen(const LLSD& info); @@ -287,6 +341,10 @@ public: /*virtual*/ bool getHasExpandableFolders() { return true; } + /*virtual*/ void onChangeSortOrder(const LLSD& userdata); + virtual LLToggleableMenu* getSortMenu(); + void updateMenuItemsVisibility(); + protected: LLOutfitListGearMenuBase* createGearMenu(); @@ -357,6 +415,8 @@ private: static void onOutfitRename(const LLSD& notification, const LLSD& response); + void handleInvFavColorChange(); + //LLInventoryCategoriesObserver* mCategoriesObserver; LLAccordionCtrl* mAccordion; @@ -374,13 +434,15 @@ private: // Used to monitor COF changes for updating items worn state. See EXT-8636. uuid_vec_t mCOFLinkedItems; - //LLOutfitListGearMenu* mGearMenu; + LLOutfitListSortMenu* mSortMenu; //bool mIsInitialized; /** * True if there is a selection inside currently selected outfit */ bool mItemSelected; + + boost::signals2::connection mSavedSettingInvFavColor; }; #endif //LL_LLOUTFITSLIST_H diff --git a/indra/newview/llpanelappearancetab.h b/indra/newview/llpanelappearancetab.h index e4d16582de..e088c3e6f0 100644 --- a/indra/newview/llpanelappearancetab.h +++ b/indra/newview/llpanelappearancetab.h @@ -29,6 +29,8 @@ #include "llpanel.h" +class LLToggleableMenu; + class LLPanelAppearanceTab : public LLPanel { public: @@ -47,6 +49,11 @@ public: const std::string& getFilterSubString() { return mFilterSubString; } + virtual void updateMenuItemsVisibility() = 0; + virtual LLToggleableMenu* getGearMenu() = 0; + virtual LLToggleableMenu* getSortMenu() = 0; + virtual bool getTrashMenuVisible() = 0; + protected: /** diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp index 3a6a6a5ec3..f0555408dd 100644 --- a/indra/newview/llpanelemojicomplete.cpp +++ b/indra/newview/llpanelemojicomplete.cpp @@ -463,6 +463,7 @@ void LLPanelEmojiComplete::updateConstraints() { mEmojiHeight = mRenderRect.getHeight(); mRenderRect.stretch((mRenderRect.getWidth() - static_cast<S32>(mVisibleEmojis) * mEmojiWidth) / -2, 0); + mRenderRect.translate(-mRenderRect.mLeft, 0); // Left align emojis to fix hitboxes } updateScrollPos(); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index b7d9df6ea6..3ab48f69c8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -162,6 +162,36 @@ void LLPanelFace::updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial* LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func); } +void LLPanelFace::updateSelectedGLTFMaterialsWithScale(std::function<void(LLGLTFMaterial*, const F32, const F32)> func) +{ + struct LLSelectedTEGLTFMaterialFunctor : public LLSelectedTEFunctor + { + LLSelectedTEGLTFMaterialFunctor(std::function<void(LLGLTFMaterial*, const F32, const F32)> func) : mFunc(func) {} + virtual ~LLSelectedTEGLTFMaterialFunctor() {}; + bool apply(LLViewerObject* object, S32 face) override + { + LLGLTFMaterial new_override; + const LLTextureEntry* tep = object->getTE(face); + if (tep->getGLTFMaterialOverride()) + { + new_override = *tep->getGLTFMaterialOverride(); + } + + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + mFunc(&new_override, object->getScale().mV[s_axis], object->getScale().mV[t_axis]); + LLGLTFMaterialList::queueModify(object, face, &new_override); + + return true; + } + + std::function<void(LLGLTFMaterial*, const F32, const F32)> mFunc; + } select_func(func); + + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func); +} + template<typename T> void readSelectedGLTFMaterial(std::function<T(const LLGLTFMaterial*)> func, T& value, bool& identical, bool has_tolerance, T tolerance) { @@ -182,6 +212,36 @@ void readSelectedGLTFMaterial(std::function<T(const LLGLTFMaterial*)> func, T& v identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&select_func, value, has_tolerance, tolerance); } +void getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo channel, F32& repeats, bool& identical) +{ + // The All channel should read base color values + if (channel == LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_COUNT) + channel = LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_BASE_COLOR; + + struct LLSelectedTEGetGLTFMaterialMaxRepeatsFunctor : public LLSelectedTEGetFunctor<F32> + { + LLSelectedTEGetGLTFMaterialMaxRepeatsFunctor(LLGLTFMaterial::TextureInfo channel) : mChannel(channel) {} + virtual ~LLSelectedTEGetGLTFMaterialMaxRepeatsFunctor() {}; + F32 get(LLViewerObject* object, S32 face) override + { + const LLTextureEntry* tep = object->getTE(face); + const LLGLTFMaterial* render_material = tep->getGLTFRenderMaterial(); + if (!render_material) + return 0.f; + + U32 s_axis = VX; + U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); + F32 repeats_u = render_material->mTextureTransform[mChannel].mScale[VX] / object->getScale().mV[s_axis]; + F32 repeats_v = render_material->mTextureTransform[mChannel].mScale[VY] / object->getScale().mV[t_axis]; + return llmax(repeats_u, repeats_v); + } + + LLGLTFMaterial::TextureInfo mChannel; + } max_repeats_func(channel); + identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&max_repeats_func, repeats); +} + BOOST_STATIC_ASSERT(MATTYPE_DIFFUSE == LLRender::DIFFUSE_MAP && MATTYPE_NORMAL == LLRender::NORMAL_MAP && MATTYPE_SPECULAR == LLRender::SPECULAR_MAP); // @@ -216,7 +276,7 @@ LLRender::eTexIndex LLPanelFace::getMatTextureChannel() return LLRender::NORMAL_MAP; break; case MATTYPE_SPECULAR: // "Shininess (specular)" - if (getCurrentNormalMap().notNull()) + if (getCurrentSpecularMap().notNull()) return LLRender::SPECULAR_MAP; break; } @@ -322,6 +382,7 @@ bool LLPanelFace::postBuild() getChildSetCommitCallback(mPBRScaleU, "gltfTextureScaleU", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureScaleU(); }); getChildSetCommitCallback(mPBRScaleV, "gltfTextureScaleV", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureScaleV(); }); + getChildSetCommitCallback(mPBRRepeat, "gltfRptctrl", [&](LLUICtrl*, const LLSD&) { onCommitGLTFRepeatsPerMeter(); }); getChildSetCommitCallback(mPBRRotate, "gltfTextureRotation", [&](LLUICtrl*, const LLSD&) { onCommitGLTFRotation(); }); getChildSetCommitCallback(mPBROffsetU, "gltfTextureOffsetU", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureOffsetU(); }); getChildSetCommitCallback(mPBROffsetV, "gltfTextureOffsetV", [&](LLUICtrl*, const LLSD&) { onCommitGLTFTextureOffsetV(); }); @@ -482,10 +543,6 @@ LLPanelFace::~LLPanelFace() void LLPanelFace::onVisibilityChange(bool new_visibility) { - if (new_visibility) - { - gAgent.showLatestFeatureNotification("gltf"); - } LLPanel::onVisibilityChange(new_visibility); } @@ -1106,6 +1163,63 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) updateVisibility(objectp); + bool missing_asset = false; + { + LLGLenum image_format = GL_RGB; + bool identical_image_format = false; + LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset); + + if (!missing_asset) + { + mIsAlpha = false; + switch (image_format) + { + case GL_RGBA: + case GL_ALPHA: + { + mIsAlpha = true; + } + break; + + case GL_RGB: + break; + default: + { + LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; + } + break; + } + } + else + { + // Don't know image's properties, use material's mode value + mIsAlpha = true; + } + + // Diffuse Alpha Mode + // Init to the default that is appropriate for the alpha content of the asset + // + U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + bool identical_alpha_mode = false; + + // See if that's been overridden by a material setting for same... + // + LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); + + // it is invalid to have any alpha mode other than blend if transparency is greater than zero ... + // Want masking? Want emissive? Tough! You get BLEND! + alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; + + // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none + alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; + + mComboAlphaMode->getSelectionInterface()->selectNthItem(alpha_mode); + updateAlphaControls(); + + mExcludeWater &= (LLMaterial::DIFFUSE_ALPHA_MODE_BLEND == alpha_mode); + } + // Water exclusion { mCheckHideWater->setEnabled(editable && !has_pbr_material && !isMediaTexSelected()); @@ -1188,65 +1302,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) // Texture { - LLGLenum image_format = GL_RGB; - bool identical_image_format = false; - bool missing_asset = false; - LLSelectedTE::getImageFormat(image_format, identical_image_format, missing_asset); - - if (!missing_asset) - { - mIsAlpha = false; - switch (image_format) - { - case GL_RGBA: - case GL_ALPHA: - { - mIsAlpha = true; - } - break; - - case GL_RGB: break; - default: - { - LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL; - } - break; - } - } - else - { - // Don't know image's properties, use material's mode value - mIsAlpha = true; - } - if (LLViewerMedia::getInstance()->textureHasMedia(id)) { mBtnAlign->setEnabled(editable); } - // Diffuse Alpha Mode - - // Init to the default that is appropriate for the alpha content of the asset - // - U8 alpha_mode = mIsAlpha ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - bool identical_alpha_mode = false; - - // See if that's been overridden by a material setting for same... - // - LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(alpha_mode, identical_alpha_mode, mIsAlpha); - - // it is invalid to have any alpha mode other than blend if transparency is greater than zero ... - // Want masking? Want emissive? Tough! You get BLEND! - alpha_mode = (transparency > 0.f) ? LLMaterial::DIFFUSE_ALPHA_MODE_BLEND : alpha_mode; - - // ... unless there is no alpha channel in the texture, in which case alpha mode MUST be none - alpha_mode = mIsAlpha ? alpha_mode : LLMaterial::DIFFUSE_ALPHA_MODE_NONE; - - mComboAlphaMode->getSelectionInterface()->selectNthItem(alpha_mode); - - updateAlphaControls(); - if (mTextureCtrl) { if (identical_diffuse) @@ -1395,9 +1455,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) spec_scale_s = editable ? spec_scale_s : 1.0f; spec_scale_s *= identical_planar_texgen ? 2.0f : 1.0f; - mTexScaleU->setValue(diff_scale_s); - mShinyScaleU->setValue(spec_scale_s); - mBumpyScaleU->setValue(norm_scale_s); + if (force_set_values) + { + mTexScaleU->forceSetValue(diff_scale_s); + mShinyScaleU->forceSetValue(spec_scale_s); + mBumpyScaleU->forceSetValue(norm_scale_s); + } + else + { + mTexScaleU->setValue(diff_scale_s); + mShinyScaleU->setValue(spec_scale_s); + mBumpyScaleU->setValue(norm_scale_s); + } mTexScaleU->setEnabled(editable && has_material); mShinyScaleU->setEnabled(editable && has_material && specmap_id.notNull()); @@ -1445,13 +1514,16 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) if (force_set_values) { mTexScaleV->forceSetValue(diff_scale_t); + mShinyScaleV->forceSetValue(spec_scale_t); + mBumpyScaleV->forceSetValue(norm_scale_t); } else { mTexScaleV->setValue(diff_scale_t); + mShinyScaleV->setValue(spec_scale_t); + mBumpyScaleV->setValue(norm_scale_t); } - mShinyScaleV->setValue(spec_scale_t); - mBumpyScaleV->setValue(norm_scale_t); + mTexScaleV->setTentative(LLSD(diff_scale_tentative)); mShinyScaleV->setTentative(LLSD(spec_scale_tentative)); @@ -1591,36 +1663,57 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) F32 repeats_norm = 1.f; F32 repeats_spec = 1.f; + F32 repeats_pbr_basecolor = 1.f; + F32 repeats_pbr_metallic_roughness = 1.f; + F32 repeats_pbr_normal = 1.f; + F32 repeats_pbr_emissive = 1.f; + bool identical_diff_repeats = false; bool identical_norm_repeats = false; bool identical_spec_repeats = false; - LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); - LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); - LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); + bool identical_pbr_basecolor_repeats = false; + bool identical_pbr_metallic_roughness_repeats = false; + bool identical_pbr_normal_repeats = false; + bool identical_pbr_emissive_repeats = false; { + LLSpinCtrl* repeats_spin_ctrl = nullptr; S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0; bool enabled = editable && (index != 1); bool identical_repeats = true; S32 material_selection = mComboMatMedia->getCurrentIndex(); F32 repeats = 1.0f; - U32 material_type = MATTYPE_DIFFUSE; - if (material_selection == MATMEDIA_MATERIAL) + LLRender::eTexIndex material_channel = LLRender::DIFFUSE_MAP; + if (material_selection != MATMEDIA_PBR) { - material_type = mRadioMaterialType->getSelectedIndex(); + repeats_spin_ctrl = mTexRepeat; + material_channel = getMatTextureChannel(); + LLSelectedTE::getMaxDiffuseRepeats(repeats_diff, identical_diff_repeats); + LLSelectedTEMaterial::getMaxNormalRepeats(repeats_norm, identical_norm_repeats); + LLSelectedTEMaterial::getMaxSpecularRepeats(repeats_spec, identical_spec_repeats); } else if (material_selection == MATMEDIA_PBR) { + repeats_spin_ctrl = mPBRRepeat; enabled = editable && has_pbr_material; - material_type = mRadioPbrType->getSelectedIndex(); + material_channel = getPBRTextureChannel(); + + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_BASE_COLOR, + repeats_pbr_basecolor, identical_pbr_basecolor_repeats); + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, + repeats_pbr_metallic_roughness, identical_pbr_metallic_roughness_repeats); + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_NORMAL, + repeats_pbr_normal, identical_pbr_normal_repeats); + getSelectedGLTFMaterialMaxRepeats(LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_EMISSIVE, + repeats_pbr_emissive, identical_pbr_emissive_repeats); } - switch (material_type) + switch (material_channel) { default: - case MATTYPE_DIFFUSE: + case LLRender::DIFFUSE_MAP: if (material_selection != MATMEDIA_PBR) { enabled = editable && !id.isNull(); @@ -1628,7 +1721,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) identical_repeats = identical_diff_repeats; repeats = repeats_diff; break; - case MATTYPE_SPECULAR: + case LLRender::SPECULAR_MAP: if (material_selection != MATMEDIA_PBR) { enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull())); @@ -1636,7 +1729,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) identical_repeats = identical_spec_repeats; repeats = repeats_spec; break; - case MATTYPE_NORMAL: + case LLRender::NORMAL_MAP: if (material_selection != MATMEDIA_PBR) { enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull())); @@ -1644,6 +1737,23 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) identical_repeats = identical_norm_repeats; repeats = repeats_norm; break; + case LLRender::NUM_TEXTURE_CHANNELS: + case LLRender::BASECOLOR_MAP: + identical_repeats = identical_pbr_basecolor_repeats; + repeats = repeats_pbr_basecolor; + break; + case LLRender::METALLIC_ROUGHNESS_MAP: + identical_repeats = identical_pbr_metallic_roughness_repeats; + repeats = repeats_pbr_metallic_roughness; + break; + case LLRender::GLTF_NORMAL_MAP: + identical_repeats = identical_pbr_normal_repeats; + repeats = repeats_pbr_normal; + break; + case LLRender::EMISSIVE_MAP: + identical_repeats = identical_pbr_emissive_repeats; + repeats = repeats_pbr_emissive; + break; } bool repeats_tentative = !identical_repeats; @@ -1651,14 +1761,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) if (force_set_values) { // onCommit, previosly edited element updates related ones - mTexRepeat->forceSetValue(editable ? repeats : 1.0f); + repeats_spin_ctrl->forceSetValue(editable ? repeats : 1.0f); } else { - mTexRepeat->setValue(editable ? repeats : 1.0f); + repeats_spin_ctrl->setValue(editable ? repeats : 1.0f); } - mTexRepeat->setTentative(LLSD(repeats_tentative)); - mTexRepeat->setEnabled(has_material && !identical_planar_texgen && enabled); + repeats_spin_ctrl->setTentative(LLSD(repeats_tentative)); + repeats_spin_ctrl->setEnabled(!identical_planar_texgen && enabled); } } @@ -1804,6 +1914,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } mLabelColorTransp->setEnabled(false); mTexRepeat->setEnabled(false); + mPBRRepeat->setEnabled(false); mLabelTexGen->setEnabled(false); mLabelShininess->setEnabled(false); mLabelBumpiness->setEnabled(false); @@ -1999,6 +2110,7 @@ void LLPanelFace::updateVisibilityGLTF(LLViewerObject* objectp /*= nullptr */) mPBRRotate->setVisible(show_pbr); mPBROffsetU->setVisible(show_pbr); mPBROffsetV->setVisible(show_pbr); + mPBRRepeat->setVisible(show_pbr); } void LLPanelFace::updateCopyTexButton() @@ -2093,7 +2205,7 @@ void LLPanelFace::refreshMedia() // check if all faces have media(or, all dont have media) - LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo = selected_objects->getSelectedTEValue(&func, bool_has_media); + bool identical_has_media_info = selected_objects->getSelectedTEValue(&func, bool_has_media); const LLMediaEntry default_media_data; @@ -2115,7 +2227,8 @@ void LLPanelFace::refreshMedia() } func_media_data(default_media_data); LLMediaEntry media_data_get; - LLFloaterMediaSettings::getInstance()->mMultipleMedia = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); + bool multiple_media = !(selected_objects->getSelectedTEValue(&func_media_data, media_data_get)); + bool multiple_valid_media = false; std::string multi_media_info_str = LLTrans::getString("Multiple Media"); std::string media_title = ""; @@ -2124,12 +2237,12 @@ void LLPanelFace::refreshMedia() mAddMedia->setEnabled(editable); // IF all the faces have media (or all dont have media) - if (LLFloaterMediaSettings::getInstance()->mIdenticalHasMediaInfo) + if (identical_has_media_info) { // TODO: get media title and set it. mTitleMediaText->clear(); // if identical is set, all faces are same (whether all empty or has the same media) - if (!(LLFloaterMediaSettings::getInstance()->mMultipleMedia)) + if (!multiple_media) { // Media data is valid if (media_data_get != default_media_data) @@ -2150,9 +2263,9 @@ void LLPanelFace::refreshMedia() else // not all face has media but at least one does. { // seleted faces have not identical value - LLFloaterMediaSettings::getInstance()->mMultipleValidMedia = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); + multiple_valid_media = selected_objects->isMultipleTEValue(&func_media_data, default_media_data); - if (LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) + if (multiple_valid_media) { media_title = multi_media_info_str; } @@ -2189,7 +2302,7 @@ void LLPanelFace::refreshMedia() // load values for media settings updateMediaSettings(); - LLFloaterMediaSettings::initValues(mMediaSettings, editable); + LLFloaterMediaSettings::initValues(mMediaSettings, editable, identical_has_media_info, multiple_media, multiple_valid_media); } void LLPanelFace::unloadMedia() @@ -3262,6 +3375,7 @@ void LLPanelFace::onSelectNormalTexture(const LLSD& data) // TODO: test if there is media on the item and only allow editing if present void LLPanelFace::onClickBtnEditMedia() { + LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia refreshMedia(); LLFloaterReg::showInstance("media_settings"); } @@ -3280,6 +3394,7 @@ void LLPanelFace::onClickBtnAddMedia() // check if multiple faces are selected if (LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected()) { + LLFloaterMediaSettings::getInstance(); // make sure floater we are about to open exists before refreshMedia refreshMedia(); LLNotificationsUtil::add("MultipleFacesSelected", LLSD(), LLSD(), multipleFacesSelectedConfirm); } @@ -3644,23 +3759,13 @@ void LLPanelFace::onCommitRepeatsPerMeter() bool identical_scale_t = false; LLSelectedTE::getObjectScaleS(obj_scale_s, identical_scale_s); - LLSelectedTE::getObjectScaleS(obj_scale_t, identical_scale_t); + LLSelectedTE::getObjectScaleT(obj_scale_t, identical_scale_t); if (gSavedSettings.getBOOL("SyncMaterialSettings")) { LLSelectMgr::getInstance()->selectionTexScaleAutofit(repeats_per_meter); - - mBumpyScaleU->setValue(obj_scale_s * repeats_per_meter); - mBumpyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setNormalRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(this, obj_scale_t * repeats_per_meter); - - mShinyScaleU->setValue(obj_scale_s * repeats_per_meter); - mShinyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setSpecularRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(this, obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::selectionNormalScaleAutofit(this, repeats_per_meter); + LLSelectedTEMaterial::selectionSpecularScaleAutofit(this, repeats_per_meter); } else { @@ -3671,18 +3776,10 @@ void LLPanelFace::onCommitRepeatsPerMeter() LLSelectMgr::getInstance()->selectionTexScaleAutofit(repeats_per_meter); break; case MATTYPE_NORMAL: - mBumpyScaleU->setValue(obj_scale_s * repeats_per_meter); - mBumpyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setNormalRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setNormalRepeatY(this, obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::selectionNormalScaleAutofit(this, repeats_per_meter); break; case MATTYPE_SPECULAR: - mBumpyScaleU->setValue(obj_scale_s * repeats_per_meter); - mBumpyScaleV->setValue(obj_scale_t * repeats_per_meter); - - LLSelectedTEMaterial::setSpecularRepeatX(this, obj_scale_s * repeats_per_meter); - LLSelectedTEMaterial::setSpecularRepeatY(this, obj_scale_t * repeats_per_meter); + LLSelectedTEMaterial::selectionSpecularScaleAutofit(this, repeats_per_meter); break; default: llassert(false); @@ -3693,6 +3790,21 @@ void LLPanelFace::onCommitRepeatsPerMeter() updateUI(true); } +// Commit the number of GLTF repeats per meter +void LLPanelFace::onCommitGLTFRepeatsPerMeter() +{ + F32 repeats_per_meter = (F32)mPBRRepeat->getValue().asReal(); + + LLGLTFMaterial::TextureInfo material_type = getPBRTextureInfo(); + updateGLTFTextureTransformWithScale(material_type, [&](LLGLTFMaterial::TextureTransform* new_transform, F32 scale_s, F32 scale_t) + { + new_transform->mScale.mV[VX] = scale_s * repeats_per_meter; + new_transform->mScale.mV[VY] = scale_t * repeats_per_meter; + }); + + updateUI(true); +} + struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor { virtual bool apply(LLViewerObject* object, S32 te) @@ -4009,6 +4121,85 @@ void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te) } } +void set_item_availability( + const LLUUID& id, + LLSD& dest, + const std::string& modifier, + bool is_creator, + std::map<LLUUID, LLUUID> &asset_item_map, + LLViewerObject* objectp) +{ + if (id.isNull()) + { + return; + } + + LLUUID item_id; + bool from_library = get_is_predefined_texture(id); + bool full_perm = from_library; + full_perm |= is_creator; + + if (!full_perm) + { + std::map<LLUUID, LLUUID>::iterator iter = asset_item_map.find(id); + if (iter != asset_item_map.end()) + { + item_id = iter->second; + } + else + { + // What this does is simply searches inventory for item with same asset id, + // as result it is Hightly unreliable, leaves little control to user, borderline hack + // but there are little options to preserve permissions - multiple inventory + // items might reference same asset and inventory search is expensive. + bool no_transfer = false; + if (objectp->getInventoryItemByAsset(id)) + { + no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm(); + } + item_id = get_copy_free_item_by_asset_id(id, no_transfer); + // record value to avoid repeating inventory search when possible + asset_item_map[id] = item_id; + } + } + + if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID())) + { + full_perm = true; + from_library = true; + } + + dest[modifier + "itemfullperm"] = full_perm; + dest[modifier + "fromlibrary"] = from_library; + + // If full permission object, texture is free to copy, + // but otherwise we need to check inventory and extract permissions + // + // Normally we care only about restrictions for current user and objects + // don't inherit any 'next owner' permissions from texture, so there is + // no need to record item id if full_perm==true + if (!full_perm && item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp) + { + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + dest[modifier + "itemid"] = item_id; + dest[modifier + "itemfullperm"] = itemp->getIsFullPerm(); + if (!itemp->isFinished()) + { + // needed for dropTextureAllFaces + LLInventoryModelBackgroundFetch::instance().start(item_id, false); + } + } + } + } +} + void LLPanelFace::onCopyTexture() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); @@ -4046,6 +4237,7 @@ void LLPanelFace::onCopyTexture() if (tep) { LLSD te_data; + LLUUID pbr_id = objectp->getRenderMaterialID(te); // asLLSD() includes media te_data["te"] = tep->asLLSD(); @@ -4054,21 +4246,20 @@ void LLPanelFace::onCopyTexture() te_data["te"]["bumpshiny"] = tep->getBumpShiny(); te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright(); te_data["te"]["texgen"] = tep->getTexGen(); - te_data["te"]["pbr"] = objectp->getRenderMaterialID(te); + te_data["te"]["pbr"] = pbr_id; if (tep->getGLTFMaterialOverride() != nullptr) { te_data["te"]["pbr_override"] = tep->getGLTFMaterialOverride()->asJSON(); } - if (te_data["te"].has("imageid")) + if (te_data["te"].has("imageid") || pbr_id.notNull()) { - LLUUID item_id; - LLUUID id = te_data["te"]["imageid"].asUUID(); - bool from_library = get_is_predefined_texture(id); - bool full_perm = from_library; + LLUUID img_id = te_data["te"]["imageid"].asUUID(); + bool pbr_from_library = false; + bool pbr_full_perm = false; + bool is_creator = false; - if (!full_perm - && objectp->permCopy() + if (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()) { @@ -4078,66 +4269,31 @@ void LLPanelFace::onCopyTexture() std::string creator_app_link; LLUUID creator_id; LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_app_link); - full_perm = objectp->mOwnerID == creator_id; + is_creator = objectp->mOwnerID == creator_id; } - if (id.notNull() && !full_perm) + // check permissions for blin-phong/diffuse image and for pbr asset + if (img_id.notNull()) { - std::map<LLUUID, LLUUID>::iterator iter = asset_item_map.find(id); - if (iter != asset_item_map.end()) - { - item_id = iter->second; - } - else - { - // What this does is simply searches inventory for item with same asset id, - // as result it is Hightly unreliable, leaves little control to user, borderline hack - // but there are little options to preserve permissions - multiple inventory - // items might reference same asset and inventory search is expensive. - bool no_transfer = false; - if (objectp->getInventoryItemByAsset(id)) - { - no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm(); - } - item_id = get_copy_free_item_by_asset_id(id, no_transfer); - // record value to avoid repeating inventory search when possible - asset_item_map[id] = item_id; - } + set_item_availability(img_id, te_data["te"], "img", is_creator, asset_item_map, objectp); } - - if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID())) + if (pbr_id.notNull()) { - full_perm = true; - from_library = true; - } + set_item_availability(pbr_id, te_data["te"], "pbr", is_creator, asset_item_map, objectp); - { - te_data["te"]["itemfullperm"] = full_perm; - te_data["te"]["fromlibrary"] = from_library; - - // If full permission object, texture is free to copy, - // but otherwise we need to check inventory and extract permissions - // - // Normally we care only about restrictions for current user and objects - // don't inherit any 'next owner' permissions from texture, so there is - // no need to record item id if full_perm==true - if (!full_perm && !from_library && item_id.notNull()) + // permissions for overrides + // Overrides do not permit no-copy textures + LLGLTFMaterial* override = tep->getGLTFMaterialOverride(); + if (override != nullptr) { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (itemp) + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) + LLUUID& texture_id = override->mTextureId[i]; + if (texture_id.notNull()) { - te_data["te"]["imageitemid"] = item_id; - te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); - if (!itemp->isFinished()) - { - // needed for dropTextureAllFaces - LLInventoryModelBackgroundFetch::instance().start(item_id, false); - } + const std::string prefix = "pbr" + std::to_string(i); + te_data["te"][prefix + "imageid"] = texture_id; + set_item_availability(texture_id, te_data["te"], prefix, is_creator, asset_item_map, objectp); } } } @@ -4201,6 +4357,44 @@ void LLPanelFace::onCopyTexture() } } +bool get_full_permission(const LLSD& te, const std::string &prefix) +{ + return te.has(prefix + "itemfullperm") && te[prefix+"itemfullperm"].asBoolean(); +} + +bool LLPanelFace::validateInventoryItem(const LLSD& te, const std::string& prefix) +{ + if (te.has(prefix + "itemid")) + { + LLUUID item_id = te[prefix + "itemid"].asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (!itemp) + { + // image might be in object's inventory, but it can be not up to date + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return false; + } + } + } + else + { + // Item was not found on 'copy' stage + // Since this happened at copy, might be better to either show this + // at copy stage or to drop clipboard here + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return false; + } + return true; +} + void LLPanelFace::onPasteTexture() { if (!mClipboardParams.has("texture")) @@ -4265,39 +4459,49 @@ void LLPanelFace::onPasteTexture() for (; iter != end; ++iter) { const LLSD& te_data = *iter; - if (te_data.has("te") && te_data["te"].has("imageid")) + if (te_data.has("te")) { - bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); - full_perm_object &= full_perm; - if (!full_perm) + if (te_data["te"].has("imageid")) { - if (te_data["te"].has("imageitemid")) + bool full_perm = get_full_permission(te_data["te"], "img"); + full_perm_object &= full_perm; + if (!full_perm) { - LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); - if (item_id.notNull()) + if (!validateInventoryItem(te_data["te"], "img")) { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (!itemp) - { - // image might be in object's inventory, but it can be not up to date - LLSD notif_args; - static std::string reason = getString("paste_error_inventory_not_found"); - notif_args["REASON"] = reason; - LLNotificationsUtil::add("FacePasteFailed", notif_args); - return; - } + return; } } - else + } + if (te_data["te"].has("pbr")) + { + bool full_perm = get_full_permission(te_data["te"], "pbr"); + full_perm_object &= full_perm; + if (!full_perm) { - // Item was not found on 'copy' stage - // Since this happened at copy, might be better to either show this - // at copy stage or to drop clipboard here - LLSD notif_args; - static std::string reason = getString("paste_error_inventory_not_found"); - notif_args["REASON"] = reason; - LLNotificationsUtil::add("FacePasteFailed", notif_args); - return; + if (!validateInventoryItem(te_data["te"], "pbr")) + { + return; + } + } + if (te_data["te"].has("pbr_override")) + { + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + const std::string prefix = "pbr" + std::to_string(i); + if (te_data["te"].has(prefix + "imageid")) + { + bool full_perm = get_full_permission(te_data["te"], prefix); + full_perm_object &= full_perm; + if (!full_perm) + { + if (!validateInventoryItem(te_data["te"], prefix)) + { + return; + } + } + } + } } } } @@ -4322,6 +4526,71 @@ void LLPanelFace::onPasteTexture() selected_objects->applyToTEs(&navigate_home_func); } +void get_item_and_permissions(const LLUUID &id, LLViewerInventoryItem*& itemp, bool& full_perm, bool& from_library, const LLSD &data, const std::string &prefix) +{ + full_perm = get_full_permission(data, prefix); + from_library = data.has(prefix + "fromlibrary") && data.get(prefix + "fromlibrary").asBoolean(); + LLViewerInventoryItem* itemp_res = NULL; + + if (data.has(prefix + "itemid")) + { + LLUUID item_id = data.get(prefix + "itemid").asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + itemp_res = itemp; + } + else + { + // Theoretically shouldn't happend, but if it does happen, we + // might need to add a notification to user that paste will fail + // since inventory isn't fully loaded + LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL; + } + } + } + + // for case when item got removed from inventory after we pressed 'copy' + // or texture got pasted into previous object + if (!itemp_res && !full_perm) + { + // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable. + LL_INFOS() << "Item " << data.get(prefix + "itemid").asUUID() << " no longer in inventory." << LL_ENDL; + // Todo: fix this, we are often searching same texture multiple times (equal to number of faces) + // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + // Extremely unreliable and perfomance unfriendly. + // But we need this to check permissions and it is how texture control finds items + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + itemp_res = itemp; + break; // first match + } + } + } + } +} + void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) { LLSD te_data; @@ -4345,77 +4614,22 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) if (te_data.has("te")) { // Texture - bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); - bool from_library = te_data["te"].has("fromlibrary") && te_data["te"]["fromlibrary"].asBoolean(); if (te_data["te"].has("imageid")) { + bool img_full_perm = false; + bool img_from_library = false; const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id - LLViewerInventoryItem* itemp_res = NULL; + LLViewerInventoryItem* img_itemp_res = NULL; - if (te_data["te"].has("imageitemid")) - { - LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); - if (item_id.notNull()) - { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (itemp && itemp->isFinished()) - { - // dropTextureAllFaces will fail if incomplete - itemp_res = itemp; - } - else - { - // Theoretically shouldn't happend, but if it does happen, we - // might need to add a notification to user that paste will fail - // since inventory isn't fully loaded - LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL; - } - } - } - // for case when item got removed from inventory after we pressed 'copy' - // or texture got pasted into previous object - if (!itemp_res && !full_perm) - { - // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable. - LL_INFOS() << "Item " << te_data["te"]["imageitemid"].asUUID() << " no longer in inventory." << LL_ENDL; - // Todo: fix this, we are often searching same texture multiple times (equal to number of faces) - // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(imageid); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - - // Extremely unreliable and perfomance unfriendly. - // But we need this to check permissions and it is how texture control finds items - for (S32 i = 0; i < items.size(); i++) - { - LLViewerInventoryItem* itemp = items[i]; - if (itemp && itemp->isFinished()) - { - // dropTextureAllFaces will fail if incomplete - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) - { - itemp_res = itemp; - break; // first match - } - } - } - } + get_item_and_permissions(imageid, img_itemp_res, img_full_perm, img_from_library, te_data["te"], "img"); - if (itemp_res) + if (img_itemp_res) { if (te == -1) // all faces { LLToolDragAndDrop::dropTextureAllFaces(objectp, - itemp_res, - from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + img_itemp_res, + img_from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null, false); } @@ -4423,15 +4637,15 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) { LLToolDragAndDrop::dropTextureOneFace(objectp, te, - itemp_res, - from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + img_itemp_res, + img_from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null, false, 0); } } // not an inventory item or no complete items - else if (full_perm) + else if (img_full_perm) { // Either library, local or existed as fullperm when user made a copy LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); @@ -4459,17 +4673,65 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) // PBR/GLTF if (te_data["te"].has("pbr")) { - objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false /*managing our own update*/); - tep->setGLTFRenderMaterial(nullptr); - tep->setGLTFMaterialOverride(nullptr); + const LLUUID pbr_id = te_data["te"]["pbr"].asUUID(); + bool pbr_full_perm = false; + bool pbr_from_library = false; + LLViewerInventoryItem* pbr_itemp_res = NULL; + + get_item_and_permissions(pbr_id, pbr_itemp_res, pbr_full_perm, pbr_from_library, te_data["te"], "pbr"); + bool allow = true; + + // check overrides first since they don't need t be moved to inventory if (te_data["te"].has("pbr_override")) { - LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID(), te_data["te"]["pbr_override"]); + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + const std::string prefix = "pbr" + std::to_string(i); + if (te_data["te"].has(prefix + "imageid")) + { + LLUUID tex_id = te_data["te"][prefix + "imageid"]; + + bool full_perm = false; + bool from_library = false; + LLViewerInventoryItem* itemp_res = NULL; + get_item_and_permissions(tex_id, itemp_res, full_perm, from_library, te_data["te"], prefix); + allow = full_perm; + if (!allow) break; + } + } } - else + + if (allow && pbr_itemp_res) + { + if (pbr_itemp_res) + { + allow = LLToolDragAndDrop::handleDropMaterialProtections( + objectp, + pbr_itemp_res, + pbr_from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, + pbr_id); + } + else + { + allow = pbr_full_perm; + } + } + + if (allow) { - LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID()); + objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false /*managing our own update*/); + tep->setGLTFRenderMaterial(nullptr); + tep->setGLTFMaterialOverride(nullptr); + + if (te_data["te"].has("pbr_override")) + { + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID(), te_data["te"]["pbr_override"]); + } + else + { + LLGLTFMaterialList::queueApply(objectp, te, te_data["te"]["pbr"].asUUID()); + } } } else @@ -4642,6 +4904,29 @@ void LLPanelFace::updateGLTFTextureTransform(std::function<void(LLGLTFMaterial:: } } +void LLPanelFace::updateGLTFTextureTransformWithScale(const LLGLTFMaterial::TextureInfo texture_info, std::function<void(LLGLTFMaterial::TextureTransform*, const F32, const F32)> edit) +{ + if (texture_info == LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT) + { + updateSelectedGLTFMaterialsWithScale([&](LLGLTFMaterial* new_override, const F32 scale_s, const F32 scale_t) + { + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLGLTFMaterial::TextureTransform& new_transform = new_override->mTextureTransform[(LLGLTFMaterial::TextureInfo)i]; + edit(&new_transform, scale_s, scale_t); + } + }); + } + else + { + updateSelectedGLTFMaterialsWithScale([&](LLGLTFMaterial* new_override, const F32 scale_s, const F32 scale_t) + { + LLGLTFMaterial::TextureTransform& new_transform = new_override->mTextureTransform[texture_info]; + edit(&new_transform, scale_s, scale_t); + }); + } +} + void LLPanelFace::setMaterialOverridesFromSelection() { const LLGLTFMaterial::TextureInfo texture_info = getPBRTextureInfo(); @@ -4717,8 +5002,9 @@ void LLPanelFace::setMaterialOverridesFromSelection() } } - mPBRScaleU->setValue(transform.mScale[VX]); - mPBRScaleV->setValue(transform.mScale[VY]); + // Force set scales just in case they were set by repeats per meter and their spinner is focused + mPBRScaleU->forceSetValue(transform.mScale[VX]); + mPBRScaleV->forceSetValue(transform.mScale[VY]); mPBRRotate->setValue(transform.mRotation * RAD_TO_DEG); mPBROffsetU->setValue(transform.mOffset[VX]); mPBROffsetV->setValue(transform.mOffset[VY]); @@ -4728,6 +5014,12 @@ void LLPanelFace::setMaterialOverridesFromSelection() mPBRRotate->setTentative(!rotation_same); mPBROffsetU->setTentative(!offset_u_same); mPBROffsetV->setTentative(!offset_v_same); + + F32 repeats = 1.f; + bool identical = false; + getSelectedGLTFMaterialMaxRepeats(getPBRDropChannel(), repeats, identical); + mPBRRepeat->forceSetValue(repeats); + mPBRRepeat->setTentative(!identical || !scale_u_same || !scale_v_same); } void LLPanelFace::Selection::connect() @@ -5151,6 +5443,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxSpecularRepeats(F32& repeats, bool LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); U32 s_axis = VX; U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); F32 repeats_s = 1.0f; F32 repeats_t = 1.0f; if (mat) @@ -5175,6 +5468,7 @@ void LLPanelFace::LLSelectedTEMaterial::getMaxNormalRepeats(F32& repeats, bool& LLMaterial* mat = object->getTE(face)->getMaterialParams().get(); U32 s_axis = VX; U32 t_axis = VY; + LLPrimitive::getTESTAxes(face, &s_axis, &t_axis); F32 repeats_s = 1.0f; F32 repeats_t = 1.0f; if (mat) @@ -5219,6 +5513,62 @@ void LLPanelFace::LLSelectedTEMaterial::getCurrentDiffuseAlphaMode(U8& diffuse_a identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &get_diff_mode, diffuse_alpha_mode); } +void LLPanelFace::LLSelectedTEMaterial::selectionNormalScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter) +{ + struct f : public LLSelectedTEFunctor + { + LLPanelFace* mFacePanel; + F32 mRepeatsPerMeter; + f(LLPanelFace* face_panel, const F32& repeats_per_meter) : mFacePanel(face_panel), mRepeatsPerMeter(repeats_per_meter) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // Compute S,T to axis mapping + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + return true; + + F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter; + F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter; + + setNormalRepeatX(mFacePanel, new_s, te); + setNormalRepeatY(mFacePanel, new_t, te); + } + return true; + } + } setfunc(panel_face, repeats_per_meter); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); +} + +void LLPanelFace::LLSelectedTEMaterial::selectionSpecularScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter) +{ + struct f : public LLSelectedTEFunctor + { + LLPanelFace* mFacePanel; + F32 mRepeatsPerMeter; + f(LLPanelFace* face_panel, const F32& repeats_per_meter) : mFacePanel(face_panel), mRepeatsPerMeter(repeats_per_meter) {} + bool apply(LLViewerObject* object, S32 te) + { + if (object->permModify()) + { + // Compute S,T to axis mapping + U32 s_axis, t_axis; + if (!LLPrimitive::getTESTAxes(te, &s_axis, &t_axis)) + return true; + + F32 new_s = object->getScale().mV[s_axis] * mRepeatsPerMeter; + F32 new_t = object->getScale().mV[t_axis] * mRepeatsPerMeter; + + setSpecularRepeatX(mFacePanel, new_s, te); + setSpecularRepeatY(mFacePanel, new_t, te); + } + return true; + } + } setfunc(panel_face, repeats_per_meter); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); +} + void LLPanelFace::LLSelectedTE::getObjectScaleS(F32& scale_s, bool& identical) { struct LLSelectedTEGetObjectScaleS : public LLSelectedTEGetFunctor<F32> diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 6e0d34cbd6..8a8460204c 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -250,6 +250,7 @@ protected: void onCommitGLTFRotation(); void onCommitGLTFTextureOffsetU(); void onCommitGLTFTextureOffsetV(); + void onCommitGLTFRepeatsPerMeter(); void onClickAutoFix(); void onAlignTexture(); @@ -264,6 +265,9 @@ public: // needs to be accessible to selection manager void onCopyTexture(); void onPasteTexture(); void onPasteTexture(LLViewerObject* objectp, S32 te); +private: + // for copy/paste operations + bool validateInventoryItem(const LLSD& te, const std::string& prefix); protected: void menuDoToSelected(const LLSD& userdata); @@ -358,6 +362,7 @@ private: LLButton* mDelMedia { nullptr }; LLSpinCtrl* mPBRScaleU { nullptr }; LLSpinCtrl* mPBRScaleV { nullptr }; + LLSpinCtrl* mPBRRepeat { nullptr }; LLSpinCtrl* mPBRRotate { nullptr }; LLSpinCtrl* mPBROffsetU { nullptr }; LLSpinCtrl* mPBROffsetV { nullptr }; @@ -551,7 +556,9 @@ private: void updateVisibilityGLTF(LLViewerObject* objectp = nullptr); void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func); + void updateSelectedGLTFMaterialsWithScale(std::function<void(LLGLTFMaterial*, const F32, const F32)> func); void updateGLTFTextureTransform(std::function<void(LLGLTFMaterial::TextureTransform*)> edit); + void updateGLTFTextureTransformWithScale(const LLGLTFMaterial::TextureInfo texture_info, std::function<void(LLGLTFMaterial::TextureTransform*, const F32, const F32)> edit); void setMaterialOverridesFromSelection(); @@ -646,6 +653,8 @@ public: static void getMaxSpecularRepeats(F32& repeats, bool& identical); static void getMaxNormalRepeats(F32& repeats, bool& identical); static void getCurrentDiffuseAlphaMode(U8& diffuse_alpha_mode, bool& identical, bool diffuse_texture_has_alpha); + static void selectionNormalScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter); + static void selectionSpecularScaleAutofit(LLPanelFace* panel_face, F32 repeats_per_meter); DEF_GET_MAT_STATE(LLUUID, const LLUUID&, getNormalID, LLUUID::null, false, LLUUID::null); DEF_GET_MAT_STATE(LLUUID, const LLUUID&, getSpecularID, LLUUID::null, false, LLUUID::null); diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 8032e207cd..81c0bd97be 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -54,17 +54,16 @@ ////////////////////////////////////////////////////////////////////////// LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : mGroupID(group_id), - mBulkAgentList(NULL), - mOKButton(NULL), + mBulkAgentList(nullptr), + mOKButton(nullptr), mAddButton(nullptr), - mRemoveButton(NULL), - mGroupName(NULL), + mRemoveButton(nullptr), + mGroupName(nullptr), mLoadingText(), mTooManySelected(), - mCloseCallback(NULL), - mCloseCallbackUserData(NULL), - mAvatarNameCacheConnection(), - mRoleNames(NULL), + mCloseCallback(nullptr), + mCloseCallbackUserData(nullptr), + mRoleNames(nullptr), mOwnerWarning(), mAlreadyInGroup(), mConfirmedOwnerInvite(false), @@ -74,10 +73,13 @@ LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() { - if (mAvatarNameCacheConnection.connected()) + for (auto& [id, connection] : mAvatarNameCacheConnections) { - mAvatarNameCacheConnection.disconnect(); + if (connection.connected()) + connection.disconnect(); } + + mAvatarNameCacheConnections.clear(); } void LLPanelGroupBulkImpl::callbackClickAdd(LLPanelGroupBulk* panelp) @@ -124,43 +126,42 @@ void LLPanelGroupBulkImpl::callbackSelect(LLUICtrl* ctrl, void* userdata) void LLPanelGroupBulkImpl::addUsers(const uuid_vec_t& agent_ids) { - std::vector<std::string> names; for (const LLUUID& agent_id : agent_ids) { - LLAvatarName av_name; - if (LLAvatarNameCache::get(agent_id, &av_name)) + if (LLAvatarName av_name; LLAvatarNameCache::get(agent_id, &av_name)) { onAvatarNameCache(agent_id, av_name); } else { - if (mAvatarNameCacheConnection.connected()) + if (auto found = mAvatarNameCacheConnections.find(agent_id); found != mAvatarNameCacheConnections.end()) { - mAvatarNameCacheConnection.disconnect(); + if (found->second.connected()) + found->second.disconnect(); + + mAvatarNameCacheConnections.erase(found); } - // *TODO : Add a callback per avatar name being fetched. - mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, + + mAvatarNameCacheConnections.try_emplace(agent_id, LLAvatarNameCache::get(agent_id, [&](const LLUUID& agent_id, const LLAvatarName& av_name) { onAvatarNameCache(agent_id, av_name); - }); + })); } } } void LLPanelGroupBulkImpl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name) { - if (mAvatarNameCacheConnection.connected()) + if (auto found = mAvatarNameCacheConnections.find(agent_id); found != mAvatarNameCacheConnections.end()) { - mAvatarNameCacheConnection.disconnect(); - } + if (found->second.connected()) + found->second.disconnect(); - std::vector<std::string> names; - uuid_vec_t agent_ids; - agent_ids.push_back(agent_id); - names.push_back(av_name.getCompleteName()); + mAvatarNameCacheConnections.erase(found); + } - addUsers(names, agent_ids); + addUsers({ av_name.getCompleteName() }, { agent_id }); } void LLPanelGroupBulkImpl::handleRemove() @@ -232,7 +233,7 @@ void LLPanelGroupBulkImpl::addUsers(const std::vector<std::string>& names, const } } -void LLPanelGroupBulkImpl::setGroupName(std::string name) +void LLPanelGroupBulkImpl::setGroupName(const std::string& name) { if (mGroupName) { @@ -337,12 +338,7 @@ void LLPanelGroupBulk::updateGroupData() void LLPanelGroupBulk::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) { - std::vector<std::string> names; - uuid_vec_t agent_ids; - agent_ids.push_back(id); - names.push_back(av_name.getAccountName()); - - mImplementation->addUsers(names, agent_ids); + mImplementation->addUsers({ av_name.getAccountName() }, { id }); } void LLPanelGroupBulk::setCloseCallback(void (*close_callback)(void*), void* data) diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h index 5515bd6d9a..f186ae5373 100644 --- a/indra/newview/llpanelgroupbulkimpl.h +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -59,7 +59,7 @@ public: void handleSelection(); void addUsers(const std::vector<std::string>& names, const uuid_vec_t& agent_ids); - void setGroupName(std::string name); + void setGroupName(const std::string& name); public: @@ -84,7 +84,7 @@ public: void (*mCloseCallback)(void* data); void* mCloseCallbackUserData; - boost::signals2::connection mAvatarNameCacheConnection; + std::map<LLUUID, boost::signals2::connection> mAvatarNameCacheConnections; // The following are for the LLPanelGroupInvite subclass only. // These aren't needed for LLPanelGroupBulkBan, but if we have to add another diff --git a/indra/newview/llpanelgroupcreate.cpp b/indra/newview/llpanelgroupcreate.cpp index 4a370525ff..bc7b5caddf 100644 --- a/indra/newview/llpanelgroupcreate.cpp +++ b/indra/newview/llpanelgroupcreate.cpp @@ -85,6 +85,7 @@ bool LLPanelGroupCreate::postBuild() mInsignia = getChild<LLTextureCtrl>("insignia", true); mInsignia->setAllowLocalTexture(false); + mInsignia->setBakeTextureEnabled(false); mInsignia->setCanApplyImmediately(false); return true; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index ca429ae2f8..270ca29403 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -197,6 +197,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group) { mInsignia->setCommitCallback(onCommitAny, this); mInsignia->setAllowLocalTexture(false); + mInsignia->setBakeTextureEnabled(false); } mFounderName = getChild<LLTextBox>("founder_name"); diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index ed80c8b732..59aa375457 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -184,7 +184,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, mCallback(callback), mCallbackData(cb_data), mListener(new LLPanelLoginListener(this)), - mFirstLoginThisInstall(gSavedSettings.getBOOL("FirstLoginThisInstall")), mUsernameLength(0), mPasswordLength(0), mLocationLength(0), @@ -203,14 +202,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, login_holder->addChild(this); } - if (mFirstLoginThisInstall) - { - buildFromFile( "panel_login_first.xml"); - } - else - { - buildFromFile( "panel_login.xml"); - } + buildFromFile("panel_login.xml"); reshape(rect.getWidth(), rect.getHeight()); @@ -224,38 +216,36 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, sendChildToBack(getChildView("sign_up_text")); std::string current_grid = LLGridManager::getInstance()->getGrid(); - if (!mFirstLoginThisInstall) - { - LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo"); - updateLocationSelectorsVisibility(); // separate so that it can be called from preferences - favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false)); - favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); - LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); - server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); + LLComboBox* favorites_combo = getChild<LLComboBox>("start_location_combo"); + updateLocationSelectorsVisibility(); // separate so that it can be called from preferences + favorites_combo->setReturnCallback(boost::bind(&LLPanelLogin::onClickConnect, false)); + favorites_combo->setFocusLostCallback(boost::bind(&LLPanelLogin::onLocationSLURL, this)); + + LLComboBox* server_choice_combo = getChild<LLComboBox>("server_combo"); + server_choice_combo->setCommitCallback(boost::bind(&LLPanelLogin::onSelectServer, this)); - // Load all of the grids, sorted, and then add a bar and the current grid at the top - server_choice_combo->removeall(); + // Load all of the grids, sorted, and then add a bar and the current grid at the top + server_choice_combo->removeall(); - std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); - for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); - grid_choice != known_grids.end(); - grid_choice++) + std::map<std::string, std::string> known_grids = LLGridManager::getInstance()->getKnownGrids(); + for (std::map<std::string, std::string>::iterator grid_choice = known_grids.begin(); + grid_choice != known_grids.end(); + grid_choice++) + { + if (!grid_choice->first.empty() && current_grid != grid_choice->first) { - if (!grid_choice->first.empty() && current_grid != grid_choice->first) - { - LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL; - server_choice_combo->add(grid_choice->second, grid_choice->first); - } + LL_DEBUGS("AppInit") << "adding " << grid_choice->first << LL_ENDL; + server_choice_combo->add(grid_choice->second, grid_choice->first); } - server_choice_combo->sortByName(); - - LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL; - server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), - current_grid, - ADD_TOP); - server_choice_combo->selectFirstItem(); } + server_choice_combo->sortByName(); + + LL_DEBUGS("AppInit") << "adding current " << current_grid << LL_ENDL; + server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), + current_grid, + ADD_TOP); + server_choice_combo->selectFirstItem(); LLSLURL start_slurl(LLStartUp::getStartSLURL()); // The StartSLURL might have been set either by an explicit command-line @@ -331,15 +321,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, void LLPanelLogin::addFavoritesToStartLocation() { - if (mFirstLoginThisInstall) - { - // first login panel has no favorites, just update name length and buttons - std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); - mUsernameLength = static_cast<unsigned int>(user_defined_name.length()); - updateLoginButtons(); - return; - } - // Clear the combo. LLComboBox* combo = getChild<LLComboBox>("start_location_combo"); if (!combo) return; @@ -559,16 +540,9 @@ void LLPanelLogin::resetFields() // function is used to reset list in case of changes by external sources return; } - if (sInstance->mFirstLoginThisInstall) - { - // no list to populate - LL_WARNS() << "Shouldn't happen, user should have no ability to modify list on first install" << LL_ENDL; - } - else - { - LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); - sInstance->populateUserList(cred); - } + + LLPointer<LLCredential> cred = gSecAPIHandler->loadCredential(LLGridManager::getInstance()->getGrid()); + sInstance->populateUserList(cred); } // static @@ -586,7 +560,6 @@ void LLPanelLogin::setFields(LLPointer<LLCredential> credential) if(identifier.has("type") && (std::string)identifier["type"] == "agent") { - // not nessesary for panel_login.xml, needed for panel_login_first.xml std::string firstname = identifier["first_name"].asString(); std::string lastname = identifier["last_name"].asString(); std::string login_id = firstname; @@ -1081,8 +1054,7 @@ void LLPanelLogin::onRememberUserCheck(void*) LLComboBox* user_combo(sInstance->getChild<LLComboBox>("username_combo")); bool remember = remember_name->getValue().asBoolean(); - if (!sInstance->mFirstLoginThisInstall - && user_combo->getCurrentIndex() != -1 + if (user_combo->getCurrentIndex() != -1 && !remember) { remember = true; @@ -1197,17 +1169,14 @@ void LLPanelLogin::updateLoginButtons() login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0); - if (!mFirstLoginThisInstall) + LLComboBox* user_combo = getChild<LLComboBox>("username_combo"); + LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); + if (user_combo->getCurrentIndex() != -1) { - LLComboBox* user_combo = getChild<LLComboBox>("username_combo"); - LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name"); - if (user_combo->getCurrentIndex() != -1) - { - remember_name->setValue(true); - LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password"); - remember_pass->setEnabled(true); - } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user - } + remember_name->setValue(true); + LLCheckBoxCtrl* remember_pass = getChild<LLCheckBoxCtrl>("remember_password"); + remember_pass->setEnabled(true); + } // Note: might be good idea to do "else remember_name->setValue(mRememberedState)" but it might behave 'weird' to user } void LLPanelLogin::populateUserList(LLPointer<LLCredential> credential) diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index a1bf25fb05..1259bf26d6 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -119,7 +119,6 @@ private: static LLPanelLogin* sInstance; static bool sCapslockDidNotification; - bool mFirstLoginThisInstall; static bool sCredentialSet; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index d964fa9170..ad7aa57842 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -68,6 +68,7 @@ const std::string FILTERS_FILENAME("filters.xml"); const std::string ALL_ITEMS("All Items"); const std::string RECENT_ITEMS("Recent Items"); const std::string WORN_ITEMS("Worn Items"); +const std::string FAVORITES("Favorites"); static LLPanelInjector<LLPanelMainInventory> t_inventory("panel_main_inventory"); @@ -78,9 +79,9 @@ static LLPanelInjector<LLPanelMainInventory> t_inventory("panel_main_inventory") class LLFloaterInventoryFinder : public LLFloater { public: - LLFloaterInventoryFinder( LLPanelMainInventory* inventory_view); - virtual void draw(); - /*virtual*/ bool postBuild(); + LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view); + void draw(); + bool postBuild(); void changeFilter(LLInventoryFilter* filter); void updateElementsFromFilter(); bool getCheckShowEmpty(); @@ -90,17 +91,35 @@ public: void onCreatorSelfFilterCommit(); void onCreatorOtherFilterCommit(); - static void onTimeAgo(LLUICtrl*, void *); - static void onCloseBtn(void* user_data); - static void selectAllTypes(void* user_data); - static void selectNoTypes(void* user_data); + void onTimeAgo(); + void onCloseBtn(); + void selectAllTypes(); + void selectNoTypes(); private: - LLPanelMainInventory* mPanelMainInventory; - LLSpinCtrl* mSpinSinceDays; - LLSpinCtrl* mSpinSinceHours; - LLCheckBoxCtrl* mCreatorSelf; - LLCheckBoxCtrl* mCreatorOthers; - LLInventoryFilter* mFilter; + LLPanelMainInventory* mPanelMainInventory{ nullptr }; + LLSpinCtrl* mSpinSinceDays{ nullptr }; + LLSpinCtrl* mSpinSinceHours{ nullptr }; + LLCheckBoxCtrl* mCreatorSelf{ nullptr }; + LLCheckBoxCtrl* mCreatorOthers{ nullptr }; + LLInventoryFilter* mFilter{ nullptr }; + + LLCheckBoxCtrl* mCheckAnimation{ nullptr }; + LLCheckBoxCtrl* mCheckCallingCard{ nullptr }; + LLCheckBoxCtrl* mCheckClothing{ nullptr }; + LLCheckBoxCtrl* mCheckGesture{ nullptr }; + LLCheckBoxCtrl* mCheckLandmark{ nullptr }; + LLCheckBoxCtrl* mCheckMaterial{ nullptr }; + LLCheckBoxCtrl* mCheckNotecard{ nullptr }; + LLCheckBoxCtrl* mCheckObject{ nullptr }; + LLCheckBoxCtrl* mCheckScript{ nullptr }; + LLCheckBoxCtrl* mCheckSounds{ nullptr }; + LLCheckBoxCtrl* mCheckTexture{ nullptr }; + LLCheckBoxCtrl* mCheckSnapshot{ nullptr }; + LLCheckBoxCtrl* mCheckSettings{ nullptr }; + LLCheckBoxCtrl* mCheckShowEmpty{ nullptr }; + LLCheckBoxCtrl* mCheckSinceLogoff{ nullptr }; + + LLRadioGroup* mRadioDateSearchDirection{ nullptr }; }; ///---------------------------------------------------------------------------- @@ -196,6 +215,17 @@ bool LLPanelMainInventory::postBuild() worn_filter.markDefault(); mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2)); } + + LLInventoryPanel* favorites_panel = getChild<LLInventoryPanel>(FAVORITES); + if (favorites_panel) + { + favorites_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER)); + LLInventoryFilter& favorites_filter = favorites_panel->getFilter(); + favorites_filter.setEmptyLookupMessage("InventoryNoMatchingFavorites"); + favorites_filter.markDefault(); + favorites_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, favorites_panel, _1, _2)); + } + mSearchTypeCombo = getChild<LLComboBox>("search_type"); if(mSearchTypeCombo) { @@ -560,7 +590,8 @@ void LLPanelMainInventory::doCreate(const LLSD& userdata) } else { - menu_create_inventory_item(getPanel(), NULL, userdata); + selectAllItemsPanel(); + menu_create_inventory_item(mAllItemsPanel, NULL, userdata); } } @@ -734,7 +765,6 @@ bool LLPanelMainInventory::filtersVisible(void* user_data) void LLPanelMainInventory::onClearSearch() { bool initially_active = false; - LLFloater *finder = getFinder(); if (mActivePanel && (getActivePanel() != mWornItemsPanel)) { initially_active = mActivePanel->getFilter().isNotDefault(); @@ -743,9 +773,9 @@ void LLPanelMainInventory::onClearSearch() mActivePanel->setFilterLinks(LLInventoryFilter::FILTERLINK_INCLUDE_LINKS); } - if (finder) + if (LLFloaterInventoryFinder* finder = getFinder()) { - LLFloaterInventoryFinder::selectAllTypes(finder); + finder->selectAllTypes(); } // re-open folders that were initially open in case filter was active @@ -1145,36 +1175,53 @@ bool LLFloaterInventoryFinder::postBuild() const LLRect& viewrect = mPanelMainInventory->getRect(); setRect(LLRect(viewrect.mLeft - getRect().getWidth(), viewrect.mTop, viewrect.mLeft, viewrect.mTop - getRect().getHeight())); - childSetAction("All", selectAllTypes, this); - childSetAction("None", selectNoTypes, this); + childSetAction("All", [this](LLUICtrl*, const LLSD&) { selectAllTypes(); }); + childSetAction("None", [this](LLUICtrl*, const LLSD&) { selectNoTypes(); }); mSpinSinceHours = getChild<LLSpinCtrl>("spin_hours_ago"); - childSetCommitCallback("spin_hours_ago", onTimeAgo, this); + mSpinSinceHours->setCommitCallback([this](LLUICtrl*, const LLSD&) { onTimeAgo(); }); mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago"); - childSetCommitCallback("spin_days_ago", onTimeAgo, this); + mSpinSinceDays->setCommitCallback([this](LLUICtrl*, const LLSD&) { onTimeAgo(); }); mCreatorSelf = getChild<LLCheckBoxCtrl>("check_created_by_me"); mCreatorOthers = getChild<LLCheckBoxCtrl>("check_created_by_others"); mCreatorSelf->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorSelfFilterCommit, this)); mCreatorOthers->setCommitCallback(boost::bind(&LLFloaterInventoryFinder::onCreatorOtherFilterCommit, this)); - childSetAction("Close", onCloseBtn, this); + mCheckAnimation = getChild<LLCheckBoxCtrl>("check_animation"); + mCheckCallingCard = getChild<LLCheckBoxCtrl>("check_calling_card"); + mCheckClothing = getChild<LLCheckBoxCtrl>("check_clothing"); + mCheckGesture = getChild<LLCheckBoxCtrl>("check_gesture"); + mCheckLandmark = getChild<LLCheckBoxCtrl>("check_landmark"); + mCheckMaterial = getChild<LLCheckBoxCtrl>("check_material"); + mCheckNotecard = getChild<LLCheckBoxCtrl>("check_notecard"); + mCheckObject = getChild<LLCheckBoxCtrl>("check_object"); + mCheckScript = getChild<LLCheckBoxCtrl>("check_script"); + mCheckSounds = getChild<LLCheckBoxCtrl>("check_sound"); + mCheckTexture = getChild<LLCheckBoxCtrl>("check_texture"); + mCheckSnapshot = getChild<LLCheckBoxCtrl>("check_snapshot"); + mCheckSettings = getChild<LLCheckBoxCtrl>("check_settings"); + mCheckShowEmpty = getChild<LLCheckBoxCtrl>("check_show_empty"); + mCheckSinceLogoff = getChild<LLCheckBoxCtrl>("check_since_logoff"); + + mRadioDateSearchDirection = getChild<LLRadioGroup>("date_search_direction"); + + childSetAction("Close", [this](LLUICtrl*, const LLSD&) { onCloseBtn(); }); updateElementsFromFilter(); + return true; } -void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) -{ - LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; - if (!self) return; - if ( self->mSpinSinceDays->get() || self->mSpinSinceHours->get() ) +void LLFloaterInventoryFinder::onTimeAgo() +{ + if (mSpinSinceDays->get() || mSpinSinceHours->get()) { - self->getChild<LLUICtrl>("check_since_logoff")->setValue(false); + mCheckSinceLogoff->setValue(false); - U32 days = (U32)self->mSpinSinceDays->get(); - U32 hours = (U32)self->mSpinSinceHours->get(); + U32 days = (U32)mSpinSinceDays->get(); + U32 hours = (U32)mSpinSinceHours->get(); if (hours >= 24) { // Try to handle both cases of spinner clicking and text input in a sensible fashion as best as possible. @@ -1190,11 +1237,11 @@ void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data) days = hours / 24; } hours = (U32)hours % 24; - self->mSpinSinceHours->setFocus(false); - self->mSpinSinceDays->setFocus(false); - self->mSpinSinceDays->set((F32)days); - self->mSpinSinceHours->set((F32)hours); - self->mSpinSinceHours->setFocus(true); + mSpinSinceHours->setFocus(false); + mSpinSinceDays->setFocus(false); + mSpinSinceDays->set((F32)days); + mSpinSinceHours->set((F32)hours); + mSpinSinceHours->setFocus(true); } } } @@ -1223,29 +1270,28 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() // update the ui elements setTitle(mFilter->getName()); - getChild<LLUICtrl>("check_animation")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); - - getChild<LLUICtrl>("check_calling_card")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); - getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); - getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); - getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); - getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL)); - getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); - getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); - getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); - getChild<LLUICtrl>("check_sound")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); - getChild<LLUICtrl>("check_texture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); - getChild<LLUICtrl>("check_snapshot")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); - getChild<LLUICtrl>("check_settings")->setValue((S32)(filter_types & 0x1 << LLInventoryType::IT_SETTINGS)); - getChild<LLUICtrl>("check_show_empty")->setValue(show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); - - getChild<LLUICtrl>("check_created_by_me")->setValue(show_created_by_me); - getChild<LLUICtrl>("check_created_by_others")->setValue(show_created_by_others); - - getChild<LLUICtrl>("check_since_logoff")->setValue(mFilter->isSinceLogoff()); + mCheckAnimation->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_ANIMATION)); + mCheckCallingCard->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_CALLINGCARD)); + mCheckClothing->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE)); + mCheckGesture->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE)); + mCheckLandmark->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK)); + mCheckMaterial->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL)); + mCheckNotecard->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD)); + mCheckObject->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT)); + mCheckScript->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL)); + mCheckSounds->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SOUND)); + mCheckTexture->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_TEXTURE)); + mCheckSnapshot->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_SNAPSHOT)); + mCheckSettings->setValue((S32)(filter_types & 0x1 << LLInventoryType::IT_SETTINGS)); + mCheckShowEmpty->setValue(show_folders == LLInventoryFilter::SHOW_ALL_FOLDERS); + + mCreatorSelf->setValue(show_created_by_me); + mCreatorOthers->setValue(show_created_by_others); + + mCheckSinceLogoff->setValue(mFilter->isSinceLogoff()); mSpinSinceHours->set((F32)(hours % 24)); mSpinSinceDays->set((F32)(hours / 24)); - getChild<LLRadioGroup>("date_search_direction")->setSelectedIndex(date_search_direction); + mRadioDateSearchDirection->setSelectedIndex(date_search_direction); } void LLFloaterInventoryFinder::draw() @@ -1253,80 +1299,80 @@ void LLFloaterInventoryFinder::draw() U64 filter = 0xffffffffffffffffULL; bool filtered_by_all_types = true; - if (!getChild<LLUICtrl>("check_animation")->getValue()) + if (!mCheckAnimation->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_ANIMATION); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_calling_card")->getValue()) + if (!mCheckCallingCard->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_CALLINGCARD); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_clothing")->getValue()) + if (!mCheckClothing->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_WEARABLE); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_gesture")->getValue()) + if (!mCheckGesture->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_GESTURE); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_landmark")->getValue()) + if (!mCheckLandmark->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_LANDMARK); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_material")->getValue()) + if (!mCheckMaterial->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_MATERIAL); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_notecard")->getValue()) + if (!mCheckNotecard->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_object")->getValue()) + if (!mCheckObject->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_OBJECT); filter &= ~(0x1 << LLInventoryType::IT_ATTACHMENT); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_script")->getValue()) + if (!mCheckScript->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_LSL); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_sound")->getValue()) + if (!mCheckSounds->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_SOUND); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_texture")->getValue()) + if (!mCheckTexture->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_TEXTURE); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_snapshot")->getValue()) + if (!mCheckSnapshot->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_SNAPSHOT); filtered_by_all_types = false; } - if (!getChild<LLUICtrl>("check_settings")->getValue()) + if (!mCheckSettings->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_SETTINGS); filtered_by_all_types = false; @@ -1444,65 +1490,56 @@ void LLFloaterInventoryFinder::onCreatorOtherFilterCommit() bool LLFloaterInventoryFinder::getCheckShowEmpty() { - return getChild<LLUICtrl>("check_show_empty")->getValue(); + return mCheckShowEmpty->getValue(); } bool LLFloaterInventoryFinder::getCheckSinceLogoff() { - return getChild<LLUICtrl>("check_since_logoff")->getValue(); + return mCheckSinceLogoff->getValue(); } U32 LLFloaterInventoryFinder::getDateSearchDirection() { - return getChild<LLRadioGroup>("date_search_direction")->getSelectedIndex(); + return mRadioDateSearchDirection->getSelectedIndex(); } -void LLFloaterInventoryFinder::onCloseBtn(void* user_data) +void LLFloaterInventoryFinder::onCloseBtn() { - LLFloaterInventoryFinder* finderp = (LLFloaterInventoryFinder*)user_data; - finderp->closeFloater(); + closeFloater(); } -// static -void LLFloaterInventoryFinder::selectAllTypes(void* user_data) -{ - LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; - if(!self) return; - - self->getChild<LLUICtrl>("check_animation")->setValue(true); - self->getChild<LLUICtrl>("check_calling_card")->setValue(true); - self->getChild<LLUICtrl>("check_clothing")->setValue(true); - self->getChild<LLUICtrl>("check_gesture")->setValue(true); - self->getChild<LLUICtrl>("check_landmark")->setValue(true); - self->getChild<LLUICtrl>("check_material")->setValue(true); - self->getChild<LLUICtrl>("check_notecard")->setValue(true); - self->getChild<LLUICtrl>("check_object")->setValue(true); - self->getChild<LLUICtrl>("check_script")->setValue(true); - self->getChild<LLUICtrl>("check_sound")->setValue(true); - self->getChild<LLUICtrl>("check_texture")->setValue(true); - self->getChild<LLUICtrl>("check_snapshot")->setValue(true); - self->getChild<LLUICtrl>("check_settings")->setValue(true); +void LLFloaterInventoryFinder::selectAllTypes() +{ + mCheckAnimation->setValue(true); + mCheckCallingCard->setValue(true); + mCheckClothing->setValue(true); + mCheckGesture->setValue(true); + mCheckLandmark->setValue(true); + mCheckMaterial->setValue(true); + mCheckNotecard->setValue(true); + mCheckObject->setValue(true); + mCheckScript->setValue(true); + mCheckSounds->setValue(true); + mCheckTexture->setValue(true); + mCheckSnapshot->setValue(true); + mCheckSettings->setValue(true); } -//static -void LLFloaterInventoryFinder::selectNoTypes(void* user_data) -{ - LLFloaterInventoryFinder* self = (LLFloaterInventoryFinder*)user_data; - if(!self) return; - - self->getChild<LLUICtrl>("check_animation")->setValue(false); - self->getChild<LLUICtrl>("check_calling_card")->setValue(false); - self->getChild<LLUICtrl>("check_clothing")->setValue(false); - self->getChild<LLUICtrl>("check_gesture")->setValue(false); - self->getChild<LLUICtrl>("check_landmark")->setValue(false); - self->getChild<LLUICtrl>("check_material")->setValue(false); - self->getChild<LLUICtrl>("check_notecard")->setValue(false); - self->getChild<LLUICtrl>("check_object")->setValue(false); - self->getChild<LLUICtrl>("check_script")->setValue(false); - self->getChild<LLUICtrl>("check_sound")->setValue(false); - self->getChild<LLUICtrl>("check_texture")->setValue(false); - self->getChild<LLUICtrl>("check_snapshot")->setValue(false); - self->getChild<LLUICtrl>("check_settings")->setValue(false); +void LLFloaterInventoryFinder::selectNoTypes() +{ + mCheckAnimation->setValue(false); + mCheckCallingCard->setValue(false); + mCheckClothing->setValue(false); + mCheckGesture->setValue(false); + mCheckLandmark->setValue(false); + mCheckMaterial->setValue(false); + mCheckNotecard->setValue(false); + mCheckObject->setValue(false); + mCheckScript->setValue(false); + mCheckSounds->setValue(false); + mCheckTexture->setValue(false); + mCheckSnapshot->setValue(false); + mCheckSettings->setValue(false); } ////////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0a3a2e753a..23e6a9fbcf 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2267,19 +2267,21 @@ void LLPanelObject::onCopyParams() if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) { LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); - - LLUUID texture_id = sculpt_params->getSculptTexture(); - if (get_can_copy_texture(texture_id)) - { - LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL; - mClipboardParams["sculpt"]["id"] = texture_id; - } - else + if (sculpt_params) { - mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE; - } + LLUUID texture_id = sculpt_params->getSculptTexture(); + if (get_can_copy_texture(texture_id)) + { + LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL; + mClipboardParams["sculpt"]["id"] = texture_id; + } + else + { + mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE; + } - mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType(); + mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType(); + } } } diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index ef7986603b..f90d6d5b3f 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -129,6 +129,7 @@ public: virtual void navigateToFolder(bool new_window = false, bool change_mode = false) {} virtual bool isItemRenameable() const; virtual bool renameItem(const std::string& new_name); + virtual bool isFavorite() const { return false; } virtual bool isItemMovable() const; virtual bool isItemRemovable(bool check_worn = true) const; virtual bool removeItem(); @@ -1364,7 +1365,23 @@ bool LLPanelObjectInventory::postBuild() void LLPanelObjectInventory::doToSelected(const LLSD& userdata) { - LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString()); + std::string action = userdata.asString(); + if ("rename" == action || "delete" == action) + { + LLViewerObject* objectp = gObjectList.findObject(mTaskUUID); + if (objectp && !objectp->permModify()) + { + LLNotificationsUtil::add("CantModifyContentInNoModTask"); + } + else + { + LLInventoryAction::doToSelected(&gInventory, mFolders, action); + } + } + else + { + LLInventoryAction::doToSelected(&gInventory, mFolders, action); + } } void LLPanelObjectInventory::clearContents() diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index 4cd4afaa5a..a9e860d2ef 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -404,7 +404,9 @@ LLPanelOutfitEdit::LLPanelOutfitEdit() mWearableListManager(NULL), mPlusBtn(NULL), mWearablesGearMenuBtn(NULL), - mGearMenuBtn(NULL) + mGearMenuBtn(NULL), + mStatus(NULL), + mCurrentOutfitName(NULL) { mSavedFolderState = new LLSaveFolderState(); mSavedFolderState->setApply(false); diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 47c02793a3..e2e2cf1a61 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -33,6 +33,7 @@ #include "llfloatersidepanelcontainer.h" #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" +#include "llmenubutton.h" #include "llnotificationsutil.h" #include "lloutfitgallery.h" #include "lloutfitobserver.h" @@ -53,12 +54,17 @@ static const std::string SAVE_BTN("save_btn"); static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory"); -LLPanelOutfitsInventory::LLPanelOutfitsInventory() : - mMyOutfitsPanel(NULL), - mCurrentOutfitPanel(NULL), - mActivePanel(NULL), - mAppearanceTabs(NULL), - mInitialized(false) +LLPanelOutfitsInventory::LLPanelOutfitsInventory() + : mMyOutfitsPanel(nullptr) + , mCurrentOutfitPanel(nullptr) + , mActivePanel(nullptr) + , mAppearanceTabs(nullptr) + , mInitialized(false) + , mGearMenu(nullptr) + , mSortMenu(nullptr) + , mTrashBtn(nullptr) + , mSortMenuPanel(nullptr) + , mTrashMenuPanel(nullptr) { gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this)); gAgentWearables.addLoadingStartedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoading, this)); @@ -75,6 +81,9 @@ LLPanelOutfitsInventory::~LLPanelOutfitsInventory() { gSavedSettings.setS32("LastAppearanceTab", mAppearanceTabs->getCurrentPanelIndex()); } + mGearMenuConnection.disconnect(); + mSortMenuConnection.disconnect(); + mTrashMenuConnection.disconnect(); } // virtual @@ -258,6 +267,22 @@ void LLPanelOutfitsInventory::initListCommandsHandlers() mOutfitGalleryPanel->childSetAction("trash_btn", boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); } +void LLPanelOutfitsInventory::setMenuButtons(LLMenuButton* gear_menu, LLMenuButton* sort_menu, LLButton* trash_btn, LLPanel* sort_menu_panel, LLPanel* trash_menu_panel) +{ + mGearMenu = gear_menu; + mSortMenu = sort_menu; + mTrashBtn = trash_btn; + mSortMenuPanel = sort_menu_panel; + mTrashMenuPanel = trash_menu_panel; + + mGearMenuConnection.disconnect(); + mSortMenuConnection.disconnect(); + mTrashMenuConnection.disconnect(); + mGearMenuConnection = mGearMenu->setMouseDownCallback(boost::bind(&LLPanelOutfitsInventory::onGearMouseDown, this)); + mSortMenuConnection = mSortMenu->setMouseDownCallback(boost::bind(&LLPanelOutfitsInventory::onGearMouseDown, this)); + mTrashMenuConnection = mTrashBtn->setClickedCallback(boost::bind(&LLPanelOutfitsInventory::onTrashButtonClick, this)); +} + void LLPanelOutfitsInventory::updateListCommands() { bool trash_enabled = isActionEnabled("delete"); @@ -284,6 +309,14 @@ void LLPanelOutfitsInventory::onTrashButtonClick() } } +void LLPanelOutfitsInventory::onGearMouseDown() +{ + if (mActivePanel) + { + mActivePanel->updateMenuItemsVisibility(); + } +} + bool LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata) { return mActivePanel && mActivePanel->isActionEnabled(userdata); @@ -320,6 +353,28 @@ void LLPanelOutfitsInventory::onTabChange() mActivePanel->checkFilterSubString(); mActivePanel->onOpen(LLSD()); + if (mGearMenu) + { + mGearMenu->setMenu(mActivePanel->getGearMenu(), LLMenuButton::MP_BOTTOM_LEFT); + } + if (mSortMenu && mSortMenuPanel) + { + LLToggleableMenu* menu = mActivePanel->getSortMenu(); + if (menu) + { + mSortMenu->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT); + mSortMenuPanel->setVisible(true); + } + else + { + mSortMenuPanel->setVisible(false); + } + } + if (mTrashMenuPanel) + { + mTrashMenuPanel->setVisible(mActivePanel->getTrashMenuVisible()); + } + updateVerbs(); } diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index e046681e95..29f7eb44f7 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -30,11 +30,13 @@ #include "llpanel.h" +class LLButton; class LLOutfitGallery; class LLOutfitsList; class LLOutfitListGearMenuBase; class LLPanelAppearanceTab; class LLPanelWearing; +class LLMenuButton; class LLMenuGL; class LLSidepanelAppearance; class LLTabContainer; @@ -63,6 +65,13 @@ public: bool isCOFPanelActive() const; + void setMenuButtons( + LLMenuButton* gear_menu, + LLMenuButton* sort_menu, + LLButton* trash_btn, + LLPanel* sort_menu_panel, + LLPanel* trash_menu_panel); + protected: void updateVerbs(); @@ -92,20 +101,29 @@ protected: void initListCommandsHandlers(); void updateListCommands(); void onWearButtonClick(); - void showGearMenu(); void onTrashButtonClick(); + void onGearMouseDown(); bool isActionEnabled(const LLSD& userdata); void setWearablesLoading(bool val); void onWearablesLoaded(); void onWearablesLoading(); private: LLPanel* mListCommands; - LLMenuGL* mMenuAdd; LLButton* mWearBtn = nullptr; // List Commands // ////////////////////////////////////////////////////////////////////////////////// bool mInitialized; + + // not owned items + LLMenuButton* mGearMenu; + LLMenuButton* mSortMenu; + LLButton* mTrashBtn; + LLPanel* mSortMenuPanel; + LLPanel* mTrashMenuPanel; + boost::signals2::connection mGearMenuConnection; + boost::signals2::connection mSortMenuConnection; + boost::signals2::connection mTrashMenuConnection; }; #endif //LL_LLPANELOUTFITSINVENTORY_H diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 25672db318..33599357a3 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -843,6 +843,10 @@ void LLPanelPeople::updateNearbyList() LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange")); mNearbyList->setDirty(); +#ifdef LL_DISCORD + if (gSavedSettings.getBOOL("EnableDiscord")) + LLAppViewer::updateDiscordPartyMaxSize((S32)mNearbyList->getIDs().size()); +#endif DISTANCE_COMPARATOR.updateAvatarsPositions(positions, mNearbyList->getIDs()); LLActiveSpeakerMgr::instance().update(true); diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index f8a73ddb46..62e726d21d 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -154,11 +154,15 @@ void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags) bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata) { + std::string item = userdata.asString(); if(gAgent.getID() == mUUIDs.front()) { + if (item == std::string("can_zoom_in")) + { + return true; + } return false; } - std::string item = userdata.asString(); // Note: can_block and can_delete is used only for one person selected menu // so we don't need to go over all uuids. @@ -350,7 +354,10 @@ void PeopleContextMenu::eject() avatar = (LLVOAvatar*) object; } } - if (!avatar) return; + + if (!avatar) + return; + LLSD payload; payload["avatar_id"] = avatar->getID(); std::string fullname = avatar->getFullname(); diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp index 0ce1f0f9d3..cbf5819fda 100644 --- a/indra/newview/llpanelpermissions.cpp +++ b/indra/newview/llpanelpermissions.cpp @@ -176,7 +176,7 @@ bool LLPanelPermissions::postBuild() childSetCommitCallback("sale type",LLPanelPermissions::onCommitSaleType,this); - childSetCommitCallback("Edit Cost", LLPanelPermissions::onCommitSaleInfo, this); + childSetCommitCallback("Edit Cost", LLPanelPermissions::onCommitSalePrice, this); childSetCommitCallback("checkbox next owner can modify",LLPanelPermissions::onCommitNextOwnerModify,this); childSetCommitCallback("checkbox next owner can copy",LLPanelPermissions::onCommitNextOwnerCopy,this); @@ -781,7 +781,9 @@ void LLPanelPermissions::refresh() if (has_change_sale_ability && (owner_mask_on & PERM_TRANSFER)) { - getChildView("checkbox for sale")->setEnabled(can_transfer || (!can_transfer && num_for_sale)); + bool change_sale_allowed = can_transfer || (!can_transfer && num_for_sale); + getChildView("checkbox for sale")->setEnabled(change_sale_allowed); + getChildView("Edit Cost")->setEnabled(change_sale_allowed && !is_for_sale_mixed); // Set the checkbox to tentative if the prices of each object selected // are not the same. getChild<LLUICtrl>("checkbox for sale")->setTentative( is_for_sale_mixed); @@ -1175,6 +1177,7 @@ void LLPanelPermissions::onCommitName(LLUICtrl*, void* data) { LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); new_item->rename(tb->getText()); + new_item->setComplete(true); // to not err at updateServer new_item->updateServer(false); gInventory.updateItem(new_item); gInventory.notifyObservers(); @@ -1223,6 +1226,16 @@ void LLPanelPermissions::onCommitSaleType(LLUICtrl*, void* data) self->setAllSaleInfo(); } +void LLPanelPermissions::onCommitSalePrice(LLUICtrl *, void *data) +{ + LLPanelPermissions *self = (LLPanelPermissions *) data; + LLCheckBoxCtrl *checkPurchase = self->getChild<LLCheckBoxCtrl>("checkbox for sale"); + if (checkPurchase && checkPurchase->get()) + { + self->setAllSaleInfo(); + } +} + void LLPanelPermissions::setAllSaleInfo() { LL_INFOS() << "LLPanelPermissions::setAllSaleInfo()" << LL_ENDL; diff --git a/indra/newview/llpanelpermissions.h b/indra/newview/llpanelpermissions.h index 77129434ed..12e88361c9 100644 --- a/indra/newview/llpanelpermissions.h +++ b/indra/newview/llpanelpermissions.h @@ -77,6 +77,7 @@ protected: static void onCommitSaleInfo(LLUICtrl* ctrl, void* data); static void onCommitSaleType(LLUICtrl* ctrl, void* data); + static void onCommitSalePrice(LLUICtrl *ctrl, void *data); void setAllSaleInfo(); static void onCommitClickAction(LLUICtrl* ctrl, void*); diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index d2ead0e134..86071e38e1 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -777,7 +777,7 @@ void LLPanelPrimMediaControls::draw() else if(mFadeTimer.getStarted()) { F32 time = mFadeTimer.getElapsedTimeF32(); - alpha *= llmax(lerp(1.0, 0.0, time / mControlFadeTime), 0.0f); + alpha *= llmax(lerp(1.f, 0.f, time / mControlFadeTime), 0.0f); if(time >= mControlFadeTime) { diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 08605f7cf4..b77ee2f439 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -328,7 +328,7 @@ public: } const std::string verb = params[1].asString(); - if (verb == "about") + if (verb == "about" || verb == "mention") { LLAvatarActions::showProfile(avatar_id); return true; @@ -2066,6 +2066,7 @@ void LLPanelProfileFirstLife::onChangePhoto() } }); texture_floaterp->setLocalTextureEnabled(false); + texture_floaterp->setBakeTextureEnabled(false); texture_floaterp->setCanApply(false, true, false); parent_floater->addDependentFloater(mFloaterTexturePickerHandle); diff --git a/indra/newview/llpanelprofileclassifieds.h b/indra/newview/llpanelprofileclassifieds.h index 9f0b27139a..1c58fa6cfa 100644 --- a/indra/newview/llpanelprofileclassifieds.h +++ b/indra/newview/llpanelprofileclassifieds.h @@ -157,17 +157,17 @@ public: void setParcelId(const LLUUID& id) { mParcelId = id; } - LLUUID getParcelId() { return mParcelId; } + LLUUID getParcelId() const { return mParcelId; } void setSimName(const std::string& sim_name) { mSimName = sim_name; } - std::string getSimName() { return mSimName; } + std::string getSimName() const { return mSimName; } void setFromSearch(bool val) { mFromSearch = val; } - bool fromSearch() { return mFromSearch; } + bool fromSearch() const { return mFromSearch; } - bool getInfoLoaded() { return mInfoLoaded; } + bool getInfoLoaded() const { return mInfoLoaded; } void setInfoLoaded(bool loaded) { mInfoLoaded = loaded; } @@ -175,9 +175,9 @@ public: void resetDirty() override; - bool isNew() { return mIsNew; } + bool isNew() const { return mIsNew; } - bool isNewWithErrors() { return mIsNewWithErrors; } + bool isNewWithErrors() const { return mIsNewWithErrors; } bool canClose(); @@ -191,10 +191,10 @@ public: bool getAutoRenew(); - S32 getPriceForListing() { return mPriceForListing; } + S32 getPriceForListing() const { return mPriceForListing; } void setEditMode(bool edit_mode); - bool getEditMode() {return mEditMode;} + bool getEditMode() const { return mEditMode; } static void setClickThrough( const LLUUID& classified_id, diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index a87ef4f0f9..c9626bf9ea 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -248,6 +248,8 @@ void LLPanelProfilePicks::onClickNewBtn() select_tab(true). label(pick_panel->getPickName())); updateButtons(); + + pick_panel->addLocationChangedCallbacks(); } void LLPanelProfilePicks::onClickDelete() @@ -607,10 +609,12 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) { mPickName->setEnabled(true); mPickDescription->setEnabled(true); + mSetCurrentLocationButton->setVisible(true); } else { mSnapshotCtrl->setEnabled(false); + mSetCurrentLocationButton->setVisible(false); } } @@ -621,6 +625,7 @@ bool LLPanelProfilePick::postBuild() mSaveButton = getChild<LLButton>("save_changes_btn"); mCreateButton = getChild<LLButton>("create_changes_btn"); mCancelButton = getChild<LLButton>("cancel_changes_btn"); + mSetCurrentLocationButton = getChild<LLButton>("set_to_curr_location_btn"); mSnapshotCtrl = getChild<LLTextureCtrl>("pick_snapshot"); mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this)); @@ -633,6 +638,7 @@ bool LLPanelProfilePick::postBuild() mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this)); + mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this)); mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL); mPickName->setEnabled(false); @@ -811,6 +817,32 @@ bool LLPanelProfilePick::isDirty() const return false; } +void LLPanelProfilePick::onClickSetLocation() +{ + // Save location for later use. + setPosGlobal(gAgent.getPositionGlobal()); + + std::string parcel_name, region_name; + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mParcelId = parcel->getID(); + parcel_name = parcel->getName(); + } + + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + region_name = region->getName(); + } + + setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal())); + + mLocationChanged = true; + enableSaveButton(true); +} + void LLPanelProfilePick::onClickSave() { if (mRegionCallbackConnection.connected()) @@ -821,6 +853,10 @@ void LLPanelProfilePick::onClickSave() { mParcelCallbackConnection.disconnect(); } + if (mLocationChanged) + { + onClickSetLocation(); + } sendUpdate(); mLocationChanged = false; @@ -871,6 +907,12 @@ void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data) } } +void LLPanelProfilePick::addLocationChangedCallbacks() +{ + mRegionCallbackConnection = gAgent.addRegionChangedCallback([this]() { onClickSetLocation(); }); + mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onClickSetLocation(); }); +} + void LLPanelProfilePick::setParcelID(const LLUUID& parcel_id) { if (mParcelId != parcel_id) diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index b4d3eb010e..847ac57cea 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -141,6 +141,8 @@ public: LLUUID getParcelID() const { return mParcelId; } void setErrorStatus(S32 status, const std::string& reason) override {}; + void addLocationChangedCallbacks(); + protected: /** @@ -203,6 +205,11 @@ public: void resetDirty() override; /** + * Callback for "Set Location" button click + */ + void onClickSetLocation(); + + /** * Callback for "Save" and "Create" button click */ void onClickSave(); @@ -224,6 +231,7 @@ protected: LLTextureCtrl* mSnapshotCtrl; LLLineEditor* mPickName; LLTextEditor* mPickDescription; + LLButton* mSetCurrentLocationButton; LLButton* mSaveButton; LLButton* mCreateButton; LLButton* mCancelButton; @@ -241,7 +249,7 @@ protected: bool mLocationChanged; bool mNewPick; - bool mIsEditing; + bool mIsEditing; void onDescriptionFocusReceived(); }; diff --git a/indra/newview/llpanelsnapshot.cpp b/indra/newview/llpanelsnapshot.cpp index 32c9f6f402..56c0294dbe 100644 --- a/indra/newview/llpanelsnapshot.cpp +++ b/indra/newview/llpanelsnapshot.cpp @@ -37,6 +37,7 @@ // newview #include "llsidetraypanelcontainer.h" +#include "llsnapshotlivepreview.h" #include "llviewercontrol.h" // gSavedSettings #include "llagentbenefits.h" @@ -99,6 +100,17 @@ void LLPanelSnapshot::onOpen(const LLSD& key) { getParentByType<LLFloater>()->notify(LLSD().with("image-format-change", true)); } + + // If resolution is set to "Current Window", force a snapshot update + // each time a snapshot panel is opened to determine the correct + // image size (and upload fee) depending on the snapshot type. + if (mSnapshotFloater && getChild<LLUICtrl>(getImageSizeComboName())->getValue().asString() == "[i0,i0]") + { + if (LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView()) + { + preview->mForceUpdateSnapshot = true; + } + } } LLSnapshotModel::ESnapshotFormat LLPanelSnapshot::getImageFormat() const diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp index 96b17acc40..b81b891685 100644 --- a/indra/newview/llpanelsnapshotinventory.cpp +++ b/indra/newview/llpanelsnapshotinventory.cpp @@ -42,77 +42,35 @@ /** * The panel provides UI for saving snapshot as an inventory texture. */ -class LLPanelSnapshotInventoryBase - : public LLPanelSnapshot -{ - LOG_CLASS(LLPanelSnapshotInventoryBase); - -public: - LLPanelSnapshotInventoryBase(); - - /*virtual*/ bool postBuild(); -protected: - void onSend(); - /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); -}; - class LLPanelSnapshotInventory - : public LLPanelSnapshotInventoryBase + : public LLPanelSnapshot { LOG_CLASS(LLPanelSnapshotInventory); public: LLPanelSnapshotInventory(); - /*virtual*/ bool postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + bool postBuild() override; + void onOpen(const LLSD& key) override; void onResolutionCommit(LLUICtrl* ctrl); private: - /*virtual*/ std::string getWidthSpinnerName() const { return "inventory_snapshot_width"; } - /*virtual*/ std::string getHeightSpinnerName() const { return "inventory_snapshot_height"; } - /*virtual*/ std::string getAspectRatioCBName() const { return "inventory_keep_aspect_check"; } - /*virtual*/ std::string getImageSizeComboName() const { return "texture_size_combo"; } - /*virtual*/ std::string getImageSizePanelName() const { return LLStringUtil::null; } - /*virtual*/ void updateControls(const LLSD& info); - -}; - -class LLPanelOutfitSnapshotInventory - : public LLPanelSnapshotInventoryBase -{ - LOG_CLASS(LLPanelOutfitSnapshotInventory); - -public: - LLPanelOutfitSnapshotInventory(); - /*virtual*/ bool postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + std::string getWidthSpinnerName() const override { return "inventory_snapshot_width"; } + std::string getHeightSpinnerName() const override { return "inventory_snapshot_height"; } + std::string getAspectRatioCBName() const override { return "inventory_keep_aspect_check"; } + std::string getImageSizeComboName() const override { return "texture_size_combo"; } + std::string getImageSizePanelName() const override { return LLStringUtil::null; } + LLSnapshotModel::ESnapshotType getSnapshotType() override; + void updateControls(const LLSD& info) override; -private: - /*virtual*/ std::string getWidthSpinnerName() const { return ""; } - /*virtual*/ std::string getHeightSpinnerName() const { return ""; } - /*virtual*/ std::string getAspectRatioCBName() const { return ""; } - /*virtual*/ std::string getImageSizeComboName() const { return "texture_size_combo"; } - /*virtual*/ std::string getImageSizePanelName() const { return LLStringUtil::null; } - /*virtual*/ void updateControls(const LLSD& info); - - /*virtual*/ void cancel(); + void onSend(); + void updateUploadCost(); + S32 calculateUploadCost(); }; static LLPanelInjector<LLPanelSnapshotInventory> panel_class1("llpanelsnapshotinventory"); -static LLPanelInjector<LLPanelOutfitSnapshotInventory> panel_class2("llpaneloutfitsnapshotinventory"); - -LLPanelSnapshotInventoryBase::LLPanelSnapshotInventoryBase() -{ -} - -bool LLPanelSnapshotInventoryBase::postBuild() -{ - return LLPanelSnapshot::postBuild(); -} - -LLSnapshotModel::ESnapshotType LLPanelSnapshotInventoryBase::getSnapshotType() +LLSnapshotModel::ESnapshotType LLPanelSnapshotInventory::getSnapshotType() { return LLSnapshotModel::SNAPSHOT_TEXTURE; } @@ -130,12 +88,14 @@ bool LLPanelSnapshotInventory::postBuild() getChild<LLSpinCtrl>(getHeightSpinnerName())->setAllowEdit(false); getChild<LLUICtrl>(getImageSizeComboName())->setCommitCallback(boost::bind(&LLPanelSnapshotInventory::onResolutionCommit, this, _1)); - return LLPanelSnapshotInventoryBase::postBuild(); + return LLPanelSnapshot::postBuild(); } // virtual void LLPanelSnapshotInventory::onOpen(const LLSD& key) { + updateUploadCost(); + LLPanelSnapshot::onOpen(key); } @@ -144,6 +104,8 @@ void LLPanelSnapshotInventory::updateControls(const LLSD& info) { const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true; getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot); + + updateUploadCost(); } void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl) @@ -153,21 +115,9 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl) getChild<LLSpinCtrl>(getHeightSpinnerName())->setVisible(!current_window_selected); } -void LLPanelSnapshotInventoryBase::onSend() +void LLPanelSnapshotInventory::onSend() { - S32 w = 0; - S32 h = 0; - - if( mSnapshotFloater ) - { - LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView(); - if( preview ) - { - preview->getSize(w, h); - } - } - - S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(w, h); + S32 expected_upload_cost = calculateUploadCost(); if (can_afford_transaction(expected_upload_cost)) { if (mSnapshotFloater) @@ -188,36 +138,24 @@ void LLPanelSnapshotInventoryBase::onSend() } } -LLPanelOutfitSnapshotInventory::LLPanelOutfitSnapshotInventory() +void LLPanelSnapshotInventory::updateUploadCost() { - mCommitCallbackRegistrar.add("Inventory.SaveOutfitPhoto", boost::bind(&LLPanelOutfitSnapshotInventory::onSend, this)); - mCommitCallbackRegistrar.add("Inventory.SaveOutfitCancel", boost::bind(&LLPanelOutfitSnapshotInventory::cancel, this)); + getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", calculateUploadCost())); } -// virtual -bool LLPanelOutfitSnapshotInventory::postBuild() +S32 LLPanelSnapshotInventory::calculateUploadCost() { - return LLPanelSnapshotInventoryBase::postBuild(); -} - -// virtual -void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key) -{ - getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLAgentBenefitsMgr::current().getTextureUploadCost())); - LLPanelSnapshot::onOpen(key); -} - -// virtual -void LLPanelOutfitSnapshotInventory::updateControls(const LLSD& info) -{ - const bool have_snapshot = info.has("have-snapshot") ? info["have-snapshot"].asBoolean() : true; - getChild<LLUICtrl>("save_btn")->setEnabled(have_snapshot); -} + S32 w = 0; + S32 h = 0; -void LLPanelOutfitSnapshotInventory::cancel() -{ if (mSnapshotFloater) { - mSnapshotFloater->closeFloater(); + if (LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView()) + { + w = preview->getEncodedImageWidth(); + h = preview->getEncodedImageHeight(); + } } + + return LLAgentBenefitsMgr::current().getTextureUploadCost(w, h); } diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp index 366030c0fa..57759fbcaa 100644 --- a/indra/newview/llpanelsnapshotlocal.cpp +++ b/indra/newview/llpanelsnapshotlocal.cpp @@ -47,18 +47,18 @@ class LLPanelSnapshotLocal public: LLPanelSnapshotLocal(); - /*virtual*/ bool postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + bool postBuild() override; + void onOpen(const LLSD& key) override; private: - /*virtual*/ std::string getWidthSpinnerName() const { return "local_snapshot_width"; } - /*virtual*/ std::string getHeightSpinnerName() const { return "local_snapshot_height"; } - /*virtual*/ std::string getAspectRatioCBName() const { return "local_keep_aspect_check"; } - /*virtual*/ std::string getImageSizeComboName() const { return "local_size_combo"; } - /*virtual*/ std::string getImageSizePanelName() const { return "local_image_size_lp"; } - /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const; - /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); - /*virtual*/ void updateControls(const LLSD& info); + std::string getWidthSpinnerName() const override { return "local_snapshot_width"; } + std::string getHeightSpinnerName() const override { return "local_snapshot_height"; } + std::string getAspectRatioCBName() const override { return "local_keep_aspect_check"; } + std::string getImageSizeComboName() const override { return "local_size_combo"; } + std::string getImageSizePanelName() const override { return "local_image_size_lp"; } + LLSnapshotModel::ESnapshotFormat getImageFormat() const override; + LLSnapshotModel::ESnapshotType getSnapshotType() override; + void updateControls(const LLSD& info) override; S32 mLocalFormat; diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp index 962d3bba16..05cd9e7b3a 100644 --- a/indra/newview/llpanelsnapshotoptions.cpp +++ b/indra/newview/llpanelsnapshotoptions.cpp @@ -30,12 +30,8 @@ #include "llsidetraypanelcontainer.h" #include "llfloatersnapshot.h" // FIXME: create a snapshot model -#include "llsnapshotlivepreview.h" #include "llfloaterreg.h" -#include "llagentbenefits.h" - - /** * Provides several ways to save a snapshot. */ @@ -46,12 +42,9 @@ class LLPanelSnapshotOptions public: LLPanelSnapshotOptions(); - ~LLPanelSnapshotOptions(); - /*virtual*/ bool postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + bool postBuild() override; private: - void updateUploadCost(); void openPanel(const std::string& panel_name); void onSaveToProfile(); void onSaveToEmail(); @@ -71,10 +64,6 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions() mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this)); } -LLPanelSnapshotOptions::~LLPanelSnapshotOptions() -{ -} - // virtual bool LLPanelSnapshotOptions::postBuild() { @@ -82,30 +71,6 @@ bool LLPanelSnapshotOptions::postBuild() return LLPanel::postBuild(); } -// virtual -void LLPanelSnapshotOptions::onOpen(const LLSD& key) -{ - updateUploadCost(); -} - -void LLPanelSnapshotOptions::updateUploadCost() -{ - S32 w = 0; - S32 h = 0; - - if( mSnapshotFloater ) - { - LLSnapshotLivePreview* preview = mSnapshotFloater->getPreviewView(); - if( preview ) - { - preview->getSize(w, h); - } - } - - S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(w, h); - getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost)); -} - void LLPanelSnapshotOptions::openPanel(const std::string& panel_name) { LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp index 23e8789e3f..f3dfdc9250 100644 --- a/indra/newview/llpanelsnapshotpostcard.cpp +++ b/indra/newview/llpanelsnapshotpostcard.cpp @@ -56,18 +56,18 @@ class LLPanelSnapshotPostcard public: LLPanelSnapshotPostcard(); - /*virtual*/ bool postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + bool postBuild() override; + void onOpen(const LLSD& key) override; private: - /*virtual*/ std::string getWidthSpinnerName() const { return "postcard_snapshot_width"; } - /*virtual*/ std::string getHeightSpinnerName() const { return "postcard_snapshot_height"; } - /*virtual*/ std::string getAspectRatioCBName() const { return "postcard_keep_aspect_check"; } - /*virtual*/ std::string getImageSizeComboName() const { return "postcard_size_combo"; } - /*virtual*/ std::string getImageSizePanelName() const { return "postcard_image_size_lp"; } - /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; } - /*virtual*/ LLSnapshotModel::ESnapshotType getSnapshotType(); - /*virtual*/ void updateControls(const LLSD& info); + std::string getWidthSpinnerName() const override { return "postcard_snapshot_width"; } + std::string getHeightSpinnerName() const override { return "postcard_snapshot_height"; } + std::string getAspectRatioCBName() const override { return "postcard_keep_aspect_check"; } + std::string getImageSizeComboName() const override { return "postcard_size_combo"; } + std::string getImageSizePanelName() const override { return "postcard_image_size_lp"; } + LLSnapshotModel::ESnapshotFormat getImageFormat() const override { return LLSnapshotModel::SNAPSHOT_FORMAT_JPEG; } + LLSnapshotModel::ESnapshotType getSnapshotType() override; + void updateControls(const LLSD& info) override; bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response); static void sendPostcardFinished(LLSD result); diff --git a/indra/newview/llpanelsnapshotprofile.cpp b/indra/newview/llpanelsnapshotprofile.cpp index aa257dea9e..b533d7bbbc 100644 --- a/indra/newview/llpanelsnapshotprofile.cpp +++ b/indra/newview/llpanelsnapshotprofile.cpp @@ -49,17 +49,17 @@ class LLPanelSnapshotProfile public: LLPanelSnapshotProfile(); - /*virtual*/ bool postBuild(); - /*virtual*/ void onOpen(const LLSD& key); + bool postBuild() override; + void onOpen(const LLSD& key) override; private: - /*virtual*/ std::string getWidthSpinnerName() const { return "profile_snapshot_width"; } - /*virtual*/ std::string getHeightSpinnerName() const { return "profile_snapshot_height"; } - /*virtual*/ std::string getAspectRatioCBName() const { return "profile_keep_aspect_check"; } - /*virtual*/ std::string getImageSizeComboName() const { return "profile_size_combo"; } - /*virtual*/ std::string getImageSizePanelName() const { return "profile_image_size_lp"; } - /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat() const { return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; } - /*virtual*/ void updateControls(const LLSD& info); + std::string getWidthSpinnerName() const override { return "profile_snapshot_width"; } + std::string getHeightSpinnerName() const override { return "profile_snapshot_height"; } + std::string getAspectRatioCBName() const override { return "profile_keep_aspect_check"; } + std::string getImageSizeComboName() const override { return "profile_size_combo"; } + std::string getImageSizePanelName() const override { return "profile_image_size_lp"; } + LLSnapshotModel::ESnapshotFormat getImageFormat() const override { return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; } + void updateControls(const LLSD& info) override; void onSend(); }; diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp index c1534c9abd..3aedde74c6 100644 --- a/indra/newview/llpanelwearing.cpp +++ b/indra/newview/llpanelwearing.cpp @@ -113,6 +113,7 @@ protected: boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); registrar.add("Wearing.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs, no_op)); + registrar.add("Wearing.Favorite", boost::bind(toggle_favorites, mUUIDs)); LLContextMenu* menu = createFromFile("menu_wearing_tab.xml"); updateMenuItemsVisibility(menu); @@ -125,6 +126,8 @@ protected: bool bp_selected = false; // true if body parts selected bool clothes_selected = false; bool attachments_selected = false; + bool can_favorite = false; + bool can_unfavorite = false; // See what types of wearables are selected. for (uuid_vec_t::const_iterator it = mUUIDs.begin(); it != mUUIDs.end(); ++it) @@ -137,6 +140,9 @@ protected: continue; } + LLUUID linked_id = item->getLinkedUUID(); + LLViewerInventoryItem* linked_item = gInventory.getItem(linked_id); + LLAssetType::EType type = item->getType(); if (type == LLAssetType::AT_CLOTHING) { @@ -150,6 +156,8 @@ protected: { attachments_selected = true; } + can_favorite |= !linked_item->getIsFavorite(); + can_unfavorite |= linked_item->getIsFavorite(); } // Enable/disable some menu items depending on the selection. @@ -166,6 +174,8 @@ protected: menu->setItemVisible("detach", allow_detach); menu->setItemVisible("edit_outfit_separator", show_touch | show_edit | allow_take_off || allow_detach); menu->setItemVisible("show_original", mUUIDs.size() == 1); + menu->setItemVisible("favorites_add", can_favorite); + menu->setItemVisible("favorites_remove", can_unfavorite); } }; @@ -232,6 +242,10 @@ LLPanelWearing::~LLPanelWearing() { mAttachmentsChangedConnection.disconnect(); } + if (mGearMenuConnection.connected()) + { + mGearMenuConnection.disconnect(); + } } bool LLPanelWearing::postBuild() @@ -249,10 +263,6 @@ bool LLPanelWearing::postBuild() mTempItemsList->setFgUnselectedColor(LLColor4::white); mTempItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onTempAttachmentsListRightClick, this, _1, _2, _3)); - LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); - - menu_gear_btn->setMenu(mGearMenu->getMenu()); - return true; } @@ -560,6 +570,16 @@ void LLPanelWearing::onRemoveAttachment() } } +LLToggleableMenu* LLPanelWearing::getGearMenu() +{ + return mGearMenu->getMenu(); +} + +LLToggleableMenu* LLPanelWearing::getSortMenu() +{ + return NULL; +} + void LLPanelWearing::onRemoveItem() { if (mWearablesTab->isExpanded()) diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h index ea0787d0ef..aa80a3fc21 100644 --- a/indra/newview/llpanelwearing.h +++ b/indra/newview/llpanelwearing.h @@ -84,6 +84,11 @@ public: void onEditAttachment(); void onRemoveAttachment(); + void updateMenuItemsVisibility() {}; + LLToggleableMenu* getGearMenu(); + LLToggleableMenu* getSortMenu(); + bool getTrashMenuVisible() { return false; } + private: void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); void onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); @@ -93,6 +98,7 @@ private: LLWearableItemsList* mCOFItemsList; LLScrollListCtrl* mTempItemsList; LLWearingGearMenu* mGearMenu; + boost::signals2::connection mGearMenuConnection; LLListContextMenu* mContextMenu; LLListContextMenu* mAttachmentsMenu; diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 86291708b0..e5c84728fe 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -646,18 +646,17 @@ bool LLPhysicsMotion::onUpdate(F32 time) velocity_new_local = 0; } - // Check for NaN values. A NaN value is detected if the variables doesn't equal itself. - // If NaN, then reset everything. - if ((mPosition_local != mPosition_local) || - (mVelocity_local != mVelocity_local) || - (position_new_local != position_new_local)) + // Check for NaN values. If NaN, then reset everything. + if (llisnan(mPosition_local) || + llisnan(mVelocity_local) || + llisnan(position_new_local)) { - position_new_local = 0; - mVelocity_local = 0; - mVelocityJoint_local = 0; - mAccelerationJoint_local = 0; - mPosition_local = 0; - mPosition_world = LLVector3(0,0,0); + position_new_local = 0.f; + mVelocity_local = 0.f; + mVelocityJoint_local = 0.f; + mAccelerationJoint_local = 0.f; + mPosition_local = 0.f; + mPosition_world = LLVector3(0.f,0.f,0.f); } const F32 position_new_local_clamped = llclamp(position_new_local, diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 02a4c7fb26..c2aa4925bd 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -703,9 +703,10 @@ void LLScriptEdCore::sync() } } -bool LLScriptEdCore::hasChanged() +bool LLScriptEdCore::hasChanged() const { - if (!mEditor) return false; + if (!mEditor) + return false; return ((!mEditor->isPristine() || mEnableSave) && mHasScriptData); } diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 70ee1a4274..0bbe540207 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -143,7 +143,7 @@ public: void setItemRemoved(bool script_removed){mScriptRemoved = script_removed;}; void setAssetID( const LLUUID& asset_id){ mAssetID = asset_id; }; - LLUUID getAssetID() { return mAssetID; } + LLUUID getAssetID() const { return mAssetID; } bool isFontSizeChecked(const LLSD &userdata); void onChangeFontSize(const LLSD &size_name); @@ -155,7 +155,7 @@ public: void onBtnDynamicHelp(); void onBtnUndoChanges(); - bool hasChanged(); + bool hasChanged() const; void selectFirstError(); @@ -211,7 +211,6 @@ class LLScriptEdContainer : public LLPreview public: LLScriptEdContainer(const LLSD& key); - LLScriptEdContainer(const LLSD& key, const bool live); bool handleKeyHere(KEY key, MASK mask); diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 910509928d..7f5076bd56 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -177,7 +177,7 @@ void LLReflectionMap::autoAdjustOrigin() mPriority = 1; mOrigin.load3(mViewerObject->getPositionAgent().mV); - if (mViewerObject->getVolume() && ((LLVOVolume*)mViewerObject)->getReflectionProbeIsBox()) + if (mViewerObject->getVolume() && ((LLVOVolume*)mViewerObject.get())->getReflectionProbeIsBox()) { LLVector3 s = mViewerObject->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); mRadius = s.magVec(); diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index d20bba7059..8da18e0945 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -124,7 +124,7 @@ public: LLSpatialGroup* mGroup = nullptr; // viewer object this probe is tracking (if any) - LLViewerObject* mViewerObject = nullptr; + LLPointer<LLViewerObject> mViewerObject; // what priority should this probe have (higher is higher priority) // currently only 0 or 1 diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 713acde887..0cb1444393 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -1150,7 +1150,7 @@ void LLReflectionMapManager::updateUniforms() { if (refmap->mViewerObject && refmap->mViewerObject->getVolume()) { // have active manual probes live-track the object they're associated with - LLVOVolume* vobj = (LLVOVolume*)refmap->mViewerObject; + LLVOVolume* vobj = (LLVOVolume*)refmap->mViewerObject.get(); refmap->mOrigin.load3(vobj->getPositionAgent().mV); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index be1e64ce54..01fd5ae63c 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -252,6 +252,7 @@ LLSelectMgr::LLSelectMgr() LLSelectMgr::~LLSelectMgr() { clearSelections(); + mSlectionLodModChangedConnection.disconnect(); } void LLSelectMgr::clearSelections() @@ -2248,6 +2249,7 @@ void LLSelectMgr::selectionRevertGLTFMaterials() { // Restore base material LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te]; + LLUUID old_asset_id = objectp->getRenderMaterialID(te); // Update material locally objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/); @@ -2258,18 +2260,29 @@ void LLSelectMgr::selectionRevertGLTFMaterials() objectp->setTEGLTFMaterialOverride(te, material); } - // Enqueue update to server - if (asset_id.notNull() && material) + if (asset_id.isNull() || !material) + { + //blank override out + LLGLTFMaterialList::queueApply(objectp, te, asset_id); + } + if (old_asset_id != asset_id) { // Restore overrides and base material + // Note: might not work reliably if asset is already there, might + // have a server sided problem where servers applies override + // first then resets it by adding asset, in which case need + // to create a server ticket and chain asset then override + // application. LLGLTFMaterialList::queueApply(objectp, te, asset_id, material); } else { - //blank override out - LLGLTFMaterialList::queueApply(objectp, te, asset_id); + // Enqueue override update to server + // Note: this is suboptimal, better to send asset id as well + // but there seems to be a server problem with queueApply + // that ignores override in some cases + LLGLTFMaterialList::queueModify(objectp, te, material); } - } return true; } @@ -3142,36 +3155,43 @@ void LLSelectMgr::adjustTexturesByScale(bool send_to_sim, bool stretch) F32 offset_x = 0; F32 offset_y = 0; - for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + if (te_num < selectNode->mGLTFScaleRatios.size()) { - LLVector3 scale_ratio = selectNode->mGLTFScaleRatios[te_num][i]; - - if (planar) - { - scale_x = scale_ratio.mV[s_axis] / object_scale.mV[s_axis]; - scale_y = scale_ratio.mV[t_axis] / object_scale.mV[t_axis]; - } - else - { - scale_x = scale_ratio.mV[s_axis] * object_scale.mV[s_axis]; - scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; - } - material->mTextureTransform[i].mScale.set(scale_x, scale_y); - - LLVector2 scales = selectNode->mGLTFScales[te_num][i]; - LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; - F64 int_part = 0; - offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); - if (offset_x < 0) - { - offset_x++; - } - offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); - if (offset_y < 0) + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) { - offset_y++; + LLVector3 scale_ratio = selectNode->mGLTFScaleRatios[te_num][i]; + + if (planar) + { + scale_x = scale_ratio.mV[s_axis] / object_scale.mV[s_axis]; + scale_y = scale_ratio.mV[t_axis] / object_scale.mV[t_axis]; + } + else + { + scale_x = scale_ratio.mV[s_axis] * object_scale.mV[s_axis]; + scale_y = scale_ratio.mV[t_axis] * object_scale.mV[t_axis]; + } + material->mTextureTransform[i].mScale.set(scale_x, scale_y); + + LLVector2 scales = selectNode->mGLTFScales[te_num][i]; + LLVector2 offsets = selectNode->mGLTFOffsets[te_num][i]; + F64 int_part = 0; + offset_x = (F32)modf((offsets[VX] + (scales[VX] - scale_x)) / 2, &int_part); + if (offset_x < 0) + { + offset_x++; + } + offset_y = (F32)modf((offsets[VY] + (scales[VY] - scale_y)) / 2, &int_part); + if (offset_y < 0) + { + offset_y++; + } + material->mTextureTransform[i].mOffset.set(offset_x, offset_y); } - material->mTextureTransform[i].mOffset.set(offset_x, offset_y); + } + else + { + llassert(false); // make sure mGLTFScaleRatios is filled } const LLGLTFMaterial* base_material = tep->getGLTFMaterial(); @@ -6927,7 +6947,6 @@ void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query) if (mObject.notNull()) { - LLVector3 scale = mObject->getScale(); for (U8 i = 0; i < mObject->getNumTEs(); i++) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 792a37297f..11aad3b806 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -943,6 +943,7 @@ private: bool mForceSelection; std::vector<LLAnimPauseRequest> mPauseRequests; + boost::signals2::connection mSlectionLodModChangedConnection; }; // *DEPRECATED: For callbacks or observers, use diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index c618483fc4..1d1b31d2a6 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -40,6 +40,7 @@ #include "llfloaterworldmap.h" #include "llfolderviewmodel.h" #include "llloadingindicator.h" +#include "llmenubutton.h" #include "lloutfitobserver.h" #include "llpaneleditwearable.h" #include "llpaneloutfitsinventory.h" @@ -145,6 +146,14 @@ bool LLSidepanelAppearance::postBuild() setWearablesLoading(gAgentWearables.isCOFChangeInProgress()); + + LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn"); + LLMenuButton* menu_sort_btn = getChild<LLMenuButton>("sorting_menu_btn"); + LLButton* menu_trash_btn = getChild<LLButton>("trash_btn"); + LLPanel* menu_sort_btn_panel = getChild<LLPanel>("options_sort_btn_panel"); + LLPanel* menu_trash_btn_panel = getChild<LLPanel>("trash_btn_panel"); + mPanelOutfitsInventory->setMenuButtons(menu_gear_btn, menu_sort_btn, menu_trash_btn, menu_sort_btn_panel, menu_trash_btn_panel); + return true; } diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index fccf745a74..3d4b4fb9c1 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -56,6 +56,8 @@ #include "llviewerregion.h" +const char* const DEFAULT_DESC = "(No Description)"; + class PropertiesChangedCallback : public LLInventoryCallback { public: @@ -128,6 +130,7 @@ LLSidepanelItemInfo::LLSidepanelItemInfo(const LLPanel::Params& p) , mUpdatePendingId(-1) , mIsDirty(false) /*Not ready*/ , mParentFloater(NULL) + , mLabelItemDesc(NULL) { gInventory.addObserver(this); gIdleCallbacks.addFunction(&LLSidepanelItemInfo::onIdle, (void*)this); @@ -158,10 +161,11 @@ bool LLSidepanelItemInfo::postBuild() mItemTypeIcon = getChild<LLIconCtrl>("item_type_icon"); mLabelOwnerName = getChild<LLTextBox>("LabelOwnerName"); mLabelCreatorName = getChild<LLTextBox>("LabelCreatorName"); + mLabelItemDesc = getChild<LLTextEditor>("LabelItemDesc"); getChild<LLLineEditor>("LabelItemName")->setPrevalidate(&LLTextValidate::validateASCIIPrintableNoPipe); getChild<LLUICtrl>("LabelItemName")->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onCommitName,this)); - getChild<LLUICtrl>("LabelItemDesc")->setCommitCallback(boost::bind(&LLSidepanelItemInfo:: onCommitDescription, this)); + mLabelItemDesc->setCommitCallback(boost::bind(&LLSidepanelItemInfo:: onCommitDescription, this)); // Thumnail edition mChangeThumbnailBtn->setCommitCallback(boost::bind(&LLSidepanelItemInfo::onEditThumbnail, this)); // acquired date @@ -923,17 +927,22 @@ void LLSidepanelItemInfo::onCommitDescription() LLViewerInventoryItem* item = findItem(); if(!item) return; - LLTextEditor* labelItemDesc = getChild<LLTextEditor>("LabelItemDesc"); - if(!labelItemDesc) + if(!mLabelItemDesc) + { + return; + } + if (!gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE)) { return; } - if((item->getDescription() != labelItemDesc->getText()) && - (gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE))) + std::string old_desc = item->getDescription(); + std::string new_desc = mLabelItemDesc->getText(); + if(old_desc != new_desc) { + mLabelItemDesc->setSelectAllOnFocusReceived(false); LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - new_item->setDescription(labelItemDesc->getText()); + new_item->setDescription(new_desc); onCommitChanges(new_item); } } diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h index 718edc79d6..0895d3360c 100644 --- a/indra/newview/llsidepaneliteminfo.h +++ b/indra/newview/llsidepaneliteminfo.h @@ -46,6 +46,7 @@ class LLObjectInventoryObserver; class LLViewerObject; class LLPermissions; class LLTextBox; +class LLTextEditor; class LLSidepanelItemInfo : public LLPanel, public LLInventoryObserver { @@ -105,6 +106,7 @@ private: LLIconCtrl* mItemTypeIcon; LLTextBox* mLabelOwnerName; LLTextBox* mLabelCreatorName; + LLTextEditor* mLabelItemDesc; // // UI Elements diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index cee43f3cff..223fc2a8f5 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -116,8 +116,8 @@ void LLSkinningUtil::scrubInvalidJoints(LLVOAvatar *avatar, LLMeshSkinInfo* skin // needed for handling of any legacy bad data. if (!avatar->getJoint(skin->mJointNames[j])) { - LL_DEBUGS("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint " << skin->mJointNames[j] << LL_ENDL; - LL_WARNS_ONCE("Avatar") << avatar->getFullname() << " mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL; + LL_DEBUGS("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint " << skin->mJointNames[j] << LL_ENDL; + LL_WARNS_ONCE("Avatar") << avatar->getDebugName() << " mesh rigged to invalid joint" << skin->mJointNames[j] << LL_ENDL; skin->mJointNames[j] = "mPelvis"; skin->mJointNumsInitialized = false; // force update after names change. } @@ -135,6 +135,12 @@ void LLSkinningUtil::initSkinningMatrixPalette( initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar); + if (skin->mInvBindMatrix.size() < count ) + { + // faulty model? mInvBindMatrix.size() should have matched mJointNames.size() + return; + } + LLMatrix4a world[LL_CHARACTER_MAX_ANIMATED_JOINTS]; for (S32 j = 0; j < count; ++j) @@ -354,7 +360,8 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a { rig_info_tab[joint_num].setIsRiggedTo(true); - const LLMatrix4a& mat = skin->mBindPoseMatrix[joint_index]; + size_t bind_poses_size = skin->mBindPoseMatrix.size(); + const LLMatrix4a& mat = bind_poses_size > joint_index ? skin->mBindPoseMatrix[joint_index] : LLMatrix4a::identity(); LLVector4a pos_joint_space; mat.affineTransform(pos, pos_joint_space); diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index 32599dcee2..d06f181357 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -28,7 +28,6 @@ #define LL_LLSKY_H #include "llmath.h" -//#include "vmath.h" #include "v3math.h" #include "v4math.h" #include "v4color.h" diff --git a/indra/newview/llslurl.cpp b/indra/newview/llslurl.cpp index 9e567e3262..6238a1145c 100644 --- a/indra/newview/llslurl.cpp +++ b/indra/newview/llslurl.cpp @@ -71,10 +71,10 @@ LLSLURL::LLSLURL(const std::string& slurl) { LLURI slurl_uri; // parse the slurl as a uri - if (slurl.find(':') == std::string::npos) + if (slurl.find("://") == std::string::npos) { - // There may be no scheme ('secondlife:' etc.) passed in. In that case - // we want to normalize the slurl by putting the appropriate scheme + // There may be no scheme ('secondlife://', 'https://' etc.) passed in. In that + // case we want to normalize the slurl by putting the appropriate scheme // in front of the slurl. So, we grab the appropriate slurl base // from the grid manager which may be http://slurl.com/secondlife/ for maingrid, or // https://<hostname>/region/ for Standalone grid (the word region, not the region name) diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 68b4ab381a..9b6a87e68d 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -1068,7 +1068,7 @@ void LLSnapshotLivePreview::saveTexture(bool outfit_snapshot, std::string name) tid, LLAssetType::AT_TEXTURE, res_name, res_desc, 0, folder_type, inv_type, PERM_ALL, LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost, !outfit_snapshot)); + expected_upload_cost, LLUUID::null, !outfit_snapshot)); upload_new_resource(assetUploadInfo); diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index 4956c188fb..b49c0119ed 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -1026,6 +1026,10 @@ void LLLocalSpeakerMgr::updateSpeakerList() uuid_vec_t avatar_ids; std::vector<LLVector3d> positions; LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), CHAT_NORMAL_RADIUS); +#ifdef LL_DISCORD + if (gSavedSettings.getBOOL("EnableDiscord")) + LLAppViewer::updateDiscordPartyCurrentSize((S32)avatar_ids.size()); +#endif for(U32 i=0; i<avatar_ids.size(); i++) { setSpeaker(avatar_ids[i]); diff --git a/indra/newview/llsprite.h b/indra/newview/llsprite.h index 44439bd30c..d6e8e37ec9 100644 --- a/indra/newview/llsprite.h +++ b/indra/newview/llsprite.h @@ -27,8 +27,6 @@ #ifndef LL_LLSPRITE_H #define LL_LLSPRITE_H -////#include "vmath.h" -//#include "llmath.h" #include "v3math.h" #include "v4math.h" #include "v4color.h" diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 3973036cc6..ba7437798a 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -342,13 +342,11 @@ void pump_idle_startup_network(void) { // while there are message to process: // process one then call display_startup() - S32 num_messages = 0; { LockMessageChecker lmc(gMessageSystem); while (lmc.checkAllMessages(gFrameCount, gServicePump)) { display_startup(); - ++num_messages; } lmc.processAcks(); } @@ -724,6 +722,10 @@ bool idle_startup() LL_WARNS("AppInit") << "Unreliable timers detected (may be bad PCI chipset)!!" << LL_ENDL; } +#ifdef LL_DISCORD + LLAppViewer::initDiscordSocial(); +#endif + // // Log on to system // @@ -2103,9 +2105,6 @@ bool idle_startup() do_startup_frame(); - // We're successfully logged in. - gSavedSettings.setBOOL("FirstLoginThisInstall", false); - LLFloaterReg::showInitialVisibleInstances(); LLFloaterGridStatus::getInstance()->startGridStatusTimer(); @@ -2451,6 +2450,27 @@ bool idle_startup() LLPerfStats::StatsRecorder::setAutotuneInit(); + // Display Avatar Welcome Pack the first time a user logs in + // (or clears their settings....) + if (gSavedSettings.getBOOL("FirstLoginThisInstall")) + { + LLFloater* avatar_welcome_pack_floater = LLFloaterReg::findInstance("avatar_welcome_pack"); + if (avatar_welcome_pack_floater != nullptr) + { + // There is a (very - 1 in ~50 times) hard to repro bug where the login + // page is not hidden when the AWP floater is presented. This (agressive) + // approach to always close it seems like the best fix for now. + LLPanelLogin::closePanel(); + + avatar_welcome_pack_floater->setVisible(true); + } + } + + //// We're successfully logged in. + // 2025-06 Moved lower down in the state machine so the Avatar Welcome Pack + // floater display can be triggered correctly. + gSavedSettings.setBOOL("FirstLoginThisInstall", false); + return true; } @@ -3566,7 +3586,7 @@ bool process_login_success_response() // Agent id needed for parcel info request in LLUrlEntryParcel // to resolve parcel name. - LLUrlEntryParcel::setAgentID(gAgentID); + LLUrlEntryBase::setAgentID(gAgentID); text = response["session_id"].asString(); if(!text.empty()) gAgentSessionID.set(text); @@ -3884,25 +3904,7 @@ bool process_login_success_response() LLViewerMedia::getInstance()->openIDSetup(openid_url, openid_token); } - - // Only save mfa_hash for future logins if the user wants their info remembered. - if(response.has("mfa_hash") - && gSavedSettings.getBOOL("RememberUser") - && LLLoginInstance::getInstance()->saveMFA()) - { - std::string grid(LLGridManager::getInstance()->getGridId()); - std::string user_id(gUserCredential->userID()); - gSecAPIHandler->addToProtectedMap("mfa_hash", grid, user_id, response["mfa_hash"]); - // TODO(brad) - related to SL-17223 consider building a better interface that sync's automatically - gSecAPIHandler->syncProtectedMap(); - } - else if (!LLLoginInstance::getInstance()->saveMFA()) - { - std::string grid(LLGridManager::getInstance()->getGridId()); - std::string user_id(gUserCredential->userID()); - gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id); - gSecAPIHandler->syncProtectedMap(); - } + LLLoginInstance::getInstance()->saveMFAHash(response); bool success = false; // JC: gesture loading done below, when we have an asset system diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 8aa2058ae1..bb93e2e79e 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -114,6 +114,8 @@ LLStatusBar::LLStatusBar(const LLRect& rect) mBtnVolume(NULL), mBoxBalance(NULL), mBalance(0), + mBalanceClicked(false), + mObscureBalance(false), mHealth(100), mSquareMetersCredit(0), mSquareMetersCommitted(0), @@ -125,20 +127,11 @@ LLStatusBar::LLStatusBar(const LLRect& rect) // status bar can possible overlay menus? setMouseOpaque(false); - mBalanceTimer = new LLFrameTimer(); - mHealthTimer = new LLFrameTimer(); - buildFromFile("panel_status_bar.xml"); } LLStatusBar::~LLStatusBar() { - delete mBalanceTimer; - mBalanceTimer = NULL; - - delete mHealthTimer; - mHealthTimer = NULL; - // LLView destructor cleans up children } @@ -171,7 +164,8 @@ bool LLStatusBar::postBuild() getChild<LLUICtrl>("goShop")->setCommitCallback(boost::bind(&LLWeb::loadURL, gSavedSettings.getString("MarketplaceURL"), LLStringUtil::null, LLStringUtil::null)); mBoxBalance = getChild<LLTextBox>("balance"); - mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this ); + mBoxBalance->setClickedCallback(&LLStatusBar::onClickRefreshBalance, this); + mBoxBalance->setDoubleClickCallback([this](LLUICtrl*, S32 x, S32 y, MASK mask) { onClickToggleBalance(); }); mIconPresetsCamera = getChild<LLIconCtrl>( "presets_icon_camera" ); mIconPresetsCamera->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterPresetsCamera, this)); @@ -191,12 +185,14 @@ bool LLStatusBar::postBuild() gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&LLStatusBar::onVolumeChanged, this, _2)); gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLStatusBar::onVoiceChanged, this, _2)); + gSavedSettings.getControl("ObscureBalanceInStatusBar")->getSignal()->connect(boost::bind(&LLStatusBar::onObscureBalanceChanged, this, _2)); if (!gSavedSettings.getBOOL("EnableVoiceChat") && LLAppViewer::instance()->isSecondInstance()) { // Indicate that second instance started without sound mBtnVolume->setImageUnselected(LLUI::getUIImage("VoiceMute_Off")); } + mObscureBalance = gSavedSettings.getBOOL("ObscureBalanceInStatusBar"); // Adding Net Stat Graph S32 x = getRect().getWidth() - 2; @@ -319,6 +315,12 @@ void LLStatusBar::refresh() mTextTime->setToolTip (dtStr); } + if (mBalanceClicked && mBalanceClickTimer.getElapsedTimeF32() > 1.f) + { + mBalanceClicked = false; + sendMoneyBalanceRequest(); + } + LLRect r; const S32 MENU_RIGHT = gMenuBarView->getRightmostMenuEdge(); @@ -384,9 +386,17 @@ void LLStatusBar::setBalance(S32 balance) std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance ); LLStringUtil::format_map_t string_args; - string_args["[AMT]"] = llformat("%s", money_str.c_str()); + if (mObscureBalance) + { + string_args["[AMT]"] = "****"; + } + else + { + string_args["[AMT]"] = llformat("%s", money_str.c_str()); + } std::string label_str = getString("buycurrencylabel", string_args); mBoxBalance->setValue(label_str); + mBoxBalance->setToolTipArg(LLStringExplicit("[AMT]"), llformat("%s", money_str.c_str())); updateBalancePanelPosition(); @@ -406,8 +416,6 @@ void LLStatusBar::setBalance(S32 balance) if( balance != mBalance ) { - mBalanceTimer->reset(); - mBalanceTimer->setTimerExpirySec( ICON_TIMER_EXPIRY ); mBalance = balance; } } @@ -459,9 +467,6 @@ void LLStatusBar::setHealth(S32 health) } } } - - mHealthTimer->reset(); - mHealthTimer->setTimerExpirySec( ICON_TIMER_EXPIRY ); } mHealth = health; @@ -621,13 +626,27 @@ static void onClickVolume(void* data) } //static -void LLStatusBar::onClickBalance(void* ) +void LLStatusBar::onClickRefreshBalance(void* data) { - // Force a balance request message: - LLStatusBar::sendMoneyBalanceRequest(); + LLStatusBar* status_bar = (LLStatusBar*)data; + + if (!status_bar->mBalanceClicked) + { + // Schedule a balance request message: + status_bar->mBalanceClicked = true; + status_bar->mBalanceClickTimer.reset(); + } // The refresh of the display (call to setBalance()) will be done by process_money_balance_reply() } +void LLStatusBar::onClickToggleBalance() +{ + mObscureBalance = !mObscureBalance; + gSavedSettings.setBOOL("ObscureBalanceInStatusBar", mObscureBalance); + setBalance(mBalance); + mBalanceClicked = false; // supress click +} + //static void LLStatusBar::onClickMediaToggle(void* data) { @@ -657,6 +676,12 @@ void LLStatusBar::onVoiceChanged(const LLSD& newvalue) refresh(); } +void LLStatusBar::onObscureBalanceChanged(const LLSD& newvalue) +{ + mObscureBalance = newvalue.asBoolean(); + setBalance(mBalance); +} + void LLStatusBar::onUpdateFilterTerm() { LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() ); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 45cbda0ef1..a8fc621ff8 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -72,7 +72,8 @@ public: void debitBalance(S32 debit); void creditBalance(S32 credit); - // Request the latest currency balance from the server + // Request the latest currency balance from the server. + // Reply at process_money_balance_reply() static void sendMoneyBalanceRequest(); void setHealth(S32 percent); @@ -102,6 +103,7 @@ private: void onClickBuyCurrency(); void onVolumeChanged(const LLSD& newvalue); void onVoiceChanged(const LLSD& newvalue); + void onObscureBalanceChanged(const LLSD& newvalue); void onMouseEnterPresetsCamera(); void onMouseEnterPresets(); @@ -109,7 +111,8 @@ private: void onMouseEnterNearbyMedia(); static void onClickMediaToggle(void* data); - static void onClickBalance(void* data); + static void onClickRefreshBalance(void* data); + void onClickToggleBalance(); LLSearchEditor *mFilterEdit; LLPanel *mSearchPanel; @@ -135,11 +138,12 @@ private: LLFrameTimer mClockUpdateTimer; S32 mBalance; + bool mBalanceClicked; + bool mObscureBalance; + LLTimer mBalanceClickTimer; S32 mHealth; S32 mSquareMetersCredit; S32 mSquareMetersCommitted; - LLFrameTimer* mBalanceTimer; - LLFrameTimer* mHealthTimer; LLPanelPresetsCameraPulldown* mPanelPresetsCameraPulldown; LLPanelPresetsPulldown* mPanelPresetsPulldown; LLPanelVolumePulldown* mPanelVolumePulldown; diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 10a104730b..fc72ab7db7 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -27,7 +27,6 @@ #ifndef LL_LLSURFACE_H #define LL_LLSURFACE_H -//#include "vmath.h" #include "v3math.h" #include "v3dmath.h" #include "v4math.h" diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 6f99da5957..875af76c10 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -210,7 +210,6 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 llassert_always(vertex && normal && tex1); U32 surface_stride = mSurfacep->getGridsPerEdge(); - U32 texture_stride = mSurfacep->getGridsPerEdge() - 1; U32 point_offset = x + y*surface_stride; *normal = getNormal(x, y); @@ -223,7 +222,7 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3 // tex0 is used for ownership overlay LLVector3 rel_pos = pos_agent - mSurfacep->getOriginAgent(); - LLVector3 tex_pos = rel_pos * (1.f / (texture_stride * mSurfacep->getMetersPerGrid())); + LLVector3 tex_pos = rel_pos * (1.f / (surface_stride * mSurfacep->getMetersPerGrid())); tex0->mV[0] = tex_pos.mV[0]; tex0->mV[1] = tex_pos.mV[1]; diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index dd7c6aa9e3..e02f76711c 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -127,6 +127,12 @@ void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d S32 removed_index = -1; if (item_iter != mItems.end()) { + // When teleporting via history it's possible that there can be + // an offset applied to the position, so each new teleport can + // be a meter higher than the last. + // Avoid it by preserving original position. + item.mGlobalPos = item_iter->mGlobalPos; + removed_index = (S32)(item_iter - mItems.begin()); mItems.erase(item_iter); } diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index be7653c011..1a7ce74ccc 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1347,27 +1347,40 @@ U32 LLTextureCache::openAndReadEntries(std::vector<Entry>& entries) } for (U32 idx=0; idx<num_entries; idx++) { - Entry entry; - S32 bytes_read = aprfile->read((void*)(&entry), (S32)sizeof(Entry)); - if (bytes_read < sizeof(Entry)) + try + { + Entry entry; + S32 bytes_read = aprfile->read((void*)(&entry), (S32)sizeof(Entry)); + if (bytes_read < sizeof(Entry)) + { + LL_WARNS() << "Corrupted header entries, failed at " << idx << " / " << num_entries << LL_ENDL; + closeHeaderEntriesFile(); + return 0; + } + entries.push_back(entry); + // LL_INFOS() << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << LL_ENDL; + if (entry.mImageSize > entry.mBodySize) + { + mHeaderIDMap[entry.mID] = idx; + mTexturesSizeMap[entry.mID] = entry.mBodySize; + mTexturesSizeTotal += entry.mBodySize; + } + else + { + mFreeList.insert(idx); + } + } + catch (std::bad_alloc&) { - LL_WARNS() << "Corrupted header entries, failed at " << idx << " / " << num_entries << LL_ENDL; + // Too little ram yet very large cache? + // Should this actually crash viewer? + entries.clear(); + LL_WARNS() << "Bad alloc trying to read texture entries from cache, mFreeList: " << (S32)mFreeList.size() + << ", added entries: " << idx << ", total entries: " << num_entries << LL_ENDL; closeHeaderEntriesFile(); purgeAllTextures(false); return 0; } - entries.push_back(entry); -// LL_INFOS() << "ENTRY: " << entry.mTime << " TEX: " << entry.mID << " IDX: " << idx << " Size: " << entry.mImageSize << LL_ENDL; - if(entry.mImageSize > entry.mBodySize) - { - mHeaderIDMap[entry.mID] = idx; - mTexturesSizeMap[entry.mID] = entry.mBodySize; - mTexturesSizeTotal += entry.mBodySize; - } - else - { - mFreeList.insert(idx); - } } closeHeaderEntriesFile(); return num_entries; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 35057a910a..2027e958d5 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -88,7 +88,8 @@ bool get_is_predefined_texture(LLUUID asset_id) || asset_id == DEFAULT_OBJECT_NORMAL || asset_id == BLANK_OBJECT_NORMAL || asset_id == IMG_WHITE - || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) + || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE) + || asset_id == BLANK_MATERIAL_ASSET_ID) { return true; } @@ -163,7 +164,6 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mFallbackImage(fallback_image), mDefaultImageAssetID(default_image_asset_id), mBlankImageAssetID(blank_image_asset_id), - mTentative(tentative), mAllowNoTexture(allow_no_texture), mLabel(label), mTentativeLabel(NULL), @@ -185,8 +185,10 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mSetImageAssetIDCallback(NULL), mOnUpdateImageStatsCallback(NULL), mBakeTextureEnabled(false), + mLocalTextureEnabled(false), mInventoryPickType(pick_type) { + setTentative(tentative); mCanApplyImmediately = can_apply_immediately; buildFromFile("floater_texture_ctrl.xml"); setCanMinimize(false); @@ -198,7 +200,7 @@ LLFloaterTexturePicker::~LLFloaterTexturePicker() void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selection /*=true*/) { - if( ((mImageAssetID != image_id) || mTentative) && mActive) + if( ((mImageAssetID != image_id) || getTentative()) && mActive) { mNoCopyTextureSelected = false; mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? @@ -276,6 +278,7 @@ void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bo asset_id = BLANK_MATERIAL_ASSET_ID; } setImageID(asset_id, set_selection); + setTentative(false); } void LLFloaterTexturePicker::setActive( bool active ) @@ -524,6 +527,8 @@ bool LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask) void LLFloaterTexturePicker::onOpen(const LLSD& key) { if (sLastPickerMode != 0 + && (mLocalTextureEnabled || sLastPickerMode != 1) + && (mBakeTextureEnabled || sLastPickerMode != 2) && mModeSelector->selectByValue(sLastPickerMode)) { changeMode(); @@ -654,7 +659,7 @@ void LLFloaterTexturePicker::draw() bool valid_dims = updateImageStats(); // if we're inactive, gray out "apply immediate" checkbox - mSelectBtn->setEnabled(mActive && mCanApply && valid_dims); + mSelectBtn->setEnabled(mActive && mCanApply && valid_dims && !getTentative()); mPipetteBtn->setEnabled(mActive); mPipetteBtn->setValue(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance()); @@ -719,9 +724,9 @@ void LLFloaterTexturePicker::draw() mTentativeLabel->setVisible( false ); } - mDefaultBtn->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative); - mBlankBtn->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID.notNull()) || mTentative); - mNoneBtn->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative)); + mDefaultBtn->setEnabled(mImageAssetID != mDefaultImageAssetID || getTentative()); + mBlankBtn->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID.notNull()) || getTentative()); + mNoneBtn->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || getTentative())); LLFloater::draw(); @@ -774,7 +779,7 @@ void LLFloaterTexturePicker::draw() } // Draw Tentative Label over the image - if( mTentative && !mViewModel->isDirty() ) + if( getTentative() && !mViewModel->isDirty() ) { mTentativeLabel->setVisible( true ); drawChild(mTentativeLabel); @@ -977,6 +982,7 @@ void LLFloaterTexturePicker::onBtnSetToDefault(void* userdata) if (self->mOwner) { self->setImageID( self->getDefaultImageAssetID() ); + self->setTentative(false); } self->commitIfImmediateSet(); } @@ -987,6 +993,7 @@ void LLFloaterTexturePicker::onBtnBlank(void* userdata) LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; self->setCanApply(true, true); self->setImageID( self->getBlankImageAssetID() ); + self->setTentative(false); self->commitIfImmediateSet(); } @@ -997,21 +1004,10 @@ void LLFloaterTexturePicker::onBtnNone(void* userdata) LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; self->setCanApply(true, true); self->setImageID( LLUUID::null ); + self->setTentative(false); self->commitIfImmediateSet(); } -/* -// static -void LLFloaterTexturePicker::onBtnRevert(void* userdata) -{ - LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - self->setImageID( self->mOriginalImageAssetID ); - // TODO: Change this to tell the owner to cancel. It needs to be - // smart enough to restore multi-texture selections. - self->mOwner->onFloaterCommit(); - self->mViewModel->resetDirty(); -}*/ - // static void LLFloaterTexturePicker::onBtnCancel(void* userdata) { @@ -1218,6 +1214,7 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata) if (self->mSetImageAssetIDCallback) { self->mSetImageAssetIDCallback(inworld_id); + self->setTentative(false); } if (self->childGetValue("apply_immediate_check").asBoolean()) @@ -1296,6 +1293,7 @@ void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data } self->setImageID(imageID); + self->setTentative(false); self->mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? if (!self->mPreviewSettingChanged) @@ -1316,7 +1314,7 @@ void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply, bool inworld_image) { - mSelectBtn->setEnabled(can_apply); + mSelectBtn->setEnabled(can_apply && !getTentative()); // will be updated on draw getChildRef<LLUICtrl>("preview_disabled").setVisible(!can_preview && inworld_image); getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview); @@ -1490,7 +1488,13 @@ void LLFloaterTexturePicker::refreshInventoryFilter() void LLFloaterTexturePicker::setLocalTextureEnabled(bool enabled) { + mLocalTextureEnabled = enabled; mModeSelector->setEnabledByValue(1, enabled); + if (!enabled && (mModeSelector->getValue().asInteger() == 2)) + { + mModeSelector->selectByValue(0); + onModeSelect(0, this); + } } void LLFloaterTexturePicker::setBakeTextureEnabled(bool enabled) @@ -1617,6 +1621,7 @@ void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) else { setImageID(te.getID()); + setTentative(false); } mNoCopyTextureSelected = false; @@ -1830,6 +1835,17 @@ void LLTextureCtrl::clear() setImageAssetID(LLUUID::null); } +void LLTextureCtrl::setTentative(bool tentative) +{ + LLFloater* floaterp = mFloaterHandle.get(); + + if (floaterp) + { + floaterp->setTentative(tentative); + } + LLUICtrl::setTentative(tentative); +} + void LLTextureCtrl::setLabel(const std::string& label) { mLabel = label; @@ -1877,11 +1893,9 @@ void LLTextureCtrl::showPicker(bool take_focus) if (texture_floaterp) { texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5)); - } - if (texture_floaterp) - { texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1)); + texture_floaterp->setLocalTextureEnabled(mAllowLocalTexture); texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled && mInventoryPickType != PICK_MATERIAL); } @@ -1891,12 +1905,6 @@ void LLTextureCtrl::showPicker(bool take_focus) floaterp->openFloater(); } - LLFloaterTexturePicker* picker_floater = dynamic_cast<LLFloaterTexturePicker*>(floaterp); - if (picker_floater) - { - picker_floater->setLocalTextureEnabled(mAllowLocalTexture); - } - if (take_focus) { floaterp->setFocus(true); @@ -2076,7 +2084,17 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb) } } -void LLTextureCtrl::setImageAssetName(const std::string& name) +void LLTextureCtrl::setAllowLocalTexture(bool b) +{ + mAllowLocalTexture = b; + LLFloaterTexturePicker* picker_floater = dynamic_cast<LLFloaterTexturePicker*>(mFloaterHandle.get()); + if (picker_floater) + { + picker_floater->setLocalTextureEnabled(mAllowLocalTexture); + } +} + +void LLTextureCtrl::setImageAssetName(const std::string& name) { LLPointer<LLUIImage> imagep = LLUI::getUIImage(name); if(imagep) @@ -2101,6 +2119,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) if( floaterp && getEnabled() ) { floaterp->setImageID( asset_id ); + floaterp->setTentative(getTentative()); floaterp->resetDirty(); } } diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index df5e763139..79957431b7 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -167,6 +167,8 @@ public: // LLUICtrl interface void clear() override; + void setTentative(bool b) override; + // Takes a UUID, wraps get/setImageAssetID void setValue(const LLSD& value) override; LLSD getValue() const override; @@ -181,7 +183,7 @@ public: void setAllowNoTexture( bool b ) { mAllowNoTexture = b; } bool getAllowNoTexture() const { return mAllowNoTexture; } - void setAllowLocalTexture(bool b) { mAllowLocalTexture = b; } + void setAllowLocalTexture(bool b); bool getAllowLocalTexture() const { return mAllowLocalTexture; } const LLUUID& getImageItemID() { return mImageItemID; } @@ -405,7 +407,6 @@ protected: LLUIImagePtr mFallbackImage; // What to show if currently selected texture is null. LLUUID mDefaultImageAssetID; LLUUID mBlankImageAssetID; - bool mTentative; bool mAllowNoTexture; LLUUID mSpecialCurrentImageAssetID; // Used when the asset id has no corresponding texture in the user's inventory. LLUUID mOriginalImageAssetID; @@ -456,6 +457,7 @@ private: set_on_update_image_stats_callback mOnUpdateImageStatsCallback; bool mBakeTextureEnabled; + bool mLocalTextureEnabled; static S32 sLastPickerMode; }; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 087761cbd0..cc187a1f98 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -2484,7 +2484,7 @@ LLTextureFetch::~LLTextureFetch() } S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, - S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) + S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http) { LL_PROFILE_ZONE_SCOPED; if (mDebugPause) @@ -2496,13 +2496,13 @@ S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const L { LL_DEBUGS("Avatar") << " requesting " << id << " " << w << "x" << h << " discard " << desired_discard << " type " << f_type << LL_ENDL; } - LLTextureFetchWorker* worker = getWorker(id) ; + LLTextureFetchWorker* worker = getWorker(id); if (worker) { if (worker->mHost != host) { LL_WARNS(LOG_TXT) << "LLTextureFetch::createRequest " << id << " called with multiple hosts: " - << host << " != " << worker->mHost << LL_ENDL; + << host << " != " << worker->mHost << LL_ENDL; removeRequest(worker, true); worker = NULL; return CREATE_REQUEST_ERROR_MHOSTS; @@ -2538,7 +2538,7 @@ S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const L // we really do get it.) desired_size = MAX_IMAGE_DATA_SIZE; } - else if (w*h*c > 0) + else if (w * h * c > 0) { // If the requester knows the dimensions of the image, // this will calculate how much data we need without having to parse the header @@ -2596,14 +2596,15 @@ S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const L worker->lockWorkMutex(); // +Mw worker->mActiveCount++; worker->mNeedsAux = needs_aux; - worker->setCanUseHTTP(can_use_http) ; + worker->setCanUseHTTP(can_use_http); worker->unlockWorkMutex(); // -Mw } LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type) - << " Discard: " << desired_discard << " size " << desired_size << LL_ENDL; + << " Discard: " << desired_discard << " size " << desired_size << LL_ENDL; return desired_discard; } + // Threads: T* // // protected diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 8ab90896dc..851d6c11a0 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -85,8 +85,9 @@ public: }; // Threads: T* (but Tmain mostly) + // returns discard on success, fail code otherwise S32 createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority, - S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); + S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http); // Requests that a fetch operation be deleted from the queue. // If @cancel is true, also stops any I/O operations pending. diff --git a/indra/newview/llthumbnailctrl.cpp b/indra/newview/llthumbnailctrl.cpp index ae21d3e733..b077262f06 100644 --- a/indra/newview/llthumbnailctrl.cpp +++ b/indra/newview/llthumbnailctrl.cpp @@ -111,7 +111,9 @@ void LLThumbnailCtrl::draw() gl_draw_scaled_image( draw_rect.mLeft, draw_rect.mBottom, draw_rect.getWidth(), draw_rect.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha); - mTexturep->setKnownDrawSize(draw_rect.getWidth(), draw_rect.getHeight()); + // Thumbnails are usually 256x256 or smaller, either report that or + // some high value to get image with higher priority + mTexturep->setKnownDrawSize(MAX_IMAGE_SIZE, MAX_IMAGE_SIZE); } else if( mImagep.notNull() ) { @@ -238,12 +240,8 @@ void LLThumbnailCtrl::initImage() { // Should it support baked textures? mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_THUMBNAIL); - mTexturep->forceToSaveRawImage(0); - - S32 desired_draw_width = MAX_IMAGE_SIZE; - S32 desired_draw_height = MAX_IMAGE_SIZE; - mTexturep->setKnownDrawSize(desired_draw_width, desired_draw_height); + mTexturep->setKnownDrawSize(MAX_IMAGE_SIZE, MAX_IMAGE_SIZE); } } else if (tvalue.isString()) diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index 84854a79d4..0f871dc1bb 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -421,7 +421,7 @@ void LLToast::setVisible(bool show) if(mHideBtn) mHideBtn->setVisible(show); } - LLFloater::setVisible(show); + LLModalDialog::setVisible(show); if (mPanel && !mPanel->isDead() && mWrapperPanel diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 9d6f44c096..b4a5955be3 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1125,28 +1125,33 @@ void set_texture_to_material(LLViewerObject* hit_obj, case LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR: default: { - material->setBaseColorId(asset_id); + material->setBaseColorId(asset_id, true); } break; case LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS: { - material->setOcclusionRoughnessMetallicId(asset_id); + material->setOcclusionRoughnessMetallicId(asset_id, true); } break; case LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE: { - material->setEmissiveId(asset_id); + material->setEmissiveId(asset_id, true); } break; case LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL: { - material->setNormalId(asset_id); + material->setNormalId(asset_id, true); } break; } + // Update viewer side, needed for updating mSavedGLTFOverrideMaterials. + // Also for parity, we are immediately setting textures and materials, + // so we should immediate set overrides to. + hit_obj->setTEGLTFMaterialOverride(hit_face, material); + // update server LLGLTFMaterialList::queueModify(hit_obj, hit_face, material); } @@ -2156,7 +2161,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( { if(mSource == SOURCE_LIBRARY) { - LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0)); + LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, false)); copy_inventory_item( gAgent.getID(), item->getPermissions().getOwner(), @@ -2167,7 +2172,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv( } else { - rez_attachment(item, 0); + rez_attachment(item, 0, false); } } return ACCEPT_YES_SINGLE; @@ -2351,6 +2356,47 @@ EAcceptance LLToolDragAndDrop::dad3dRezScript( return rv; } + +bool is_water_exclusion_face(LLViewerObject* obj, S32 face) +{ + LLViewerTexture* image = obj->getTEImage(face); + if (!image) + return false; + + // magic texture and alpha blending + bool exclude_water = (image->getID() == IMG_ALPHA_GRAD) && obj->isImageAlphaBlended(face); + + // transparency + exclude_water &= (obj->getTE(face)->getColor().mV[VALPHA] == 1); + + //absence of normal and specular textures + image = obj->getTENormalMap(face); + if (image && image != LLViewerFetchedTexture::sDefaultImagep) + exclude_water &= image->getID().isNull(); + image = obj->getTESpecularMap(face); + if (image && image != LLViewerFetchedTexture::sDefaultImagep) + exclude_water &= image->getID().isNull(); + + return exclude_water; +} + +bool is_water_exclusion_surface(LLViewerObject* obj, S32 face, bool all_faces) +{ + if (all_faces) + { + bool exclude_water = false; + for (S32 it_face = 0; it_face < obj->getNumTEs(); it_face++) + { + exclude_water |= is_water_exclusion_face(obj, it_face); + } + return exclude_water; + } + else + { + return is_water_exclusion_face(obj, face); + } +} + EAcceptance LLToolDragAndDrop::dad3dApplyToObject( LLViewerObject* obj, S32 face, MASK mask, bool drop, EDragAndDropType cargo_type) { @@ -2441,7 +2487,13 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( else if (cargo_type == DAD_MATERIAL) { bool all_faces = mask & MASK_SHIFT; - if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + + if (is_water_exclusion_surface(obj, face, all_faces)) + { + LLNotificationsUtil::add("WaterExclusionNoMaterial"); + return ACCEPT_NO; + } + else if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) { dropMaterial(obj, face, item, mSource, mSourceID, all_faces); } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 8cdc2e94f4..0a69be528f 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -72,6 +72,7 @@ #include "llweb.h" #include "pipeline.h" // setHighlightObject #include "lluiusage.h" +#include "llcallingcard.h" extern bool gDebugClicks; @@ -1501,6 +1502,142 @@ static void handle_click_action_play() } } +bool LLToolPie::shouldAllowFirstMediaInteraction(const LLPickInfo& pick, bool moap_flag) +{ + // Early failure cases + if(!pick.getObject()) + { + LL_WARNS() << "pick.getObject() is NULL" << LL_ENDL; + return false; + } + + static LLCachedControl<S32> FirstClickPref(gSavedSettings, "MediaFirstClickInteract", 1); + + // Special / early-exit cases first, then checks get more complex and needy as we go down + // Feature disabled + if(FirstClickPref == MEDIA_FIRST_CLICK_NONE) + { + LL_DEBUGS_ONCE() << "FirstClickPref == MEDIA_FIRST_CLICK_NONE" << LL_ENDL; + return false; + } + // Every check beyond this point requires PRIM_MEDIA_FIRST_CLICK_INTERACT to be TRUE + if(!moap_flag && !(FirstClickPref & MEDIA_FIRST_CLICK_BYPASS_MOAP_FLAG)) + { + LL_DEBUGS_ONCE() << "PRIM_MEDIA_FIRST_CLICK_INTERACT not set" << LL_ENDL; + return false; + } + // Any object with PRIM_MEDIA_FIRST_CLICK_INTERACT set to TRUE + if((FirstClickPref & MEDIA_FIRST_CLICK_ANY) == MEDIA_FIRST_CLICK_ANY) + { + LL_DEBUGS_ONCE() << "FirstClickPref & MEDIA_FIRST_CLICK_ANY" << LL_ENDL; + return true; + } + + // The following checks require some object information so we obtain that + LLPointer<LLViewerObject> object = pick.getObject(); + if(object.isNull()) + { + LL_WARNS() << "pick.getObject() is NULL" << LL_ENDL; + return false; + } + + // HUD attachments + if((FirstClickPref & MEDIA_FIRST_CLICK_HUD) && object->isHUDAttachment()) + { + LL_DEBUGS_ONCE() << "FirstClickPref & MEDIA_FIRST_CLICK_HUD" << LL_ENDL; + return true; + } + + // Further object detail required beyond this point + LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode(); + if (hover_node == nullptr) + { + LL_WARNS() << "No Hover node" << LL_ENDL; + return false; + } + LLPermissions* perms = hover_node->mPermissions; + if(perms == nullptr) + { + LL_WARNS() << "LLSelectMgr::getInstance()->getHoverNode()->mPermissions is NULL" << LL_ENDL; + return false; + } + LLUUID owner_id = perms->getOwner(); + LLUUID group_id = perms->getGroup(); + if(owner_id.isNull() && group_id.isNull()) + { + LL_WARNS() << "Owner information was not reliably obtained" << LL_ENDL; + return false; + } + + // Own objects + if((FirstClickPref & MEDIA_FIRST_CLICK_OWN) && owner_id == gAgent.getID()) + { + LL_DEBUGS_ONCE() << "FirstClickPref & MEDIA_FIRST_CLICK_OWN" << LL_ENDL; + return true; + } + + // Check if the object is owned by a friend of the agent + if(FirstClickPref & MEDIA_FIRST_CLICK_FRIEND) + { + if(LLAvatarTracker::instance().isBuddy(owner_id)) + { + LL_DEBUGS_ONCE() << "FirstClickPref & MEDIA_FIRST_CLICK_FRIEND. id: " << owner_id << LL_ENDL; + return true; + } + } + + // Check for objects set to or owned by the active group + if(FirstClickPref & MEDIA_FIRST_CLICK_GROUP) + { + if(gAgent.isInGroup(group_id) || gAgent.isInGroup(owner_id)) + { + LL_DEBUGS_ONCE() << "FirstClickPref & MEDIA_FIRST_CLICK_GROUP. group_id:" << group_id << ", owner_id: " << owner_id << LL_ENDL; + return true; + } + } + + // This check ensures that the following conditions are met: + // 1. The object is located in the same parcel as the agent. + // 2. One of the following is true: + // a. The object is owned by the same group as the parcel. + // b. The object is set to the same group as the parcel. + // c. The object is owned by the same owner as the parcel. + // Conditions 2a and 2b are mutually exclusive, our check is the same for both. + if(FirstClickPref & MEDIA_FIRST_CLICK_LAND) + { + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if(parcel == nullptr) + { + LL_WARNS() << "LLViewerParcelMgr::getInstance()->getAgentParcel() is NULL" << LL_ENDL; + return false; + } + + // Same parcel as the agent only + if(!LLViewerParcelMgr::getInstance()->inAgentParcel(object->getPositionGlobal())) + { + LL_WARNS_ONCE() << "Object is not in the same parcel as the agent" << LL_ENDL; + return false; + } + + LLUUID parcel_owner = parcel->getOwnerID(); + LLUUID parcel_group = parcel->getGroupID(); + + // The parcel owner and group can't both be null + if(parcel_owner.isNull() && parcel_group.isNull()) + { + LL_WARNS() << "Parcel owner and group are both null" << LL_ENDL; + return false; + } + + if(owner_id == parcel_owner || group_id == parcel_group) + { + LL_DEBUGS_ONCE() << "FirstClickPref & MEDIA_FIRST_CLICK_LAND. Parcel owner: " << parcel_owner << ", group_id:" << group_id << ", owner_id: " << owner_id << LL_ENDL; + return true; + } + } + return false; +} + bool LLToolPie::handleMediaClick(const LLPickInfo& pick) { //FIXME: how do we handle object in different parcel than us? @@ -1535,6 +1672,16 @@ bool LLToolPie::handleMediaClick(const LLPickInfo& pick) { // It's okay to give this a null impl LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); + if (shouldAllowFirstMediaInteraction(pick, mep->getFirstClickInteract())) + { + if (media_impl.notNull()) + { + media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(true)); + mMediaMouseCaptureID = mep->getMediaID(); + setMouseCapture(true); + return true; + } + } } else { @@ -1647,7 +1794,7 @@ bool LLToolPie::handleMediaHover(const LLPickInfo& pick) } // If this is the focused media face, send mouse move events. - if (LLViewerMediaFocus::getInstance()->isFocusedOnFace(objectp, pick.mObjectFace)) + if (LLViewerMediaFocus::getInstance()->isFocusedOnFace(objectp, pick.mObjectFace) || (shouldAllowFirstMediaInteraction(pick, mep->getFirstClickInteract()))) { media_impl->mouseMove(pick.mUVCoords, gKeyboard->currentMask(true)); gViewerWindow->setCursor(media_impl->getLastSetCursor()); diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index b3884a6bfc..ec54e0207d 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -89,6 +89,22 @@ private: void showVisualContextMenuEffect(); ECursorType cursorFromObject(LLViewerObject* object); + enum MediaFirstClickTypes + { + MEDIA_FIRST_CLICK_NONE = 0, // Special case: Feature is disabled + MEDIA_FIRST_CLICK_HUD = 1 << 0, // 0b00000001 (1) + MEDIA_FIRST_CLICK_OWN = 1 << 1, // 0b00000010 (2) + MEDIA_FIRST_CLICK_FRIEND = 1 << 2, // 0b00000100 (4) + MEDIA_FIRST_CLICK_GROUP = 1 << 3, // 0b00001000 (8) + MEDIA_FIRST_CLICK_LAND = 1 << 4, // 0b00010000 (16) + + // Covers any object with PRIM_MEDIA_FIRST_CLICK_INTERACT (combines all previous flags) + MEDIA_FIRST_CLICK_ANY = (1 << 15) - 1, // 0b0111111111111111 (32767) + + // Covers all media regardless of other rules or PRIM_MEDIA_FIRST_CLICK_INTERACT + MEDIA_FIRST_CLICK_BYPASS_MOAP_FLAG = 1 << 15 // 0b10000000000000000 (32768) + }; + bool shouldAllowFirstMediaInteraction(const LLPickInfo& info, bool moap_flag); bool handleMediaClick(const LLPickInfo& info); bool handleMediaDblClick(const LLPickInfo& info); bool handleMediaHover(const LLPickInfo& info); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 7ef2c8d697..7d5386110d 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -62,7 +62,8 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId, LLAssetType::EType assetType, std::string name, std::string description, S32 compressionInfo, LLFolderType::EType destinationType, LLInventoryType::EType inventoryType, U32 nextOWnerPerms, - U32 groupPerms, U32 everyonePerms, S32 expectedCost, bool showInventory) : + U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID& destFolderId, bool showInventory) : mTransactionId(transactId), mAssetType(assetType), mName(name), @@ -75,7 +76,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId, mEveryonePerms(everyonePerms), mExpectedUploadCost(expectedCost), mShowInventory(showInventory), - mFolderId(LLUUID::null), + mFolderId(destFolderId), mItemId(LLUUID::null), mAssetId(LLAssetID::null) { } @@ -84,7 +85,8 @@ LLResourceUploadInfo::LLResourceUploadInfo(LLTransactionID transactId, LLResourceUploadInfo::LLResourceUploadInfo(std::string name, std::string description, S32 compressionInfo, LLFolderType::EType destinationType, LLInventoryType::EType inventoryType, - U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, S32 expectedCost, bool showInventory) : + U32 nextOWnerPerms, U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID& destFolderId, bool showInventory) : mName(name), mDescription(description), mCompressionInfo(compressionInfo), @@ -97,7 +99,7 @@ LLResourceUploadInfo::LLResourceUploadInfo(std::string name, mShowInventory(showInventory), mTransactionId(), mAssetType(LLAssetType::AT_NONE), - mFolderId(LLUUID::null), + mFolderId(destFolderId), mItemId(LLUUID::null), mAssetId(LLAssetID::null) { @@ -306,10 +308,10 @@ void LLResourceUploadInfo::assignDefaults() } else { - mFolderId = gInventory.findUserDefinedCategoryUUIDForType( - (mDestinationFolderType == LLFolderType::FT_NONE) ? - (LLFolderType::EType)mAssetType : mDestinationFolderType); -} + mFolderId = gInventory.findUserDefinedCategoryUUIDForType( + (mDestinationFolderType == LLFolderType::FT_NONE) ? + (LLFolderType::EType)mAssetType : mDestinationFolderType); + } } std::string LLResourceUploadInfo::getDisplayName() const @@ -366,10 +368,12 @@ LLNewFileResourceUploadInfo::LLNewFileResourceUploadInfo( U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID& destFolderId, bool show_inventory) : LLResourceUploadInfo(name, description, compressionInfo, destinationType, inventoryType, - nextOWnerPerms, groupPerms, everyonePerms, expectedCost, show_inventory), + nextOWnerPerms, groupPerms, everyonePerms, expectedCost, + destFolderId, show_inventory), mFileName(fileName), mMaxImageSize(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT) { @@ -580,12 +584,13 @@ LLNewBufferedResourceUploadInfo::LLNewBufferedResourceUploadInfo( U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID& destFolderId, bool show_inventory, uploadFinish_f finish, uploadFailure_f failure) : LLResourceUploadInfo(name, description, compressionInfo, destinationType, inventoryType, - nextOWnerPerms, groupPerms, everyonePerms, expectedCost, show_inventory) + nextOWnerPerms, groupPerms, everyonePerms, expectedCost, destFolderId, show_inventory) , mBuffer(buffer) , mFinishFn(finish) , mFailureFn(failure) diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h index 365436ede0..c627e9dbb8 100644 --- a/indra/newview/llviewerassetupload.h +++ b/indra/newview/llviewerassetupload.h @@ -54,6 +54,7 @@ public: U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID &destFolderId = LLUUID::null, bool showInventory = true); virtual ~LLResourceUploadInfo() @@ -104,6 +105,7 @@ protected: U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID& destFolderId = LLUUID::null, bool showInventory = true); LLResourceUploadInfo( @@ -155,6 +157,7 @@ public: U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID &destFolderId = LLUUID::null, bool show_inventory = true); virtual LLSD prepareUpload(); @@ -193,6 +196,7 @@ public: U32 groupPerms, U32 everyonePerms, S32 expectedCost, + const LLUUID& destFolderId, // use null for default bool show_inventory, uploadFinish_f finish, uploadFailure_f failure); @@ -219,6 +223,7 @@ public: typedef std::function<void(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)> taskUploadFinish_f; typedef std::function<bool(LLUUID itemId, LLUUID taskId, LLSD response, std::string reason)> uploadFailed_f; + // destFolderId is the folder to put the new item in, leave null for default LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish, uploadFailed_f failed); LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LLImageFormatted> image, invnUploadFinish_f finish); LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish, uploadFailed_f failed); diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp index f2557e299c..9828ab1fdf 100644 --- a/indra/newview/llviewerattachmenu.cpp +++ b/indra/newview/llviewerattachmenu.cpp @@ -116,12 +116,12 @@ void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::strin LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getLinkedItem(id); if(item && gInventory.isObjectDescendentOf(id, gInventory.getRootFolderID())) { - rez_attachment(item, attachmentp); // don't replace if called from an "Attach To..." menu + rez_attachment(item, attachmentp, false); // don't replace if called from an "Attach To..." menu } else if(item && item->isFinished()) { // must be in library. copy it to our inventory and put it on. - LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp)); + LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp, false)); copy_inventory_item(gAgent.getID(), item->getPermissions().getOwner(), item->getUUID(), diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 404297c58f..aa0cbac91f 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -390,6 +390,7 @@ void init_audio() gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose"))); gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen"))); gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndRestart"))); + gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndChatMention"))); } audio_update_volume(true); diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index 7d777162ed..511293a808 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -73,26 +73,26 @@ LLViewerCamera::LLViewerCamera() : LLCamera() mAverageSpeed = 0.f; mAverageAngularSpeed = 0.f; - mCameraAngleChangedSignal = gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); -} - -LLViewerCamera::~LLViewerCamera() -{ - mCameraAngleChangedSignal.disconnect(); + LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl("CameraAngle"); + if (cntrl_ptr.notNull()) + { + cntrl_ptr->getCommitSignal()->connect([](LLControlVariable* control, const LLSD& value, const LLSD& previous) + { + LLViewerCamera::getInstance()->setDefaultFOV((F32)value.asReal()); + }); + } } -void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) +bool LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) { // do not update if avatar didn't move if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate()) { - return; + return true; } - LLVector3 last_position; - LLVector3 last_axis; - last_position = getOrigin(); - last_axis = getAtAxis(); + LLVector3 last_position = getOrigin(); + LLVector3 last_axis = getAtAxis(); mLastPointOfInterest = point_of_interest; @@ -102,30 +102,49 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVecto regp = gAgent.getRegion(); } - F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f; + F32 water_height = regp ? regp->getWaterHeight() : 0.f; LLVector3 origin = center; + // Move origin[VZ] far enough (up or down) from the water surface + static const F32 MIN_DIST_TO_WATER = 0.2f; + F32& zpos = origin.mV[VZ]; + if (zpos < water_height + MIN_DIST_TO_WATER) { - if (origin.mV[2] > water_height) + if (zpos >= water_height) { - origin.mV[2] = llmax(origin.mV[2], water_height + 0.20f); + zpos = water_height + MIN_DIST_TO_WATER; } - else + else if (zpos > water_height - MIN_DIST_TO_WATER) { - origin.mV[2] = llmin(origin.mV[2], water_height - 0.20f); + zpos = water_height - MIN_DIST_TO_WATER; } } - setOriginAndLookAt(origin, up_direction, point_of_interest); + LLVector3 at(point_of_interest - origin); + at.normalize(); + if (at.isNull() || !at.isFinite()) + return false; + + LLVector3 left(up_direction % at); + left.normalize(); + if (left.isNull() || !left.isFinite()) + return false; + + LLVector3 up = at % left; + up.normalize(); + if (up.isNull() || !up.isFinite()) + return false; + + setOrigin(origin); + setAxes(at, left, up); mVelocityDir = origin - last_position ; F32 dpos = mVelocityDir.normVec() ; LLQuaternion rotation; rotation.shortestArc(last_axis, getAtAxis()); - F32 x, y, z; - F32 drot; + F32 drot, x, y, z; rotation.getAngleAxis(&drot, &x, &y, &z); add(sVelocityStat, dpos); @@ -138,6 +157,8 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVecto // update pixel meter ratio using default fov, not modified one mPixelMeterRatio = (F32)(getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5f))); // update screen pixel area + + return true; mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect())); } @@ -145,7 +166,6 @@ const LLMatrix4 &LLViewerCamera::getProjection() const { calcProjection(getFar()); return mProjectionMatrix; - } const LLMatrix4 &LLViewerCamera::getModelview() const @@ -158,13 +178,12 @@ const LLMatrix4 &LLViewerCamera::getModelview() const void LLViewerCamera::calcProjection(const F32 far_distance) const { - F32 fov_y, z_far, z_near, aspect, f; - fov_y = getView(); - z_far = far_distance; - z_near = getNear(); - aspect = getAspect(); + F32 fov_y = getView(); + F32 z_far = far_distance; + F32 z_near = getNear(); + F32 aspect = getAspect(); - f = 1/tan(fov_y*0.5f); + F32 f = 1 / tan(fov_y * 0.5f); mProjectionMatrix.setZero(); mProjectionMatrix.mMatrix[0][0] = f/aspect; @@ -270,9 +289,9 @@ void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, bool ortho, bool zfli } void LLViewerCamera::setPerspective(bool for_selection, - S32 x, S32 y_from_bot, S32 width, S32 height, - bool limit_select_distance, - F32 z_near, F32 z_far) + S32 x, S32 y_from_bot, S32 width, S32 height, + bool limit_select_distance, + F32 z_near, F32 z_far) { F32 fov_y, aspect; fov_y = getView(); @@ -334,7 +353,7 @@ void LLViewerCamera::setPerspective(bool for_selection, { float offset = mZoomFactor - 1.f; int pos_y = mZoomSubregion / llceil(mZoomFactor); - int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor)); + int pos_x = mZoomSubregion - (pos_y * llceil(mZoomFactor)); glm::mat4 translate; translate = glm::translate(glm::vec3(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f)); @@ -347,7 +366,7 @@ void LLViewerCamera::setPerspective(bool for_selection, calcProjection(z_far); // Update the projection matrix cache - proj_mat *= glm::perspective(fov_y,aspect,z_near,z_far); + proj_mat *= glm::perspective(fov_y, aspect, z_near, z_far); gGL.loadMatrix(glm::value_ptr(proj_mat)); @@ -355,7 +374,7 @@ void LLViewerCamera::setPerspective(bool for_selection, gGL.matrixMode(LLRender::MM_MODELVIEW); - glm::mat4 modelview(glm::make_mat4((GLfloat*) OGL_TO_CFR_ROTATION)); + glm::mat4 modelview(glm::make_mat4((GLfloat*)OGL_TO_CFR_ROTATION)); GLfloat ogl_matrix[16]; @@ -371,9 +390,9 @@ void LLViewerCamera::setPerspective(bool for_selection, // however, it is also unused (the GL matricies are used for selection, (see LLCamera::sphereInFrustum())) and so i'm not // comfortable hacking on it. calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f, - (F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f, - (F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f, - (F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f); + (F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f, + (F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidthScaled() - 0.5f, + (F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeightScaled() - 0.5f); } @@ -387,7 +406,6 @@ void LLViewerCamera::setPerspective(bool for_selection, updateFrustumPlanes(*this); } - // Uses the last GL matrices set in set_perspective to project a point from // screen coordinates to the agent's region. void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 screen_y, LLVector3* pos_agent) const @@ -814,8 +832,3 @@ bool LLViewerCamera::isDefaultFOVChanged() return false; } -void LLViewerCamera::updateCameraAngle(const LLSD& value) -{ - setDefaultFOV((F32)value.asReal()); -} - diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index a204b85d88..cb0994be0a 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -43,7 +43,6 @@ class alignas(16) LLViewerCamera : public LLCamera, public LLSimpleton<LLViewerC LL_ALIGN_NEW public: LLViewerCamera(); - ~LLViewerCamera(); typedef enum { @@ -61,12 +60,11 @@ public: static eCameraID sCurCameraID; - void updateCameraLocation(const LLVector3 ¢er, + bool updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest); static void updateFrustumPlanes(LLCamera& camera, bool ortho = false, bool zflip = false, bool no_hacks = false); - void updateCameraAngle(const LLSD& value); void setPerspective(bool for_selection, S32 x, S32 y_from_bot, S32 width, S32 height, bool limit_select_distance, F32 z_near = 0, F32 z_far = 0); const LLMatrix4 &getProjection() const; @@ -77,12 +75,12 @@ public: bool projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const bool clamp = true) const; bool projectPosAgentToScreenEdge(const LLVector3 &pos_agent, LLCoordGL &out_point) const; + F32 getCosHalfFov() const { return mCosHalfCameraFOV; } + F32 getAverageSpeed() const { return mAverageSpeed; } + F32 getAverageAngularSpeed() const { return mAverageAngularSpeed; } LLVector3 getVelocityDir() const {return mVelocityDir;} static LLTrace::CountStatHandle<>* getVelocityStat() {return &sVelocityStat; } static LLTrace::CountStatHandle<>* getAngularVelocityStat() {return &sAngularVelocityStat; } - F32 getCosHalfFov() {return mCosHalfCameraFOV;} - F32 getAverageSpeed() {return mAverageSpeed ;} - F32 getAverageAngularSpeed() {return mAverageAngularSpeed;} void getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right); LLVector3 roundToPixel(const LLVector3 &pos_agent); @@ -90,21 +88,21 @@ public: // Sets the current matrix /* virtual */ void setView(F32 vertical_fov_rads); // NOTE: broadcasts to simulator void setViewNoBroadcast(F32 vertical_fov_rads); // set FOV without broadcasting to simulator (for temporary local cameras) + F32 getDefaultFOV() const { return mCameraFOVDefault; } void setDefaultFOV(F32 fov) ; - F32 getDefaultFOV() { return mCameraFOVDefault; } bool isDefaultFOVChanged(); bool cameraUnderWater() const; bool areVertsVisible(LLViewerObject* volumep, bool all_verts); - const LLVector3 &getPointOfInterest() { return mLastPointOfInterest; } + const LLVector3& getPointOfInterest() const { return mLastPointOfInterest; } F32 getPixelMeterRatio() const { return mPixelMeterRatio; } S32 getScreenPixelArea() const { return mScreenPixelArea; } void setZoomParameters(F32 factor, S16 subregion) { mZoomFactor = factor; mZoomSubregion = subregion; } - F32 getZoomFactor() { return mZoomFactor; } - S16 getZoomSubRegion() { return mZoomSubregion; } + F32 getZoomFactor() const { return mZoomFactor; } + S16 getZoomSubRegion() const { return mZoomSubregion; } protected: void calcProjection(const F32 far_distance) const; @@ -126,8 +124,6 @@ protected: F32 mZoomFactor; S16 mZoomSubregion; - boost::signals2::connection mCameraAngleChangedSignal; - public: }; diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 8b01c4ef88..2ca2c5c07d 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -36,6 +36,7 @@ #include "llviewerregion.h" #include "llworld.h" #include "llinstantmessage.h" //SYSTEM_FROM +#include "llurlregistry.h" // LLViewerChat LLViewerChat::font_change_signal_t LLViewerChat::sChatFontChangedSignal; @@ -222,6 +223,13 @@ void LLViewerChat::formatChatMsg(const LLChat& chat, std::string& formated_msg) { std::string tmpmsg = chat.mText; + // show @name instead of slurl for chat mentions + LLUrlMatch match; + while (LLUrlRegistry::instance().findUrl(tmpmsg, match, LLUrlRegistryNullCallback, false, true)) + { + tmpmsg.replace(match.getStart(), match.getEnd() - match.getStart() + 1, match.getLabel()); + } + if(chat.mChatStyle == CHAT_STYLE_IRC) { formated_msg = chat.mFromName + tmpmsg.substr(3); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 1333c2cd2f..7a93536c00 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -100,13 +100,13 @@ extern LLPointer<LLViewerTexture> gStartTexture; extern bool gShiftFrame; -LLPointer<LLViewerTexture> gDisconnectedImagep = NULL; +LLPointer<LLViewerTexture> gDisconnectedImagep = nullptr; // used to toggle renderer back on after teleport bool gTeleportDisplay = false; LLFrameTimer gTeleportDisplayTimer; LLFrameTimer gTeleportArrivalTimer; -const F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain +constexpr F32 RESTORE_GL_TIME = 5.f; // Wait this long while reloading textures before we raise the curtain bool gForceRenderLandFence = false; bool gDisplaySwapBuffers = false; @@ -120,9 +120,9 @@ bool gSnapshotNoPost = false; bool gShaderProfileFrame = false; // This is how long the sim will try to teleport you before giving up. -const F32 TELEPORT_EXPIRY = 15.0f; +constexpr F32 TELEPORT_EXPIRY = 15.0f; // Additional time (in seconds) to wait per attachment -const F32 TELEPORT_EXPIRY_PER_ATTACHMENT = 3.f; +constexpr F32 TELEPORT_EXPIRY_PER_ATTACHMENT = 3.f; U32 gRecentFrameCount = 0; // number of 'recent' frames LLFrameTimer gRecentFPSTime; @@ -130,8 +130,6 @@ LLFrameTimer gRecentMemoryTime; LLFrameTimer gAssetStorageLogTime; // Rendering stuff -void pre_show_depth_buffer(); -void post_show_depth_buffer(); void render_ui(F32 zoom_factor = 1.f, int subfield = 0); void swap(); void render_hud_attachments(); @@ -212,7 +210,8 @@ void display_update_camera() F32 final_far = gAgentCamera.mDrawDistance; if (gCubeSnapshot) { - final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance"); + static LLCachedControl<F32> reflection_probe_draw_distance(gSavedSettings, "RenderReflectionProbeDrawDistance", 64.f); + final_far = reflection_probe_draw_distance(); } else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode()) { @@ -237,7 +236,7 @@ void display_update_camera() void display_stats() { LL_PROFILE_ZONE_SCOPED; - const F32 FPS_LOG_FREQUENCY = 10.f; + constexpr F32 FPS_LOG_FREQUENCY = 10.f; if (gRecentFPSTime.getElapsedTimeF32() >= FPS_LOG_FREQUENCY) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS"); @@ -246,7 +245,7 @@ void display_stats() gRecentFrameCount = 0; gRecentFPSTime.reset(); } - F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); + static LLCachedControl<F32> mem_log_freq(gSavedSettings, "MemoryLogFrequency", 600.f); if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Memory"); @@ -256,7 +255,7 @@ void display_stats() LLMemory::logMemoryInfo(true) ; gRecentMemoryTime.reset(); } - const F32 ASSET_STORAGE_LOG_FREQUENCY = 60.f; + constexpr F32 ASSET_STORAGE_LOG_FREQUENCY = 60.f; if (gAssetStorageLogTime.getElapsedTimeF32() >= ASSET_STORAGE_LOG_FREQUENCY) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - Asset Storage"); @@ -573,8 +572,10 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) LLImageGL::updateStats(gFrameTimeSeconds); - LLVOAvatar::sRenderName = gSavedSettings.getS32("AvatarNameTagMode"); - LLVOAvatar::sRenderGroupTitles = (gSavedSettings.getBOOL("NameTagShowGroupTitles") && gSavedSettings.getS32("AvatarNameTagMode")); + static LLCachedControl<S32> avatar_name_tag_mode(gSavedSettings, "AvatarNameTagMode", 1); + static LLCachedControl<bool> name_tag_show_group_titles(gSavedSettings, "NameTagShowGroupTitles", true); + LLVOAvatar::sRenderName = avatar_name_tag_mode; + LLVOAvatar::sRenderGroupTitles = name_tag_show_group_titles && avatar_name_tag_mode > 0; gPipeline.mBackfaceCull = true; gFrameCount++; @@ -798,7 +799,7 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) } gGL.setColorMask(true, true); - glClearColor(0,0,0,0); + glClearColor(0.f, 0.f, 0.f, 0.f); LLGLState::checkStates(); @@ -966,7 +967,7 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) gPipeline.mRT->deferredScreen.bindTarget(); if (gUseWireframe) { - F32 g = 0.5f; + constexpr F32 g = 0.5f; glClearColor(g, g, g, 1.f); } else @@ -985,11 +986,12 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 5") LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - if (gSavedSettings.getBOOL("RenderDepthPrePass")) + static LLCachedControl<bool> render_depth_pre_pass(gSavedSettings, "RenderDepthPrePass", false); + if (render_depth_pre_pass) { gGL.setColorMask(false, false); - static const U32 types[] = { + constexpr U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY @@ -1203,7 +1205,7 @@ void display_cube_face() gGL.setColorMask(true, true); - glClearColor(0, 0, 0, 0); + glClearColor(0.f, 0.f, 0.f, 0.f); gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT); @@ -1239,7 +1241,7 @@ void display_cube_face() } else { - glClearColor(1, 0, 1, 1); + glClearColor(1.f, 0.f, 1.f, 1.f); } gPipeline.mRT->deferredScreen.clear(); @@ -1280,11 +1282,12 @@ void render_hud_attachments() { LLPipeline::sRenderingHUDs = true; LLCamera hud_cam = *LLViewerCamera::getInstance(); - hud_cam.setOrigin(-1.f,0,0); - hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); + hud_cam.setOrigin(-1.f, 0.f, 0.f); + hud_cam.setAxes(LLVector3(1.f, 0.f, 0.f), LLVector3(0.f, 1.f, 0.f), LLVector3(0.f, 0.f, 1.f)); LLViewerCamera::updateFrustumPlanes(hud_cam, true); - bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles"); + static LLCachedControl<bool> render_hud_particles(gSavedSettings, "RenderHUDParticles", false); + bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && render_hud_particles; //only render hud objects gPipeline.pushRenderTypeMask(); @@ -1644,10 +1647,11 @@ void render_ui_3d() stop_glerror(); gUIProgram.bind(); - gGL.color4f(1, 1, 1, 1); + gGL.color4f(1.f, 1.f, 1.f, 1.f); // Coordinate axes - if (gSavedSettings.getBOOL("ShowAxes")) + static LLCachedControl<bool> show_axes(gSavedSettings, "ShowAxes"); + if (show_axes()) { draw_axes(); } @@ -1707,7 +1711,7 @@ void render_ui_2d() gGL.pushMatrix(); S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2); S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2); - gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f); + gGL.scalef(LLUI::getScaleFactor().mV[VX], LLUI::getScaleFactor().mV[VY], 1.f); gGL.translatef((F32)half_width, (F32)half_height, 0.f); F32 zoom = gAgentCamera.mHUDCurZoom; gGL.scalef(zoom,zoom,1.f); @@ -1729,7 +1733,7 @@ void render_ui_2d() gPipeline.mUIScreen.bindTarget(); gGL.setColorMask(true, true); { - static const S32 pad = 8; + constexpr S32 pad = 8; LLView::sDirtyRect.mLeft -= pad; LLView::sDirtyRect.mRight += pad; @@ -1782,8 +1786,6 @@ void render_ui_2d() gViewerWindow->draw(); } - - // reset current origin for font rendering, in case of tiling render LLFontGL::sCurOrigin.set(0, 0); } @@ -1792,7 +1794,7 @@ void render_disconnected_background() { gUIProgram.bind(); - gGL.color4f(1,1,1,1); + gGL.color4f(1.f, 1.f, 1.f, 1.f); if (!gDisconnectedImagep && gDisconnected) { LL_INFOS() << "Loading last bitmap..." << LL_ENDL; @@ -1832,7 +1834,7 @@ void render_disconnected_background() raw->expandToPowerOfTwo(); - gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), false ); + gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), false); gStartTexture = gDisconnectedImagep; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -1867,6 +1869,5 @@ void render_disconnected_background() void display_cleanup() { - gDisconnectedImagep = NULL; + gDisconnectedImagep = nullptr; } - diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 95c2a77ba8..4b3af6d7e8 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -38,8 +38,8 @@ #include "llfloateraddpaymentmethod.h" #include "llfloaterauction.h" #include "llfloaterautoreplacesettings.h" -#include "llfloateravatar.h" #include "llfloateravatarpicker.h" +#include "llfloateravatarwelcomepack.h" #include "llfloateravatarrendersettings.h" #include "llfloateravatartextures.h" #include "llfloaterbanduration.h" @@ -58,6 +58,7 @@ #include "llfloatercamera.h" #include "llfloatercamerapresets.h" #include "llfloaterchangeitemthumbnail.h" +#include "llfloaterchatmentionpicker.h" #include "llfloaterchatvoicevolume.h" #include "llfloaterclassified.h" #include "llfloaterconversationlog.h" @@ -330,8 +331,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>); LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>); LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>); - LLFloaterReg::add("avatar", "floater_avatar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>); LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>); + LLFloaterReg::add("avatar_welcome_pack", "floater_avatar_welcome_pack.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarWelcomePack>); LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>); LLFloaterReg::add("avatar_textures", "floater_avatar_textures.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarTextures>); @@ -353,6 +354,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>); LLFloaterReg::add("change_item_thumbnail", "floater_change_item_thumbnail.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChangeItemThumbnail>); LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater); + LLFloaterReg::add("chat_mention_picker", "floater_chat_mention_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatMentionPicker>); LLFloaterReg::add("classified", "floater_classified.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterClassified>); LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>); LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index e2022cae37..6155058f14 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -71,6 +71,9 @@ #include "llclipboard.h" #include "llhttpretrypolicy.h" #include "llsettingsvo.h" +#include "llinventorylistener.h" + +LLInventoryListener sInventoryListener; // do-nothing ops for use in callbacks. void no_op_inventory_func(const LLUUID&) {} @@ -751,27 +754,30 @@ S32 LLViewerInventoryCategory::getViewerDescendentCount() const return descendents_actual; } -LLSD LLViewerInventoryCategory::exportLLSD() const +void LLViewerInventoryCategory::exportLLSD(LLSD & cat_data) const { - LLSD cat_data = LLInventoryCategory::exportLLSD(); + LLInventoryCategory::exportLLSD(cat_data); cat_data[INV_OWNER_ID] = mOwnerID; cat_data[INV_VERSION] = mVersion; - - return cat_data; } -bool LLViewerInventoryCategory::importLLSD(const LLSD& cat_data) +bool LLViewerInventoryCategory::importLLSD(const std::string& label, const LLSD& value) { - LLInventoryCategory::importLLSD(cat_data); - if (cat_data.has(INV_OWNER_ID)) + if (LLInventoryCategory::importLLSD(label, value)) { - mOwnerID = cat_data[INV_OWNER_ID].asUUID(); + return true; } - if (cat_data.has(INV_VERSION)) + else if (label == INV_OWNER_ID) { - setVersion(cat_data[INV_VERSION].asInteger()); + mOwnerID = value.asUUID(); + return true; } - return true; + else if (label == INV_VERSION) + { + setVersion(value.asInteger()); + return true; + } + return false; } bool LLViewerInventoryCategory::acceptItem(LLInventoryItem* inv_item) @@ -966,7 +972,7 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id) } } -void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp) +void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace) { if (inv_item.isNull()) return; @@ -974,7 +980,7 @@ void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachme LLViewerInventoryItem *item = gInventory.getItem(inv_item); if (item) { - rez_attachment(item, attachmentp); + rez_attachment(item, attachmentp, replace); } } @@ -1436,7 +1442,8 @@ void update_inventory_category( if(obj) { if (LLFolderType::lookupIsProtectedType(obj->getPreferredType()) - && (updates.size() != 1 || !updates.has("thumbnail"))) + && (updates.size() != 1 + || !(updates.has("thumbnail") || updates.has("favorite")))) { LLNotificationsUtil::add("CannotModifyProtectedCategories"); return; diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index 21a6606253..0dfbf0cced 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -232,8 +232,8 @@ public: // How many descendents do we currently have information for in the InventoryModel? S32 getViewerDescendentCount() const; - LLSD exportLLSD() const; - bool importLLSD(const LLSD& cat_data); + virtual void exportLLSD(LLSD &sd) const; + virtual bool importLLSD(const std::string& label, const LLSD& value); void determineFolderType(); void changeType(LLFolderType::EType new_folder_type); @@ -264,7 +264,7 @@ public: class LLViewerJointAttachment; -void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp); +void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace); void activate_gesture_cb(const LLUUID& inv_item); diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index 13d101f881..8edb21956f 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -881,6 +881,10 @@ void LLViewerJoystick::moveObjects(bool reset) { gAgent.clearAFK(); } + else + { + gAwayTriggerTimer.reset(); + } if (sDelta[0] || sDelta[1] || sDelta[2]) { @@ -1055,6 +1059,10 @@ void LLViewerJoystick::moveAvatar(bool reset) { gAgent.clearAFK(); } + else + { + gAwayTriggerTimer.reset(); + } setCameraNeedsUpdate(true); } @@ -1267,10 +1275,17 @@ void LLViewerJoystick::moveFlycam(bool reset) } // Clear AFK state if moved beyond the deadzone - if (!is_zero && gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) + if (!is_zero) + { + if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) { gAgent.clearAFK(); } + else + { + gAwayTriggerTimer.reset(); + } + } sFlycamPosition += LLVector3(sDelta) * sFlycamRotation; @@ -1331,6 +1346,10 @@ bool LLViewerJoystick::toggleFlycam() { gAgent.clearAFK(); } + else + { + gAwayTriggerTimer.reset(); + } mOverrideCamera = !mOverrideCamera; if (mOverrideCamera) diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp index b68ffbe1a2..4a1c433f8e 100644 --- a/indra/newview/llviewermedia_streamingaudio.cpp +++ b/indra/newview/llviewermedia_streamingaudio.cpp @@ -60,13 +60,26 @@ void LLStreamingAudio_MediaPlugins::start(const std::string& url) if(!mMediaPlugin) return; - if (!url.empty()) { + if (!url.empty()) + { LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; - mURL = url; - mMediaPlugin->loadURI ( url ); + + mURL = url; // keep original url here for comparison purposes + std::string snt_url = url; + LLStringUtil::trim(snt_url); + size_t pos = snt_url.find(' '); + if (pos != std::string::npos) + { + // fmod permited having names after the url and people were using it. + // People label their streams this way, ignore the 'label'. + snt_url = snt_url.substr(0, pos); + } + mMediaPlugin->loadURI(snt_url); mMediaPlugin->start(); LL_INFOS() << "Playing stream..." << LL_ENDL; - } else { + } + else + { LL_INFOS() << "setting stream to NULL"<< LL_ENDL; mURL.clear(); mMediaPlugin->stop(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 1c9a892a4f..7a8a57c03d 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -85,6 +85,7 @@ #include "lltoolface.h" #include "llhints.h" #include "llhudeffecttrail.h" +#include "llhudeffectresetskeleton.h" #include "llhudmanager.h" #include "llimview.h" #include "llinventorybridge.h" @@ -289,6 +290,7 @@ void force_error_coroutine_crash(); void force_error_coroprocedure_crash(); void force_error_work_queue_crash(); void force_error_thread_crash(); +void force_exception_thread_crash(); void handle_force_delete(); void print_object_info(); @@ -1846,7 +1848,6 @@ class LLAdvancedAppearanceToXML : public view_listener_t { bool handleEvent(const LLSD& userdata) { - std::string emptyname; LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); LLVOAvatar *avatar = NULL; if (obj) @@ -1873,7 +1874,7 @@ class LLAdvancedAppearanceToXML : public view_listener_t } if (avatar) { - avatar->dumpArchetypeXML(emptyname); + avatar->dumpArchetypeXML(LLStringUtil::null); } return true; } @@ -2663,6 +2664,15 @@ class LLAdvancedForceErrorThreadCrash : public view_listener_t } }; +class LLAdvancedForceExceptionThreadCrash : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + force_exception_thread_crash(); + return true; + } +}; + class LLAdvancedForceErrorDisconnectViewer : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -5634,6 +5644,38 @@ class LLToolsEnablePathfindingRebakeRegion : public view_listener_t } }; +class LLToolsCheckSelectionLODMode : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string param = userdata.asString(); + static LLCachedControl<S32> debug_selection_lods(gSavedSettings, "DebugSelectionLODs", 0); + if ("default" == param) + { + return debug_selection_lods() < 0; + } + else if ("high" == param) + { + return debug_selection_lods() == 3; + } + else if ("medium" == param) + { + return debug_selection_lods() == 2; + } + else if ("low" == param) + { + return debug_selection_lods() == 1; + } + else if ("lowest" == param) + { + return debug_selection_lods() == 0; + } + + return false; + } +}; + + // Round the position of all root objects to the grid class LLToolsSnapObjectXY : public view_listener_t { @@ -6475,7 +6517,7 @@ void handle_look_at_selection(const LLSD& param) } } -void handle_zoom_to_object(const LLUUID& object_id) +bool handle_zoom_to_object(const LLUUID& object_id) { const F32 PADDING_FACTOR = 2.f; @@ -6493,12 +6535,14 @@ void handle_zoom_to_object(const LLUUID& object_id) obj_to_cam.normVec(); - LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent()); + LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent()); - gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), + gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), object_center_global, object_id ); + return true; } + return false; } class LLAvatarInviteToGroup : public view_listener_t @@ -6609,8 +6653,18 @@ class LLAvatarResetSkeleton : public view_listener_t { if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())) { + if(avatar->getID() == gAgentID) + { + LLHUDEffectResetSkeleton* effectp = (LLHUDEffectResetSkeleton*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_RESET_SKELETON, true); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject((LLViewerObject*)avatar); + effectp->setResetAnimations(false); + } + else + { avatar->resetSkeleton(false); } + } return true; } }; @@ -6633,8 +6687,18 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t { if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())) { + if(avatar->getID() == gAgentID) + { + LLHUDEffectResetSkeleton* effectp = (LLHUDEffectResetSkeleton*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_RESET_SKELETON, true); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject((LLViewerObject*)avatar); + effectp->setResetAnimations(true); + } + else + { avatar->resetSkeleton(true); } + } return true; } }; @@ -6661,11 +6725,24 @@ class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t { if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())) { - avatar->resetSkeleton(true); + if(avatar->getID() == gAgentID) + { + LLHUDEffectResetSkeleton* effectp = (LLHUDEffectResetSkeleton*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_RESET_SKELETON, true); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject((LLViewerObject*)avatar); + effectp->setResetAnimations(true); } else { - gAgentAvatarp->resetSkeleton(true); + avatar->resetSkeleton(true); + } + } + else + { + LLHUDEffectResetSkeleton* effectp = (LLHUDEffectResetSkeleton*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_RESET_SKELETON, true); + effectp->setSourceObject(gAgentAvatarp); + effectp->setTargetObject(gAgentAvatarp); + effectp->setResetAnimations(true); } return true; } @@ -8458,6 +8535,36 @@ class LLToolsSelectBySurrounding : public view_listener_t } }; +class LLToolsSelectionLODMode : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string param = userdata.asString(); + if ("default" == param) + { + gSavedSettings.setS32("DebugSelectionLODs", -1); + } + else if ("high" == param) + { + gSavedSettings.setS32("DebugSelectionLODs", 3); + } + else if ("medium" == param) + { + gSavedSettings.setS32("DebugSelectionLODs", 2); + } + else if ("low" == param) + { + gSavedSettings.setS32("DebugSelectionLODs", 1); + } + else if ("lowest" == param) + { + gSavedSettings.setS32("DebugSelectionLODs", 0); + } + + return true; + } +}; + class LLToolsShowHiddenSelection : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -8696,6 +8803,11 @@ void force_error_thread_crash() LLAppViewer::instance()->forceErrorThreadCrash(); } +void force_exception_thread_crash() +{ + LLAppViewer::instance()->forceExceptionThreadCrash(); +} + class LLToolsUseSelectionForGrid : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -9692,6 +9804,7 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects"); view_listener_t::addMenu(new LLToolsSelectReflectionProbes(), "Tools.SelectReflectionProbes"); view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding"); + view_listener_t::addMenu(new LLToolsSelectionLODMode(), "Tools.SelectionLODMode"); view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection"); view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius"); view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts"); @@ -9724,6 +9837,7 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView"); view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion"); view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion"); + view_listener_t::addMenu(new LLToolsCheckSelectionLODMode(), "Tools.ToolsCheckSelectionLODMode"); // Help menu // most items use the ShowFloater method @@ -9898,6 +10012,7 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedForceErrorCoroprocedureCrash(), "Advanced.ForceErrorCoroprocedureCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorWorkQueueCrash(), "Advanced.ForceErrorWorkQueueCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash"); + view_listener_t::addMenu(new LLAdvancedForceExceptionThreadCrash(), "Advanced.ForceExceptionThreadCrash"); view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer"); // Advanced (toplevel) diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 68c3dbc126..522c7e8109 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -73,7 +73,7 @@ void handle_buy(); void handle_take(bool take_separate = false); void handle_take_copy(); void handle_look_at_selection(const LLSD& param); -void handle_zoom_to_object(const LLUUID& object_id); +bool handle_zoom_to_object(const LLUUID& object_id); void handle_object_return(); void handle_object_delete(); void handle_object_edit(); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 9743ec0c59..3695478061 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -69,6 +69,7 @@ #include "llviewerassetupload.h" // linden libraries +#include "llfilesystem.h" #include "llnotificationsutil.h" #include "llsdserialize.h" #include "llsdutil.h" @@ -94,7 +95,7 @@ class LLFileEnableUploadModel : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterModelPreview* fmp = (LLFloaterModelPreview*) LLFloaterReg::findInstance("upload_model"); - if (fmp && fmp->isModelLoading()) + if (fmp && !fmp->isDead() && fmp->isModelLoading()) { return false; } @@ -478,13 +479,19 @@ const bool check_file_extension(const std::string& filename, LLFilePicker::ELoad return true; } -const void upload_single_file(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type) +void upload_single_file( + const std::vector<std::string>& filenames, + LLFilePicker::ELoadFilter type, + const LLUUID& dest) { std::string filename = filenames[0]; if (!check_file_extension(filename, type)) return; if (!filename.empty()) { + LLSD args; + args["filename"] = filename; + args["dest"] = dest; if (type == LLFilePicker::FFLOAD_WAV) { // pre-qualify wavs to make sure the format is acceptable @@ -499,12 +506,12 @@ const void upload_single_file(const std::vector<std::string>& filenames, LLFileP } else { - LLFloaterReg::showInstance("upload_sound", LLSD(filename)); + LLFloaterReg::showInstance("upload_sound", args); } } if (type == LLFilePicker::FFLOAD_IMAGE) { - LLFloaterReg::showInstance("upload_image", LLSD(filename)); + LLFloaterReg::showInstance("upload_image", args); } if (type == LLFilePicker::FFLOAD_ANIM) { @@ -512,11 +519,11 @@ const void upload_single_file(const std::vector<std::string>& filenames, LLFileP LLStringUtil::toLower(filename_lc); if (filename_lc.rfind(".anim") != std::string::npos) { - LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename)); + LLFloaterReg::showInstance("upload_anim_anim", args); } else { - LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename)); + LLFloaterReg::showInstance("upload_anim_bvh", args); } } } @@ -544,16 +551,9 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k) if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec)) { bool resource_upload = false; - if (asset_type == LLAssetType::AT_TEXTURE && allow_2k) + if (asset_type == LLAssetType::AT_TEXTURE) { - LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec); - if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename)) - { - S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); - S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); - expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height); - resource_upload = true; - } + resource_upload = true; } else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost)) { @@ -562,23 +562,115 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k) if (resource_upload) { - LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo( - filename, - asset_name, - asset_name, 0, - LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost); - - if (!allow_2k) + if (asset_type == LLAssetType::AT_TEXTURE) { - info_p->setMaxImageSize(1024); - } - LLResourceUploadInfo::ptr_t uploadInfo(info_p); + std::string exten = gDirUtilp->getExtension(filename); + U32 codec = LLImageBase::getCodecFromExtension(exten); + + // Load the image + LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); + if (image.isNull()) + { + LL_WARNS() << "Failed to create image container for " << filename << LL_ENDL; + continue; + } + if (!image->load(filename)) + { + LL_WARNS() << "Failed to load image: " << filename << LL_ENDL; + continue; + } + // Decompress or expand it in a raw image structure + LLPointer<LLImageRaw> raw_image = new LLImageRaw; + if (!image->decode(raw_image, 0.0f)) + { + LL_WARNS() << "Failed to decode image: " << filename << LL_ENDL; + continue; + } + // Check the image constraints + if ((image->getComponents() != 3) && (image->getComponents() != 4)) + { + LL_WARNS() << "Attempted to upload a texture that has " << image->getComponents() + << " components, but only 3 (RGB) or 4 (RGBA) are allowed." << LL_ENDL; + continue; + } + // Downscale images to fit the max_texture_dimensions_*, or 1024 if allow_2k is false + S32 max_width = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024; + S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024; + + S32 orig_width = raw_image->getWidth(); + S32 orig_height = raw_image->getHeight(); + + if (orig_width > max_width || orig_height > max_height) + { + // Calculate scale factors + F32 width_scale = (F32)max_width / (F32)orig_width; + F32 height_scale = (F32)max_height / (F32)orig_height; + F32 scale = llmin(width_scale, height_scale); + + // Calculate new dimensions, preserving aspect ratio + S32 new_width = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width)); + S32 new_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height)); - upload_new_resource(uploadInfo); + if (!raw_image->scale(new_width, new_height)) + { + LL_WARNS() << "Failed to scale image from " << orig_width << "x" << orig_height << " to " << new_width << "x" + << new_height << LL_ENDL; + continue; + } + + // Inform the resident about the resized image + LLSD subs; + subs["[ORIGINAL_WIDTH]"] = orig_width; + subs["[ORIGINAL_HEIGHT]"] = orig_height; + subs["[NEW_WIDTH]"] = new_width; + subs["[NEW_HEIGHT]"] = new_height; + subs["[MAX_WIDTH]"] = max_width; + subs["[MAX_HEIGHT]"] = max_height; + LLNotificationsUtil::add("ImageUploadResized", subs); + } + + raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + + LLTransactionID tid; + tid.generate(); + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + + LLPointer<LLImageJ2C> formatted = new LLImageJ2C; + + if (formatted->encode(raw_image, 0.0f)) + { + LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE); + fmt_file.write(formatted->getData(), formatted->getDataSize()); + + LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( + tid, LLAssetType::AT_TEXTURE, + asset_name, + asset_name, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight()) + )); + + upload_new_resource(assetUploadInfo); + } + } + else + { + LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo( + filename, + asset_name, + asset_name, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost); + LLResourceUploadInfo::ptr_t uploadInfo(info_p); + + upload_new_resource(uploadInfo); + } } } @@ -647,8 +739,31 @@ bool get_bulk_upload_expected_cost( LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType(codec); if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename)) { - S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); - S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + S32 biased_width, biased_height; + + S32 max_width = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024; + S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024; + + S32 orig_width = image_frmted->getWidth(); + S32 orig_height = image_frmted->getHeight(); + + if (orig_width > max_width || orig_height > max_height) + { + // Calculate scale factors + F32 width_scale = (F32)max_width / (F32)orig_width; + F32 height_scale = (F32)max_height / (F32)orig_height; + F32 scale = llmin(width_scale, height_scale); + + // Calculate new dimensions, preserving aspect ratio + biased_width = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width)); + biased_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height)); + } + else + { + biased_width = LLImageRaw::biasedDimToPowerOfTwo(orig_width, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + biased_height = LLImageRaw::biasedDimToPowerOfTwo(orig_height, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + } + total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height); S32 area = biased_width * biased_height; if (area >= LLAgentBenefits::MIN_2K_TEXTURE_AREA) @@ -709,7 +824,7 @@ bool get_bulk_upload_expected_cost( return file_count > 0; } -const void upload_bulk(const std::vector<std::string>& filtered_filenames, bool allow_2k) +void upload_bulk(const std::vector<std::string>& filtered_filenames, bool allow_2k, const LLUUID& dest) { S32 expected_upload_cost; S32 expected_upload_count; @@ -721,6 +836,7 @@ const void upload_bulk(const std::vector<std::string>& filtered_filenames, bool key["upload_cost"] = expected_upload_cost; key["upload_count"] = expected_upload_count; key["has_2k_textures"] = (textures_2k_count > 0); + key["dest"] = dest; LLSD array; for (const std::string& str : filtered_filenames) @@ -754,7 +870,7 @@ const void upload_bulk(const std::vector<std::string>& filtered_filenames, bool } -const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type, bool allow_2k) +void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type, bool allow_2k, const LLUUID& dest) { // TODO: // Check user balance for entire cost @@ -776,7 +892,7 @@ const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker:: filtered_filenames.push_back(filename); } } - upload_bulk(filtered_filenames, allow_2k); + upload_bulk(filtered_filenames, allow_2k, dest); } class LLFileUploadImage : public view_listener_t @@ -787,7 +903,7 @@ class LLFileUploadImage : public view_listener_t { gAgentCamera.changeCameraToDefault(); } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false); + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2, LLUUID::null), LLFilePicker::FFLOAD_IMAGE, false); return true; } }; @@ -818,7 +934,7 @@ class LLFileUploadSound : public view_listener_t { gAgentCamera.changeCameraToDefault(); } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false); + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2, LLUUID::null), LLFilePicker::FFLOAD_WAV, false); return true; } }; @@ -831,7 +947,7 @@ class LLFileUploadAnim : public view_listener_t { gAgentCamera.changeCameraToDefault(); } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false); + LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2, LLUUID::null), LLFilePicker::FFLOAD_ANIM, false); return true; } }; @@ -844,7 +960,7 @@ class LLFileUploadBulk : public view_listener_t { gAgentCamera.changeCameraToDefault(); } - LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2, true), LLFilePicker::FFLOAD_ALL, true); + LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2, true, LLUUID::null), LLFilePicker::FFLOAD_ALL, true); return true; } }; @@ -1134,7 +1250,7 @@ LLUUID upload_new_resource( name, desc, compression_info, destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms, - expected_upload_cost, show_inventory)); + expected_upload_cost, LLUUID::null, show_inventory)); upload_new_resource(uploadInfo, callback, userdata); return LLUUID::null; diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index d99f9dc4c6..8f7df48a2e 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -74,6 +74,17 @@ bool get_bulk_upload_expected_cost( void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k); +void upload_single_file( + const std::vector<std::string>& filenames, + LLFilePicker::ELoadFilter type, + const LLUUID& dest); + +void upload_bulk( + const std::vector<std::string>& filenames, + LLFilePicker::ELoadFilter type, + bool allow_2k, + const LLUUID& dest); + //consider moving all file pickers below to more suitable place class LLFilePickerThread : public LLThread { //multi-threaded file picker (runs system specific file picker in background and calls "notify" from main thread) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index b274ba5abb..44831aea03 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2137,6 +2137,21 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) EInstantMessage dialog = (EInstantMessage)d; LLHost sender = msg->getSender(); + LLSD metadata; + if (msg->getNumberOfBlocksFast(_PREHASH_MetaData) > 0) + { + S32 metadata_size = msg->getSizeFast(_PREHASH_MetaData, 0, _PREHASH_Data); + std::string metadata_buffer; + metadata_buffer.resize(metadata_size, 0); + + msg->getBinaryDataFast(_PREHASH_MetaData, _PREHASH_Data, &metadata_buffer[0], metadata_size, 0, metadata_size ); + std::stringstream metadata_stream(metadata_buffer); + if (LLSDSerialize::fromBinary(metadata, metadata_stream, metadata_size) == LLSDParser::PARSE_FAILURE) + { + metadata.clear(); + } + } + LLIMProcessing::processNewMessage(from_id, from_group, to_id, @@ -2151,7 +2166,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) position, binary_bucket, binary_bucket_size, - sender); + sender, + metadata); } void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id) @@ -2567,6 +2583,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) msg_notify["session_id"] = LLUUID(); msg_notify["from_id"] = chat.mFromID; msg_notify["source_type"] = chat.mSourceType; + // used to check if there is agent mention in the message + msg_notify["message"] = mesg; on_new_message(msg_notify); } @@ -3034,6 +3052,11 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**) } } +#ifdef LL_DISCORD + if (gSavedSettings.getBOOL("EnableDiscord")) + LLAppViewer::updateDiscordActivity(); +#endif + if ( LLTracker::isTracking(NULL) ) { // Check distance to beacon, if < 5m, remove beacon @@ -3171,6 +3194,7 @@ void send_agent_update(bool force_send, bool send_reliable) static F64 last_send_time = 0.0; static U32 last_control_flags = 0; + static bool control_flags_follow_up = false; static U8 last_render_state = 0; static U8 last_flags = AU_FLAGS_NONE; static LLQuaternion last_body_rot, @@ -3248,6 +3272,20 @@ void send_agent_update(bool force_send, bool send_reliable) break; } + // example: + // user taps crouch (control_flags 4128), viewer sends 4128 then immediately 0 + // server starts crouching motion but does not stop it, only once viewer sends 0 + // second time will server stop the motion. follow_up exists to make sure all + // states like 'crouch' motion are properly cleared server side. + // + // P.S. Server probably shouldn't require a reminder to stop a motion, + // but at the moment it does. + if (control_flags_follow_up) + { + send_update = true; + break; + } + // check translation constexpr F32 TRANSLATE_THRESHOLD = 0.01f; if ((last_camera_pos_agent - camera_pos_agent).magVec() > TRANSLATE_THRESHOLD) @@ -3381,6 +3419,7 @@ void send_agent_update(bool force_send, bool send_reliable) // remember last update data last_send_time = now; + control_flags_follow_up = last_control_flags != control_flags; last_control_flags = control_flags; last_render_state = render_state; last_flags = flags; diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 16ddc2f89c..f11fa09ce9 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -450,7 +450,7 @@ std::string LLGridManager::getGridLabel(const std::string& grid) { std::string grid_label; std::string grid_name = getGrid(grid); - if (!grid.empty()) + if (!grid_name.empty()) { grid_label = mGridList[grid_name][GRID_LABEL_VALUE].asString(); } @@ -466,7 +466,7 @@ std::string LLGridManager::getGridId(const std::string& grid) { std::string grid_id; std::string grid_name = getGrid(grid); - if (!grid.empty()) + if (!grid_name.empty()) { grid_id = mGridList[grid_name][GRID_ID_VALUE].asString(); } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8d90187e91..9e77b40a45 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4184,8 +4184,11 @@ void LLViewerObject::boostTexturePriority(bool boost_children /* = true */) if (isSculpted() && !isMesh()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID sculpt_id = sculpt_params->getSculptTexture(); - LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED); + if (sculpt_params) + { + LLUUID sculpt_id = sculpt_params->getSculptTexture(); + LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED); + } } if (boost_children) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 66a19d3601..432da2e990 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1328,12 +1328,12 @@ const S32 LLViewerParcelMgr::getAgentParcelId() const return INVALID_PARCEL_ID; } -void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region) +void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel) { if(!parcel) return; - LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth ); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromID(parcel->getRegionID()); if (!region) return; @@ -1677,10 +1677,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // Actually extract the data. if (parcel) { + // store region_id in the parcel so we can find it again later + LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion(msg->getSender()); + if (parcel_region) + { + parcel->setRegionID(parcel_region->getRegionID()); + } + if (local_id == parcel_mgr.mAgentParcel->getLocalID()) { // Parcels in different regions can have same ids. - LLViewerRegion* parcel_region = LLWorld::getInstance()->getRegion(msg->getSender()); LLViewerRegion* agent_region = gAgent.getRegion(); if (parcel_region && agent_region && parcel_region->getRegionID() == agent_region->getRegionID()) { diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 95d693662e..1925cd23ed 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -219,7 +219,7 @@ public: // containing the southwest corner of the selection. // If want_reply_to_update, simulator will send back a ParcelProperties // message. - void sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region = false); + void sendParcelPropertiesUpdate(LLParcel* parcel); // Takes an Access List flag, like AL_ACCESS or AL_BAN void sendParcelAccessListUpdate(U32 which); diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index da03d3b015..e36ad0e722 100755 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -33,6 +33,7 @@ #include "llfloaterreg.h" #include "llgl.h" #include "llrender.h" +#include "lluicolor.h" #include "v4color.h" #include "v2math.h" @@ -50,8 +51,8 @@ #include "pipeline.h" -static const U8 OVERLAY_IMG_COMPONENTS = 4; -static const F32 LINE_WIDTH = 0.0625f; +static constexpr U8 OVERLAY_IMG_COMPONENTS = 4; +static constexpr F32 LINE_WIDTH = 0.0625f; bool LLViewerParcelOverlay::sColorSetInitialized = false; LLUIColor LLViewerParcelOverlay::sAvailColor; @@ -91,7 +92,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ // Initialize the GL texture with empty data. // // Create the base texture. - U8 *raw = mImageRaw->getData(); + U8* raw = mImageRaw->getData(); const S32 COUNT = mParcelGridsPerEdge * mParcelGridsPerEdge * OVERLAY_IMG_COMPONENTS; for (S32 i = 0; i < COUNT; i++) { @@ -158,10 +159,10 @@ bool LLViewerParcelOverlay::encroachesOwned(const std::vector<LLBBox>& boxes) co LLVector3 min = boxes[i].getMinAgent(); LLVector3 max = boxes[i].getMaxAgent(); - S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 top = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 top = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); for (S32 row = top; row <= bottom; row++) { @@ -186,10 +187,10 @@ bool LLViewerParcelOverlay::encroachesOnUnowned(const std::vector<LLBBox>& boxes LLVector3 min = boxes[i].getMinAgent(); LLVector3 max = boxes[i].getMaxAgent(); - S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 top = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 top = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); for (S32 row = top; row <= bottom; row++) { @@ -223,10 +224,10 @@ bool LLViewerParcelOverlay::encroachesOnNearbyParcel(const std::vector<LLBBox>& return true; } - S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 bottom = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); - S32 top = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1)); + S32 left = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 right = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 bottom = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); + S32 top = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1.f)); const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; @@ -348,11 +349,11 @@ void LLViewerParcelOverlay::updateOverlayTexture() const LLColor4U auction = sAuctionColor.get(); // Create the base texture. - U8 *raw = mImageRaw->getData(); + U8* raw = mImageRaw->getData(); const S32 COUNT = mParcelGridsPerEdge * mParcelGridsPerEdge; S32 max = mOverlayTextureIdx + mParcelGridsPerEdge; if (max > COUNT) max = COUNT; - S32 pixel_index = mOverlayTextureIdx*OVERLAY_IMG_COMPONENTS; + S32 pixel_index = mOverlayTextureIdx * OVERLAY_IMG_COMPONENTS; S32 i; for (i = mOverlayTextureIdx; i < max; i++) { @@ -361,7 +362,7 @@ void LLViewerParcelOverlay::updateOverlayTexture() U8 r,g,b,a; // Color stored in low three bits - switch( ownership & 0x7 ) + switch (ownership & 0x7) { case PARCEL_PUBLIC: r = avail.mV[VRED]; @@ -407,10 +408,10 @@ void LLViewerParcelOverlay::updateOverlayTexture() break; } - raw[pixel_index + 0] = (U8)r; - raw[pixel_index + 1] = (U8)g; - raw[pixel_index + 2] = (U8)b; - raw[pixel_index + 3] = (U8)a; + raw[pixel_index + VRED] = (U8)r; + raw[pixel_index + VGREEN] = (U8)g; + raw[pixel_index + VBLUE] = (U8)b; + raw[pixel_index + VALPHA] = (U8)a; pixel_index += OVERLAY_IMG_COMPONENTS; } @@ -431,11 +432,10 @@ void LLViewerParcelOverlay::updateOverlayTexture() } } - -void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8 *packed_overlay) +void LLViewerParcelOverlay::uncompressLandOverlay(S32 chunk, U8* packed_overlay) { // Unpack the message data into the ownership array - S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge; + S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge; S32 chunk_size = size / PARCEL_OVERLAY_CHUNKS; memcpy(mOwnership + chunk*chunk_size, packed_overlay, chunk_size); /*Flawfinder: ignore*/ @@ -460,7 +460,7 @@ void LLViewerParcelOverlay::updatePropertyLines() mEdges.clear(); - const F32 GRID_STEP = PARCEL_GRID_STEP_METERS; + constexpr F32 GRID_STEP = PARCEL_GRID_STEP_METERS; const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; for (S32 row = 0; row < GRIDS_PER_EDGE; row++) @@ -537,16 +537,16 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3 auto split = [&](const LLVector3& start, F32 x, F32 y, F32 z, F32 part) { - F32 new_x = start.mV[0] + (x - start.mV[0]) * part; - F32 new_y = start.mV[1] + (y - start.mV[1]) * part; - F32 new_z = start.mV[2] + (z - start.mV[2]) * part; + F32 new_x = start.mV[VX] + (x - start.mV[VX]) * part; + F32 new_y = start.mV[VY] + (y - start.mV[VY]) * part; + F32 new_z = start.mV[VZ] + (z - start.mV[VZ]) * part; edge.vertices.emplace_back(new_x, new_y, new_z); }; auto checkForSplit = [&]() { const LLVector3& last_outside = edge.vertices.back(); - F32 z0 = last_outside.mV[2]; + F32 z0 = last_outside.mV[VZ]; F32 z1 = outside_z; if ((z0 >= water_z && z1 >= water_z) || (z0 < water_z && z1 < water_z)) return; @@ -581,7 +581,7 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3 outside_y += dy * (dy - LINE_WIDTH); // Middle part, full width - const S32 GRID_STEP = (S32)PARCEL_GRID_STEP_METERS; + constexpr S32 GRID_STEP = (S32)PARCEL_GRID_STEP_METERS; for (S32 i = 1; i < GRID_STEP; i++) { inside_z = land.resolveHeightRegion( inside_x, inside_y ); @@ -711,7 +711,7 @@ void LLViewerParcelOverlay::renderPropertyLines() bool render_hidden = LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build"); - const F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f; + constexpr F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f; for (const Edge& edge : mEdges) { @@ -744,7 +744,7 @@ void LLViewerParcelOverlay::renderPropertyLines() else { LLVector3 visible = vertex; - visible.mV[2] = water_z; + visible.mV[VZ] = water_z; gGL.vertex3fv(visible.mV); } } @@ -758,7 +758,7 @@ void LLViewerParcelOverlay::renderPropertyLines() gGL.begin(LLRender::TRIANGLE_STRIP); LLColor4U color = edge.color; - color.mV[3] /= 4; + color.mV[VALPHA] /= 4; gGL.color4ubv(color.mV); for (const LLVector3& vertex : edge.vertices) @@ -792,7 +792,7 @@ void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F3 gGL.end(); } -void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color) { static LLCachedControl<bool> show(gSavedSettings, "MiniMapShowPropertyLines"); @@ -803,8 +803,8 @@ void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_me LLVector3 origin_agent = mRegion->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); - F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter; - F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter; + F32 region_left = rel_region_pos.mV[VX] * scale_pixels_per_meter; + F32 region_bottom = rel_region_pos.mV[VY] * scale_pixels_per_meter; F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter; const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 03ae464cb8..50bef02ddf 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -34,12 +34,11 @@ #include "llframetimer.h" #include "lluuid.h" #include "llviewertexture.h" -#include "llgl.h" -#include "lluicolor.h" class LLViewerRegion; class LLVector3; class LLColor4U; +class LLUIColor; class LLVector2; class LLViewerParcelOverlay : public LLGLUpdate @@ -65,19 +64,18 @@ public: bool isSoundLocal(const LLVector3& pos) const; - bool isBuildCameraAllowed(const LLVector3& pos) const; F32 getOwnedRatio() const; // Returns the number of vertices drawn void renderPropertyLines(); void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); - U8 ownership( const LLVector3& pos) const; - U8 parcelLineFlags( const LLVector3& pos) const; + U8 ownership(const LLVector3& pos) const; + U8 parcelLineFlags(const LLVector3& pos) const; U8 parcelLineFlags(S32 row, S32 col) const; // MANIPULATE - void uncompressLandOverlay(S32 chunk, U8 *compressed_overlay); + void uncompressLandOverlay(S32 chunk, U8* compressed_overlay); // Indicate property lines and overlay texture need to be rebuilt. void setDirty(); @@ -88,8 +86,7 @@ public: private: // This is in parcel rows and columns, not grid rows and columns // Stored in bottom three bits. - U8 ownership(S32 row, S32 col) const - { return parcelFlags(row, col, (U8)0x7); } + U8 ownership(S32 row, S32 col) const { return parcelFlags(row, col, (U8)0x7); } U8 parcelFlags(S32 row, S32 col, U8 flags) const; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 697433148b..a085bc4d91 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -38,7 +38,6 @@ #include "llregionhandle.h" #include "llsurface.h" #include "message.h" -//#include "vmath.h" #include "v3math.h" #include "v4math.h" @@ -3720,12 +3719,6 @@ bool LLViewerRegion::bakesOnMeshEnabled() const mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean()); } -bool LLViewerRegion::meshRezEnabled() const -{ - return (mSimulatorFeatures.has("MeshRezEnabled") && - mSimulatorFeatures["MeshRezEnabled"].asBoolean()); -} - bool LLViewerRegion::dynamicPathfindingEnabled() const { return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") && diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index d0ec1fe877..244e2b7835 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -333,7 +333,6 @@ public: void getInfo(LLSD& info); - bool meshRezEnabled() const; bool meshUploadEnabled() const; bool bakesOnMeshEnabled() const; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 73aabf49d1..d39d466205 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -220,7 +220,22 @@ SimMeasurement<F64Megabytes > SIM_PHYSICS_MEM("physicsmemoryallocated", "", LL LLTrace::SampleStatHandle<F64Milliseconds > FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"), FRAMETIME("frametime", "Measured frame time"), - SIM_PING("simpingstat"); + SIM_PING("simpingstat"), + FRAMETIME_JITTER_99TH("frametimejitter99", "99th percentile of frametime jitter over the last 5 seconds."), + FRAMETIME_JITTER_95TH("frametimejitter95", "99th percentile of frametime jitter over the last 5 seconds."), + FRAMETIME_99TH("frametime99", "99th percentile of frametime over the last 5 seconds."), + FRAMETIME_95TH("frametime95", "99th percentile of frametime over the last 5 seconds."), + FRAMETIME_JITTER_CUMULATIVE("frametimejitcumulative", "Cumulative frametime jitter over the session."), + FRAMETIME_JITTER_STDDEV("frametimejitterstddev", "Standard deviation of frametime jitter in a 5 second period."), + FRAMETIME_STDDEV("frametimestddev", "Standard deviation of frametime in a 5 second period."); + +LLTrace::SampleStatHandle<U32> FRAMETIME_JITTER_EVENTS("frametimeevents", "Number of frametime events in the session. Applies when jitter exceeds 10% of the previous frame."), + FRAMETIME_JITTER_EVENTS_PER_MINUTE("frametimeeventspm", "Average number of frametime events per minute."), + FRAMETIME_JITTER_EVENTS_LAST_MINUTE("frametimeeventslastmin", "Number of frametime events in the last minute."); + +LLTrace::SampleStatHandle<F64> NOTRMALIZED_FRAMETIME_JITTER_SESSION("normalizedframetimejitter", "Normalized frametime jitter over the session."); +LLTrace::SampleStatHandle<F64> NFTV("nftv", "Normalized frametime variation."); +LLTrace::SampleStatHandle<F64> NORMALIZED_FRAMTIME_JITTER_PERIOD("normalizedframetimejitterperiod", "Normalized frametime jitter over the last 5 seconds."); LLTrace::EventStatHandle<LLUnit<F64, LLUnits::Meters> > AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections"); @@ -264,16 +279,128 @@ void LLViewerStats::resetStats() getRecording().reset(); } +// Helper for calculating Nth percentile with linear interpolation +template<typename T> +T calcPercentile(const std::vector<T>& sorted, double percent) +{ + if (sorted.empty()) + return T(0); + double idx = percent * (sorted.size() - 1); + size_t idx_below = static_cast<size_t>(std::floor(idx)); + size_t idx_above = static_cast<size_t>(std::ceil(idx)); + if (idx_below == idx_above) + return sorted[idx_below]; + double weight_above = idx - idx_below; + return sorted[idx_below] * (1.0 - weight_above) + sorted[idx_above] * weight_above; +} + +template<typename T> +T calcStddev(const std::vector<T>& values) +{ + if (values.size() < 2) + return T(0); + double sum = 0, sq_sum = 0; + for (const auto& v : values) + { + double d = v.value(); + sum += d; + sq_sum += d * d; + } + double mean = sum / values.size(); + double variance = (sq_sum / values.size()) - (mean * mean); + return T(std::sqrt(variance)); +} + void LLViewerStats::updateFrameStats(const F64Seconds time_diff) { if (gFrameCount && mLastTimeDiff > (F64Seconds)0.0) { + mTotalTime += time_diff; sample(LLStatViewer::FRAMETIME, time_diff); // old stats that were never really used F64Seconds jit = (F64Seconds)std::fabs((mLastTimeDiff - time_diff)); sample(LLStatViewer::FRAMETIME_JITTER, jit); - } + mTotalFrametimeJitter += jit; + sample(LLStatViewer::FRAMETIME_JITTER_CUMULATIVE, mTotalFrametimeJitter); + sample(LLStatViewer::NOTRMALIZED_FRAMETIME_JITTER_SESSION, mTotalFrametimeJitter / mTotalTime); + + mLastNoramlizedSessionJitter = mTotalFrametimeJitter / mTotalTime; + + static LLCachedControl<F32> frameTimeEventThreshold(gSavedSettings, "StatsFrametimeEventThreshold", 0.1f); + + if (time_diff - mLastTimeDiff > mLastTimeDiff * frameTimeEventThreshold()) + { + sample(LLStatViewer::FRAMETIME_JITTER_EVENTS, mFrameJitterEvents++); + mFrameJitterEventsLastMinute++; + } + + mFrameTimes.push_back(time_diff); + mFrameTimesJitter.push_back(jit); + + mLastFrameTimeSample += time_diff; + mTimeSinceLastEventSample += time_diff; + + static LLCachedControl<S32> frameTimeSampleSeconds(gSavedSettings, "StatsFrametimeSampleSeconds", 5); + + if (mLastFrameTimeSample >= frameTimeSampleSeconds()) + { + std::sort(mFrameTimes.begin(), mFrameTimes.end()); + std::sort(mFrameTimesJitter.begin(), mFrameTimesJitter.end()); + + // Use new helpers for calculations + F64Seconds frame_time_stddev = calcStddev(mFrameTimes); + sample(LLStatViewer::FRAMETIME_STDDEV, frame_time_stddev); + F64Seconds ninety_ninth_percentile = calcPercentile(mFrameTimes, 0.99); + F64Seconds ninety_fifth_percentile = calcPercentile(mFrameTimes, 0.95); + sample(LLStatViewer::FRAMETIME_99TH, ninety_ninth_percentile); + sample(LLStatViewer::FRAMETIME_95TH, ninety_fifth_percentile); + + frame_time_stddev = calcStddev(mFrameTimesJitter); + sample(LLStatViewer::FRAMETIME_JITTER_STDDEV, frame_time_stddev); + + ninety_ninth_percentile = calcPercentile(mFrameTimesJitter, 0.99); + ninety_fifth_percentile = calcPercentile(mFrameTimesJitter, 0.95); + sample(LLStatViewer::FRAMETIME_JITTER_99TH, ninety_ninth_percentile); + sample(LLStatViewer::FRAMETIME_JITTER_95TH, ninety_fifth_percentile); + + F64 averageFrameTime = 0; + for (const auto& frame_time : mFrameTimes) + { + averageFrameTime += frame_time.value(); + } + averageFrameTime /= mFrameTimes.size(); + + sample(LLStatViewer::NFTV, frame_time_stddev / averageFrameTime); + mLastNormalizedFrametimeVariance = frame_time_stddev / averageFrameTime; + + // Add up all of the jitter values. + F64 totalJitter = 0; + for (const auto& frame_jitter : mFrameTimesJitter) + { + totalJitter += frame_jitter.value(); + } + + mLastNormalizedPeriodJitter = totalJitter / mLastFrameTimeSample; + + sample(LLStatViewer::NORMALIZED_FRAMTIME_JITTER_PERIOD, mLastNormalizedPeriodJitter); + + mFrameTimes.clear(); + mFrameTimesJitter.clear(); + mLastFrameTimeSample = F64Seconds(0); + } + + if (mTimeSinceLastEventSample >= 60) + { + mEventMinutes++; + // Calculate average events per minute + U64 frame_time_events_per_minute = (U64)mFrameJitterEvents / mEventMinutes; + sample(LLStatViewer::FRAMETIME_JITTER_EVENTS_PER_MINUTE, frame_time_events_per_minute); + sample(LLStatViewer::FRAMETIME_JITTER_EVENTS_LAST_MINUTE, mFrameJitterEventsLastMinute); + mFrameJitterEventsLastMinute = 0; + mTimeSinceLastEventSample = F64Seconds(0); + } + } mLastTimeDiff = time_diff; } @@ -546,6 +673,11 @@ void send_viewer_stats(bool include_preferences) // send fps only for time app spends in foreground agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32(); + + agent["normalized_session_jitter"] = LLViewerStats::instance().getLastNormalizedSessionJitter(); + agent["normalized_frametime_variance"] = LLViewerStats::instance().getLastNormalizedFrametimeVariance(); + agent["normalized_period_jitter"] = LLViewerStats::instance().getLastNormalizedPeriodJitter(); + agent["version"] = LLVersionInfo::instance().getChannelAndVersion(); std::string language = LLUI::getLanguage(); agent["language"] = language; diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 8aed1c537e..011269d7ee 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -271,10 +271,30 @@ public: LLTrace::Recording& getRecording() { return mRecording; } const LLTrace::Recording& getRecording() const { return mRecording; } + F64 getLastNormalizedSessionJitter() const { return mLastNoramlizedSessionJitter; } + F64 getLastNormalizedFrametimeVariance() const { return mLastNormalizedFrametimeVariance; } + F64 getLastNormalizedPeriodJitter() const { return mLastNormalizedPeriodJitter; } + private: LLTrace::Recording mRecording; F64Seconds mLastTimeDiff; // used for time stat updates + F64Seconds mTotalFrametimeJitter; + + U32 mFrameJitterEvents = 0; + U32 mFrameJitterEventsLastMinute = 0; + U32 mEventMinutes = 0; + F64Seconds mTotalTime; + + F64Seconds mLastFrameTimeSample; // used for frame time stats + F64Seconds mTimeSinceLastEventSample; + std::vector<F64Seconds> mFrameTimes; // used for frame time stats + std::vector<F64Seconds> mFrameTimesJitter; // used for frame time jitter stats + + F64 mLastNoramlizedSessionJitter; // used for frame time jitter stats + F64 mLastNormalizedFrametimeVariance; // Used when submitting jitter stats + F64 mLastNormalizedPeriodJitter; + }; static const F32 SEND_STATS_PERIOD = 300.0f; diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 4a9dd1c1b6..52939dbbae 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -524,7 +524,6 @@ void LLViewerTexture::updateClass() bool is_low = is_sys_low || over_pct > 0.f; static bool was_low = false; - static bool was_sys_low = false; if (is_low && !was_low) { @@ -542,7 +541,6 @@ void LLViewerTexture::updateClass() } was_low = is_low; - was_sys_low = is_sys_low; if (is_low) { @@ -1107,6 +1105,7 @@ void LLViewerFetchedTexture::init(bool firstinit) mOrigHeight = 0; mHasAux = false; mNeedsAux = false; + mLastWorkerDiscardLevel = -1; mRequestedDiscardLevel = -1; mRequestedDownloadPriority = 0.f; mFullyLoaded = false; @@ -1259,12 +1258,11 @@ void LLViewerFetchedTexture::loadFromFastCache() if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL) { - S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS; - S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS; - if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)) + if (mRawImage && (mRawImage->getWidth() > DEFAULT_THUMBNAIL_DIMENSIONS || mRawImage->getHeight() > DEFAULT_THUMBNAIL_DIMENSIONS)) { - // scale oversized icon, no need to give more work to gl - mRawImage->scale(expected_width, expected_height); + // Scale oversized thumbnail + // thumbnails aren't supposed to go over DEFAULT_THUMBNAIL_DIMENSIONS + mRawImage->scale(DEFAULT_THUMBNAIL_DIMENSIONS, DEFAULT_THUMBNAIL_DIMENSIONS); } } @@ -1957,9 +1955,9 @@ bool LLViewerFetchedTexture::processFetchResults(S32& desired_discard, S32 curre bool LLViewerFetchedTexture::updateFetch() { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false); + static LLCachedControl<bool> textures_decode_disabled(gSavedSettings, "TextureDecodeDisabled", false); - if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode + if (textures_decode_disabled) // don't fetch the surface textures in wireframe mode { return false; } @@ -1994,7 +1992,7 @@ bool LLViewerFetchedTexture::updateFetch() LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending"); return false; // process any raw image data in callbacks before replacing } - if(mInFastCacheList) + if (mInFastCacheList) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache"); return false; @@ -2019,7 +2017,7 @@ bool LLViewerFetchedTexture::updateFetch() if (mAuxRawImage.notNull()) sAuxCount--; // keep in mind that fetcher still might need raw image, don't modify original bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mFetchState, mRawImage, mAuxRawImage, - mLastHttpGetStatus); + mLastHttpGetStatus); if (mRawImage.notNull()) sRawCount++; if (mAuxRawImage.notNull()) { @@ -2035,7 +2033,7 @@ bool LLViewerFetchedTexture::updateFetch() else { mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, - mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); } if (!processFetchResults(desired_discard, current_discard, fetch_discard, decode_priority)) @@ -2046,7 +2044,7 @@ bool LLViewerFetchedTexture::updateFetch() if (mIsFetching) { static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f. - if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME) + if (decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME) { mStopFetchingTimer.reset(); LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority); @@ -2062,7 +2060,7 @@ bool LLViewerFetchedTexture::updateFetch() LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0"); make_request = false; } - else if(mDesiredDiscardLevel > getMaxDiscardLevel()) + else if (mDesiredDiscardLevel > getMaxDiscardLevel()) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max"); make_request = false; @@ -2103,7 +2101,7 @@ bool LLViewerFetchedTexture::updateFetch() if (make_request) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request"); - S32 w=0, h=0, c=0; + S32 w = 0, h = 0, c = 0; if (getDiscardLevel() >= 0) { w = mGLTexturep->getWidth(0); @@ -2121,18 +2119,19 @@ bool LLViewerFetchedTexture::updateFetch() S32 fetch_request_response = -1; S32 worker_discard = -1; fetch_request_response = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority, - w, h, c, desired_discard, needsAux(), mCanUseHTTP); + w, h, c, desired_discard, needsAux(), mCanUseHTTP); if (fetch_request_response >= 0) // positive values and 0 are discard values { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created"); mHasFetcher = true; mIsFetching = true; + mLastWorkerDiscardLevel = worker_discard; // in some cases createRequest can modify discard, as an example // bake textures are always at discard 0 mRequestedDiscardLevel = llmin(desired_discard, fetch_request_response); mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, - mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); } else if (fetch_request_response == LLTextureFetch::CREATE_REQUEST_ERROR_TRANSITION) { @@ -2146,7 +2145,7 @@ bool LLViewerFetchedTexture::updateFetch() S32 decoded_discard; bool decoded; S32 fetch_state = LLAppViewer::getTextureFetch()->getLastFetchState(mID, desired_discard, decoded_discard, decoded); - if (fetch_state > 1 && decoded && decoded_discard >=0 && decoded_discard <= desired_discard) + if (fetch_state > 1 && decoded && decoded_discard >= 0 && decoded_discard <= desired_discard) { // worker actually has the image if (mRawImage.notNull()) sRawCount--; @@ -2770,11 +2769,9 @@ void LLViewerFetchedTexture::saveRawImage() } else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL) { - S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS; - S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS; - if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height) + if (mRawImage->getWidth() > DEFAULT_THUMBNAIL_DIMENSIONS || mRawImage->getHeight() > DEFAULT_THUMBNAIL_DIMENSIONS) { - mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents()); + mSavedRawImage = new LLImageRaw(DEFAULT_THUMBNAIL_DIMENSIONS, DEFAULT_THUMBNAIL_DIMENSIONS, mRawImage->getComponents()); mSavedRawImage->copyScaled(mRawImage); } else diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index e1582c74bd..f9311d85cb 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -444,6 +444,7 @@ protected: bool mKnownDrawSizeChanged ; std::string mUrl; + S32 mLastWorkerDiscardLevel; S32 mRequestedDiscardLevel; F32 mRequestedDownloadPriority; S32 mFetchState; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 0d02dc034e..6f79532ec3 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -911,6 +911,7 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag bool on_screen = false; U32 face_count = 0; + U32 max_faces_to_check = 1024; // get adjusted bias based on image resolution LLImageGL* img = imagep->getGLTexture(); @@ -923,13 +924,15 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) { - for (S32 fi = 0; fi < imagep->getNumFaces(i); ++fi) + face_count += imagep->getNumFaces(i); + S32 faces_to_check = (face_count > max_faces_to_check) ? 0 : imagep->getNumFaces(i); + + for (S32 fi = 0; fi < faces_to_check; ++fi) { LLFace* face = (*(imagep->getFaceList(i)))[fi]; if (face && face->getViewerObject()) { - ++face_count; F32 radius; F32 cos_angle_to_view_dir; @@ -992,11 +995,10 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag } } - if (face_count > 1024) + if (face_count > max_faces_to_check) { // this texture is used in so many places we should just boost it and not bother checking its vsize // this is especially important because the above is not time sliced and can hit multiple ms for a single texture - imagep->setBoostLevel(LLViewerFetchedTexture::BOOST_HIGH); - // Do we ever remove it? This also sets texture nodelete! + max_vsize = MAX_IMAGE_AREA; } if (imagep->getType() == LLViewerTexture::LOD_TEXTURE && imagep->getBoostLevel() == LLViewerTexture::BOOST_NONE) @@ -1195,6 +1197,8 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time) enditer = iter; LLViewerFetchedTexture *imagep = *curiter; imagep->loadFromFastCache(); + if (timer.getElapsedTimeF32() > max_time) + break; } mFastCacheList.erase(mFastCacheList.begin(), enditer); return timer.getElapsedTimeF32(); @@ -1306,7 +1310,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time) LLTimer timer; //loading from fast cache - updateImagesLoadingFastCache(max_time); + max_time -= updateImagesLoadingFastCache(max_time); // Update texture stats and priorities std::vector<LLPointer<LLViewerFetchedTexture> > image_list; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index f8017bb4ed..fdd75f9c6c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1424,11 +1424,17 @@ void LLViewerWindow::handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask mWindow->showCursorFromMouseMove(); - if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME - && !gDisconnected) + if (!gDisconnected) + { + if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME) { gAgent.clearAFK(); } + else + { + gAwayTriggerTimer.reset(); + } + } } void LLViewerWindow::handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask) @@ -1547,6 +1553,10 @@ bool LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, bool repeated) { gAgent.clearAFK(); } + else + { + gAwayTriggerTimer.reset(); + } // *NOTE: We want to interpret KEY_RETURN later when it arrives as // a Unicode char, not as a keydown. Otherwise when client frame @@ -2291,13 +2301,13 @@ void LLViewerWindow::initWorldUI() url = LLWeb::expandURLSubstitutions(url, LLSD()); destinations->navigateTo(url, HTTP_CONTENT_TEXT_HTML); } - LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents"); - if (avatar_picker) + LLMediaCtrl* avatar_welcome_pack = LLFloaterReg::getInstance("avatar_welcome_pack")->findChild<LLMediaCtrl>("avatar_picker_contents"); + if (avatar_welcome_pack) { - avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); - std::string url = gSavedSettings.getString("AvatarPickerURL"); + avatar_welcome_pack->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL")); + std::string url = gSavedSettings.getString("AvatarWelcomePack"); url = LLWeb::expandURLSubstitutions(url, LLSD()); - avatar_picker->navigateTo(url, HTTP_CONTENT_TEXT_HTML); + avatar_welcome_pack->navigateTo(url, HTTP_CONTENT_TEXT_HTML); } } } @@ -3015,7 +3025,8 @@ bool LLViewerWindow::handleKey(KEY key, MASK mask) { if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel")) { - if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove")) + LLCachedControl<bool> key_move(gSavedSettings, "ArrowKeysAlwaysMove"); + if (key_move()) { // let Control-Up and Control-Down through for chat line history, if (!(key == KEY_UP && mask == MASK_CONTROL) @@ -3029,10 +3040,9 @@ bool LLViewerWindow::handleKey(KEY key, MASK mask) case KEY_RIGHT: case KEY_UP: case KEY_DOWN: - case KEY_PAGE_UP: - case KEY_PAGE_DOWN: - case KEY_HOME: - case KEY_END: + case KEY_PAGE_UP: //jump + case KEY_PAGE_DOWN: // down + case KEY_HOME: // toggle fly // when chatbar is empty or ArrowKeysAlwaysMove set, // pass arrow keys on to avatar... return false; @@ -4780,7 +4790,18 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save #else boost::filesystem::path b_path(lastSnapshotDir); #endif - if (!boost::filesystem::is_directory(b_path)) + boost::system::error_code ec; + if (!boost::filesystem::is_directory(b_path, ec) || ec.failed()) + { + LLSD args; + args["PATH"] = lastSnapshotDir; + LLNotificationsUtil::add("SnapshotToLocalDirNotExist", args); + resetSnapshotLoc(); + failure_cb(); + return; + } + boost::filesystem::space_info b_space = boost::filesystem::space(b_path, ec); + if (ec.failed()) { LLSD args; args["PATH"] = lastSnapshotDir; @@ -4789,7 +4810,6 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save failure_cb(); return; } - boost::filesystem::space_info b_space = boost::filesystem::space(b_path); if (b_space.free < image->getDataSize()) { LLSD args; @@ -4806,6 +4826,8 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save LLNotificationsUtil::add("SnapshotToComputerFailed", args); failure_cb(); + + // Shouldn't there be a return here? } // Look for an unused file name diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 3306289f51..c6a7a59034 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -575,7 +575,7 @@ private: // joint states to be animated //------------------------------------------------------------------------- LLPointer<LLJointState> mPelvisState; - LLCharacter* mCharacter; + LLCharacter* mCharacter; }; /** @@ -678,11 +678,13 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mVisuallyMuteSetting(AV_RENDER_NORMALLY), mMutedAVColor(LLColor4::white /* used for "uninitialize" */), mFirstFullyVisible(true), + mWaitingForMeshes(false), mFirstDecloudTime(-1.f), mFullyLoaded(false), mPreviousFullyLoaded(false), mFullyLoadedInitialized(false), mLastCloudAttachmentCount(-1), + mFullyLoadedFrameCounter(0), mVisualComplexity(VISUAL_COMPLEXITY_UNKNOWN), mLoadedCallbacksPaused(false), mLoadedCallbackTextures(0), @@ -776,11 +778,9 @@ std::string LLVOAvatar::avString() const { return " " + getFullname() + " "; } - else - { - std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); - return " Avatar '" + getFullname() + "' " + viz_string + " "; - } + + std::string status = LLVOAvatar::rezStatusToString(getRezzedStatus()); + return " Avatar '" + getDebugName() + "' " + status + " "; } void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string comment) @@ -803,10 +803,10 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c if (gSavedSettings.getBOOL("DebugAvatarRezTime")) { LLSD args; - args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32()); - args["TIME"] = llformat("%d",(U32)mRuthDebugTimer.getElapsedTimeF32()); + args["EXISTENCE"] = llformat("%d", (U32)mDebugExistenceTimer.getElapsedTimeF32()); + args["TIME"] = llformat("%d", (U32)mRuthDebugTimer.getElapsedTimeF32()); args["NAME"] = getFullname(); - LLNotificationsUtil::add(notification_name,args); + LLNotificationsUtil::add(notification_name, args); } } @@ -819,14 +819,14 @@ LLVOAvatar::~LLVOAvatar() if (!mFullyLoaded) { - debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud"); + debugAvatarRezTime("AvatarRezLeftCloudNotification", "left after ruth seconds as cloud"); } else { - debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding"); + debugAvatarRezTime("AvatarRezLeftNotification", "left sometime after declouding"); } - if(mTuned) + if (mTuned) { LLPerfStats::tunedAvatars--; mTuned = false; @@ -920,12 +920,12 @@ bool LLVOAvatar::isFullyTextured() const bool LLVOAvatar::hasGray() const { - return !getIsCloud() && !isFullyTextured(); + return !getHasMissingParts() && !isFullyTextured(); } S32 LLVOAvatar::getRezzedStatus() const { - if (getIsCloud()) return 0; + if (getHasMissingParts()) return 0; bool textured = isFullyTextured(); bool all_baked_loaded = allBakedTexturesCompletelyDownloaded(); if (textured && all_baked_loaded && getAttachmentCount() == mSimAttachments.size()) return 4; @@ -968,34 +968,49 @@ bool LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars) ++grey_avatars; } } - return !grey_avatars; + return grey_avatars == 0; } // static -void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars) +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars) { counts.clear(); counts.resize(5); avg_cloud_time = 0; cloud_avatars = 0; + pending_meshes = 0; + control_avatars = 0; S32 count_avg = 0; for (LLCharacter* character : LLCharacter::sInstances) { - if (LLVOAvatar* inst = (LLVOAvatar*)character) + LLVOAvatar* inst = (LLVOAvatar*)character; + if (inst && !inst->isUIAvatar() && !inst->isSelf()) { - S32 rez_status = inst->getRezzedStatus(); - counts[rez_status]++; - F32 time = inst->getFirstDecloudTime(); - if (time >= 0) + if (inst->isControlAvatar()) { - avg_cloud_time+=time; - count_avg++; + control_avatars++; } - if (!inst->isFullyLoaded() || time < 0) + else { - // still renders as cloud - cloud_avatars++; + S32 rez_status = inst->getRezzedStatus(); + counts[rez_status]++; + F32 time = inst->getFirstDecloudTime(); + if (time >= 0) + { + avg_cloud_time += time; + count_avg++; + } + if (!inst->isFullyLoaded() || time < 0) + { + // still renders as cloud + cloud_avatars++; + if (rez_status >= 4 + && inst->mWaitingForMeshes) + { + pending_meshes++; + } + } } } } @@ -1012,7 +1027,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status) switch (rez_status) { case 0: - return "cloud"; + return "missing parts"; case 1: return "gray"; case 2: @@ -2967,7 +2982,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (LLVOAvatar::sJointDebug) { - LL_INFOS() << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL; + LL_INFOS() << getDebugName() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << LL_ENDL; } LLJoint::sNumUpdates = 0; @@ -3187,17 +3202,17 @@ F32 LLVOAvatar::calcMorphAmount() const void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) { // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync - if ( voice_enabled + if (voice_enabled && mLastRezzedStatus > 0 // no point updating lip-sync for clouds && LLVoiceVisualizer::getLipSyncEnabled() - && LLVoiceClient::getInstance()->getIsSpeaking( mID ) ) + && LLVoiceClient::getInstance()->getIsSpeaking(mID)) { F32 ooh_morph_amount = 0.0f; F32 aah_morph_amount = 0.0f; mVoiceVisualizer->lipSyncOohAah( ooh_morph_amount, aah_morph_amount ); - if( mOohMorph ) + if (mOohMorph) { F32 ooh_weight = mOohMorph->getMinWeight() + ooh_morph_amount * (mOohMorph->getMaxWeight() - mOohMorph->getMinWeight()); @@ -3205,7 +3220,7 @@ void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) mOohMorph->setWeight( ooh_weight); } - if( mAahMorph ) + if (mAahMorph) { F32 aah_weight = mAahMorph->getMinWeight() + aah_morph_amount * (mAahMorph->getMaxWeight() - mAahMorph->getMinWeight()); @@ -3474,7 +3489,7 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name) is_muted = isInMuteList(); } bool is_friend = isBuddy(); - bool is_cloud = getIsCloud(); + bool is_cloud = getHasMissingParts(); if (is_appearance != mNameAppearance) { @@ -4292,8 +4307,8 @@ void LLVOAvatar::computeUpdatePeriod() { const LLVector4a* ext = mDrawable->getSpatialExtents(); LLVector4a size; - size.setSub(ext[1],ext[0]); - F32 mag = size.getLength3().getF32()*0.5f; + size.setSub(ext[1], ext[0]); + F32 mag = size.getLength3().getF32() * 0.5f; const S32 UPDATE_RATE_SLOW = 64; const S32 UPDATE_RATE_MED = 48; @@ -4303,14 +4318,14 @@ void LLVOAvatar::computeUpdatePeriod() { // visually muted avatars update at lowest rate mUpdatePeriod = UPDATE_RATE_SLOW; } - else if (! shouldImpostor() - || mDrawable->mDistanceWRTCamera < 1.f + mag) + else if (!shouldImpostor() + || mDrawable->mDistanceWRTCamera < 1.f + mag) { // first 25% of max visible avatars are not impostored // also, don't impostor avatars whose bounding box may be penetrating the // impostor camera near clip plane mUpdatePeriod = 1; } - else if ( shouldImpostor(4.0) ) + else if (shouldImpostor(4.0)) { //background avatars are REALLY slow updating impostors mUpdatePeriod = UPDATE_RATE_SLOW; } @@ -4319,7 +4334,7 @@ void LLVOAvatar::computeUpdatePeriod() // Don't update cloud avatars too often mUpdatePeriod = UPDATE_RATE_SLOW; } - else if ( shouldImpostor(3.0) ) + else if (shouldImpostor(3.0)) { //back 25% of max visible avatars are slow updating impostors mUpdatePeriod = UPDATE_RATE_MED; } @@ -4750,14 +4765,6 @@ bool LLVOAvatar::updateCharacter(LLAgent &agent) } bool visible = isVisible(); - bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing - bool is_attachment = false; - - if (is_control_avatar) - { - LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this); - is_attachment = cav && cav->mRootVolp && cav->mRootVolp->isAttachment(); // For attached animated objects - } // For fading out the names above heads, only let the timer // run if we're visible. @@ -6168,8 +6175,11 @@ void LLVOAvatar::resetAnimations() flushAllMotions(); } -// Override selectively based on avatar sex and whether we're using new -// animations. +//----------------------------------------------------------------------------- +// remapMotionID() +// Override selectively based on avatar sex and whether we're using new animations. +//----------------------------------------------------------------------------- +// virtual LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) { static LLCachedControl<bool> use_new_walk_run(gSavedSettings, "UseNewWalkRun"); @@ -6219,7 +6229,6 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) } return result; - } //----------------------------------------------------------------------------- @@ -6227,6 +6236,7 @@ LLUUID LLVOAvatar::remapMotionID(const LLUUID& id) // id is the asset if of the animation to start // time_offset is the offset into the animation at which to start playing //----------------------------------------------------------------------------- +// virtual bool LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) { LL_DEBUGS("Motion") << "motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL; @@ -6249,6 +6259,7 @@ bool LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) //----------------------------------------------------------------------------- // stopMotion() //----------------------------------------------------------------------------- +// virtual bool LLVOAvatar::stopMotion(const LLUUID& id, bool stop_immediate) { LL_DEBUGS("Motion") << "Motion requested " << id.asString() << " " << gAnimLibrary.animationName(id) << LL_ENDL; @@ -6288,6 +6299,7 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id) //----------------------------------------------------------------------------- // addDebugText() //----------------------------------------------------------------------------- +// virtual void LLVOAvatar::addDebugText(const std::string& text) { mDebugText.append(1, '\n'); @@ -6295,8 +6307,22 @@ void LLVOAvatar::addDebugText(const std::string& text) } //----------------------------------------------------------------------------- +// getDebugName() +//----------------------------------------------------------------------------- +// virtual +std::string LLVOAvatar::getDebugName() const +{ +#if LL_RELEASE_WITH_DEBUG_INFO + return getFullname(); +#else + return getID().asString(); +#endif // LL_RELEASE_WITH_DEBUG_INFO +} + +//----------------------------------------------------------------------------- // getID() //----------------------------------------------------------------------------- +// virtual const LLUUID& LLVOAvatar::getID() const { return mID; @@ -6306,13 +6332,14 @@ const LLUUID& LLVOAvatar::getID() const // getJoint() //----------------------------------------------------------------------------- // RN: avatar joints are multi-rooted to include screen-based attachments -LLJoint *LLVOAvatar::getJoint( const std::string &name ) +// virtual +LLJoint* LLVOAvatar::getJoint(std::string_view name) { joint_map_t::iterator iter = mJointMap.find(name); - LLJoint* jointp = NULL; + LLJoint* jointp = nullptr; - if (iter == mJointMap.end() || iter->second == NULL) + if (iter == mJointMap.end() || iter->second == nullptr) { //search for joint and cache found joint in lookup table if (mJointAliasMap.empty()) { @@ -6329,7 +6356,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) canonical_name = name; } jointp = mRoot->findJoint(canonical_name); - mJointMap[name] = jointp; + mJointMap[std::string(name)] = jointp; } else { //return cached pointer @@ -6375,6 +6402,16 @@ LLJoint *LLVOAvatar::getJoint( S32 joint_num ) return pJoint; } +void LLVOAvatar::initAllJoints() +{ + getJointAliases(); + for (auto& alias : mJointAliasMap) + { + mJointMap[alias.first] = mRoot->findJoint(alias.second); + } + // ignore mScreen and mRoot +} + //----------------------------------------------------------------------------- // getRiggedMeshID // @@ -6421,6 +6458,7 @@ bool LLVOAvatar::jointIsRiggedTo(const LLJoint *joint) const void LLVOAvatar::clearAttachmentOverrides() { + for (S32 i=0; i<LL_CHARACTER_MAX_ANIMATED_JOINTS; i++) { LLJoint *pJoint = getJoint(i); @@ -6451,6 +6489,7 @@ void LLVOAvatar::clearAttachmentOverrides() //----------------------------------------------------------------------------- void LLVOAvatar::rebuildAttachmentOverrides() { + LL_DEBUGS("AnimatedObjects") << "rebuilding" << LL_ENDL; clearAttachmentOverrides(); @@ -6499,6 +6538,7 @@ void LLVOAvatar::rebuildAttachmentOverrides() // ----------------------------------------------------------------------------- void LLVOAvatar::updateAttachmentOverrides() { + LL_DEBUGS("AnimatedObjects") << "updating" << LL_ENDL; std::set<LLUUID> meshes_seen; @@ -6574,11 +6614,11 @@ void LLVOAvatar::updateAttachmentOverrides() } } pelvis_fixups = mPelvisFixups; - //dumpArchetypeXML(getFullname() + "_paranoid_updated"); + //dumpArchetypeXML(getDebugName() + "_paranoid_updated"); // Rebuild and compare rebuildAttachmentOverrides(); - //dumpArchetypeXML(getFullname() + "_paranoid_rebuilt"); + //dumpArchetypeXML(getDebugName() + "_paranoid_rebuilt"); bool mismatched = false; for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) { @@ -6807,22 +6847,22 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const { std::stringstream ss; std::copy(pos_names.begin(), pos_names.end(), std::ostream_iterator<std::string>(ss, ",")); - LL_INFOS() << getFullname() << " attachment positions defined for joints: " << ss.str() << "\n" << LL_ENDL; + LL_INFOS() << avString() << " attachment positions defined for joints: " << ss.str() << "\n" << LL_ENDL; } else { - LL_DEBUGS("Avatar") << getFullname() << " no attachment positions defined for any joints" << "\n" << LL_ENDL; + LL_DEBUGS("Avatar") << avString() << " no attachment positions defined for any joints" << "\n" << LL_ENDL; } if (scale_names.size()) { std::stringstream ss; std::copy(scale_names.begin(), scale_names.end(), std::ostream_iterator<std::string>(ss, ",")); - LL_INFOS() << getFullname() << " attachment scales defined for joints: " << ss.str() << "\n" << LL_ENDL; + LL_INFOS() << getDebugName() << " attachment scales defined for joints: " << ss.str() << "\n" << LL_ENDL; } else { - LL_INFOS() << getFullname() << " no attachment scales defined for any joints" << "\n" << LL_ENDL; + LL_INFOS() << getDebugName() << " no attachment scales defined for any joints" << "\n" << LL_ENDL; } if (!verbose) @@ -8191,7 +8231,7 @@ bool LLVOAvatar::isVisible() const } // Determine if we have enough avatar data to render -bool LLVOAvatar::getIsCloud() const +bool LLVOAvatar::getHasMissingParts() const { if (mIsDummy) { @@ -8209,7 +8249,7 @@ bool LLVOAvatar::getIsCloud() const void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status) { // State machine for rezzed status. Statuses are -1 on startup, 0 - // = cloud, 1 = gray, 2 = downloading, 3 = waiting for attachments, 4 = full. + // Statuses are -1 on startup, 0 = cloud, 1 = gray, 2 = downloading, 3 = waiting for attachments, 4 = full. // Purpose is to collect time data for each it takes avatar to reach // various loading landmarks: gray, textured (partial), textured fully. @@ -8229,7 +8269,7 @@ void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status) if (rez_status < mLastRezzedStatus) { // load level has decreased. start phase timers for higher load levels. - for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) + for (S32 i = rez_status + 1; i <= mLastRezzedStatus; i++) { startPhase("load_" + LLVOAvatar::rezStatusToString(i)); } @@ -8237,7 +8277,7 @@ void LLVOAvatar::updateRezzedStatusTimers(S32 rez_status) else if (rez_status > mLastRezzedStatus) { // load level has increased. stop phase timers for lower and equal load levels. - for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++) + for (S32 i = llmax(mLastRezzedStatus + 1, 1); i <= rez_status; i++) { stopPhase("load_" + LLVOAvatar::rezStatusToString(i)); stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false); @@ -8398,8 +8438,12 @@ bool LLVOAvatar::updateIsFullyLoaded() || (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC) || !mPendingAttachment.empty() || (rez_status < 3 && !isFullyBaked()) - || hasPendingAttachedMeshes() ); + if (!loading) + { + mWaitingForMeshes = hasPendingAttachedMeshes(); + loading = mWaitingForMeshes; + } // compare amount of attachments to one reported by simulator if (!isSelf() && mLastCloudAttachmentCount < mSimAttachments.size() && mSimAttachments.size() > 0) @@ -8478,19 +8522,19 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading) F32 first_use_delay = FIRST_APPEARANCE_CLOUD_MIN_DELAY; if (!isSelf() && loading) { - // Note that textures can causes 60s delay on thier own - // so this delay might end up on top of textures' delay - first_use_delay = llclamp( - mFirstAppearanceMessageTimer.getElapsedTimeF32(), - FIRST_APPEARANCE_CLOUD_MIN_DELAY, - FIRST_APPEARANCE_CLOUD_MAX_DELAY); + // Note that textures can causes 60s delay on thier own + // so this delay might end up on top of textures' delay + first_use_delay = llclamp( + mFirstAppearanceMessageTimer.getElapsedTimeF32(), + FIRST_APPEARANCE_CLOUD_MIN_DELAY, + FIRST_APPEARANCE_CLOUD_MAX_DELAY); - if (shouldImpostor()) - { - // Impostors are less of a priority, - // let them stay cloud longer - first_use_delay *= FIRST_APPEARANCE_CLOUD_IMPOSTOR_MODIFIER; - } + if (shouldImpostor()) + { + // Impostors are less of a priority, + // let them stay cloud longer + first_use_delay *= FIRST_APPEARANCE_CLOUD_IMPOSTOR_MODIFIER; + } } mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > first_use_delay); } @@ -8507,12 +8551,12 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading) // did our loading state "change" from last call? // FIXME runway - why are we updating every 30 calls even if nothing has changed? // This causes updateLOD() to run every 30 frames, among other things. + bool fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded); const S32 UPDATE_RATE = 30; bool changed = ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call - (!mFullyLoadedInitialized) || // if we've never been called before - (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change - bool fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded); + (!mFullyLoadedInitialized) || // if we've never been called before + (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change mPreviousFullyLoaded = mFullyLoaded; mFullyLoadedInitialized = true; @@ -8530,6 +8574,7 @@ bool LLVOAvatar::processFullyLoadedChange(bool loading) mNeedsImpostorUpdate = true; mLastImpostorUpdateReason = 6; } + return changed; } @@ -9424,12 +9469,12 @@ void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value) void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix, const LLAppearanceMessageContents& contents) { - std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml"); + std::string outfilename = get_sequential_numbered_file_name(dump_prefix, ".xml"); const std::vector<F32>& params_for_dump = contents.mParamWeights; const LLTEContents& tec = contents.mTEContents; LLAPRFile outfile; - std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, outfilename); outfile.open(fullpath, LL_APR_WB ); apr_file_t* file = outfile.getFileHandle(); if (!file) @@ -9642,7 +9687,7 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) static LLCachedControl<bool> enable_verbose_dumps(gSavedSettings, "DebugAvatarAppearanceMessage"); static LLCachedControl<bool> block_avatar_appearance_messages(gSavedSettings, "BlockAvatarAppearanceMessages"); - std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_"; + std::string dump_prefix = getDebugName() + (isSelf() ? "_s_" : "_o_"); if (block_avatar_appearance_messages) { LL_WARNS() << "Blocking AvatarAppearance message" << LL_ENDL; @@ -10276,17 +10321,13 @@ void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_weara std::string outprefix(prefix); if (outprefix.empty()) { - outprefix = getFullname() + (isSelf()?"_s":"_o"); - } - if (outprefix.empty()) - { - outprefix = std::string("new_archetype"); + outprefix = getDebugName() + (isSelf() ? "_s" : "_o"); } - std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml"); + std::string outfilename = get_sequential_numbered_file_name(outprefix, ".xml"); LLAPRFile outfile; LLWearableType *wr_inst = LLWearableType::getInstance(); - std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename); + std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, outfilename); if (APR_SUCCESS == outfile.open(fullpath, LL_APR_WB )) { apr_file_t* file = outfile.getFileHandle(); @@ -10772,7 +10813,7 @@ void LLVOAvatar::updateRiggingInfo() { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - LL_DEBUGS("RigSpammish") << getFullname() << " updating rig tab" << LL_ENDL; + LL_DEBUGS("RigSpammish") << getDebugName() << " updating rig tab" << LL_ENDL; // use a local static for scratch space to avoid reallocation here static std::vector<LLVOVolume*> volumes; @@ -11753,16 +11794,24 @@ void LLVOAvatar::readProfileQuery(S32 retries) } else - { // wait until next frame - LLUUID id = getID(); + { + // wait until next frame + const LLUUID id = getID(); - LL::WorkQueue::getInstance("mainloop")->post([id, retries] { - LLVOAvatar* avatar = (LLVOAvatar*) gObjectList.findObject(id); - if(avatar) + LL::WorkQueue::getInstance("mainloop")->post([id, retries] + { + LLViewerObject* object = gObjectList.findObject(id); + if (object + && !object->isDead() + && object->isAvatar()) // probably excessive, pcode isn't supposed to change { - avatar->readProfileQuery(retries); + LLVOAvatar* avatar = (LLVOAvatar*)object; + if (avatar) + { + avatar->readProfileQuery(retries); + } } - }); + }); } } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a2232d21a2..1e563c4869 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -202,8 +202,9 @@ public: void startDefaultMotions(); void dumpAnimationState(); - virtual LLJoint* getJoint(const std::string &name); + virtual LLJoint* getJoint(std::string_view name); LLJoint* getJoint(S32 num); + void initAllJoints(); //if you KNOW joint_num is a valid animated joint index, use getSkeletonJoint for efficiency inline LLJoint* getSkeletonJoint(S32 joint_num) { return mSkeleton[joint_num]; } @@ -232,6 +233,7 @@ public: virtual void onActiveOverrideMeshesChanged(); /*virtual*/ const LLUUID& getID() const; + /*virtual*/ std::string getDebugName() const; /*virtual*/ void addDebugText(const std::string& text); /*virtual*/ F32 getTimeDilation(); /*virtual*/ void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm); @@ -329,16 +331,16 @@ public: // avatar render cost - U32 getVisualComplexity() { return mVisualComplexity; }; + U32 getVisualComplexity() { return mVisualComplexity; }; // surface area calculation - F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; }; + F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; }; - U32 getReportedVisualComplexity() { return mReportedVisualComplexity; }; // Numbers as reported by the SL server - void setReportedVisualComplexity(U32 value) { mReportedVisualComplexity = value; }; + U32 getReportedVisualComplexity() { return mReportedVisualComplexity; }; // Numbers as reported by the SL server + void setReportedVisualComplexity(U32 value) { mReportedVisualComplexity = value; }; - S32 getUpdatePeriod() { return mUpdatePeriod; }; - const LLColor4 & getMutedAVColor() { return mMutedAVColor; }; + S32 getUpdatePeriod() { return mUpdatePeriod; }; + const LLColor4 & getMutedAVColor() { return mMutedAVColor; }; static void updateImpostorRendering(U32 newMaxNonImpostorsValue); void idleUpdateBelowWater(); @@ -399,15 +401,14 @@ public: bool isTooComplex() const; bool visualParamWeightsAreDefault(); - virtual bool getIsCloud() const; + virtual bool getHasMissingParts() const; bool isFullyTextured() const; bool hasGray() const; - S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded. + S32 getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = waiting for attachments, 4 = full. void updateRezzedStatusTimers(S32 status); S32 mLastRezzedStatus; - void startPhase(const std::string& phase_name); void stopPhase(const std::string& phase_name, bool err_check = true); void clearPhases(); @@ -426,6 +427,7 @@ protected: private: bool mFirstFullyVisible; + bool mWaitingForMeshes; F32 mFirstDecloudTime; LLFrameTimer mFirstAppearanceMessageTimer; @@ -722,7 +724,7 @@ public: bool isFullyBaked(); static bool areAllNearbyInstancesBaked(S32& grey_avatars); - static void getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars); + static void getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars); static std::string rezStatusToString(S32 status); //-------------------------------------------------------------------- @@ -741,7 +743,7 @@ protected: LLViewerTexLayerSet* getTexLayerSet(const U32 index) const { return dynamic_cast<LLViewerTexLayerSet*>(mBakedTextureDatas[index].mTexLayerSet); } - LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ; + LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList; bool mLoadedCallbacksPaused; S32 mLoadedCallbackTextures; // count of 'loaded' baked textures, filled from mCallbackTextureList LLFrameTimer mLastTexCallbackAddedTime; diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index f23af5afa4..653c7e82eb 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -225,6 +225,8 @@ void LLVOAvatarSelf::initInstance() doPeriodically(update_avatar_rez_metrics, 5.0); doPeriodically(boost::bind(&LLVOAvatarSelf::checkStuckAppearance, this), 30.0); + initAllJoints(); // mesh thread uses LLVOAvatarSelf as a joint source + mInitFlags |= 1<<2; } @@ -695,17 +697,17 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) } // virtual -LLJoint *LLVOAvatarSelf::getJoint(const std::string &name) +LLJoint* LLVOAvatarSelf::getJoint(std::string_view name) { std::lock_guard lock(mJointMapMutex); - LLJoint *jointp = NULL; + LLJoint* jointp = nullptr; jointp = LLVOAvatar::getJoint(name); if (!jointp && mScreenp) { jointp = mScreenp->findJoint(name); if (jointp) { - mJointMap[name] = jointp; + mJointMap[std::string(name)] = jointp; } } if (jointp && jointp != mScreenp && jointp != mRoot) @@ -1925,7 +1927,7 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount() LL_INFOS() << "Total Avatar LocTex GL:" << (gl_bytes/1024) << "KB" << LL_ENDL; } -bool LLVOAvatarSelf::getIsCloud() const +bool LLVOAvatarSelf::getHasMissingParts() const { // Let people know why they're clouded without spamming them into oblivion. bool do_warn = false; @@ -2235,14 +2237,18 @@ void LLVOAvatarSelf::appearanceChangeMetricsCoro(std::string url) std::vector<S32> rez_counts; F32 avg_time; S32 total_cloud_avatars; - LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars); + S32 waiting_for_meshes; + S32 control_avatars; + LLVOAvatar::getNearbyRezzedStats(rez_counts, avg_time, total_cloud_avatars, waiting_for_meshes, control_avatars); for (S32 rez_stat = 0; rez_stat < rez_counts.size(); ++rez_stat) { std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat); msg["nearby"][rez_status_name] = rez_counts[rez_stat]; } + msg["nearby"]["waiting_for_meshes"] = waiting_for_meshes; msg["nearby"]["avg_decloud_time"] = avg_time; msg["nearby"]["cloud_total"] = total_cloud_avatars; + msg["nearby"]["animeshes"] = control_avatars; // std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake"); std::vector<std::string> by_fields; @@ -2824,6 +2830,12 @@ void LLVOAvatarSelf::setHoverOffset(const LLVector3& hover_offset, bool send_upd //------------------------------------------------------------------------ bool LLVOAvatarSelf::needsRenderBeam() { + static LLCachedControl<bool> enable_selection_hints(gSavedSettings, "EnableSelectionHints", true); + if (!enable_selection_hints) + { + return false; + } + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); bool is_touching_or_grabbing = (tool == LLToolGrab::getInstance() && LLToolGrab::getInstance()->isEditing()); diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index f9bea41b1d..45985b2a80 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -90,7 +90,7 @@ public: /*virtual*/ bool hasMotionFromSource(const LLUUID& source_id); /*virtual*/ void stopMotionFromSource(const LLUUID& source_id); /*virtual*/ void requestStopMotion(LLMotion* motion); - /*virtual*/ LLJoint* getJoint(const std::string &name); + /*virtual*/ LLJoint* getJoint(std::string_view name); /*virtual*/ void renderJoints(); @@ -129,7 +129,7 @@ public: // Loading state //-------------------------------------------------------------------- public: - /*virtual*/ bool getIsCloud() const; + /*virtual*/ bool getHasMissingParts() const; //-------------------------------------------------------------------- // Region state diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 27c105c8d6..501828eee8 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -1875,11 +1875,11 @@ void LLVOCache::removeGenericExtrasForHandle(U64 handle) } // NOTE: when removing the extras, we must also remove the objects so the simulator will send us a full upddate with the valid overrides - auto* entry = mHandleEntryMap[handle]; - if (entry) + handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle); + if (iter != mHandleEntryMap.end()) { - LL_WARNS("GLTF", "VOCache") << "Removing generic extras for handle " << entry->mHandle << "Filename: " << getObjectCacheExtrasFilename(handle) << LL_ENDL; - removeEntry(entry); + LL_WARNS("GLTF", "VOCache") << "Removing generic extras for handle " << handle << "Filename: " << getObjectCacheExtrasFilename(handle) << LL_ENDL; + removeEntry(iter->second); } else { diff --git a/indra/newview/llvoicecallhandler.cpp b/indra/newview/llvoicecallhandler.cpp index 25b0e69436..d2c947fef2 100644 --- a/indra/newview/llvoicecallhandler.cpp +++ b/indra/newview/llvoicecallhandler.cpp @@ -38,6 +38,11 @@ public: { } + virtual bool canHandleUntrusted(const LLSD ¶ms, const LLSD &query_map, LLMediaCtrl *web, const std::string &nav_type) + { + return (nav_type == NAV_TYPE_CLICKED || nav_type == NAV_TYPE_EXTERNAL); + } + bool handle(const LLSD& params, const LLSD& query_map, const std::string& grid, LLMediaCtrl* web) { //Make sure we have some parameters diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index cf128f381a..b3ac28eb7a 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -369,6 +369,12 @@ void LLVoiceChannel::resume() { if (sSuspendedVoiceChannel) { + if (sSuspendedVoiceChannel->callStarted()) + { + // should have channel data already, restart + sSuspendedVoiceChannel->setState(STATE_READY); + } + // won't do anything if call is already started sSuspendedVoiceChannel->activate(); } else diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 264c15dc05..34f3e22182 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -52,6 +52,7 @@ #include "llcachename.h" #include "llimview.h" // for LLIMMgr #include "llworld.h" +#include "llviewerregion.h" #include "llparcel.h" #include "llviewerparcelmgr.h" #include "llfirstuse.h" @@ -336,35 +337,37 @@ void LLWebRTCVoiceClient::updateSettings() LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE; setVoiceEnabled(LLVoiceClient::getInstance()->voiceEnabled()); - static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation"); - setEarLocation(sVoiceEarLocation); - - static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice"); - setCaptureDevice(sInputDevice); + if (mVoiceEnabled) + { + static LLCachedControl<S32> sVoiceEarLocation(gSavedSettings, "VoiceEarLocation"); + setEarLocation(sVoiceEarLocation); - static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice"); - setRenderDevice(sOutputDevice); + static LLCachedControl<std::string> sInputDevice(gSavedSettings, "VoiceInputAudioDevice"); + setCaptureDevice(sInputDevice); - LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL; + static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice"); + setRenderDevice(sOutputDevice); - static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic"); - setMicGain(sMicLevel); + LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL; - llwebrtc::LLWebRTCDeviceInterface::AudioConfig config; + static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic"); + setMicGain(sMicLevel); - static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true); - config.mEchoCancellation = sEchoCancellation; + llwebrtc::LLWebRTCDeviceInterface::AudioConfig config; - static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true); - config.mAGC = sAGC; + static LLCachedControl<bool> sEchoCancellation(gSavedSettings, "VoiceEchoCancellation", true); + config.mEchoCancellation = sEchoCancellation; - static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings, - "VoiceNoiseSuppressionLevel", - llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH); - config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel) (U32)sNoiseSuppressionLevel; + static LLCachedControl<bool> sAGC(gSavedSettings, "VoiceAutomaticGainControl", true); + config.mAGC = sAGC; - mWebRTCDeviceInterface->setAudioConfig(config); + static LLCachedControl<U32> sNoiseSuppressionLevel(gSavedSettings, + "VoiceNoiseSuppressionLevel", + llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel::NOISE_SUPPRESSION_LEVEL_VERY_HIGH); + config.mNoiseSuppressionLevel = (llwebrtc::LLWebRTCDeviceInterface::AudioConfig::ENoiseSuppressionLevel)(U32)sNoiseSuppressionLevel; + mWebRTCDeviceInterface->setAudioConfig(config); + } } // Observers @@ -985,7 +988,10 @@ void LLWebRTCVoiceClient::updatePosition(void) LLWebRTCVoiceClient::participantStatePtr_t participant = findParticipantByID("Estate", gAgentID); if(participant) { - participant->mRegion = gAgent.getRegion()->getRegionID(); + if (participant->mRegion != region->getRegionID()) { + participant->mRegion = region->getRegionID(); + setMuteMic(mMuteMic); + } } } } @@ -1999,6 +2005,33 @@ bool LLWebRTCVoiceClient::sessionState::processConnectionStates() return !mWebRTCConnections.empty(); } +// Helper function to check if a region supports WebRTC voice +bool LLWebRTCVoiceClient::estateSessionState::isRegionWebRTCEnabled(const LLUUID& regionID) +{ + LLViewerRegion* region = LLWorld::getInstance()->getRegionFromID(regionID); + if (!region) + { + LL_WARNS("Voice") << "Could not find region " << regionID + << " for voice server type validation" << LL_ENDL; + return false; + } + + LLSD simulatorFeatures; + region->getSimulatorFeatures(simulatorFeatures); + + bool isWebRTCEnabled = simulatorFeatures.has("VoiceServerType") && + simulatorFeatures["VoiceServerType"].asString() == "webrtc"; + + if (!isWebRTCEnabled) + { + LL_DEBUGS("Voice") << "Region " << regionID << " VoiceServerType is not 'webrtc' (got: " + << (simulatorFeatures.has("VoiceServerType") ? simulatorFeatures["VoiceServerType"].asString() : "none") << ")" + << LL_ENDL; + } + + return isWebRTCEnabled; +} + // processing of spatial voice connection states requires special handling. // as neighboring regions need to be started up or shut down depending // on our location. @@ -2023,6 +2056,13 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates() // shut down connections to neighbors that are too far away. spatialConnection.get()->shutDown(); } + else if (!isRegionWebRTCEnabled(regionID)) + { + // shut down connections to neighbors that no longer support WebRTC voice. + LL_DEBUGS("Voice") << "Shutting down connection to neighbor region " << regionID + << " - no longer supports WebRTC voice" << LL_ENDL; + spatialConnection.get()->shutDown(); + } if (!spatialConnection.get()->isShuttingDown()) { neighbor_ids.erase(regionID); @@ -2032,11 +2072,20 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates() // add new connections for new neighbors for (auto &neighbor : neighbor_ids) { - connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID)); + // Only connect if the region supports WebRTC voice server type + if (isRegionWebRTCEnabled(neighbor)) + { + connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID)); - mWebRTCConnections.push_back(connection); - connection->setMuteMic(mMuted); - connection->setSpeakerVolume(mSpeakerVolume); + mWebRTCConnections.push_back(connection); + connection->setMuteMic(mMuted); // mute will be set for primary connection when that connection comes up + connection->setSpeakerVolume(mSpeakerVolume); + } + else + { + LL_DEBUGS("Voice") << "Skipping neighbor region " << neighbor + << " - does not support WebRTC voice" << LL_ENDL; + } } } return LLWebRTCVoiceClient::sessionState::processConnectionStates(); @@ -2259,7 +2308,6 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection) return; } - bool iceCompleted = false; LLSD body; if (!connection->mIceCandidates.empty() || connection->mIceCompleted) { @@ -2298,7 +2346,6 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection) LLSD body_candidate; body_candidate["completed"] = true; body["candidate"] = body_candidate; - iceCompleted = connection->mIceCompleted; connection->mIceCompleted = false; } @@ -2386,6 +2433,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac } LL_DEBUGS("Voice") << "On AudioEstablished." << LL_ENDL; mWebRTCAudioInterface = audio_interface; + mWebRTCAudioInterface->setMute(true); // mute will be set appropriately later when we finish setting up. setVoiceConnectionState(VOICE_STATE_SESSION_ESTABLISHED); }); } @@ -2745,7 +2793,12 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() } // update the peer connection with the various characteristics of // this connection. - mWebRTCAudioInterface->setMute(mMuted); + // For spatial this connection will come up as muted, but will be set to the appropriate + // value later on when we determine the regions we connect to. + if (!isSpatial()) + { + mWebRTCAudioInterface->setMute(mMuted); + } mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume); LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID); setVoiceConnectionState(VOICE_STATE_WAIT_FOR_DATA_CHANNEL); @@ -2790,6 +2843,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine() if (primary != mPrimary) { mPrimary = primary; + if (mWebRTCAudioInterface) + { + mWebRTCAudioInterface->setMute(mMuted || !mPrimary); + } sendJoin(); } } @@ -2925,7 +2982,6 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b return; } boost::json::object voice_data = voice_data_parsed.as_object(); - bool new_participant = false; boost::json::object mute; boost::json::object user_gain; for (auto &participant_elem : voice_data) @@ -2978,7 +3034,6 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b } } - new_participant |= joined; if (!participant && joined && (primary || !isSpatial())) { participant = LLWebRTCVoiceClient::getInstance()->addParticipantByID(mChannelID, agent_id, mRegionID); @@ -3096,10 +3151,7 @@ LLVoiceWebRTCSpatialConnection::LLVoiceWebRTCSpatialConnection(const LLUUID ® LLVoiceWebRTCConnection(regionID, channelID), mParcelLocalID(parcelLocalID) { - if (gAgent.getRegion()) - { - mPrimary = (regionID == gAgent.getRegion()->getRegionID()); - } + mPrimary = false; // will be set to primary after connection established } LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection() @@ -3108,23 +3160,20 @@ LLVoiceWebRTCSpatialConnection::~LLVoiceWebRTCSpatialConnection() void LLVoiceWebRTCSpatialConnection::setMuteMic(bool muted) { - if (mMuted != muted) + mMuted = muted; + if (mWebRTCAudioInterface) { - mMuted = muted; - if (mWebRTCAudioInterface) + LLViewerRegion *regionp = gAgent.getRegion(); + if (regionp && mRegionID == regionp->getRegionID()) { - LLViewerRegion *regionp = gAgent.getRegion(); - if (regionp && mRegionID == regionp->getRegionID()) - { - mWebRTCAudioInterface->setMute(muted); - } - else - { - // Always mute this agent with respect to neighboring regions. - // Peers don't want to hear this agent from multiple regions - // as that'll echo. - mWebRTCAudioInterface->setMute(true); - } + mWebRTCAudioInterface->setMute(muted); + } + else + { + // Always mute this agent with respect to neighboring regions. + // Peers don't want to hear this agent from multiple regions + // as that'll echo. + mWebRTCAudioInterface->setMute(true); } } } diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index ff82d2739d..71347f206a 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -351,6 +351,9 @@ public: bool isSpatial() override { return true; } bool isEstate() override { return true; } bool isCallbackPossible() override { return false; } + + private: + bool isRegionWebRTCEnabled(const LLUUID& regionID); }; class parcelSessionState : public sessionState diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 4e8932f912..80fc486a10 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -352,8 +352,11 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (isSculpted()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - sculpt_id = sculpt_params->getSculptTexture(); - sculpt_type = sculpt_params->getSculptType(); + if (sculpt_params) + { + sculpt_id = sculpt_params->getSculptTexture(); + sculpt_type = sculpt_params->getSculptType(); + } LL_DEBUGS("ObjectUpdate") << "uuid " << mID << " set sculpt_id " << sculpt_id << LL_ENDL; } @@ -860,8 +863,11 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) // animated faces get moved to a smaller partition to reduce // side-effects of their updates (see shrinkWrap in // LLVOVolume::animateTextures). - mDrawable->getSpatialGroup()->dirtyGeom(); - gPipeline.markRebuild(mDrawable->getSpatialGroup()); + if (mDrawable->getSpatialGroup()) + { + mDrawable->getSpatialGroup()->dirtyGeom(); + gPipeline.markRebuild(mDrawable->getSpatialGroup()); + } } } @@ -1188,12 +1194,15 @@ void LLVOVolume::updateSculptTexture() if (isSculpted() && !isMesh()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID id = sculpt_params->getSculptTexture(); - if (id.notNull()) + if (sculpt_params) { - mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_SCULPTED, LLViewerTexture::LOD_TEXTURE); - mSculptTexture->forceToSaveRawImage(0, F32_MAX); - mSculptTexture->setKnownDrawSize(256, 256); + LLUUID id = sculpt_params->getSculptTexture(); + if (id.notNull()) + { + mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_SCULPTED, LLViewerTexture::LOD_TEXTURE); + mSculptTexture->forceToSaveRawImage(0, F32_MAX); + mSculptTexture->setKnownDrawSize(256, 256); + } } mSkinInfoUnavaliable = false; @@ -1481,6 +1490,7 @@ bool LLVOVolume::calcLOD() const LLVector3* box = avatar->getLastAnimExtents(); LLVector3 diag = box[1] - box[0]; radius = diag.magVec() * 0.5f; + LL_DEBUGS("DynamicBox") << avatar->getDebugName() << " diag " << diag << " radius " << radius << LL_ENDL; } else { @@ -1491,6 +1501,7 @@ bool LLVOVolume::calcLOD() const LLVector3* box = avatar->getLastAnimExtents(); LLVector3 diag = box[1] - box[0]; radius = diag.magVec(); // preserve old BinRadius behavior - 2x off + LL_DEBUGS("DynamicBox") << avatar->getDebugName() << " diag " << diag << " radius " << radius << LL_ENDL; } if (distance <= 0.f || radius <= 0.f) { @@ -1555,11 +1566,16 @@ bool LLVOVolume::calcLOD() mLODAdjustedDistance = distance; + static LLCachedControl<S32> debug_selection_lods(gSavedSettings, "DebugSelectionLODs", 0); if (isHUDAttachment()) { // HUDs always show at highest detail cur_detail = 3; } + else if (isSelected() && debug_selection_lods() >= 0) + { + cur_detail = llmin(debug_selection_lods(), 3); + } else { cur_detail = computeLODDetail(ll_round(distance, 0.01f), ll_round(radius, 0.01f), lod_factor); @@ -2640,6 +2656,17 @@ void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool m } viewer_media_t media_impl = LLViewerMedia::getInstance()->updateMediaImpl(mep, previous_url, update_from_self); + static LLCachedControl<bool> media_autoplay_huds(gSavedSettings, "MediaAutoPlayHuds", true); + bool was_loaded = media_impl->hasMedia(); + if (isHUDAttachment() && media_autoplay_huds && !was_loaded) + { + std::string url = mep->getCurrentURL(); + if (media_impl->getCurrentMediaURL() != url) + { + media_impl->navigateTo(url, "", false, true); + } + } + addMediaImpl(media_impl, texture_index) ; } else @@ -3573,12 +3600,15 @@ bool LLVOVolume::isMesh() const if (isSculpted()) { LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - U8 sculpt_type = sculpt_params->getSculptType(); - - if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) - // mesh is a mesh + if (sculpt_params) { - return true; + U8 sculpt_type = sculpt_params->getSculptType(); + + if ((sculpt_type & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + // mesh is a mesh + { + return true; + } } } @@ -3780,7 +3810,12 @@ bool LLVOVolume::canBeAnimatedObject() const bool LLVOVolume::isAnimatedObject() const { - LLVOVolume *root_vol = (LLVOVolume*)getRootEdit(); + LLViewerObject *root_obj = getRootEdit(); + if (root_obj->getPCode() != LL_PCODE_VOLUME) + { + return false; // at the moment only volumes can be animated + } + LLVOVolume* root_vol = (LLVOVolume*)root_obj; mIsAnimatedObject = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG; return mIsAnimatedObject; } diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index 0a1d346266..bf171fe954 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -29,7 +29,7 @@ #include "llwatchdog.h" #include "llthread.h" -const U32 WATCHDOG_SLEEP_TIME_USEC = 1000000; +constexpr U32 WATCHDOG_SLEEP_TIME_USEC = 1000000U; // This class runs the watchdog timing thread. class LLWatchdogTimerThread : public LLThread @@ -51,7 +51,7 @@ public: mSleepMsecs = 1; } - /* virtual */ void run() + void run() override { while(!mStopping) { @@ -83,7 +83,7 @@ void LLWatchdogEntry::start() void LLWatchdogEntry::stop() { // this can happen very late in the shutdown sequence - if (! LLWatchdog::wasDeleted()) + if (!LLWatchdog::wasDeleted()) { LLWatchdog::getInstance()->remove(this); } @@ -117,7 +117,7 @@ void LLWatchdogTimeout::setTimeout(F32 d) mTimeout = d; } -void LLWatchdogTimeout::start(const std::string& state) +void LLWatchdogTimeout::start(std::string_view state) { if (mTimeout == 0) { @@ -139,9 +139,9 @@ void LLWatchdogTimeout::stop() mTimer.stop(); } -void LLWatchdogTimeout::ping(const std::string& state) +void LLWatchdogTimeout::ping(std::string_view state) { - if(!state.empty()) + if (!state.empty()) { mPingState = state; } @@ -151,7 +151,7 @@ void LLWatchdogTimeout::ping(const std::string& state) // LLWatchdog LLWatchdog::LLWatchdog() :mSuspectsAccessMutex() - ,mTimer(NULL) + ,mTimer(nullptr) ,mLastClockCount(0) { } @@ -176,7 +176,7 @@ void LLWatchdog::remove(LLWatchdogEntry* e) void LLWatchdog::init() { - if(!mSuspectsAccessMutex && !mTimer) + if (!mSuspectsAccessMutex && !mTimer) { mSuspectsAccessMutex = new LLMutex(); mTimer = new LLWatchdogTimerThread(); @@ -191,17 +191,17 @@ void LLWatchdog::init() void LLWatchdog::cleanup() { - if(mTimer) + if (mTimer) { mTimer->stop(); delete mTimer; - mTimer = NULL; + mTimer = nullptr; } - if(mSuspectsAccessMutex) + if (mSuspectsAccessMutex) { delete mSuspectsAccessMutex; - mSuspectsAccessMutex = NULL; + mSuspectsAccessMutex = nullptr; } mLastClockCount = 0; @@ -214,12 +214,12 @@ void LLWatchdog::run() // Check the time since the last call to run... // If the time elapsed is two times greater than the regualr sleep time // reset the active timeouts. - const U32 TIME_ELAPSED_MULTIPLIER = 2; + constexpr U32 TIME_ELAPSED_MULTIPLIER = 2; U64 current_time = LLTimer::getTotalTime(); U64 current_run_delta = current_time - mLastClockCount; mLastClockCount = current_time; - if(current_run_delta > (WATCHDOG_SLEEP_TIME_USEC * TIME_ELAPSED_MULTIPLIER)) + if (current_run_delta > (WATCHDOG_SLEEP_TIME_USEC * TIME_ELAPSED_MULTIPLIER)) { LL_INFOS() << "Watchdog thread delayed: resetting entries." << LL_ENDL; for (const auto& suspect : mSuspects) @@ -233,7 +233,7 @@ void LLWatchdog::run() std::find_if(mSuspects.begin(), mSuspects.end(), [](const LLWatchdogEntry* suspect){ return ! suspect->isAlive(); }); - if(result != mSuspects.end()) + if (result != mSuspects.end()) { // error!!! if(mTimer) @@ -251,7 +251,7 @@ void LLWatchdog::run() void LLWatchdog::lockThread() { - if(mSuspectsAccessMutex != NULL) + if (mSuspectsAccessMutex) { mSuspectsAccessMutex->lock(); } @@ -259,7 +259,7 @@ void LLWatchdog::lockThread() void LLWatchdog::unlockThread() { - if(mSuspectsAccessMutex != NULL) + if (mSuspectsAccessMutex) { mSuspectsAccessMutex->unlock(); } diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h index fe8932e298..1931c582b0 100644 --- a/indra/newview/llwatchdog.h +++ b/indra/newview/llwatchdog.h @@ -56,14 +56,14 @@ public: LLWatchdogTimeout(); virtual ~LLWatchdogTimeout(); - /* virtual */ bool isAlive() const; - /* virtual */ void reset(); - /* virtual */ void start() { start(""); } - /* virtual */ void stop(); + bool isAlive() const override; + void reset() override; + void start() override { start(""); } + void stop() override; - void start(const std::string& state); + void start(std::string_view state); void setTimeout(F32 d); - void ping(const std::string& state); + void ping(std::string_view state); const std::string& getState() {return mPingState; } private: diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index c708e804b2..5fb22184c3 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -185,6 +185,7 @@ LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item // virtual void LLPanelWearableOutfitItem::updateItem(const std::string& name, + bool favorite, EItemState item_state) { std::string search_label = name; @@ -215,7 +216,7 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name, } } - LLPanelInventoryListItemBase::updateItem(search_label, item_state); + LLPanelInventoryListItemBase::updateItem(search_label, favorite, item_state); } ////////////////////////////////////////////////////////////////////////// @@ -442,6 +443,7 @@ LLPanelAttachmentListItem* LLPanelAttachmentListItem::create(LLViewerInventoryIt } void LLPanelAttachmentListItem::updateItem(const std::string& name, + bool favorite, EItemState item_state) { std::string title_joint = name; @@ -459,7 +461,7 @@ void LLPanelAttachmentListItem::updateItem(const std::string& name, title_joint = title_joint + " (" + trans_name + ")"; } - LLPanelInventoryListItemBase::updateItem(title_joint, item_state); + LLPanelInventoryListItemBase::updateItem(title_joint, favorite, item_state); } ////////////////////////////////////////////////////////////////////////// @@ -487,7 +489,7 @@ bool LLPanelDummyClothingListItem::postBuild() addWidgetToRightSide("btn_add_panel"); setIconImage(LLInventoryIcon::getIcon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, false)); - updateItem(wearableTypeToString(mWearableType)); + updateItem(wearableTypeToString(mWearableType), false); // Make it look loke clothing item - reserve space for 'delete' button setLeftWidgetsWidth(getChildView("item_icon")->getRect().mLeft); @@ -921,8 +923,8 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id)); registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id)); registrar.add("Wearable.TakeOffDetach", - boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); + boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); // Register handlers for clothing. registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); @@ -932,6 +934,7 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu() // Register handlers for attachments. registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids, no_op)); + registrar.add("Attachment.Favorite", boost::bind(toggle_favorites, ids)); registrar.add("Attachment.Touch", boost::bind(handle_attachment_touch, selected_id)); registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id)); registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2)); @@ -965,6 +968,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu U32 n_touchable = 0; // number of touchable items among the selected ones bool can_be_worn = true; + bool can_favorite = false; + bool can_unfavorite = false; for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it) { @@ -986,6 +991,12 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu const bool is_editable = get_is_item_editable(id); const bool is_touchable = enable_attachment_touch(id); const bool is_already_worn = gAgentWearables.selfHasWearable(wearable_type); + + LLUUID linked_id = item->getLinkedUUID(); + LLViewerInventoryItem* linked_item = gInventory.getItem(linked_id); + can_favorite |= !linked_item->getIsFavorite(); + can_unfavorite |= linked_item->getIsFavorite(); + if (is_worn) { ++n_worn; @@ -1009,7 +1020,7 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu if (can_be_worn) { - can_be_worn = get_can_item_be_worn(item->getLinkedUUID()); + can_be_worn = get_can_item_be_worn(linked_id); } } // for @@ -1031,6 +1042,8 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu setMenuItemEnabled(menu, "create_new", LLAppearanceMgr::instance().canAddWearables(ids)); setMenuItemVisible(menu, "show_original", !standalone); setMenuItemEnabled(menu, "show_original", n_items == 1 && n_links == n_items); + setMenuItemVisible(menu, "favorites_add", can_favorite); + setMenuItemVisible(menu, "favorites_remove", can_unfavorite); setMenuItemVisible(menu, "take_off", mask == MASK_CLOTHING && n_worn == n_items); setMenuItemVisible(menu, "detach", mask == MASK_ATTACHMENT && n_worn == n_items); setMenuItemVisible(menu, "take_off_or_detach", mask == (MASK_ATTACHMENT|MASK_CLOTHING)); diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index 7a5f29020e..915a557239 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -95,6 +95,7 @@ public: * Updates item name and (worn) suffix. */ /*virtual*/ void updateItem(const std::string& name, + bool favorite, EItemState item_state = IS_DEFAULT); void onAddWearable(); @@ -148,6 +149,7 @@ public: /** Set item title. Joint name is added to the title in parenthesis */ /*virtual*/ void updateItem(const std::string& name, + bool favorite, EItemState item_state = IS_DEFAULT); protected: diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 46fbd16188..b18e01c646 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -121,7 +121,7 @@ #include "SMAAAreaTex.h" #include "SMAASearchTex.h" - +#include "llerror.h" #ifndef LL_WINDOWS #define A_GCC 1 #pragma GCC diagnostic ignored "-Wunused-function" @@ -599,7 +599,6 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderMirrors"); connectRefreshCachedSettingsSafe("RenderHeroProbeUpdateRate"); connectRefreshCachedSettingsSafe("RenderHeroProbeConservativeUpdateMultiplier"); - connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit"); LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl("CollectFontVertexBuffers"); if (cntrl_ptr.notNull()) @@ -1286,8 +1285,11 @@ void LLPipeline::createGLBuffers() } allocateScreenBuffer(resX, resY); - mRT->width = 0; - mRT->height = 0; + // Do not zero out mRT dimensions here. allocateScreenBuffer() above + // already sets the correct dimensions. Zeroing them caused resizeShadowTexture() + // to fail if called immediately after createGLBuffers (e.g., post graphics change). + // mRT->width = 0; + // mRT->height = 0; if (!mNoiseMap) diff --git a/indra/newview/res/ll_icon_small.ico b/indra/newview/res/ll_icon_small.ico Binary files differnew file mode 100644 index 0000000000..a3f6877935 --- /dev/null +++ b/indra/newview/res/ll_icon_small.ico diff --git a/indra/newview/res/resource.h b/indra/newview/res/resource.h index e904f4a1a8..1d3289d784 100644 --- a/indra/newview/res/resource.h +++ b/indra/newview/res/resource.h @@ -30,6 +30,7 @@ #define IDREMOVE 3 #define IDI_LL_ICON 103 #define IDC_GRABHAND 104 +#define IDI_LL_ICON_SMALL 105 #define IDC_CURSOR1 134 #define IDC_CURSOR2 136 #define IDC_CURSOR3 147 diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 4ee26a312a..dc2ba5f171 100755 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -56,6 +56,7 @@ END // remains consistent on all systems. IDI_LL_ICON ICON "ll_icon.ico" IDI_LCD_LL_ICON ICON "icon1.ico" +IDI_LL_ICON_SMALL ICON "ll_icon_small.ico" ///////////////////////////////////////////////////////////////////////////// // diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index f0af4acf20..2ad285eb1f 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -454,6 +454,9 @@ name="InventoryBackgroundColor" reference="DkGray2" /> <color + name="InventoryFavoriteColor" + reference="Yellow" /> + <color name="InventoryFocusOutlineColor" reference="White_25" /> <color @@ -1000,4 +1003,16 @@ <color name="OutfitSnapshotMacMask2" value="0.1 0.1 0.1 1"/> + <color + name="ChatMentionFont" + value="0.3 0.82 1 1" /> + <color + name="ChatMentionHighlight" + value="0.82 0.91 0.98 0.15" /> + <color + name="ChatSelfMentionHighlight" + value="1 1 0 0.35" /> + <color + name="MentionFlashBgColor" + value="1 1 0 0.5" /> </colors> diff --git a/indra/newview/skins/default/textures/icons/Icon_Pointer.png b/indra/newview/skins/default/textures/icons/Icon_Pointer.png Binary files differnew file mode 100644 index 0000000000..021942a8aa --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Icon_Pointer.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Favorite_Star_Content.png b/indra/newview/skins/default/textures/icons/Inv_Favorite_Star_Content.png Binary files differnew file mode 100644 index 0000000000..b71b202234 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Favorite_Star_Content.png diff --git a/indra/newview/skins/default/textures/icons/Inv_Favorite_Star_Full.png b/indra/newview/skins/default/textures/icons/Inv_Favorite_Star_Full.png Binary files differnew file mode 100644 index 0000000000..7d55fb5cfe --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Favorite_Star_Full.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 97468c3b2e..b18d151ab7 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -306,6 +306,8 @@ with the same filename but different name <texture name="Inv_CallingCard" file_name="icons/Inv_CallingCard.png" preload="false" /> <texture name="Inv_Clothing" file_name="icons/Inv_Clothing.png" preload="false" /> <texture name="Inv_Eye" file_name="icons/Inv_Eye.png" preload="false" /> + <texture name="Inv_Favorite_Star_Content" file_name="icons/Inv_Favorite_Star_Content.png" preload="false" /> + <texture name="Inv_Favorite_Star_Full" file_name="icons/Inv_Favorite_Star_Full.png" preload="false" /> <texture name="Inv_FolderClosed" file_name="icons/Inv_FolderClosed.png" preload="false" /> <texture name="Inv_FolderOpen" file_name="icons/Inv_FolderOpen.png" preload="false" /> <texture name="Inv_Gesture" file_name="icons/Inv_Gesture.png" preload="false" /> @@ -655,7 +657,6 @@ with the same filename but different name <texture name="login_sl_logo" file_name="windows/login_sl_logo.png" preload="true" /> <texture name="login_sl_logo_small" file_name="windows/login_sl_logo_small.png" preload="true" /> - <texture name="first_login_image" file_name="windows/first_login_image.jpg" preload="true" /> <texture name="Stepper_Down_Off" file_name="widgets/Stepper_Down_Off.png" preload="false" /> <texture name="Stepper_Down_Press" file_name="widgets/Stepper_Down_Press.png" preload="false" /> @@ -907,4 +908,5 @@ with the same filename but different name <texture name="Single_Folder_Up" file_name="icons/single_folder_up.png" preload="true"/> <texture name="Icon_Color_Palette" file_name="icons/Icon_Color_Palette.png" preload="false"/> <texture name="Icon_Font_Size" file_name="icons/Icon_Font_Size.png" preload="false"/> + <texture name="Icon_Pointer" file_name="icons/Icon_Pointer.png" preload="false"/> </textures> diff --git a/indra/newview/skins/default/textures/windows/first_login_image.jpg b/indra/newview/skins/default/textures/windows/first_login_image.jpg Binary files differdeleted file mode 100644 index 30f31341ed..0000000000 --- a/indra/newview/skins/default/textures/windows/first_login_image.jpg +++ /dev/null diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index e4f99d14e9..e54995890c 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -1,8 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- This file contains strings that used to be hardcoded in the source. - It is only for those strings which do not belong in a floater. - For example, the strings used in avatar chat bubbles, and strings - that are returned from one component and may appear in many places--> <strings> <string name="CAPITALIZED_APP_NAME"> SECOND LIFE @@ -554,9 +550,9 @@ Prøv venligst om lidt igen. <string name="mesh"> mesh </string> - <string name="settings"> - indstillinger - </string> + <string name="settings"> + indstillinger + </string> <string name="AvatarEditingAppearance"> (Redigering Udseende) </string> @@ -819,10 +815,10 @@ Prøv venligst om lidt igen. Du vil nu blive dirigeret til lokal stemme chat </string> <string name="ScriptQuestionCautionChatGranted"> - '[OBJECTNAME]', en genstand, ejet af '[OWNERNAME]', lokaliseret i [REGIONNAME] på [REGIONPOS], har fået tilladelse til: [PERMISSIONS]. + '[OBJECTNAME]', en genstand, ejet af '[OWNERNAME]', lokaliseret i [REGIONNAME] på [REGIONPOS], har fået tilladelse til: [PERMISSIONS]. </string> <string name="ScriptQuestionCautionChatDenied"> - '[OBJECTNAME]', en genstand, ejet af '[OWNERNAME]', lokaliseret i [REGIONNAME] på [REGIONPOS], er afvist tilladelse til: [PERMISSIONS]. + '[OBJECTNAME]', en genstand, ejet af '[OWNERNAME]', lokaliseret i [REGIONNAME] på [REGIONPOS], er afvist tilladelse til: [PERMISSIONS]. </string> <string name="ScriptTakeMoney"> Tag Linden dollars (L$) fra dig @@ -933,16 +929,16 @@ Prøv venligst om lidt igen. Vælg bibliotek </string> <string name="AvatarSetNotAway"> - Sæt "til stede" + Sæt "til stede" </string> <string name="AvatarSetAway"> - Sæt "væk" + Sæt "væk" </string> <string name="AvatarSetNotBusy"> - Sæt "ledig" + Sæt "ledig" </string> <string name="AvatarSetBusy"> - Sæt "optaget" + Sæt "optaget" </string> <string name="shape"> Form @@ -1169,8 +1165,10 @@ Prøv venligst om lidt igen. <string name="InventoryNoTexture"> Du har ikke en kopi af denne tekstur i din beholdning </string> - <string name="Unconstrained">Ikke låst</string> - <string name="no_transfer" value=" (ikke overdragbar)"/> + <string name="Unconstrained"> + Ikke låst + </string> + <string name="no_transfer" value=" (ikke overdragbar)"/> <string name="no_modify" value=" (ikke redigere)"/> <string name="no_copy" value=" (ikke kopiere)"/> <string name="worn" value=" (båret)"/> @@ -1568,16 +1566,16 @@ Prøv venligst om lidt igen. nulstil </string> <string name="RunQueueTitle"> - Sæt "running" fremskridt + Sæt "running" fremskridt </string> <string name="RunQueueStart"> - sæt til "running" + sæt til "running" </string> <string name="NotRunQueueTitle"> - Sæt "Not Running" fremskridt + Sæt "Not Running" fremskridt </string> <string name="NotRunQueueStart"> - sæt til "not running" + sæt til "not running" </string> <string name="CompileSuccessful"> Kompleret uden fejl! @@ -1589,7 +1587,7 @@ Prøv venligst om lidt igen. Gemt. </string> <string name="ObjectOutOfRange"> - Script ("object out of range") + Script ("object out of range") </string> <string name="GodToolsObjectOwnedBy"> Objekt [OBJECT] ejet af [OWNER] @@ -1660,13 +1658,13 @@ Prøv venligst om lidt igen. Memory brugt: [COUNT] kb </string> <string name="ScriptLimitsParcelScriptURLs"> - Parcel Script URL'er + Parcel Script URL'er </string> <string name="ScriptLimitsURLsUsed"> - URL'er brugt: [COUNT] ud af [MAX]; [AVAILABLE] tilgængelige + URL'er brugt: [COUNT] ud af [MAX]; [AVAILABLE] tilgængelige </string> <string name="ScriptLimitsURLsUsedSimple"> - URL'er brugt: [COUNT] + URL'er brugt: [COUNT] </string> <string name="ScriptLimitsRequestError"> Fejl ved anmodning om information @@ -1813,7 +1811,7 @@ Prøv venligst om lidt igen. Nyt script </string> <string name="BusyModeResponseDefault"> - Beboeren du sendte en besked er 'optaget', hvilket betyder at han/hun ikke vil forstyrres. Din besked vil blive vis i hans/hendes IM panel til senere visning. + Beboeren du sendte en besked er 'optaget', hvilket betyder at han/hun ikke vil forstyrres. Din besked vil blive vis i hans/hendes IM panel til senere visning. </string> <string name="MuteByName"> (Efter navn) @@ -2121,11 +2119,11 @@ Hvis fejlen stadig bliver ved, kan det være nødvendigt at afinstallere [APP_NA </string> <string name="MBAlreadyRunning"> [APP_NAME] kører allerede. -Undersøg din "task bar" for at se efter minimeret version af programmet. +Undersøg din "task bar" for at se efter minimeret version af programmet. Hvis fejlen fortsætter, prøv at genstarte din computer. </string> <string name="MBFrozenCrashed"> - [APP_NAME] ser ud til at være "frosset" eller gået ned tidligere. + [APP_NAME] ser ud til at være "frosset" eller gået ned tidligere. Ønsker du at sende en fejlrapport? </string> <string name="MBAlert"> @@ -2161,39 +2159,39 @@ Afvikler i vindue. Fejl ved nedlukning </string> <string name="MBDevContextErr"> - Kan ikke oprette "GL device context" + Kan ikke oprette "GL device context" </string> <string name="MBPixelFmtErr"> - Kan ikke finde passende "pixel format" + Kan ikke finde passende "pixel format" </string> <string name="MBPixelFmtDescErr"> - Kan ikke finde "pixel format" beskrivelse + Kan ikke finde "pixel format" beskrivelse </string> <string name="MBTrueColorWindow"> - [APP_NAME] kræver "True Color (32-bit)" for at kunne køre. -Gå venligst til din computers skærmopsætning og sæt "color mode" til 32-bit. + [APP_NAME] kræver "True Color (32-bit)" for at kunne køre. +Gå venligst til din computers skærmopsætning og sæt "color mode" til 32-bit. </string> <string name="MBAlpha"> - [APP_NAME] kan ikke køre, da den ikke kan finde en "8 bit alpha channel". Normalt skyldes dette et problem med en video driver. + [APP_NAME] kan ikke køre, da den ikke kan finde en "8 bit alpha channel". Normalt skyldes dette et problem med en video driver. Venligst undersøg om du har de nyeste drivere til dit videokort installeret. -Din skærm skal også være sat op til at køre "True Color (32-bit)" i din displayopsætning. +Din skærm skal også være sat op til at køre "True Color (32-bit)" i din displayopsætning. Hvis du bliver ved med at modtage denne besked, kontakt [SUPPORT_SITE]. </string> <string name="MBPixelFmtSetErr"> - Kan ikke sætte "pixel format" + Kan ikke sætte "pixel format" </string> <string name="MBGLContextErr"> - Kan ikke oprette "GL rendering context" + Kan ikke oprette "GL rendering context" </string> <string name="MBGLContextActErr"> - Kan ikke aktivere "GL rendering context" + Kan ikke aktivere "GL rendering context" </string> <string name="MBVideoDrvErr"> [APP_NAME] kan ikke afvikles da driverne til dit videokort ikke blev installeret korrekt, er forældede, eller du benytter hardware der ikke er supporteret. Undersøg venligst om du har installeret de nyeste drivere til dit grafikkort, og selv om du har de nyeste, prøv at geninstallere dem. Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE]. </string> - <string name="5 O'Clock Shadow"> + <string name="5 O'Clock Shadow"> Skægstubbe </string> <string name="All White"> @@ -3328,7 +3326,7 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE]. Skævt ansigt </string> <string name="Shear Front"> - "Måne" + "Måne" </string> <string name="Shear Left Up"> Venstre op @@ -3463,7 +3461,7 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE]. Sparsomt </string> <string name="Spiked Hair"> - Hår med "spikes" + Hår med "spikes" </string> <string name="Square"> Firkantet @@ -3723,6 +3721,10 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE]. <string name="conference-title-incoming"> Konference med [AGENT_NAME] </string> + <string name="bot_warning"> + Du chatter med en bot, [NAME]. Del ikke personlige oplysninger. +Læs mere på https://second.life/scripted-agents. + </string> <string name="no_session_message"> (IM session eksisterer ikke) </string> @@ -3763,7 +3765,7 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE]. En gruppe moderator har deaktiveret din tekst chat. </string> <string name="muted_error"> - Du er blevet "blokeret". + Du er blevet "blokeret". </string> <string name="add_session_event"> Ikke muligt at tilføge brugere til samtale med [RECIPIENT]. @@ -3793,7 +3795,7 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE]. [SOURCES] har sagt noget nyt </string> <string name="session_initialization_timed_out_error"> - Initialisering af session er "timed out" + Initialisering af session er "timed out" </string> <string name="Home position set."> Hjemmeposition sat. @@ -4026,7 +4028,7 @@ Krænkelsesanmeldelse Kvinde - Latter </string> <string name="Female - Looking good"> - Kvinde - "Ser godt ud" + Kvinde - "Ser godt ud" </string> <string name="Female - Over here"> Kvinde - Herovre @@ -4140,7 +4142,7 @@ Krænkelsesanmeldelse <string name="ExternalEditorNotFound"> Kan ikke benytte deb eksterne editor der er angivet. Prøv at omkrandse stien til editor med anførselstegn. -(f.eks. "/stil til min editor" "%s") +(f.eks. "/stil til min editor" "%s") </string> <string name="ExternalEditorCommandParseError"> Fejl ved håndtering af kommando til ekstern editor. @@ -4464,10 +4466,10 @@ Prøv at omkrandse stien til editor med anførselstegn. Viser pejlelys for fysiske objekter (grøn) </string> <string name="BeaconScripted"> - Viser pejlelys for "scriptede" objekter (rød) + Viser pejlelys for "scriptede" objekter (rød) </string> <string name="BeaconScriptedTouch"> - Viser pejlelys for "scriptede" objekter med berøringsfunktion (rød) + Viser pejlelys for "scriptede" objekter med berøringsfunktion (rød) </string> <string name="BeaconSound"> Viser pejlelys for lyd (gul) diff --git a/indra/newview/skins/default/xui/da/teleport_strings.xml b/indra/newview/skins/default/xui/da/teleport_strings.xml index 0d89fae986..79ec69fd9b 100644 --- a/indra/newview/skins/default/xui/da/teleport_strings.xml +++ b/indra/newview/skins/default/xui/da/teleport_strings.xml @@ -21,8 +21,8 @@ Hvis du stadig ikke kan teleporte, prøv venligst at logge ud og ligge ind for a Prøv igen om lidt. </message> <message name="NoHelpIslandTP"> - Du kan ikke teleportere tilbage til Welcome Island. -Gå til 'Welcome Island Puclic' for at prøve tutorial igen. + Du kan ikke teleportere tilbage til Welcome Island. +Gå til 'Welcome Island Puclic' for at prøve tutorial igen. </message> <message name="noaccess_tport"> Beklager, du har ikke adgang til denne teleport destination. diff --git a/indra/newview/skins/default/xui/de/panel_login_first.xml b/indra/newview/skins/default/xui/de/panel_login_first.xml deleted file mode 100644 index 038001157e..0000000000 --- a/indra/newview/skins/default/xui/de/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php?lang=de - </panel.string> - <panel.string name="sign_up_url"> - https://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Benutzername" name="username_combo" tool_tip="Bei der Registrierung gewählter Benutzername wie „berndschmidt12“ oder „Liebe Sonne“"/> - <line_editor label="Kennwort" name="password_edit"/> - <button label="Anmelden" name="connect_btn"/> - <check_box label="Details speichern" name="remember_check"/> - <text name="forgot_password_text"> - Kennwort vergessen - </text> - <text name="sign_up_text"> - Registrieren - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Ihr erster Schritt ist Learning Island. Suchen Sie die Pforte! - </text> - <text name="image_caption_right"> - Erkunden Sie dann Social Island und lernen Sie andere Einwohner kennen! - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/de/panel_snapshot_options.xml b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml index dab20d63eb..2a51f10894 100644 --- a/indra/newview/skins/default/xui/de/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/de/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="Auf Datenträger speichern" name="save_to_computer_btn"/> - <button label="In Inventar speichern ([AMOUNT] L$)" name="save_to_inventory_btn"/> + <button label="In Inventar speichern" name="save_to_inventory_btn"/> <button label="Im Profil-Feed teilen" name="save_to_profile_btn"/> <button label="Auf Facebook teilen" name="send_to_facebook_btn"/> <button label="Auf Twitter teilen" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 3f5fccf57f..f0945234a6 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -1,618 +1,1686 @@ <?xml version="1.0" ?> <strings> - <string name="SECOND_LIFE">Second Life</string> - <string name="APP_NAME">Second Life</string> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> - <string name="SECOND_LIFE_GRID">Second Life-Grid:</string> - <string name="SUPPORT_SITE">Second Life Support-Portal</string> - <string name="StartupDetectingHardware">Hardware wird erfasst...</string> - <string name="StartupLoading">[APP_NAME] wird geladen...</string> - <string name="StartupClearingCache">Cache wird gelöscht...</string> - <string name="StartupInitializingTextureCache">Textur-Cache wird initialisiert...</string> - <string name="StartupRequireDriverUpdate">Grafikinitialisierung fehlgeschlagen. Bitte aktualisieren Sie Ihren Grafiktreiber.</string> - <string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]Bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string> - <string name="BuildConfig">Build-Konfiguration [BUILD_CONFIG]</string> - <string name="AboutPosition">Sie befinden sich an [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> + <string name="SECOND_LIFE"> + Second Life + </string> + <string name="APP_NAME"> + Second Life + </string> + <string name="CAPITALIZED_APP_NAME"> + SECOND LIFE + </string> + <string name="SECOND_LIFE_GRID"> + Second Life-Grid: + </string> + <string name="SUPPORT_SITE"> + Second Life Support-Portal + </string> + <string name="StartupDetectingHardware"> + Hardware wird erfasst... + </string> + <string name="StartupLoading"> + [APP_NAME] wird geladen... + </string> + <string name="StartupClearingCache"> + Cache wird gelöscht... + </string> + <string name="StartupInitializingTextureCache"> + Textur-Cache wird initialisiert... + </string> + <string name="StartupRequireDriverUpdate"> + Grafikinitialisierung fehlgeschlagen. Bitte aktualisieren Sie Ihren Grafiktreiber. + </string> + <string name="AboutHeader"> + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]Bit) [[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Build-Konfiguration [BUILD_CONFIG] + </string> + <string name="AboutPosition"> + Sie befinden sich an [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf <nolink>[HOSTNAME]</nolink> SLURL: <nolink>[SLURL]</nolink> (globale Koordinaten [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] -[SERVER_RELEASE_NOTES_URL]</string> - <string name="AboutSystem">CPU: [CPU] +[SERVER_RELEASE_NOTES_URL] + </string> + <string name="AboutSystem"> + CPU: [CPU] Speicher: [MEMORY_MB] MB Betriebssystemversion: [OS_VERSION] Grafikkartenhersteller: [GRAPHICS_CARD_VENDOR] -Grafikkarte: [GRAPHICS_CARD]</string> - <string name="AboutDriver">Windows-Grafiktreiberversion: [GRAPHICS_DRIVER_VERSION]</string> - <string name="AboutOGL">OpenGL-Version: [OPENGL_VERSION]</string> - <string name="AboutSettings">Fenstergröße: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Grafikkarte: [GRAPHICS_CARD] + </string> + <string name="AboutDriver"> + Windows-Grafiktreiberversion: [GRAPHICS_DRIVER_VERSION] + </string> + <string name="AboutOGL"> + OpenGL-Version: [OPENGL_VERSION] + </string> + <string name="AboutSettings"> + Fenstergröße: [WINDOW_WIDTH]x[WINDOW_HEIGHT] Schriftgrößenanpassung: [FONT_SIZE_ADJUSTMENT] pt UI-Skalierung: [UI_SCALE] Sichtweite: [DRAW_DISTANCE] m Bandbreite: [NET_BANDWITH] kbit/s LOD-Faktor: [LOD_FACTOR] Darstellungsqualität: [RENDER_QUALITY] -Texturspeicher: [TEXTURE_MEMORY] MB</string> - <string name="AboutOSXHiDPI">HiDPI-Anzeigemodus: [HIDPI]</string> - <string name="AboutLibs">J2C-Decoderversion: [J2C_VERSION] +Texturspeicher: [TEXTURE_MEMORY] MB + </string> + <string name="AboutOSXHiDPI"> + HiDPI-Anzeigemodus: [HIDPI] + </string> + <string name="AboutLibs"> + J2C-Decoderversion: [J2C_VERSION] Audiotreiberversion: [AUDIO_DRIVER_VERSION] [LIBCEF_VERSION] LibVLC-Version: [LIBVLC_VERSION] -Voice-Server-Version: [VOICE_VERSION]</string> - <string name="AboutTraffic">Paketverlust: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1] %)</string> - <string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string> - <string name="ErrorFetchingServerReleaseNotesURL">Fehler beim Abrufen der URL für die Server-Versionshinweise.</string> - <string name="BuildConfiguration">Build-Konfiguration</string> - <string name="ProgressRestoring">Wird wiederhergestellt...</string> - <string name="ProgressChangingResolution">Auflösung wird geändert...</string> - <string name="Fullbright">Fullbright (Legacy)</string> - <string name="LoginInProgress">Anmeldevorgang gestartet. [APP_NAME] reagiert möglicherweise nicht. Bitte warten.</string> - <string name="LoginInProgressNoFrozen">Anmeldung erfolgt...</string> - <string name="LoginAuthenticating">Authentifizierung</string> - <string name="LoginMaintenance">Account wird aktualisiert...</string> - <string name="LoginAttempt">Ein früherer Anmeldeversuch ist fehlgeschlagen. Anmeldung, Versuch [NUMBER]</string> - <string name="LoginPrecaching">Welt wird geladen...</string> - <string name="LoginInitializingBrowser">Integrierter Webbrowser wird initialisiert...</string> - <string name="LoginInitializingMultimedia">Multimedia wird initialisiert...</string> - <string name="LoginInitializingFonts">Schriftarten werden geladen...</string> - <string name="LoginVerifyingCache">Cache-Dateien werden überprüft (dauert 60-90 Sekunden)...</string> - <string name="LoginProcessingResponse">Antwort wird verarbeitet...</string> - <string name="LoginInitializingWorld">Welt wird initialisiert...</string> - <string name="LoginDecodingImages">Bilder werden entpackt...</string> - <string name="LoginInitializingQuicktime">QuickTime wird initialisiert...</string> - <string name="LoginQuicktimeNotFound">QuickTime nicht gefunden - Initialisierung nicht möglich.</string> - <string name="LoginQuicktimeOK">QuickTime wurde initialisiert.</string> - <string name="LoginRequestSeedCapGrant">Regionsfähigkeiten anfordern...</string> - <string name="LoginRetrySeedCapGrant">Regionsfähigkeiten anfordern. Versuch [NUMBER]...</string> - <string name="LoginWaitingForRegionHandshake">Region-Handshake...</string> - <string name="LoginConnectingToRegion">Region-Verbindung...</string> - <string name="LoginDownloadingClothing">Kleidung wird geladen...</string> - <string name="InvalidCertificate">Der Server hat ein ungültiges oder korruptes Zertifikate zurückgegeben. Bitte kontaktieren Sie den Grid-Administrator.</string> - <string name="CertInvalidHostname">Ein ungültiger Hostname wurde verwendet, um auf den Server zuzugreifen. Bitte überprüfen Sie Ihre SLURL oder den Grid-Hostnamen.</string> - <string name="CertExpired">Das vom Grid ausgegebene Zertifikate ist abgelaufen. Bitte überprüfen Sie Ihre Systemuhr oder kontaktieren Sie Ihren Grid-Administrator.</string> - <string name="CertKeyUsage">Das vom Server ausgegebene Zertifikat konnte nicht für SSL verwendet werden. Bitte kontaktieren Sie Ihren Grid-Administrator.</string> - <string name="CertBasicConstraints">In der Zertifikatskette des Servers befanden sich zu viele Zertifikate. Bitte kontaktieren Sie Ihren Grid-Administrator.</string> - <string name="CertInvalidSignature">Die Zertifikatsunterschrift des Gridservers konnte nicht bestätigt werden. Bitte kontaktieren Sie Ihren Grid-Administrator.</string> - <string name="LoginFailedNoNetwork">Netzwerkfehler: Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihre Netzwerkverbindung.</string> - <string name="LoginFailedHeader">Anmeldung fehlgeschlagen</string> - <string name="Quit">Beenden</string> - <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - <string name="AgniGridLabel">Second Life Main Grid (Agni)</string> - <string name="AditiGridLabel">Second Life Beta Test Grid (Aditi)</string> - <string name="ViewerDownloadURL">http://secondlife.com/download</string> - <string name="LoginFailedViewerNotPermitted">Mit dem von Ihnen verwendeten Viewer ist der Zugriff auf Second Life nicht mehr möglich. Laden Sie von den folgenden Seite einen neuen Viewer herunter: +Voice-Server-Version: [VOICE_VERSION] + </string> + <string name="AboutTraffic"> + Paketverlust: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1] %) + </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> + <string name="ErrorFetchingServerReleaseNotesURL"> + Fehler beim Abrufen der URL für die Server-Versionshinweise. + </string> + <string name="BuildConfiguration"> + Build-Konfiguration + </string> + <string name="ProgressRestoring"> + Wird wiederhergestellt... + </string> + <string name="ProgressChangingResolution"> + Auflösung wird geändert... + </string> + <string name="Fullbright"> + Fullbright (Legacy) + </string> + <string name="LoginInProgress"> + Anmeldevorgang gestartet. [APP_NAME] reagiert möglicherweise nicht. Bitte warten. + </string> + <string name="LoginInProgressNoFrozen"> + Anmeldung erfolgt... + </string> + <string name="LoginAuthenticating"> + Authentifizierung + </string> + <string name="LoginMaintenance"> + Account wird aktualisiert... + </string> + <string name="LoginAttempt"> + Ein früherer Anmeldeversuch ist fehlgeschlagen. Anmeldung, Versuch [NUMBER] + </string> + <string name="LoginPrecaching"> + Welt wird geladen... + </string> + <string name="LoginInitializingBrowser"> + Integrierter Webbrowser wird initialisiert... + </string> + <string name="LoginInitializingMultimedia"> + Multimedia wird initialisiert... + </string> + <string name="LoginInitializingFonts"> + Schriftarten werden geladen... + </string> + <string name="LoginVerifyingCache"> + Cache-Dateien werden überprüft (dauert 60-90 Sekunden)... + </string> + <string name="LoginProcessingResponse"> + Antwort wird verarbeitet... + </string> + <string name="LoginInitializingWorld"> + Welt wird initialisiert... + </string> + <string name="LoginDecodingImages"> + Bilder werden entpackt... + </string> + <string name="LoginInitializingQuicktime"> + QuickTime wird initialisiert... + </string> + <string name="LoginQuicktimeNotFound"> + QuickTime nicht gefunden - Initialisierung nicht möglich. + </string> + <string name="LoginQuicktimeOK"> + QuickTime wurde initialisiert. + </string> + <string name="LoginRequestSeedCapGrant"> + Regionsfähigkeiten anfordern... + </string> + <string name="LoginRetrySeedCapGrant"> + Regionsfähigkeiten anfordern. Versuch [NUMBER]... + </string> + <string name="LoginWaitingForRegionHandshake"> + Region-Handshake... + </string> + <string name="LoginConnectingToRegion"> + Region-Verbindung... + </string> + <string name="LoginDownloadingClothing"> + Kleidung wird geladen... + </string> + <string name="InvalidCertificate"> + Der Server hat ein ungültiges oder korruptes Zertifikate zurückgegeben. Bitte kontaktieren Sie den Grid-Administrator. + </string> + <string name="CertInvalidHostname"> + Ein ungültiger Hostname wurde verwendet, um auf den Server zuzugreifen. Bitte überprüfen Sie Ihre SLURL oder den Grid-Hostnamen. + </string> + <string name="CertExpired"> + Das vom Grid ausgegebene Zertifikate ist abgelaufen. Bitte überprüfen Sie Ihre Systemuhr oder kontaktieren Sie Ihren Grid-Administrator. + </string> + <string name="CertKeyUsage"> + Das vom Server ausgegebene Zertifikat konnte nicht für SSL verwendet werden. Bitte kontaktieren Sie Ihren Grid-Administrator. + </string> + <string name="CertBasicConstraints"> + In der Zertifikatskette des Servers befanden sich zu viele Zertifikate. Bitte kontaktieren Sie Ihren Grid-Administrator. + </string> + <string name="CertInvalidSignature"> + Die Zertifikatsunterschrift des Gridservers konnte nicht bestätigt werden. Bitte kontaktieren Sie Ihren Grid-Administrator. + </string> + <string name="LoginFailedNoNetwork"> + Netzwerkfehler: Verbindung konnte nicht hergestellt werden. Bitte überprüfen Sie Ihre Netzwerkverbindung. + </string> + <string name="LoginFailedHeader"> + Anmeldung fehlgeschlagen + </string> + <string name="Quit"> + Beenden + </string> + <string name="create_account_url"> + http://join.secondlife.com/?sourceid=[sourceid] + </string> + <string name="AgniGridLabel"> + Second Life Main Grid (Agni) + </string> + <string name="AditiGridLabel"> + Second Life Beta Test Grid (Aditi) + </string> + <string name="ViewerDownloadURL"> + http://secondlife.com/download + </string> + <string name="LoginFailedViewerNotPermitted"> + Mit dem von Ihnen verwendeten Viewer ist der Zugriff auf Second Life nicht mehr möglich. Laden Sie von den folgenden Seite einen neuen Viewer herunter: http://secondlife.com/download Weitere Informationen finden Sie auf der folgenden FAQ-Seite: -http://secondlife.com/viewer-access-faq</string> - <string name="LoginIntermediateOptionalUpdateAvailable">Optionales Viewer-Update verfügbar: [VERSION]</string> - <string name="LoginFailedRequiredUpdate">Erforderliches Viewer-Update: [VERSION]</string> - <string name="LoginFailedAlreadyLoggedIn">Dieser Agent ist bereits angemeldet.</string> - <string name="LoginFailedAuthenticationFailed">Wir bitten um Entschuldigung! Wir konnten Sie nicht anmelden. +http://secondlife.com/viewer-access-faq + </string> + <string name="LoginIntermediateOptionalUpdateAvailable"> + Optionales Viewer-Update verfügbar: [VERSION] + </string> + <string name="LoginFailedRequiredUpdate"> + Erforderliches Viewer-Update: [VERSION] + </string> + <string name="LoginFailedAlreadyLoggedIn"> + Dieser Agent ist bereits angemeldet. + </string> + <string name="LoginFailedAuthenticationFailed"> + Wir bitten um Entschuldigung! Wir konnten Sie nicht anmelden. Stellen Sie sicher, dass Sie die richtigen Informationen eingegeben haben: * Benutzername (wie robertschmidt12 oder warme.sonne) * Kennwort -Stellen Sie außerdem sicher, dass die Umschaltsperre deaktiviert ist.</string> - <string name="LoginFailedPasswordChanged">Ihr Kennwort wurde aus Sicherheitsgründen geändert. +Stellen Sie außerdem sicher, dass die Umschaltsperre deaktiviert ist. + </string> + <string name="LoginFailedPasswordChanged"> + Ihr Kennwort wurde aus Sicherheitsgründen geändert. Gehen Sie zur Seite „Mein Account“ unter http://secondlife.com/password und beantworten Sie die Sicherheitsfrage, um Ihr Kennwort zurückzusetzen. -Wir entschuldigen uns für eventuell enstandene Unannehmlichkeiten.</string> - <string name="LoginFailedPasswordReset">Aufgrund von Systemänderungen müssen Sie Ihr Kennwort zurücksetzen. +Wir entschuldigen uns für eventuell enstandene Unannehmlichkeiten. + </string> + <string name="LoginFailedPasswordReset"> + Aufgrund von Systemänderungen müssen Sie Ihr Kennwort zurücksetzen. Gehen Sie zur Seite „Mein Account“ unter http://secondlife.com/password und beantworten Sie die Sicherheitsfrage, um Ihr Kennwort zurückzusetzen. -Wir entschuldigen uns für eventuell enstandene Unannehmlichkeiten.</string> - <string name="LoginFailedEmployeesOnly">Second Life ist vorübergehend wegen Wartung geschlossen. +Wir entschuldigen uns für eventuell enstandene Unannehmlichkeiten. + </string> + <string name="LoginFailedEmployeesOnly"> + Second Life ist vorübergehend wegen Wartung geschlossen. Nur Mitarbeiter können sich anmelden. -Aktuelle Informationen finden Sie unter www.secondlife.com/status.</string> - <string name="LoginFailedPremiumOnly">Die Anmeldung bei Second Life ist vorübergehend eingeschränkt, um sicherzustellen, dass Einwohner, die sich bereits inworld aufhalten, das bestmögliche Erlebnis haben. +Aktuelle Informationen finden Sie unter www.secondlife.com/status. + </string> + <string name="LoginFailedPremiumOnly"> + Die Anmeldung bei Second Life ist vorübergehend eingeschränkt, um sicherzustellen, dass Einwohner, die sich bereits inworld aufhalten, das bestmögliche Erlebnis haben. -Benutzer mit kostenlosen Konten können sich während dieses Zeitraums nicht bei Second Life anmelden, damit die Kapazität Benutzern zur Verfügung steht, die ein gebührenpflichtiges Premium-Konto besitzen.</string> - <string name="LoginFailedComputerProhibited">Der Zugriff auf Second Life ist von diesem Computer aus nicht möglich. +Benutzer mit kostenlosen Konten können sich während dieses Zeitraums nicht bei Second Life anmelden, damit die Kapazität Benutzern zur Verfügung steht, die ein gebührenpflichtiges Premium-Konto besitzen. + </string> + <string name="LoginFailedComputerProhibited"> + Der Zugriff auf Second Life ist von diesem Computer aus nicht möglich. Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an -support@secondlife.com.</string> - <string name="LoginFailedAcountSuspended">Ihr Konto ist erst ab -[TIME] Pacific Time wieder verfügbar.</string> - <string name="LoginFailedAccountDisabled">Ihre Anfrage kann derzeit nicht bearbeitet werden. -Bitte wenden Sie sich unter http://secondlife.com/support an den Second Life-Support.</string> - <string name="LoginFailedTransformError">Nicht übereinstimmende Daten bei der Anmeldung festgestellt. -Wenden Sie sich an support@secondlife.com.</string> - <string name="LoginFailedAccountMaintenance">An Ihrem Konto werden gerade kleinere Wartungsarbeiten durchgeführt. +support@secondlife.com. + </string> + <string name="LoginFailedAcountSuspended"> + Ihr Konto ist erst ab +[TIME] Pacific Time wieder verfügbar. + </string> + <string name="LoginFailedAccountDisabled"> + Ihre Anfrage kann derzeit nicht bearbeitet werden. +Bitte wenden Sie sich unter http://secondlife.com/support an den Second Life-Support. + </string> + <string name="LoginFailedTransformError"> + Nicht übereinstimmende Daten bei der Anmeldung festgestellt. +Wenden Sie sich an support@secondlife.com. + </string> + <string name="LoginFailedAccountMaintenance"> + An Ihrem Konto werden gerade kleinere Wartungsarbeiten durchgeführt. Ihr Konto ist erst ab [TIME] Pacific Time wieder verfügbar. -Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com.</string> - <string name="LoginFailedPendingLogoutFault">Abmeldeanforderung führte zu einem Simulatorfehler.</string> - <string name="LoginFailedPendingLogout">Das System meldet Sie gerade ab. -Bitte warten Sie eine Minute, bevor Sie sich erneut einloggen.</string> - <string name="LoginFailedUnableToCreateSession">Es kann keine gültige Sitzung erstellt werden.</string> - <string name="LoginFailedUnableToConnectToSimulator">Es kann keine Simulatorverbindung hergestellt werden.</string> - <string name="LoginFailedRestrictedHours">Mit Ihrem Konto ist der Zugriff auf Second Life +Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com. + </string> + <string name="LoginFailedPendingLogoutFault"> + Abmeldeanforderung führte zu einem Simulatorfehler. + </string> + <string name="LoginFailedPendingLogout"> + Das System meldet Sie gerade ab. +Bitte warten Sie eine Minute, bevor Sie sich erneut einloggen. + </string> + <string name="LoginFailedUnableToCreateSession"> + Es kann keine gültige Sitzung erstellt werden. + </string> + <string name="LoginFailedUnableToConnectToSimulator"> + Es kann keine Simulatorverbindung hergestellt werden. + </string> + <string name="LoginFailedRestrictedHours"> + Mit Ihrem Konto ist der Zugriff auf Second Life nur zwischen [START] und [END] Pacific Time möglich. Schauen Sie während dieses Zeitraums vorbei. -Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com.</string> - <string name="LoginFailedIncorrectParameters">Falsche Parameter. -Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com.</string> - <string name="LoginFailedFirstNameNotAlphanumeric">Vorname muss alphanumerisch sein. -Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com.</string> - <string name="LoginFailedLastNameNotAlphanumeric">Nachname muss alphanumerisch sein. -Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com.</string> - <string name="LogoutFailedRegionGoingOffline">Die Region wird gerade offline geschaltet. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="LogoutFailedAgentNotInRegion">Agent nicht in Region. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="LogoutFailedPendingLogin">Die Region war gerade dabei, eine andere Sitzung anzumelden. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="LogoutFailedLoggingOut">Die Region war gerade dabei, die vorherige Sitzung abzumelden. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="LogoutFailedStillLoggingOut">Die Region ist noch immer dabei, die vorherige Sitzung abzumelden. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="LogoutSucceeded">Die Region hat soeben die letzte Sitzung abgemeldet. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="LogoutFailedLogoutBegun">Die Region hat den Abmeldevorgang gestartet. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="LoginFailedLoggingOutSession">Das System hat begonnen, Ihre letzte Sitzung abzumelden. -Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden.</string> - <string name="AgentLostConnection">In dieser Region kann es zu Problemen kommen. Bitte überprüfen Sie Ihre Internetverbindung.</string> - <string name="SavingSettings">Ihr Einstellungen werden gespeichert...</string> - <string name="LoggingOut">Abmeldung erfolgt...</string> - <string name="ShuttingDown">Programm wird beendet...</string> - <string name="YouHaveBeenDisconnected">Die Verbindung zu der Region ist abgebrochen.</string> - <string name="SentToInvalidRegion">Sie wurden in eine ungültige Region geschickt.</string> - <string name="TestingDisconnect">Verbindungsabbruch wird getestet</string> - <string name="SocialFacebookConnecting">Mit Facebook verbinden...</string> - <string name="SocialFacebookPosting">Posten...</string> - <string name="SocialFacebookDisconnecting">Facebook-Verbindung trennen...</string> - <string name="SocialFacebookErrorConnecting">Problem beim Verbinden mit Facebook</string> - <string name="SocialFacebookErrorPosting">Problem beim Posten auf Facebook</string> - <string name="SocialFacebookErrorDisconnecting">Problem beim Trennen der Facebook-Verbindung</string> - <string name="SocialFlickrConnecting">Verbinden mit Flickr...</string> - <string name="SocialFlickrPosting">Posten...</string> - <string name="SocialFlickrDisconnecting">Flickr-Verbindung wird getrennt...</string> - <string name="SocialFlickrErrorConnecting">Problem beim Verbinden mit Flickr</string> - <string name="SocialFlickrErrorPosting">Problem beim Posten auf Flickr</string> - <string name="SocialFlickrErrorDisconnecting">Problem beim Trennen der Flickr-Verbindung</string> - <string name="SocialTwitterConnecting">Verbinden mit Twitter...</string> - <string name="SocialTwitterPosting">Posten...</string> - <string name="SocialTwitterDisconnecting">Twitter-Verbindung wird getrennt...</string> - <string name="SocialTwitterErrorConnecting">Problem beim Verbinden mit Twitter</string> - <string name="SocialTwitterErrorPosting">Problem beim Posten auf Twitter</string> - <string name="SocialTwitterErrorDisconnecting">Problem beim Trennen der Twitter-Verbindung</string> - <string name="BlackAndWhite">Schwarzweiß</string> - <string name="Colors1970">Farben der Siebziger Jahre</string> - <string name="Intense">Intensiv</string> - <string name="Newspaper">Zeitungspapier</string> - <string name="Sepia">Sepia</string> - <string name="Spotlight">Spotlight</string> - <string name="Video">Video</string> - <string name="Autocontrast">Autokontrast</string> - <string name="LensFlare">Blendenfleck</string> - <string name="Miniature">Miniatur</string> - <string name="Toycamera">Spielzeugkamera</string> - <string name="TooltipPerson">Person</string> - <string name="TooltipNoName">(namenlos)</string> - <string name="TooltipOwner">Eigentümer:</string> - <string name="TooltipPublic">Öffentlich</string> - <string name="TooltipIsGroup">(Gruppe)</string> - <string name="TooltipForSaleL$">Zum Verkauf: [AMOUNT] L$</string> - <string name="TooltipFlagGroupBuild">Gruppenbau</string> - <string name="TooltipFlagNoBuild">Bauen aus</string> - <string name="TooltipFlagNoEdit">Gruppenbau</string> - <string name="TooltipFlagNotSafe">Unsicher</string> - <string name="TooltipFlagNoFly">Fliegen aus</string> - <string name="TooltipFlagGroupScripts">Gruppenskripte</string> - <string name="TooltipFlagNoScripts">Skripte aus</string> - <string name="TooltipLand">Land:</string> - <string name="TooltipMustSingleDrop">Sie können nur ein einzelnes Objekt hierher ziehen</string> - <string name="TooltipTooManyWearables">Sie können keinen Ordner tragen, der mehr als [AMOUNT] Elemente enthält. Sie können diesen Höchstwert unter „Erweitert“ > „Debug-Einstellungen anzeigen“ > „WearFolderLimit“ ändern.</string> +Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com. + </string> + <string name="LoginFailedIncorrectParameters"> + Falsche Parameter. +Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com. + </string> + <string name="LoginFailedFirstNameNotAlphanumeric"> + Vorname muss alphanumerisch sein. +Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com. + </string> + <string name="LoginFailedLastNameNotAlphanumeric"> + Nachname muss alphanumerisch sein. +Wenn Sie der Ansicht sind, dass Sie diese Meldung fälschlicherweise erhalten haben, wenden Sie sich an support@secondlife.com. + </string> + <string name="LogoutFailedRegionGoingOffline"> + Die Region wird gerade offline geschaltet. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="LogoutFailedAgentNotInRegion"> + Agent nicht in Region. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="LogoutFailedPendingLogin"> + Die Region war gerade dabei, eine andere Sitzung anzumelden. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="LogoutFailedLoggingOut"> + Die Region war gerade dabei, die vorherige Sitzung abzumelden. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="LogoutFailedStillLoggingOut"> + Die Region ist noch immer dabei, die vorherige Sitzung abzumelden. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="LogoutSucceeded"> + Die Region hat soeben die letzte Sitzung abgemeldet. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="LogoutFailedLogoutBegun"> + Die Region hat den Abmeldevorgang gestartet. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="LoginFailedLoggingOutSession"> + Das System hat begonnen, Ihre letzte Sitzung abzumelden. +Warten Sie kurz und versuchen Sie dann noch einmal, sich anzumelden. + </string> + <string name="AgentLostConnection"> + In dieser Region kann es zu Problemen kommen. Bitte überprüfen Sie Ihre Internetverbindung. + </string> + <string name="SavingSettings"> + Ihr Einstellungen werden gespeichert... + </string> + <string name="LoggingOut"> + Abmeldung erfolgt... + </string> + <string name="ShuttingDown"> + Programm wird beendet... + </string> + <string name="YouHaveBeenDisconnected"> + Die Verbindung zu der Region ist abgebrochen. + </string> + <string name="SentToInvalidRegion"> + Sie wurden in eine ungültige Region geschickt. + </string> + <string name="TestingDisconnect"> + Verbindungsabbruch wird getestet + </string> + <string name="SocialFacebookConnecting"> + Mit Facebook verbinden... + </string> + <string name="SocialFacebookPosting"> + Posten... + </string> + <string name="SocialFacebookDisconnecting"> + Facebook-Verbindung trennen... + </string> + <string name="SocialFacebookErrorConnecting"> + Problem beim Verbinden mit Facebook + </string> + <string name="SocialFacebookErrorPosting"> + Problem beim Posten auf Facebook + </string> + <string name="SocialFacebookErrorDisconnecting"> + Problem beim Trennen der Facebook-Verbindung + </string> + <string name="SocialFlickrConnecting"> + Verbinden mit Flickr... + </string> + <string name="SocialFlickrPosting"> + Posten... + </string> + <string name="SocialFlickrDisconnecting"> + Flickr-Verbindung wird getrennt... + </string> + <string name="SocialFlickrErrorConnecting"> + Problem beim Verbinden mit Flickr + </string> + <string name="SocialFlickrErrorPosting"> + Problem beim Posten auf Flickr + </string> + <string name="SocialFlickrErrorDisconnecting"> + Problem beim Trennen der Flickr-Verbindung + </string> + <string name="SocialTwitterConnecting"> + Verbinden mit Twitter... + </string> + <string name="SocialTwitterPosting"> + Posten... + </string> + <string name="SocialTwitterDisconnecting"> + Twitter-Verbindung wird getrennt... + </string> + <string name="SocialTwitterErrorConnecting"> + Problem beim Verbinden mit Twitter + </string> + <string name="SocialTwitterErrorPosting"> + Problem beim Posten auf Twitter + </string> + <string name="SocialTwitterErrorDisconnecting"> + Problem beim Trennen der Twitter-Verbindung + </string> + <string name="BlackAndWhite"> + Schwarzweiß + </string> + <string name="Colors1970"> + Farben der Siebziger Jahre + </string> + <string name="Intense"> + Intensiv + </string> + <string name="Newspaper"> + Zeitungspapier + </string> + <string name="Sepia"> + Sepia + </string> + <string name="Spotlight"> + Spotlight + </string> + <string name="Video"> + Video + </string> + <string name="Autocontrast"> + Autokontrast + </string> + <string name="LensFlare"> + Blendenfleck + </string> + <string name="Miniature"> + Miniatur + </string> + <string name="Toycamera"> + Spielzeugkamera + </string> + <string name="TooltipPerson"> + Person + </string> + <string name="TooltipNoName"> + (namenlos) + </string> + <string name="TooltipOwner"> + Eigentümer: + </string> + <string name="TooltipPublic"> + Öffentlich + </string> + <string name="TooltipIsGroup"> + (Gruppe) + </string> + <string name="TooltipForSaleL$"> + Zum Verkauf: [AMOUNT] L$ + </string> + <string name="TooltipFlagGroupBuild"> + Gruppenbau + </string> + <string name="TooltipFlagNoBuild"> + Bauen aus + </string> + <string name="TooltipFlagNoEdit"> + Gruppenbau + </string> + <string name="TooltipFlagNotSafe"> + Unsicher + </string> + <string name="TooltipFlagNoFly"> + Fliegen aus + </string> + <string name="TooltipFlagGroupScripts"> + Gruppenskripte + </string> + <string name="TooltipFlagNoScripts"> + Skripte aus + </string> + <string name="TooltipLand"> + Land: + </string> + <string name="TooltipMustSingleDrop"> + Sie können nur ein einzelnes Objekt hierher ziehen + </string> + <string name="TooltipTooManyWearables"> + Sie können keinen Ordner tragen, der mehr als [AMOUNT] Elemente enthält. Sie können diesen Höchstwert unter „Erweitert“ > „Debug-Einstellungen anzeigen“ > „WearFolderLimit“ ändern. + </string> <string name="TooltipPrice" value="[AMOUNT] L$"/> - <string name="TooltipSLIcon">Führt zu einer Seite in der offiziellen Domäne SecondLife.com oder LindenLab.com.</string> - <string name="TooltipOutboxDragToWorld">Sie können keine Objekte aus dem Marktplatz-Auflistungsordner rezzen</string> - <string name="TooltipOutboxWorn">Sie können Objekte, die Sie tragen, nicht in den Marktplatz-Auflistungsordner stellen</string> - <string name="TooltipOutboxFolderLevels">Tiefe der verschachtelten Ordner überschreitet [AMOUNT]. Reduzieren Sie die Ordnertiefe. Verpacken Sie ggf. einige Artikel.</string> - <string name="TooltipOutboxTooManyFolders">Anzahl von Unterordnern überschreitet [AMOUNT]. Reduzieren Sie die Anzahl von Ordnern in Ihrer Auflistung. Verpacken Sie ggf. einige Artikel.</string> - <string name="TooltipOutboxTooManyObjects">Anzahl von Objekten überschreitet [AMOUNT]. Um mehr als [AMOUNT] Objekte in einer Auflistung verkaufen zu können, müssen Sie einige davon verpacken.</string> - <string name="TooltipOutboxTooManyStockItems">Anzahl von Bestandsobjekten überschreitet [AMOUNT].</string> - <string name="TooltipOutboxCannotDropOnRoot">Sie können Objekte oder Ordner nur in der Registerkarte „ALLE“ oder „NICHT VERKNüPFT“ ablegen. Klicken Sie auf eine dieser Registerkarten und versuchen Sie dann erneut, Ihre Objekte bzw. Ordner zu verschieben.</string> - <string name="TooltipOutboxNoTransfer">Mindestens eines dieser Objekte kann nicht verkauft oder übertragen werden</string> - <string name="TooltipOutboxNotInInventory">Sie können nur Objekte aus Ihrem Inventar in den Marktplatz einstellen</string> - <string name="TooltipOutboxLinked">Sie können keine verknüpften Objekte oder Ordner in den Marktplatz einstellen</string> - <string name="TooltipOutboxCallingCard">Sie können Visitenkarten nicht in den Marktplatz einstellen</string> - <string name="TooltipOutboxDragActive">Sie können keine gelistete Auflistung entfernen</string> - <string name="TooltipOutboxCannotMoveRoot">Der Stammordner mit Marktplatz-Auflistungen kann nicht verschoben werden.</string> - <string name="TooltipOutboxMixedStock">Alle Objekte in einem Bestandsordner müssen vom gleichen Typ sein und die gleiche Berechtigung haben</string> - <string name="TooltipDragOntoOwnChild">Sie können einen Ordner nicht in einen seiner untergeordneten Ordner verschieben</string> - <string name="TooltipDragOntoSelf">Sie können einen Ordner nicht in sich selbst verschieben</string> - <string name="TooltipHttpUrl">Anklicken, um Webseite anzuzeigen</string> - <string name="TooltipSLURL">Anklicken, um Informationen zu diesem Standort anzuzeigen</string> - <string name="TooltipAgentUrl">Anklicken, um das Profil dieses Einwohners anzuzeigen</string> - <string name="TooltipAgentInspect">Mehr über diesen Einwohner</string> - <string name="TooltipAgentMute">Klicken, um diesen Einwohner stummzuschalten</string> - <string name="TooltipAgentUnmute">Klicken, um diesen Einwohner freizuschalten</string> - <string name="TooltipAgentIM">Klicken, um diesem Einwohner eine IM zu schicken.</string> - <string name="TooltipAgentPay">Klicken, um diesen Einwohner zu bezahlen</string> - <string name="TooltipAgentOfferTeleport">Klicken, um diesem Einwohner einen Teleport anzubieten.</string> - <string name="TooltipAgentRequestFriend">Klicken, um diesem Einwohner ein Freundschaftsangebot zu schicken.</string> - <string name="TooltipGroupUrl">Anklicken, um Beschreibung der Gruppe anzuzeigen</string> - <string name="TooltipEventUrl">Anklicken, um Beschreibung der Veranstaltung anzuzeigen</string> - <string name="TooltipClassifiedUrl">Anklicken, um diese Anzeige anzuzeigen</string> - <string name="TooltipParcelUrl">Anklicken, um Beschreibung der Parzelle anzuzeigen</string> - <string name="TooltipTeleportUrl">Anklicken, um zu diesem Standort zu teleportieren</string> - <string name="TooltipObjectIMUrl">Anklicken, um Beschreibung des Objekts anzuzeigen</string> - <string name="TooltipMapUrl">Klicken, um diese Position auf der Karte anzuzeigen</string> - <string name="TooltipSLAPP">Anklicken, um Befehl secondlife:// auszuführen</string> + <string name="TooltipSLIcon"> + Führt zu einer Seite in der offiziellen Domäne SecondLife.com oder LindenLab.com. + </string> + <string name="TooltipOutboxDragToWorld"> + Sie können keine Objekte aus dem Marktplatz-Auflistungsordner rezzen + </string> + <string name="TooltipOutboxWorn"> + Sie können Objekte, die Sie tragen, nicht in den Marktplatz-Auflistungsordner stellen + </string> + <string name="TooltipOutboxFolderLevels"> + Tiefe der verschachtelten Ordner überschreitet [AMOUNT]. Reduzieren Sie die Ordnertiefe. Verpacken Sie ggf. einige Artikel. + </string> + <string name="TooltipOutboxTooManyFolders"> + Anzahl von Unterordnern überschreitet [AMOUNT]. Reduzieren Sie die Anzahl von Ordnern in Ihrer Auflistung. Verpacken Sie ggf. einige Artikel. + </string> + <string name="TooltipOutboxTooManyObjects"> + Anzahl von Objekten überschreitet [AMOUNT]. Um mehr als [AMOUNT] Objekte in einer Auflistung verkaufen zu können, müssen Sie einige davon verpacken. + </string> + <string name="TooltipOutboxTooManyStockItems"> + Anzahl von Bestandsobjekten überschreitet [AMOUNT]. + </string> + <string name="TooltipOutboxCannotDropOnRoot"> + Sie können Objekte oder Ordner nur in der Registerkarte „ALLE“ oder „NICHT VERKNüPFT“ ablegen. Klicken Sie auf eine dieser Registerkarten und versuchen Sie dann erneut, Ihre Objekte bzw. Ordner zu verschieben. + </string> + <string name="TooltipOutboxNoTransfer"> + Mindestens eines dieser Objekte kann nicht verkauft oder übertragen werden + </string> + <string name="TooltipOutboxNotInInventory"> + Sie können nur Objekte aus Ihrem Inventar in den Marktplatz einstellen + </string> + <string name="TooltipOutboxLinked"> + Sie können keine verknüpften Objekte oder Ordner in den Marktplatz einstellen + </string> + <string name="TooltipOutboxCallingCard"> + Sie können Visitenkarten nicht in den Marktplatz einstellen + </string> + <string name="TooltipOutboxDragActive"> + Sie können keine gelistete Auflistung entfernen + </string> + <string name="TooltipOutboxCannotMoveRoot"> + Der Stammordner mit Marktplatz-Auflistungen kann nicht verschoben werden. + </string> + <string name="TooltipOutboxMixedStock"> + Alle Objekte in einem Bestandsordner müssen vom gleichen Typ sein und die gleiche Berechtigung haben + </string> + <string name="TooltipDragOntoOwnChild"> + Sie können einen Ordner nicht in einen seiner untergeordneten Ordner verschieben + </string> + <string name="TooltipDragOntoSelf"> + Sie können einen Ordner nicht in sich selbst verschieben + </string> + <string name="TooltipHttpUrl"> + Anklicken, um Webseite anzuzeigen + </string> + <string name="TooltipSLURL"> + Anklicken, um Informationen zu diesem Standort anzuzeigen + </string> + <string name="TooltipAgentUrl"> + Anklicken, um das Profil dieses Einwohners anzuzeigen + </string> + <string name="TooltipAgentInspect"> + Mehr über diesen Einwohner + </string> + <string name="TooltipAgentMute"> + Klicken, um diesen Einwohner stummzuschalten + </string> + <string name="TooltipAgentUnmute"> + Klicken, um diesen Einwohner freizuschalten + </string> + <string name="TooltipAgentIM"> + Klicken, um diesem Einwohner eine IM zu schicken. + </string> + <string name="TooltipAgentPay"> + Klicken, um diesen Einwohner zu bezahlen + </string> + <string name="TooltipAgentOfferTeleport"> + Klicken, um diesem Einwohner einen Teleport anzubieten. + </string> + <string name="TooltipAgentRequestFriend"> + Klicken, um diesem Einwohner ein Freundschaftsangebot zu schicken. + </string> + <string name="TooltipGroupUrl"> + Anklicken, um Beschreibung der Gruppe anzuzeigen + </string> + <string name="TooltipEventUrl"> + Anklicken, um Beschreibung der Veranstaltung anzuzeigen + </string> + <string name="TooltipClassifiedUrl"> + Anklicken, um diese Anzeige anzuzeigen + </string> + <string name="TooltipParcelUrl"> + Anklicken, um Beschreibung der Parzelle anzuzeigen + </string> + <string name="TooltipTeleportUrl"> + Anklicken, um zu diesem Standort zu teleportieren + </string> + <string name="TooltipObjectIMUrl"> + Anklicken, um Beschreibung des Objekts anzuzeigen + </string> + <string name="TooltipMapUrl"> + Klicken, um diese Position auf der Karte anzuzeigen + </string> + <string name="TooltipSLAPP"> + Anklicken, um Befehl secondlife:// auszuführen + </string> <string name="CurrentURL" value=" CurrentURL: [CurrentURL]"/> - <string name="TooltipEmail">Klicken, um eine E-Mail zu verfassen</string> - <string name="SLurlLabelTeleport">Teleportieren nach</string> - <string name="SLurlLabelShowOnMap">Karte anzeigen für</string> - <string name="SLappAgentMute">Stummschalten</string> - <string name="SLappAgentUnmute">Stummschaltung aufheben</string> - <string name="SLappAgentIM">IM</string> - <string name="SLappAgentPay">Bezahlen</string> - <string name="SLappAgentOfferTeleport">Teleportangebot an</string> - <string name="SLappAgentRequestFriend">Freundschaftsangebot</string> - <string name="SLappAgentRemoveFriend">Entfernen von Freunden</string> - <string name="BUTTON_CLOSE_DARWIN">Schließen (⌘W)</string> - <string name="BUTTON_CLOSE_WIN">Schließen (Strg+W)</string> - <string name="BUTTON_CLOSE_CHROME">Schließen</string> - <string name="BUTTON_RESTORE">Wiederherstellen</string> - <string name="BUTTON_MINIMIZE">Minimieren</string> - <string name="BUTTON_TEAR_OFF">Abnehmen</string> - <string name="BUTTON_DOCK">Andocken</string> - <string name="BUTTON_HELP">Hilfe anzeigen</string> - <string name="TooltipNotecardNotAllowedTypeDrop">Objekte dieses Typs können nicht an Notizkarten -für diese Region angehängt werden.</string> - <string name="TooltipNotecardOwnerRestrictedDrop">An Notizkarten können nur Objekte ohne + <string name="TooltipEmail"> + Klicken, um eine E-Mail zu verfassen + </string> + <string name="SLurlLabelTeleport"> + Teleportieren nach + </string> + <string name="SLurlLabelShowOnMap"> + Karte anzeigen für + </string> + <string name="SLappAgentMute"> + Stummschalten + </string> + <string name="SLappAgentUnmute"> + Stummschaltung aufheben + </string> + <string name="SLappAgentIM"> + IM + </string> + <string name="SLappAgentPay"> + Bezahlen + </string> + <string name="SLappAgentOfferTeleport"> + Teleportangebot an + </string> + <string name="SLappAgentRequestFriend"> + Freundschaftsangebot + </string> + <string name="SLappAgentRemoveFriend"> + Entfernen von Freunden + </string> + <string name="BUTTON_CLOSE_DARWIN"> + Schließen (⌘W) + </string> + <string name="BUTTON_CLOSE_WIN"> + Schließen (Strg+W) + </string> + <string name="BUTTON_CLOSE_CHROME"> + Schließen + </string> + <string name="BUTTON_RESTORE"> + Wiederherstellen + </string> + <string name="BUTTON_MINIMIZE"> + Minimieren + </string> + <string name="BUTTON_TEAR_OFF"> + Abnehmen + </string> + <string name="BUTTON_DOCK"> + Andocken + </string> + <string name="BUTTON_HELP"> + Hilfe anzeigen + </string> + <string name="TooltipNotecardNotAllowedTypeDrop"> + Objekte dieses Typs können nicht an Notizkarten +für diese Region angehängt werden. + </string> + <string name="TooltipNotecardOwnerRestrictedDrop"> + An Notizkarten können nur Objekte ohne Berechtigungseinschränkungen für den -nächsten Eigentümer angehängt werden.</string> - <string name="Searching">Suchen...</string> - <string name="NoneFound">Nicht gefunden.</string> - <string name="RetrievingData">Laden...</string> - <string name="ReleaseNotes">Versionshinweise</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> - <string name="LoadingData">Wird geladen...</string> - <string name="AvatarNameNobody">(niemand)</string> - <string name="AvatarNameWaiting">(wartet)</string> - <string name="AvatarNameMultiple">(mehrere)</string> - <string name="GroupNameNone">(keiner)</string> - <string name="AssetErrorNone">Kein Fehler</string> - <string name="AssetErrorRequestFailed">Asset-Anforderung: fehlgeschlagen</string> - <string name="AssetErrorNonexistentFile">Asset-Anforderung: Datei existiert nicht</string> - <string name="AssetErrorNotInDatabase">Asset-Anforderung: Asset in Datenbank nicht gefunden</string> - <string name="AssetErrorEOF">Ende der Datei</string> - <string name="AssetErrorCannotOpenFile">Datei kann nicht geöffnet werden</string> - <string name="AssetErrorFileNotFound">Datei nicht gefunden</string> - <string name="AssetErrorTCPTimeout">Zeitüberschreitung bei Dateiübertragung</string> - <string name="AssetErrorCircuitGone">Verbindung verloren</string> - <string name="AssetErrorPriceMismatch">Viewer und Server sind sich nicht über Preis einig</string> - <string name="AssetErrorUnknownStatus">Status unbekannt</string> - <string name="AssetUploadServerUnreacheble">Dienst nicht verfügbar.</string> - <string name="AssetUploadServerDifficulties">Auf dem Server sind unerwartete Probleme aufgetreten.</string> - <string name="AssetUploadServerUnavaliable">Dienst nicht verfügbar oder Zeitüberschreitung beim Upload.</string> - <string name="AssetUploadRequestInvalid">Fehler bei der Upload-Anforderung. Um das Problem zu lösen, -besuchen Sie bitte http://secondlife.com/support</string> - <string name="SettingValidationError">Validierung für das Importieren der Einstellungen [NAME] fehlgeschlagen</string> - <string name="SettingImportFileError">[FILE] konnte nicht geöffnet werden</string> - <string name="SettingParseFileError">[FILE] konnte nicht geöffnet werden</string> - <string name="SettingTranslateError">Altes Windlight [NAME] konnte nicht übernommen werden</string> - <string name="texture">Textur</string> - <string name="sound">Sound</string> - <string name="calling card">Visitenkarte</string> - <string name="landmark">Landmarke</string> - <string name="legacy script">Skript (veraltet)</string> - <string name="clothing">Kleidung</string> - <string name="object">Objekt</string> - <string name="note card">Notizkarte</string> - <string name="folder">Ordner</string> - <string name="root">Hauptverzeichnis</string> - <string name="lsl2 script">LSL2 Skript</string> - <string name="lsl bytecode">LSL Bytecode</string> - <string name="tga texture">tga-Textur</string> - <string name="body part">Körperteil</string> - <string name="snapshot">Foto</string> - <string name="lost and found">Fundbüro</string> - <string name="targa image">targa-Bild</string> - <string name="trash">Papierkorb</string> - <string name="jpeg image">jpeg-Bild</string> - <string name="animation">Animation</string> - <string name="gesture">Geste</string> - <string name="simstate">simstate</string> - <string name="favorite">Favoriten</string> - <string name="symbolic link">Link</string> - <string name="symbolic folder link">Link zu Ordner</string> - <string name="settings blob">Einstellungen</string> - <string name="mesh">mesh</string> - <string name="AvatarEditingAppearance">(Aussehen wird bearbeitet)</string> - <string name="AvatarAway">Abwesend</string> - <string name="AvatarDoNotDisturb">Nicht stören</string> - <string name="AvatarMuted">Ignoriert</string> - <string name="anim_express_afraid">Ängstlich</string> - <string name="anim_express_anger">Verärgert</string> - <string name="anim_away">Abwesend</string> - <string name="anim_backflip">Rückwärtssalto</string> - <string name="anim_express_laugh">Lachkrampf</string> - <string name="anim_express_toothsmile">Grinsen</string> - <string name="anim_blowkiss">Kusshand</string> - <string name="anim_express_bored">Gelangweilt</string> - <string name="anim_bow">Verbeugen</string> - <string name="anim_clap">Klatschen</string> - <string name="anim_courtbow">Diener</string> - <string name="anim_express_cry">Weinen</string> - <string name="anim_dance1">Tanz 1</string> - <string name="anim_dance2">Tanz 2</string> - <string name="anim_dance3">Tanz 3</string> - <string name="anim_dance4">Tanz 4</string> - <string name="anim_dance5">Tanz 5</string> - <string name="anim_dance6">Tanz 6</string> - <string name="anim_dance7">Tanz 7</string> - <string name="anim_dance8">Tanz 8</string> - <string name="anim_express_disdain">Verachten</string> - <string name="anim_drink">Trinken</string> - <string name="anim_express_embarrased">Verlegen</string> - <string name="anim_angry_fingerwag">Drohen</string> - <string name="anim_fist_pump">Faust pumpen</string> - <string name="anim_yoga_float">Yogaflieger</string> - <string name="anim_express_frown">Stirnrunzeln</string> - <string name="anim_impatient">Ungeduldig</string> - <string name="anim_jumpforjoy">Freudensprung</string> - <string name="anim_kissmybutt">LMA</string> - <string name="anim_express_kiss">Küssen</string> - <string name="anim_laugh_short">Lachen</string> - <string name="anim_musclebeach">Posen</string> - <string name="anim_no_unhappy">Nein (Bedauernd)</string> - <string name="anim_no_head">Nein</string> - <string name="anim_nyanya">Ällabätsch</string> - <string name="anim_punch_onetwo">Eins-Zwei-Punch</string> - <string name="anim_express_open_mouth">Mund offen</string> - <string name="anim_peace">Friede</string> - <string name="anim_point_you">Auf anderen zeigen</string> - <string name="anim_point_me">Auf mich zeigen</string> - <string name="anim_punch_l">Linker Haken</string> - <string name="anim_punch_r">Rechter Haken</string> - <string name="anim_rps_countdown">SSP zählen</string> - <string name="anim_rps_paper">SSP Papier</string> - <string name="anim_rps_rock">SSP Stein</string> - <string name="anim_rps_scissors">SSP Schere</string> - <string name="anim_express_repulsed">Angewidert</string> - <string name="anim_kick_roundhouse_r">Rundkick</string> - <string name="anim_express_sad">Traurig</string> - <string name="anim_salute">Salutieren</string> - <string name="anim_shout">Rufen</string> - <string name="anim_express_shrug">Schulterzucken</string> - <string name="anim_express_smile">Lächeln</string> - <string name="anim_smoke_idle">Zigarette halten</string> - <string name="anim_smoke_inhale">Rauchen</string> - <string name="anim_smoke_throw_down">Zigarette wegwerfen</string> - <string name="anim_express_surprise">Überraschung</string> - <string name="anim_sword_strike_r">Schwerthieb</string> - <string name="anim_angry_tantrum">Wutanfall</string> - <string name="anim_express_tongue_out">Zunge rausstrecken</string> - <string name="anim_hello">Winken</string> - <string name="anim_whisper">Flüstern</string> - <string name="anim_whistle">Pfeifen</string> - <string name="anim_express_wink">Zwinkern</string> - <string name="anim_wink_hollywood">Zwinkern (Hollywood)</string> - <string name="anim_express_worry">Sorgenvoll</string> - <string name="anim_yes_happy">Ja (Erfreut)</string> - <string name="anim_yes_head">Ja</string> - <string name="multiple_textures">Mehrfach</string> - <string name="use_texture">Textur verwenden</string> - <string name="manip_hint1">Zum Einrasten Mauscursor</string> - <string name="manip_hint2">über Lineal bewegen</string> - <string name="texture_loading">Wird geladen...</string> - <string name="worldmap_offline">Offline</string> - <string name="worldmap_item_tooltip_format">[PRICE] L$ für [AREA] m²</string> - <string name="worldmap_results_none_found">Nicht gefunden.</string> - <string name="Ok">OK</string> - <string name="Premature end of file">Unvollständige Datei</string> - <string name="ST_NO_JOINT">HAUPTVERZEICHNIS oder VERBINDUNG nicht gefunden.</string> - <string name="NearbyChatTitle">Chat in der Nähe</string> - <string name="NearbyChatLabel">(Chat in der Nähe)</string> - <string name="whisper">flüstert:</string> - <string name="shout">ruft:</string> - <string name="ringing">Verbindung mit In-Welt-Voice-Chat...</string> - <string name="connected">Verbunden</string> - <string name="unavailable">Der aktuelle Standort unterstützt keine Voice-Kommunikation</string> - <string name="hang_up">Verbindung mit In-Welt-Voice-Chat getrennt</string> - <string name="reconnect_nearby">Sie werden nun wieder mit dem Chat in Ihrer Nähe verbunden</string> - <string name="ScriptQuestionCautionChatGranted">Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung erteilt: [PERMISSIONS].</string> - <string name="ScriptQuestionCautionChatDenied">Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung verweigert: [PERMISSIONS].</string> - <string name="AdditionalPermissionsRequestHeader">Wenn Sie dem Objekt Zugriff auf Ihr Konto gewähren, kann dieses außerdem:</string> - <string name="ScriptTakeMoney">Linden-Dollar (L$) von Ihnen nehmen</string> - <string name="ActOnControlInputs">Steuerung festlegen</string> - <string name="RemapControlInputs">Steuerung neu zuweisen</string> - <string name="AnimateYourAvatar">Avatar animieren</string> - <string name="AttachToYourAvatar">An Avatar anhängen</string> - <string name="ReleaseOwnership">Eigentum aufgeben und öffentlich machen</string> - <string name="LinkAndDelink">Mit Objekten verknüpfen und davon trennen</string> - <string name="AddAndRemoveJoints">Verbindungen zu anderen Objekten hinzufügen und entfernen</string> - <string name="ChangePermissions">Berechtigungen ändern</string> - <string name="TrackYourCamera">Kameraverfolgung</string> - <string name="ControlYourCamera">Kamerasteuerung</string> - <string name="TeleportYourAgent">Sie teleportieren</string> - <string name="ForceSitAvatar">Ihren Avatar zwingen, sich zu setzen</string> - <string name="ChangeEnvSettings">Umgebungseinstellungen ändern</string> - <string name="NotConnected">Nicht verbunden</string> - <string name="AgentNameSubst">(Sie)</string> +nächsten Eigentümer angehängt werden. + </string> + <string name="Searching"> + Suchen... + </string> + <string name="NoneFound"> + Nicht gefunden. + </string> + <string name="RetrievingData"> + Laden... + </string> + <string name="ReleaseNotes"> + Versionshinweise + </string> + <string name="RELEASE_NOTES_BASE_URL"> + https://releasenotes.secondlife.com/viewer/ + </string> + <string name="LoadingData"> + Wird geladen... + </string> + <string name="AvatarNameNobody"> + (niemand) + </string> + <string name="AvatarNameWaiting"> + (wartet) + </string> + <string name="AvatarNameMultiple"> + (mehrere) + </string> + <string name="GroupNameNone"> + (keiner) + </string> + <string name="AssetErrorNone"> + Kein Fehler + </string> + <string name="AssetErrorRequestFailed"> + Asset-Anforderung: fehlgeschlagen + </string> + <string name="AssetErrorNonexistentFile"> + Asset-Anforderung: Datei existiert nicht + </string> + <string name="AssetErrorNotInDatabase"> + Asset-Anforderung: Asset in Datenbank nicht gefunden + </string> + <string name="AssetErrorEOF"> + Ende der Datei + </string> + <string name="AssetErrorCannotOpenFile"> + Datei kann nicht geöffnet werden + </string> + <string name="AssetErrorFileNotFound"> + Datei nicht gefunden + </string> + <string name="AssetErrorTCPTimeout"> + Zeitüberschreitung bei Dateiübertragung + </string> + <string name="AssetErrorCircuitGone"> + Verbindung verloren + </string> + <string name="AssetErrorPriceMismatch"> + Viewer und Server sind sich nicht über Preis einig + </string> + <string name="AssetErrorUnknownStatus"> + Status unbekannt + </string> + <string name="AssetUploadServerUnreacheble"> + Dienst nicht verfügbar. + </string> + <string name="AssetUploadServerDifficulties"> + Auf dem Server sind unerwartete Probleme aufgetreten. + </string> + <string name="AssetUploadServerUnavaliable"> + Dienst nicht verfügbar oder Zeitüberschreitung beim Upload. + </string> + <string name="AssetUploadRequestInvalid"> + Fehler bei der Upload-Anforderung. Um das Problem zu lösen, +besuchen Sie bitte http://secondlife.com/support + </string> + <string name="SettingValidationError"> + Validierung für das Importieren der Einstellungen [NAME] fehlgeschlagen + </string> + <string name="SettingImportFileError"> + [FILE] konnte nicht geöffnet werden + </string> + <string name="SettingParseFileError"> + [FILE] konnte nicht geöffnet werden + </string> + <string name="SettingTranslateError"> + Altes Windlight [NAME] konnte nicht übernommen werden + </string> + <string name="texture"> + Textur + </string> + <string name="sound"> + Sound + </string> + <string name="calling card"> + Visitenkarte + </string> + <string name="landmark"> + Landmarke + </string> + <string name="legacy script"> + Skript (veraltet) + </string> + <string name="clothing"> + Kleidung + </string> + <string name="object"> + Objekt + </string> + <string name="note card"> + Notizkarte + </string> + <string name="folder"> + Ordner + </string> + <string name="root"> + Hauptverzeichnis + </string> + <string name="lsl2 script"> + LSL2 Skript + </string> + <string name="lsl bytecode"> + LSL Bytecode + </string> + <string name="tga texture"> + tga-Textur + </string> + <string name="body part"> + Körperteil + </string> + <string name="snapshot"> + Foto + </string> + <string name="lost and found"> + Fundbüro + </string> + <string name="targa image"> + targa-Bild + </string> + <string name="trash"> + Papierkorb + </string> + <string name="jpeg image"> + jpeg-Bild + </string> + <string name="animation"> + Animation + </string> + <string name="gesture"> + Geste + </string> + <string name="simstate"> + simstate + </string> + <string name="favorite"> + Favoriten + </string> + <string name="symbolic link"> + Link + </string> + <string name="symbolic folder link"> + Link zu Ordner + </string> + <string name="settings blob"> + Einstellungen + </string> + <string name="mesh"> + mesh + </string> + <string name="AvatarEditingAppearance"> + (Aussehen wird bearbeitet) + </string> + <string name="AvatarAway"> + Abwesend + </string> + <string name="AvatarDoNotDisturb"> + Nicht stören + </string> + <string name="AvatarMuted"> + Ignoriert + </string> + <string name="anim_express_afraid"> + Ängstlich + </string> + <string name="anim_express_anger"> + Verärgert + </string> + <string name="anim_away"> + Abwesend + </string> + <string name="anim_backflip"> + Rückwärtssalto + </string> + <string name="anim_express_laugh"> + Lachkrampf + </string> + <string name="anim_express_toothsmile"> + Grinsen + </string> + <string name="anim_blowkiss"> + Kusshand + </string> + <string name="anim_express_bored"> + Gelangweilt + </string> + <string name="anim_bow"> + Verbeugen + </string> + <string name="anim_clap"> + Klatschen + </string> + <string name="anim_courtbow"> + Diener + </string> + <string name="anim_express_cry"> + Weinen + </string> + <string name="anim_dance1"> + Tanz 1 + </string> + <string name="anim_dance2"> + Tanz 2 + </string> + <string name="anim_dance3"> + Tanz 3 + </string> + <string name="anim_dance4"> + Tanz 4 + </string> + <string name="anim_dance5"> + Tanz 5 + </string> + <string name="anim_dance6"> + Tanz 6 + </string> + <string name="anim_dance7"> + Tanz 7 + </string> + <string name="anim_dance8"> + Tanz 8 + </string> + <string name="anim_express_disdain"> + Verachten + </string> + <string name="anim_drink"> + Trinken + </string> + <string name="anim_express_embarrased"> + Verlegen + </string> + <string name="anim_angry_fingerwag"> + Drohen + </string> + <string name="anim_fist_pump"> + Faust pumpen + </string> + <string name="anim_yoga_float"> + Yogaflieger + </string> + <string name="anim_express_frown"> + Stirnrunzeln + </string> + <string name="anim_impatient"> + Ungeduldig + </string> + <string name="anim_jumpforjoy"> + Freudensprung + </string> + <string name="anim_kissmybutt"> + LMA + </string> + <string name="anim_express_kiss"> + Küssen + </string> + <string name="anim_laugh_short"> + Lachen + </string> + <string name="anim_musclebeach"> + Posen + </string> + <string name="anim_no_unhappy"> + Nein (Bedauernd) + </string> + <string name="anim_no_head"> + Nein + </string> + <string name="anim_nyanya"> + Ällabätsch + </string> + <string name="anim_punch_onetwo"> + Eins-Zwei-Punch + </string> + <string name="anim_express_open_mouth"> + Mund offen + </string> + <string name="anim_peace"> + Friede + </string> + <string name="anim_point_you"> + Auf anderen zeigen + </string> + <string name="anim_point_me"> + Auf mich zeigen + </string> + <string name="anim_punch_l"> + Linker Haken + </string> + <string name="anim_punch_r"> + Rechter Haken + </string> + <string name="anim_rps_countdown"> + SSP zählen + </string> + <string name="anim_rps_paper"> + SSP Papier + </string> + <string name="anim_rps_rock"> + SSP Stein + </string> + <string name="anim_rps_scissors"> + SSP Schere + </string> + <string name="anim_express_repulsed"> + Angewidert + </string> + <string name="anim_kick_roundhouse_r"> + Rundkick + </string> + <string name="anim_express_sad"> + Traurig + </string> + <string name="anim_salute"> + Salutieren + </string> + <string name="anim_shout"> + Rufen + </string> + <string name="anim_express_shrug"> + Schulterzucken + </string> + <string name="anim_express_smile"> + Lächeln + </string> + <string name="anim_smoke_idle"> + Zigarette halten + </string> + <string name="anim_smoke_inhale"> + Rauchen + </string> + <string name="anim_smoke_throw_down"> + Zigarette wegwerfen + </string> + <string name="anim_express_surprise"> + Überraschung + </string> + <string name="anim_sword_strike_r"> + Schwerthieb + </string> + <string name="anim_angry_tantrum"> + Wutanfall + </string> + <string name="anim_express_tongue_out"> + Zunge rausstrecken + </string> + <string name="anim_hello"> + Winken + </string> + <string name="anim_whisper"> + Flüstern + </string> + <string name="anim_whistle"> + Pfeifen + </string> + <string name="anim_express_wink"> + Zwinkern + </string> + <string name="anim_wink_hollywood"> + Zwinkern (Hollywood) + </string> + <string name="anim_express_worry"> + Sorgenvoll + </string> + <string name="anim_yes_happy"> + Ja (Erfreut) + </string> + <string name="anim_yes_head"> + Ja + </string> + <string name="multiple_textures"> + Mehrfach + </string> + <string name="use_texture"> + Textur verwenden + </string> + <string name="manip_hint1"> + Zum Einrasten Mauscursor + </string> + <string name="manip_hint2"> + über Lineal bewegen + </string> + <string name="texture_loading"> + Wird geladen... + </string> + <string name="worldmap_offline"> + Offline + </string> + <string name="worldmap_item_tooltip_format"> + [PRICE] L$ für [AREA] m² + </string> + <string name="worldmap_results_none_found"> + Nicht gefunden. + </string> + <string name="Ok"> + OK + </string> + <string name="Premature end of file"> + Unvollständige Datei + </string> + <string name="ST_NO_JOINT"> + HAUPTVERZEICHNIS oder VERBINDUNG nicht gefunden. + </string> + <string name="NearbyChatTitle"> + Chat in der Nähe + </string> + <string name="NearbyChatLabel"> + (Chat in der Nähe) + </string> + <string name="whisper"> + flüstert: + </string> + <string name="shout"> + ruft: + </string> + <string name="ringing"> + Verbindung mit In-Welt-Voice-Chat... + </string> + <string name="connected"> + Verbunden + </string> + <string name="unavailable"> + Der aktuelle Standort unterstützt keine Voice-Kommunikation + </string> + <string name="hang_up"> + Verbindung mit In-Welt-Voice-Chat getrennt + </string> + <string name="reconnect_nearby"> + Sie werden nun wieder mit dem Chat in Ihrer Nähe verbunden + </string> + <string name="ScriptQuestionCautionChatGranted"> + Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung erteilt: [PERMISSIONS]. + </string> + <string name="ScriptQuestionCautionChatDenied"> + Dem Objekt „[OBJECTNAME]“, ein Objekt von „[OWNERNAME]“, in [REGIONNAME] [REGIONPOS], wurde folgende Berechtigung verweigert: [PERMISSIONS]. + </string> + <string name="AdditionalPermissionsRequestHeader"> + Wenn Sie dem Objekt Zugriff auf Ihr Konto gewähren, kann dieses außerdem: + </string> + <string name="ScriptTakeMoney"> + Linden-Dollar (L$) von Ihnen nehmen + </string> + <string name="ActOnControlInputs"> + Steuerung festlegen + </string> + <string name="RemapControlInputs"> + Steuerung neu zuweisen + </string> + <string name="AnimateYourAvatar"> + Avatar animieren + </string> + <string name="AttachToYourAvatar"> + An Avatar anhängen + </string> + <string name="ReleaseOwnership"> + Eigentum aufgeben und öffentlich machen + </string> + <string name="LinkAndDelink"> + Mit Objekten verknüpfen und davon trennen + </string> + <string name="AddAndRemoveJoints"> + Verbindungen zu anderen Objekten hinzufügen und entfernen + </string> + <string name="ChangePermissions"> + Berechtigungen ändern + </string> + <string name="TrackYourCamera"> + Kameraverfolgung + </string> + <string name="ControlYourCamera"> + Kamerasteuerung + </string> + <string name="TeleportYourAgent"> + Sie teleportieren + </string> + <string name="ForceSitAvatar"> + Ihren Avatar zwingen, sich zu setzen + </string> + <string name="ChangeEnvSettings"> + Umgebungseinstellungen ändern + </string> + <string name="NotConnected"> + Nicht verbunden + </string> + <string name="AgentNameSubst"> + (Sie) + </string> <string name="JoinAnExperience"/> - <string name="SilentlyManageEstateAccess">Beim Verwalten von Grundbesitzzugangslisten Warnhinweise unterdrücken</string> - <string name="OverrideYourAnimations">Ihre Standardanimationen ersetzen</string> - <string name="ScriptReturnObjects">Objekte in Ihrem Namen zurückgeben</string> - <string name="UnknownScriptPermission">(unbekannt)</string> - <string name="SIM_ACCESS_PG">Generell</string> - <string name="SIM_ACCESS_MATURE">Moderat</string> - <string name="SIM_ACCESS_ADULT">Adult</string> - <string name="SIM_ACCESS_DOWN">Offline</string> - <string name="SIM_ACCESS_MIN">Unbekannt</string> - <string name="land_type_unknown">(unbekannt)</string> - <string name="Estate / Full Region">Grundstück / Vollständige Region</string> - <string name="Estate / Homestead">Grundbesitz/Homestead</string> - <string name="Mainland / Homestead">Mainland/Homestead</string> - <string name="Mainland / Full Region">Mainland / Vollständige Region</string> - <string name="all_files">Alle Dateien</string> - <string name="sound_files">Sounds</string> - <string name="animation_files">Animationen</string> - <string name="image_files">Bilder</string> - <string name="save_file_verb">Speichern</string> - <string name="load_file_verb">Laden</string> - <string name="targa_image_files">Targa-Bilder</string> - <string name="bitmap_image_files">Bitmap-Bilder</string> - <string name="png_image_files">PNG-Bilder</string> - <string name="save_texture_image_files">Targa- oder PNG-Bilder</string> - <string name="avi_movie_file">AVI-Filmdatei</string> - <string name="xaf_animation_file">XAF Anim-Datei</string> - <string name="xml_file">XML-Datei</string> - <string name="raw_file">RAW-Datei</string> - <string name="compressed_image_files">Komprimierte Bilder</string> - <string name="load_files">Dateien laden</string> - <string name="choose_the_directory">Verzeichnis auswählen</string> - <string name="script_files">Skripts</string> - <string name="dictionary_files">Wörterbücher</string> - <string name="shape">Form</string> - <string name="skin">Haut</string> - <string name="hair">Haare</string> - <string name="eyes">Augen</string> - <string name="shirt">Hemd</string> - <string name="pants">Hose</string> - <string name="shoes">Schuhe</string> - <string name="socks">Socken</string> - <string name="jacket">Jacke</string> - <string name="gloves">Handschuhe</string> - <string name="undershirt">Unterhemd</string> - <string name="underpants">Unterhose</string> - <string name="skirt">Rock</string> - <string name="alpha">Alpha</string> - <string name="tattoo">Tätowierung</string> - <string name="universal">Universal</string> - <string name="physics">Physik</string> - <string name="invalid">ungültig</string> - <string name="none">keine</string> - <string name="shirt_not_worn">Hemd nicht getragen</string> - <string name="pants_not_worn">Hosen nicht getragen</string> - <string name="shoes_not_worn">Schuhe nicht getragen</string> - <string name="socks_not_worn">Socken nicht getragen</string> - <string name="jacket_not_worn">Jacke nicht getragen</string> - <string name="gloves_not_worn">Handschuhe nicht getragen</string> - <string name="undershirt_not_worn">Unterhemd nicht getragen</string> - <string name="underpants_not_worn">Unterhose nicht getragen</string> - <string name="skirt_not_worn">Rock nicht getragen</string> - <string name="alpha_not_worn">Alpha nicht getragen</string> - <string name="tattoo_not_worn">Tätowierung nicht getragen</string> - <string name="universal_not_worn">Universal nicht getragen</string> - <string name="physics_not_worn">Physik nicht getragen</string> - <string name="invalid_not_worn">ungültig</string> - <string name="create_new_shape">Neue Form/Gestalt erstellen</string> - <string name="create_new_skin">Neue Haut erstellen</string> - <string name="create_new_hair">Neue Haare erstellen</string> - <string name="create_new_eyes">Neue Augen erstellen</string> - <string name="create_new_shirt">Neues Hemd erstellen</string> - <string name="create_new_pants">Neue Hose erstellen</string> - <string name="create_new_shoes">Neue Schuhe erstellen</string> - <string name="create_new_socks">Neue Socken erstellen</string> - <string name="create_new_jacket">Neue Jacke erstellen</string> - <string name="create_new_gloves">Neue Handschuhe erstellen</string> - <string name="create_new_undershirt">Neues Unterhemd erstellen</string> - <string name="create_new_underpants">Neue Unterhose erstellen</string> - <string name="create_new_skirt">Neuer Rock erstellen</string> - <string name="create_new_alpha">Neue Alpha erstellen</string> - <string name="create_new_tattoo">Neue Tätowierung erstellen</string> - <string name="create_new_universal">Neues Universal erstellen</string> - <string name="create_new_physics">Neue Physik erstellen</string> - <string name="create_new_invalid">ungültig</string> - <string name="NewWearable">Neue/r/s [WEARABLE_ITEM]</string> - <string name="next">Weiter</string> - <string name="ok">OK</string> - <string name="GroupNotifyGroupNotice">Gruppenmitteilung</string> - <string name="GroupNotifyGroupNotices">Gruppenmitteilungen</string> - <string name="GroupNotifySentBy">Gesendet von</string> - <string name="GroupNotifyAttached">Im Anhang:</string> - <string name="GroupNotifyViewPastNotices">Alte Mitteilungen anzeigen oder hier Auswahl treffen, um keine Mitteilungen mehr zu erhalten.</string> - <string name="GroupNotifyOpenAttachment">Anlage öffnen</string> - <string name="GroupNotifySaveAttachment">Siehe Anhang</string> - <string name="TeleportOffer">Teleport-Angebot</string> - <string name="StartUpNotifications">Sie haben neue Benachrichtigungen erhalten, während Sie abwesend waren.</string> - <string name="OverflowInfoChannelString">Sie haben noch %d weitere Benachrichtigungen</string> - <string name="BodyPartsRightArm">Rechter Arm</string> - <string name="BodyPartsHead">Kopf</string> - <string name="BodyPartsLeftArm">Linker Arm</string> - <string name="BodyPartsLeftLeg">Linkes Bein</string> - <string name="BodyPartsTorso">Oberkörper</string> - <string name="BodyPartsRightLeg">Rechtes Bein</string> - <string name="BodyPartsEnhancedSkeleton">Erweitertes Skelett</string> - <string name="GraphicsQualityLow">Niedrig</string> - <string name="GraphicsQualityMid">Mittel</string> - <string name="GraphicsQualityHigh">Hoch</string> - <string name="LeaveMouselook">ESC drücken, um zur Normalansicht zurückzukehren</string> - <string name="InventoryNoMatchingItems">Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/all/[SEARCH_TERM] Suche].</string> - <string name="InventoryNoMatchingRecentItems">Sie haben nicht das Richtige gefunden? Versuchen Sie [secondlife:///app/inventory/filters Show filters].</string> - <string name="PlacesNoMatchingItems">Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/places/[SEARCH_TERM] Suche].</string> - <string name="FavoritesNoMatchingItems">Landmarke hier hin ziehen, um diese hinzuzufügen.</string> - <string name="MarketplaceNoMatchingItems">Keine übereinstimmenden Objekte gefunden. Überprüfen Sie die Schreibweise des Suchbegriffs und versuchen Sie es noch einmal.</string> - <string name="InventoryNoTexture">Sie haben keine Kopie dieser Textur in Ihrem Inventar.</string> - <string name="InventoryInboxNoItems">Einkäufe aus dem Marktplatz erscheinen hier. Sie können diese dann zur Verwendung in Ihr Inventar ziehen.</string> - <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> - <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3</string> - <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string> - <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string> - <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string> - <string name="InventoryPlayAnimationTooltip">Fenster mit Spieloptionen öffnen.</string> - <string name="InventoryPlayGestureTooltip">Ausgewählte Geste inworld ausführen.</string> - <string name="InventoryPlaySoundTooltip">Fenster mit Spieloptionen öffnen.</string> - <string name="InventoryOutboxNotMerchantTitle">Jeder kann Artikel im Marktplatz verkaufen.</string> + <string name="SilentlyManageEstateAccess"> + Beim Verwalten von Grundbesitzzugangslisten Warnhinweise unterdrücken + </string> + <string name="OverrideYourAnimations"> + Ihre Standardanimationen ersetzen + </string> + <string name="ScriptReturnObjects"> + Objekte in Ihrem Namen zurückgeben + </string> + <string name="UnknownScriptPermission"> + (unbekannt) + </string> + <string name="SIM_ACCESS_PG"> + Generell + </string> + <string name="SIM_ACCESS_MATURE"> + Moderat + </string> + <string name="SIM_ACCESS_ADULT"> + Adult + </string> + <string name="SIM_ACCESS_DOWN"> + Offline + </string> + <string name="SIM_ACCESS_MIN"> + Unbekannt + </string> + <string name="land_type_unknown"> + (unbekannt) + </string> + <string name="Estate / Full Region"> + Grundstück / Vollständige Region + </string> + <string name="Estate / Homestead"> + Grundbesitz/Homestead + </string> + <string name="Mainland / Homestead"> + Mainland/Homestead + </string> + <string name="Mainland / Full Region"> + Mainland / Vollständige Region + </string> + <string name="all_files"> + Alle Dateien + </string> + <string name="sound_files"> + Sounds + </string> + <string name="animation_files"> + Animationen + </string> + <string name="image_files"> + Bilder + </string> + <string name="save_file_verb"> + Speichern + </string> + <string name="load_file_verb"> + Laden + </string> + <string name="targa_image_files"> + Targa-Bilder + </string> + <string name="bitmap_image_files"> + Bitmap-Bilder + </string> + <string name="png_image_files"> + PNG-Bilder + </string> + <string name="save_texture_image_files"> + Targa- oder PNG-Bilder + </string> + <string name="avi_movie_file"> + AVI-Filmdatei + </string> + <string name="xaf_animation_file"> + XAF Anim-Datei + </string> + <string name="xml_file"> + XML-Datei + </string> + <string name="raw_file"> + RAW-Datei + </string> + <string name="compressed_image_files"> + Komprimierte Bilder + </string> + <string name="load_files"> + Dateien laden + </string> + <string name="choose_the_directory"> + Verzeichnis auswählen + </string> + <string name="script_files"> + Skripts + </string> + <string name="dictionary_files"> + Wörterbücher + </string> + <string name="shape"> + Form + </string> + <string name="skin"> + Haut + </string> + <string name="hair"> + Haare + </string> + <string name="eyes"> + Augen + </string> + <string name="shirt"> + Hemd + </string> + <string name="pants"> + Hose + </string> + <string name="shoes"> + Schuhe + </string> + <string name="socks"> + Socken + </string> + <string name="jacket"> + Jacke + </string> + <string name="gloves"> + Handschuhe + </string> + <string name="undershirt"> + Unterhemd + </string> + <string name="underpants"> + Unterhose + </string> + <string name="skirt"> + Rock + </string> + <string name="alpha"> + Alpha + </string> + <string name="tattoo"> + Tätowierung + </string> + <string name="universal"> + Universal + </string> + <string name="physics"> + Physik + </string> + <string name="invalid"> + ungültig + </string> + <string name="none"> + keine + </string> + <string name="shirt_not_worn"> + Hemd nicht getragen + </string> + <string name="pants_not_worn"> + Hosen nicht getragen + </string> + <string name="shoes_not_worn"> + Schuhe nicht getragen + </string> + <string name="socks_not_worn"> + Socken nicht getragen + </string> + <string name="jacket_not_worn"> + Jacke nicht getragen + </string> + <string name="gloves_not_worn"> + Handschuhe nicht getragen + </string> + <string name="undershirt_not_worn"> + Unterhemd nicht getragen + </string> + <string name="underpants_not_worn"> + Unterhose nicht getragen + </string> + <string name="skirt_not_worn"> + Rock nicht getragen + </string> + <string name="alpha_not_worn"> + Alpha nicht getragen + </string> + <string name="tattoo_not_worn"> + Tätowierung nicht getragen + </string> + <string name="universal_not_worn"> + Universal nicht getragen + </string> + <string name="physics_not_worn"> + Physik nicht getragen + </string> + <string name="invalid_not_worn"> + ungültig + </string> + <string name="create_new_shape"> + Neue Form/Gestalt erstellen + </string> + <string name="create_new_skin"> + Neue Haut erstellen + </string> + <string name="create_new_hair"> + Neue Haare erstellen + </string> + <string name="create_new_eyes"> + Neue Augen erstellen + </string> + <string name="create_new_shirt"> + Neues Hemd erstellen + </string> + <string name="create_new_pants"> + Neue Hose erstellen + </string> + <string name="create_new_shoes"> + Neue Schuhe erstellen + </string> + <string name="create_new_socks"> + Neue Socken erstellen + </string> + <string name="create_new_jacket"> + Neue Jacke erstellen + </string> + <string name="create_new_gloves"> + Neue Handschuhe erstellen + </string> + <string name="create_new_undershirt"> + Neues Unterhemd erstellen + </string> + <string name="create_new_underpants"> + Neue Unterhose erstellen + </string> + <string name="create_new_skirt"> + Neuer Rock erstellen + </string> + <string name="create_new_alpha"> + Neue Alpha erstellen + </string> + <string name="create_new_tattoo"> + Neue Tätowierung erstellen + </string> + <string name="create_new_universal"> + Neues Universal erstellen + </string> + <string name="create_new_physics"> + Neue Physik erstellen + </string> + <string name="create_new_invalid"> + ungültig + </string> + <string name="NewWearable"> + Neue/r/s [WEARABLE_ITEM] + </string> + <string name="next"> + Weiter + </string> + <string name="ok"> + OK + </string> + <string name="GroupNotifyGroupNotice"> + Gruppenmitteilung + </string> + <string name="GroupNotifyGroupNotices"> + Gruppenmitteilungen + </string> + <string name="GroupNotifySentBy"> + Gesendet von + </string> + <string name="GroupNotifyAttached"> + Im Anhang: + </string> + <string name="GroupNotifyViewPastNotices"> + Alte Mitteilungen anzeigen oder hier Auswahl treffen, um keine Mitteilungen mehr zu erhalten. + </string> + <string name="GroupNotifyOpenAttachment"> + Anlage öffnen + </string> + <string name="GroupNotifySaveAttachment"> + Siehe Anhang + </string> + <string name="TeleportOffer"> + Teleport-Angebot + </string> + <string name="StartUpNotifications"> + Sie haben neue Benachrichtigungen erhalten, während Sie abwesend waren. + </string> + <string name="OverflowInfoChannelString"> + Sie haben noch %d weitere Benachrichtigungen + </string> + <string name="BodyPartsRightArm"> + Rechter Arm + </string> + <string name="BodyPartsHead"> + Kopf + </string> + <string name="BodyPartsLeftArm"> + Linker Arm + </string> + <string name="BodyPartsLeftLeg"> + Linkes Bein + </string> + <string name="BodyPartsTorso"> + Oberkörper + </string> + <string name="BodyPartsRightLeg"> + Rechtes Bein + </string> + <string name="BodyPartsEnhancedSkeleton"> + Erweitertes Skelett + </string> + <string name="GraphicsQualityLow"> + Niedrig + </string> + <string name="GraphicsQualityMid"> + Mittel + </string> + <string name="GraphicsQualityHigh"> + Hoch + </string> + <string name="LeaveMouselook"> + ESC drücken, um zur Normalansicht zurückzukehren + </string> + <string name="InventoryNoMatchingItems"> + Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/all/[SEARCH_TERM] Suche]. + </string> + <string name="InventoryNoMatchingRecentItems"> + Sie haben nicht das Richtige gefunden? Versuchen Sie [secondlife:///app/inventory/filters Show filters]. + </string> + <string name="PlacesNoMatchingItems"> + Sie haben nicht das Richtige gefunden? Versuchen Sie es mit der [secondlife:///app/search/places/[SEARCH_TERM] Suche]. + </string> + <string name="FavoritesNoMatchingItems"> + Landmarke hier hin ziehen, um diese hinzuzufügen. + </string> + <string name="MarketplaceNoMatchingItems"> + Keine übereinstimmenden Objekte gefunden. Überprüfen Sie die Schreibweise des Suchbegriffs und versuchen Sie es noch einmal. + </string> + <string name="InventoryNoTexture"> + Sie haben keine Kopie dieser Textur in Ihrem Inventar. + </string> + <string name="InventoryInboxNoItems"> + Einkäufe aus dem Marktplatz erscheinen hier. Sie können diese dann zur Verwendung in Ihr Inventar ziehen. + </string> + <string name="MarketplaceURL"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ + </string> + <string name="MarketplaceURL_CreateStore"> + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3 + </string> + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard + </string> + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports + </string> + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more + </string> + <string name="InventoryPlayAnimationTooltip"> + Fenster mit Spieloptionen öffnen. + </string> + <string name="InventoryPlayGestureTooltip"> + Ausgewählte Geste inworld ausführen. + </string> + <string name="InventoryPlaySoundTooltip"> + Fenster mit Spieloptionen öffnen. + </string> + <string name="InventoryOutboxNotMerchantTitle"> + Jeder kann Artikel im Marktplatz verkaufen. + </string> <string name="InventoryOutboxNotMerchantTooltip"/> - <string name="InventoryOutboxNotMerchant">Wenn Sie als Händler aktiv werden möchten, müssen Sie einen [[MARKETPLACE_CREATE_STORE_URL] Laden im Marktplatz erstellen].</string> - <string name="InventoryOutboxNoItemsTitle">Ihre Outbox ist leer.</string> + <string name="InventoryOutboxNotMerchant"> + Wenn Sie als Händler aktiv werden möchten, müssen Sie einen [[MARKETPLACE_CREATE_STORE_URL] Laden im Marktplatz erstellen]. + </string> + <string name="InventoryOutboxNoItemsTitle"> + Ihre Outbox ist leer. + </string> <string name="InventoryOutboxNoItemsTooltip"/> - <string name="InventoryOutboxNoItems">Ziehen Sie Ordner in dien Bereich und klicken Sie auf „In Marktplatz übertragen“, um sie im [[MARKETPLACE_DASHBOARD_URL] Marktplatz] zum Verkauf anzubieten.</string> - <string name="InventoryOutboxInitializingTitle">Marktplatz wird initialisiert.</string> - <string name="InventoryOutboxInitializing">Wir greifen auf Ihr Konto im [[MARKETPLACE_CREATE_STORE_URL] Marktplatz-Laden] zu.</string> - <string name="InventoryOutboxErrorTitle">Marktplatzfehler.</string> - <string name="InventoryOutboxError">Der [[MARKETPLACE_CREATE_STORE_URL] Marktplatz-Laden] gibt Fehler zurück.</string> - <string name="InventoryMarketplaceError">Beim Öffnen der Marktplatz-Auflistungen ist ein Fehler aufgetreten. -Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://support.secondlife.com an den Support von Second Life.</string> - <string name="InventoryMarketplaceListingsNoItemsTitle">Ihr Ordner mit Marktplatz-Auflistungen ist leer.</string> - <string name="InventoryMarketplaceListingsNoItems">Ziehen Sie Ordner in diesen Bereich, um sie im [[MARKETPLACE_DASHBOARD_URL] Marktplatz] zum Verkauf anzubieten.</string> - <string name="InventoryItemsCount">( [ITEMS_COUNT] Artikel )</string> - <string name="Marketplace Validation Warning Stock">Bestandsordner müssen in einem Versionsordner gespeichert sein</string> - <string name="Marketplace Validation Error Mixed Stock">: Fehler: Alle Objekte in einem Bestandsordner müssen kopiergeschützt und vom gleichen Typ sein.</string> - <string name="Marketplace Validation Error Subfolder In Stock">: Fehler: Bestandsordner kann keine Unterordner enthalten</string> - <string name="Marketplace Validation Warning Empty">: Warnung: Ordner enthält keine Objekte</string> - <string name="Marketplace Validation Warning Create Stock">: Warnung: Bestandsordner wird erstellt</string> - <string name="Marketplace Validation Warning Create Version">: Warnung: Versionsordner wird erstellt</string> - <string name="Marketplace Validation Warning Move">: Warnung: Objekte werden verschoben</string> - <string name="Marketplace Validation Warning Delete">: Warnung: Ordnerinhalte wurden in Bestandsordner übertragen; leerer Ordner wird entfernt</string> - <string name="Marketplace Validation Error Stock Item">: Fehler: Kopiergeschützte Objekte müssen in einem Bestandsordner gespeichert sein</string> - <string name="Marketplace Validation Warning Unwrapped Item">: Warnung: Objekte müssen in einem Versionsordner gespeichert sein</string> - <string name="Marketplace Validation Error">: Fehler:</string> - <string name="Marketplace Validation Warning">: Warnung:</string> - <string name="Marketplace Validation Error Empty Version">: Warnung: Versionsordner muss mindestens 1 Objekt enthalten</string> - <string name="Marketplace Validation Error Empty Stock">: Warnung: Bestandsordner muss mindestens 1 Objekt enthalten</string> - <string name="Marketplace Validation No Error">Keine Fehler oder Warnungen</string> - <string name="Marketplace Error None">Keine Fehler</string> - <string name="Marketplace Error Prefix">Fehler:</string> - <string name="Marketplace Error Not Merchant">Bevor Sie Artikel in den Marktplatz übertragen können, müssen Sie sich als Händler registrieren (kostenlos).</string> - <string name="Marketplace Error Not Accepted">Objekt kann nicht in diesen Ordner verschoben werden.</string> - <string name="Marketplace Error Unsellable Item">Dieses Objekt kann nicht im Marktplatz verkauft werden.</string> - <string name="MarketplaceNoID">keine Mkt-ID</string> - <string name="MarketplaceLive">aufgelistet</string> - <string name="MarketplaceActive">aktiv</string> - <string name="MarketplaceMax">max.</string> - <string name="MarketplaceStock">Bestand</string> - <string name="MarketplaceNoStock">ausverkauft</string> - <string name="MarketplaceUpdating">Aktualisierung läuft...</string> - <string name="UploadFeeInfo">Die Gebühr richtet sich nach deiner Abonnementstufe. Für höhere Stufen werden niedrigere Gebühren erhoben. [https://secondlife.com/my/account/membership.php? Mehr erfahren]</string> - <string name="Open landmarks">Wegweiser öffnen</string> - <string name="Unconstrained">Unbegrenzt</string> + <string name="InventoryOutboxNoItems"> + Ziehen Sie Ordner in dien Bereich und klicken Sie auf „In Marktplatz übertragen“, um sie im [[MARKETPLACE_DASHBOARD_URL] Marktplatz] zum Verkauf anzubieten. + </string> + <string name="InventoryOutboxInitializingTitle"> + Marktplatz wird initialisiert. + </string> + <string name="InventoryOutboxInitializing"> + Wir greifen auf Ihr Konto im [[MARKETPLACE_CREATE_STORE_URL] Marktplatz-Laden] zu. + </string> + <string name="InventoryOutboxErrorTitle"> + Marktplatzfehler. + </string> + <string name="InventoryOutboxError"> + Der [[MARKETPLACE_CREATE_STORE_URL] Marktplatz-Laden] gibt Fehler zurück. + </string> + <string name="InventoryMarketplaceError"> + Beim Öffnen der Marktplatz-Auflistungen ist ein Fehler aufgetreten. +Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://support.secondlife.com an den Support von Second Life. + </string> + <string name="InventoryMarketplaceListingsNoItemsTitle"> + Ihr Ordner mit Marktplatz-Auflistungen ist leer. + </string> + <string name="InventoryMarketplaceListingsNoItems"> + Ziehen Sie Ordner in diesen Bereich, um sie im [[MARKETPLACE_DASHBOARD_URL] Marktplatz] zum Verkauf anzubieten. + </string> + <string name="InventoryItemsCount"> + ( [ITEMS_COUNT] Artikel ) + </string> + <string name="Marketplace Validation Warning Stock"> + Bestandsordner müssen in einem Versionsordner gespeichert sein + </string> + <string name="Marketplace Validation Error Mixed Stock"> + : Fehler: Alle Objekte in einem Bestandsordner müssen kopiergeschützt und vom gleichen Typ sein. + </string> + <string name="Marketplace Validation Error Subfolder In Stock"> + : Fehler: Bestandsordner kann keine Unterordner enthalten + </string> + <string name="Marketplace Validation Warning Empty"> + : Warnung: Ordner enthält keine Objekte + </string> + <string name="Marketplace Validation Warning Create Stock"> + : Warnung: Bestandsordner wird erstellt + </string> + <string name="Marketplace Validation Warning Create Version"> + : Warnung: Versionsordner wird erstellt + </string> + <string name="Marketplace Validation Warning Move"> + : Warnung: Objekte werden verschoben + </string> + <string name="Marketplace Validation Warning Delete"> + : Warnung: Ordnerinhalte wurden in Bestandsordner übertragen; leerer Ordner wird entfernt + </string> + <string name="Marketplace Validation Error Stock Item"> + : Fehler: Kopiergeschützte Objekte müssen in einem Bestandsordner gespeichert sein + </string> + <string name="Marketplace Validation Warning Unwrapped Item"> + : Warnung: Objekte müssen in einem Versionsordner gespeichert sein + </string> + <string name="Marketplace Validation Error"> + : Fehler: + </string> + <string name="Marketplace Validation Warning"> + : Warnung: + </string> + <string name="Marketplace Validation Error Empty Version"> + : Warnung: Versionsordner muss mindestens 1 Objekt enthalten + </string> + <string name="Marketplace Validation Error Empty Stock"> + : Warnung: Bestandsordner muss mindestens 1 Objekt enthalten + </string> + <string name="Marketplace Validation No Error"> + Keine Fehler oder Warnungen + </string> + <string name="Marketplace Error None"> + Keine Fehler + </string> + <string name="Marketplace Error Prefix"> + Fehler: + </string> + <string name="Marketplace Error Not Merchant"> + Bevor Sie Artikel in den Marktplatz übertragen können, müssen Sie sich als Händler registrieren (kostenlos). + </string> + <string name="Marketplace Error Not Accepted"> + Objekt kann nicht in diesen Ordner verschoben werden. + </string> + <string name="Marketplace Error Unsellable Item"> + Dieses Objekt kann nicht im Marktplatz verkauft werden. + </string> + <string name="MarketplaceNoID"> + keine Mkt-ID + </string> + <string name="MarketplaceLive"> + aufgelistet + </string> + <string name="MarketplaceActive"> + aktiv + </string> + <string name="MarketplaceMax"> + max. + </string> + <string name="MarketplaceStock"> + Bestand + </string> + <string name="MarketplaceNoStock"> + ausverkauft + </string> + <string name="MarketplaceUpdating"> + Aktualisierung läuft... + </string> + <string name="UploadFeeInfo"> + Die Gebühr richtet sich nach deiner Abonnementstufe. Für höhere Stufen werden niedrigere Gebühren erhoben. [https://secondlife.com/my/account/membership.php? Mehr erfahren] + </string> + <string name="Open landmarks"> + Wegweiser öffnen + </string> + <string name="Unconstrained"> + Unbegrenzt + </string> <string name="no_transfer" value=" (kein Transferieren)"/> <string name="no_modify" value=" (kein Bearbeiten)"/> <string name="no_copy" value=" (kein Kopieren)"/> <string name="worn" value=" (getragen)"/> <string name="link" value=" (Link)"/> <string name="broken_link" value=" (unvollständiger_Link)"/> - <string name="LoadingContents">Inhalte werden geladen...</string> - <string name="NoContents">Keine Inhalte</string> + <string name="LoadingContents"> + Inhalte werden geladen... + </string> + <string name="NoContents"> + Keine Inhalte + </string> <string name="WornOnAttachmentPoint" value=" (getragen am [ATTACHMENT_POINT])"/> <string name="AttachmentErrorMessage" value="([ATTACHMENT_ERROR])"/> <string name="ActiveGesture" value="[GESLABEL] (aktiviert)"/> - <string name="PermYes">Ja</string> - <string name="PermNo">Nein</string> + <string name="PermYes"> + Ja + </string> + <string name="PermNo"> + Nein + </string> <string name="Chat Message" value="Chat:"/> <string name="Sound" value=" Sound:"/> <string name="Wait" value=" --- Warten:"/> @@ -636,1439 +1704,4215 @@ Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich unter http://suppo <string name="Snapshots" value=" Fotos,"/> <string name="No Filters" value="Nein "/> <string name="Since Logoff" value=" - Seit Abmeldung"/> - <string name="InvFolder My Inventory">Mein Inventar</string> - <string name="InvFolder Library">Bibliothek</string> - <string name="InvFolder Textures">Texturen</string> - <string name="InvFolder Sounds">Sounds</string> - <string name="InvFolder Calling Cards">Visitenkarten</string> - <string name="InvFolder Landmarks">Landmarken</string> - <string name="InvFolder Scripts">Skripts</string> - <string name="InvFolder Clothing">Kleidung</string> - <string name="InvFolder Objects">Objekte</string> - <string name="InvFolder Notecards">Notizkarten</string> - <string name="InvFolder New Folder">Neuer Ordner</string> - <string name="InvFolder Inventory">Inventar</string> - <string name="InvFolder Uncompressed Images">Nicht-Komprimierte Bilder</string> - <string name="InvFolder Body Parts">Körperteile</string> - <string name="InvFolder Trash">Papierkorb</string> - <string name="InvFolder Photo Album">Fotoalbum</string> - <string name="InvFolder Lost And Found">Fundbüro</string> - <string name="InvFolder Uncompressed Sounds">Nicht-Komprimierte Sounds</string> - <string name="InvFolder Animations">Animationen</string> - <string name="InvFolder Gestures">Gesten</string> - <string name="InvFolder Favorite">Meine Favoriten</string> - <string name="InvFolder favorite">Meine Favoriten</string> - <string name="InvFolder Favorites">Meine Favoriten</string> - <string name="InvFolder favorites">Meine Favoriten</string> - <string name="InvFolder Current Outfit">Aktuelles Outfit</string> - <string name="InvFolder Initial Outfits">Ursprüngliche Outfits</string> - <string name="InvFolder My Outfits">Meine Outfits</string> - <string name="InvFolder Accessories">Zubehör</string> - <string name="InvFolder Meshes">Netze</string> - <string name="InvFolder Received Items">Erhaltene Artikel</string> - <string name="InvFolder Merchant Outbox">Händler-Outbox</string> - <string name="InvFolder Friends">Freunde</string> - <string name="InvFolder All">Alle</string> - <string name="no_attachments">Keine Anhänge getragen</string> - <string name="Attachments remain">Anhänge (noch [COUNT] Positionen frei)</string> - <string name="Buy">Kaufen</string> - <string name="BuyforL$">Kaufen für L$</string> - <string name="Stone">Stein</string> - <string name="Metal">Metall</string> - <string name="Glass">Glas</string> - <string name="Wood">Holz</string> - <string name="Flesh">Fleisch</string> - <string name="Plastic">Plastik</string> - <string name="Rubber">Gummi</string> - <string name="Light">Hell</string> - <string name="KBShift">Umschalt-Taste</string> - <string name="KBCtrl">Strg</string> - <string name="Chest">Brust</string> - <string name="Skull">Schädel</string> - <string name="Left Shoulder">Linke Schulter</string> - <string name="Right Shoulder">Rechte Schulter</string> - <string name="Left Hand">Linke Hand</string> - <string name="Right Hand">Rechte Hand</string> - <string name="Left Foot">Linker Fuß</string> - <string name="Right Foot">Rechter Fuß</string> - <string name="Spine">Wirbelsäule</string> - <string name="Pelvis">Becken</string> - <string name="Mouth">Mund</string> - <string name="Chin">Kinn</string> - <string name="Left Ear">Linkes Ohr</string> - <string name="Right Ear">Rechtes Ohr</string> - <string name="Left Eyeball">Linker Augapfel</string> - <string name="Right Eyeball">Rechter Augapfel</string> - <string name="Nose">Nase</string> - <string name="R Upper Arm">R Oberarm</string> - <string name="R Forearm">R Unterarm</string> - <string name="L Upper Arm">L Oberarm</string> - <string name="L Forearm">L Unterarm</string> - <string name="Right Hip">Rechte Hüfte</string> - <string name="R Upper Leg">R Oberschenkel</string> - <string name="R Lower Leg">R Unterschenkel</string> - <string name="Left Hip">Linke Hüfte</string> - <string name="L Upper Leg">L Oberschenkel</string> - <string name="L Lower Leg">L Unterschenkel</string> - <string name="Stomach">Bauch</string> - <string name="Left Pec">Linke Brust</string> - <string name="Right Pec">Rechts</string> - <string name="Neck">Hals</string> - <string name="Avatar Center">Avatar-Mitte</string> - <string name="Left Ring Finger">Linker Ringfinger</string> - <string name="Right Ring Finger">Rechter Ringfinger</string> - <string name="Tail Base">Schwanzansatz</string> - <string name="Tail Tip">Schwanzspitze</string> - <string name="Left Wing">Linker Flügel</string> - <string name="Right Wing">Rechter Flügel</string> - <string name="Jaw">Kiefer</string> - <string name="Alt Left Ear">Alt. linkes Ohr</string> - <string name="Alt Right Ear">Alt. rechtes Ohr</string> - <string name="Alt Left Eye">Alt. linkes Auge</string> - <string name="Alt Right Eye">Alt. rechtes Auge</string> - <string name="Tongue">Zunge</string> - <string name="Groin">Leiste</string> - <string name="Left Hind Foot">Linker hinterer Fuß</string> - <string name="Right Hind Foot">Rechter hinterer Fuß</string> - <string name="Invalid Attachment">Ungültige Stelle für Anhang</string> - <string name="ATTACHMENT_MISSING_ITEM">Fehler: fehlendes Objekt</string> - <string name="ATTACHMENT_MISSING_BASE_ITEM">Fehler: Basisobjekt fehlt</string> - <string name="ATTACHMENT_NOT_ATTACHED">Fehler: Objekt ist im aktuellen Outfit, aber nicht angehängt</string> - <string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS] alt</string> - <string name="YearsOld">[AGEYEARS] alt</string> - <string name="MonthsOld">[AGEMONTHS] alt</string> - <string name="WeeksOld">[AGEWEEKS] alt</string> - <string name="DaysOld">[AGEDAYS] alt</string> - <string name="TodayOld">Seit heute Mitglied</string> - <string name="av_render_everyone_now">Jetzt kann jeder Sie sehen.</string> - <string name="av_render_not_everyone">Sie sind u. U. nicht für alle Leute in Ihrer Nähe sichtbar.</string> - <string name="av_render_over_half">Sie sind u. U. für mehr als die Hälfte der Leute in Ihrer Nähe nicht sichtbar.</string> - <string name="av_render_most_of">Sie sind u. U. für die meisten Leuten in Ihrer Nähe nicht sichtbar.</string> - <string name="av_render_anyone">Sie sind u. U. für niemanden in Ihrer Nähe sichtbar.</string> - <string name="hud_description_total">Ihr HUD</string> - <string name="hud_name_with_joint">[OBJ_NAME] (getragen von [JNT_NAME])</string> - <string name="hud_render_memory_warning">[HUD_DETAILS] beansprucht viel Texturspeicher</string> - <string name="hud_render_cost_warning">[HUD_DETAILS] enthält zu viele ressourcenintensive Objekte und Texturen</string> - <string name="hud_render_heavy_textures_warning">[HUD_DETAILS] enthält viele große Texturen</string> - <string name="hud_render_cramped_warning">[HUD_DETAILS] enthält zu viele Objekte</string> - <string name="hud_render_textures_warning">[HUD_DETAILS] enthält zu viele Texturen</string> - <string name="AgeYearsA">[COUNT] Jahr</string> - <string name="AgeYearsB">[COUNT] Jahre</string> - <string name="AgeYearsC">[COUNT] Jahre</string> - <string name="AgeMonthsA">[COUNT] Monat</string> - <string name="AgeMonthsB">[COUNT] Monate</string> - <string name="AgeMonthsC">[COUNT] Monate</string> - <string name="AgeWeeksA">[COUNT] Woche</string> - <string name="AgeWeeksB">[COUNT] Wochen</string> - <string name="AgeWeeksC">[COUNT] Wochen</string> - <string name="AgeDaysA">[COUNT] Tag</string> - <string name="AgeDaysB">[COUNT] Tage</string> - <string name="AgeDaysC">[COUNT] Tage</string> - <string name="GroupMembersA">[COUNT] Mitglied</string> - <string name="GroupMembersB">[COUNT] Mitglieder</string> - <string name="GroupMembersC">[COUNT] Mitglieder</string> - <string name="AcctTypeResident">Einwohner</string> - <string name="AcctTypeTrial">Test</string> - <string name="AcctTypeCharterMember">Charta-Mitglied</string> - <string name="AcctTypeEmployee">Linden Lab-Mitarbeiter</string> - <string name="PaymentInfoUsed">Zahlungsinfo verwendet</string> - <string name="PaymentInfoOnFile">Zahlungsinfo archiviert</string> - <string name="NoPaymentInfoOnFile">Keine Zahlungsinfo archiviert</string> - <string name="AgeVerified">Altersgeprüft</string> - <string name="NotAgeVerified">Nicht altersgeprüft</string> - <string name="Center 2">Mitte 2</string> - <string name="Top Right">Oben rechts</string> - <string name="Top">Oben</string> - <string name="Top Left">Oben links</string> - <string name="Center">Mitte</string> - <string name="Bottom Left">Unten links</string> - <string name="Bottom">Unten</string> - <string name="Bottom Right">Unten rechts</string> - <string name="CompileQueueDownloadedCompiling">Heruntergeladen, wird kompiliert</string> - <string name="CompileQueueServiceUnavailable">Kein Skriptkompilierungsdienst verfügbar</string> - <string name="CompileQueueScriptNotFound">Skript wurde auf Server nicht gefunden.</string> - <string name="CompileQueueProblemDownloading">Beim Herunterladen ist ein Problem aufgetreten</string> - <string name="CompileQueueInsufficientPermDownload">Unzureichende Rechte zum Herunterladen eines Skripts.</string> - <string name="CompileQueueInsufficientPermFor">Unzureichende Berechtigungen für</string> - <string name="CompileQueueUnknownFailure">Unbekannter Fehler beim Herunterladen</string> - <string name="CompileNoExperiencePerm">Skript „[SCRIPT]“ mit Erlebnis „[EXPERIENCE]“ wird übersprungen.</string> - <string name="CompileQueueTitle">Rekompilierung</string> - <string name="CompileQueueStart">rekompilieren</string> - <string name="ResetQueueTitle">Zurücksetzen</string> - <string name="ResetQueueStart">Zurücksetzen</string> - <string name="RunQueueTitle">Skript ausführen</string> - <string name="RunQueueStart">Skript ausführen</string> - <string name="NotRunQueueTitle">Skript anhalten</string> - <string name="NotRunQueueStart">Skript anhalten</string> - <string name="CompileSuccessful">Kompilieren erfolgreich abgeschlossen!</string> - <string name="CompileSuccessfulSaving">Kompilieren erfolgreich abgeschlossen, speichern...</string> - <string name="SaveComplete">Speichervorgang abgeschlossen.</string> - <string name="UploadFailed">Datei-Upload fehlgeschlagen:</string> - <string name="ObjectOutOfRange">Skript (Objekt außerhalb des Bereichs)</string> - <string name="ScriptWasDeleted">Skript (aus Inventar gelöscht)</string> - <string name="GodToolsObjectOwnedBy">Objekt [OBJECT], Besitzer [OWNER]</string> - <string name="GroupsNone">keine</string> + <string name="InvFolder My Inventory"> + Mein Inventar + </string> + <string name="InvFolder Library"> + Bibliothek + </string> + <string name="InvFolder Textures"> + Texturen + </string> + <string name="InvFolder Sounds"> + Sounds + </string> + <string name="InvFolder Calling Cards"> + Visitenkarten + </string> + <string name="InvFolder Landmarks"> + Landmarken + </string> + <string name="InvFolder Scripts"> + Skripts + </string> + <string name="InvFolder Clothing"> + Kleidung + </string> + <string name="InvFolder Objects"> + Objekte + </string> + <string name="InvFolder Notecards"> + Notizkarten + </string> + <string name="InvFolder New Folder"> + Neuer Ordner + </string> + <string name="InvFolder Inventory"> + Inventar + </string> + <string name="InvFolder Uncompressed Images"> + Nicht-Komprimierte Bilder + </string> + <string name="InvFolder Body Parts"> + Körperteile + </string> + <string name="InvFolder Trash"> + Papierkorb + </string> + <string name="InvFolder Photo Album"> + Fotoalbum + </string> + <string name="InvFolder Lost And Found"> + Fundbüro + </string> + <string name="InvFolder Uncompressed Sounds"> + Nicht-Komprimierte Sounds + </string> + <string name="InvFolder Animations"> + Animationen + </string> + <string name="InvFolder Gestures"> + Gesten + </string> + <string name="InvFolder Favorite"> + Meine Favoriten + </string> + <string name="InvFolder favorite"> + Meine Favoriten + </string> + <string name="InvFolder Favorites"> + Meine Favoriten + </string> + <string name="InvFolder favorites"> + Meine Favoriten + </string> + <string name="InvFolder Current Outfit"> + Aktuelles Outfit + </string> + <string name="InvFolder Initial Outfits"> + Ursprüngliche Outfits + </string> + <string name="InvFolder My Outfits"> + Meine Outfits + </string> + <string name="InvFolder Accessories"> + Zubehör + </string> + <string name="InvFolder Meshes"> + Netze + </string> + <string name="InvFolder Received Items"> + Erhaltene Artikel + </string> + <string name="InvFolder Merchant Outbox"> + Händler-Outbox + </string> + <string name="InvFolder Friends"> + Freunde + </string> + <string name="InvFolder All"> + Alle + </string> + <string name="no_attachments"> + Keine Anhänge getragen + </string> + <string name="Attachments remain"> + Anhänge (noch [COUNT] Positionen frei) + </string> + <string name="Buy"> + Kaufen + </string> + <string name="BuyforL$"> + Kaufen für L$ + </string> + <string name="Stone"> + Stein + </string> + <string name="Metal"> + Metall + </string> + <string name="Glass"> + Glas + </string> + <string name="Wood"> + Holz + </string> + <string name="Flesh"> + Fleisch + </string> + <string name="Plastic"> + Plastik + </string> + <string name="Rubber"> + Gummi + </string> + <string name="Light"> + Hell + </string> + <string name="KBShift"> + Umschalt-Taste + </string> + <string name="KBCtrl"> + Strg + </string> + <string name="Chest"> + Brust + </string> + <string name="Skull"> + Schädel + </string> + <string name="Left Shoulder"> + Linke Schulter + </string> + <string name="Right Shoulder"> + Rechte Schulter + </string> + <string name="Left Hand"> + Linke Hand + </string> + <string name="Right Hand"> + Rechte Hand + </string> + <string name="Left Foot"> + Linker Fuß + </string> + <string name="Right Foot"> + Rechter Fuß + </string> + <string name="Spine"> + Wirbelsäule + </string> + <string name="Pelvis"> + Becken + </string> + <string name="Mouth"> + Mund + </string> + <string name="Chin"> + Kinn + </string> + <string name="Left Ear"> + Linkes Ohr + </string> + <string name="Right Ear"> + Rechtes Ohr + </string> + <string name="Left Eyeball"> + Linker Augapfel + </string> + <string name="Right Eyeball"> + Rechter Augapfel + </string> + <string name="Nose"> + Nase + </string> + <string name="R Upper Arm"> + R Oberarm + </string> + <string name="R Forearm"> + R Unterarm + </string> + <string name="L Upper Arm"> + L Oberarm + </string> + <string name="L Forearm"> + L Unterarm + </string> + <string name="Right Hip"> + Rechte Hüfte + </string> + <string name="R Upper Leg"> + R Oberschenkel + </string> + <string name="R Lower Leg"> + R Unterschenkel + </string> + <string name="Left Hip"> + Linke Hüfte + </string> + <string name="L Upper Leg"> + L Oberschenkel + </string> + <string name="L Lower Leg"> + L Unterschenkel + </string> + <string name="Stomach"> + Bauch + </string> + <string name="Left Pec"> + Linke Brust + </string> + <string name="Right Pec"> + Rechts + </string> + <string name="Neck"> + Hals + </string> + <string name="Avatar Center"> + Avatar-Mitte + </string> + <string name="Left Ring Finger"> + Linker Ringfinger + </string> + <string name="Right Ring Finger"> + Rechter Ringfinger + </string> + <string name="Tail Base"> + Schwanzansatz + </string> + <string name="Tail Tip"> + Schwanzspitze + </string> + <string name="Left Wing"> + Linker Flügel + </string> + <string name="Right Wing"> + Rechter Flügel + </string> + <string name="Jaw"> + Kiefer + </string> + <string name="Alt Left Ear"> + Alt. linkes Ohr + </string> + <string name="Alt Right Ear"> + Alt. rechtes Ohr + </string> + <string name="Alt Left Eye"> + Alt. linkes Auge + </string> + <string name="Alt Right Eye"> + Alt. rechtes Auge + </string> + <string name="Tongue"> + Zunge + </string> + <string name="Groin"> + Leiste + </string> + <string name="Left Hind Foot"> + Linker hinterer Fuß + </string> + <string name="Right Hind Foot"> + Rechter hinterer Fuß + </string> + <string name="Invalid Attachment"> + Ungültige Stelle für Anhang + </string> + <string name="ATTACHMENT_MISSING_ITEM"> + Fehler: fehlendes Objekt + </string> + <string name="ATTACHMENT_MISSING_BASE_ITEM"> + Fehler: Basisobjekt fehlt + </string> + <string name="ATTACHMENT_NOT_ATTACHED"> + Fehler: Objekt ist im aktuellen Outfit, aber nicht angehängt + </string> + <string name="YearsMonthsOld"> + [AGEYEARS] [AGEMONTHS] alt + </string> + <string name="YearsOld"> + [AGEYEARS] alt + </string> + <string name="MonthsOld"> + [AGEMONTHS] alt + </string> + <string name="WeeksOld"> + [AGEWEEKS] alt + </string> + <string name="DaysOld"> + [AGEDAYS] alt + </string> + <string name="TodayOld"> + Seit heute Mitglied + </string> + <string name="av_render_everyone_now"> + Jetzt kann jeder Sie sehen. + </string> + <string name="av_render_not_everyone"> + Sie sind u. U. nicht für alle Leute in Ihrer Nähe sichtbar. + </string> + <string name="av_render_over_half"> + Sie sind u. U. für mehr als die Hälfte der Leute in Ihrer Nähe nicht sichtbar. + </string> + <string name="av_render_most_of"> + Sie sind u. U. für die meisten Leuten in Ihrer Nähe nicht sichtbar. + </string> + <string name="av_render_anyone"> + Sie sind u. U. für niemanden in Ihrer Nähe sichtbar. + </string> + <string name="hud_description_total"> + Ihr HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (getragen von [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] beansprucht viel Texturspeicher + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] enthält zu viele ressourcenintensive Objekte und Texturen + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] enthält viele große Texturen + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] enthält zu viele Objekte + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] enthält zu viele Texturen + </string> + <string name="AgeYearsA"> + [COUNT] Jahr + </string> + <string name="AgeYearsB"> + [COUNT] Jahre + </string> + <string name="AgeYearsC"> + [COUNT] Jahre + </string> + <string name="AgeMonthsA"> + [COUNT] Monat + </string> + <string name="AgeMonthsB"> + [COUNT] Monate + </string> + <string name="AgeMonthsC"> + [COUNT] Monate + </string> + <string name="AgeWeeksA"> + [COUNT] Woche + </string> + <string name="AgeWeeksB"> + [COUNT] Wochen + </string> + <string name="AgeWeeksC"> + [COUNT] Wochen + </string> + <string name="AgeDaysA"> + [COUNT] Tag + </string> + <string name="AgeDaysB"> + [COUNT] Tage + </string> + <string name="AgeDaysC"> + [COUNT] Tage + </string> + <string name="GroupMembersA"> + [COUNT] Mitglied + </string> + <string name="GroupMembersB"> + [COUNT] Mitglieder + </string> + <string name="GroupMembersC"> + [COUNT] Mitglieder + </string> + <string name="AcctTypeResident"> + Einwohner + </string> + <string name="AcctTypeTrial"> + Test + </string> + <string name="AcctTypeCharterMember"> + Charta-Mitglied + </string> + <string name="AcctTypeEmployee"> + Linden Lab-Mitarbeiter + </string> + <string name="PaymentInfoUsed"> + Zahlungsinfo verwendet + </string> + <string name="PaymentInfoOnFile"> + Zahlungsinfo archiviert + </string> + <string name="NoPaymentInfoOnFile"> + Keine Zahlungsinfo archiviert + </string> + <string name="AgeVerified"> + Altersgeprüft + </string> + <string name="NotAgeVerified"> + Nicht altersgeprüft + </string> + <string name="Center 2"> + Mitte 2 + </string> + <string name="Top Right"> + Oben rechts + </string> + <string name="Top"> + Oben + </string> + <string name="Top Left"> + Oben links + </string> + <string name="Center"> + Mitte + </string> + <string name="Bottom Left"> + Unten links + </string> + <string name="Bottom"> + Unten + </string> + <string name="Bottom Right"> + Unten rechts + </string> + <string name="CompileQueueDownloadedCompiling"> + Heruntergeladen, wird kompiliert + </string> + <string name="CompileQueueServiceUnavailable"> + Kein Skriptkompilierungsdienst verfügbar + </string> + <string name="CompileQueueScriptNotFound"> + Skript wurde auf Server nicht gefunden. + </string> + <string name="CompileQueueProblemDownloading"> + Beim Herunterladen ist ein Problem aufgetreten + </string> + <string name="CompileQueueInsufficientPermDownload"> + Unzureichende Rechte zum Herunterladen eines Skripts. + </string> + <string name="CompileQueueInsufficientPermFor"> + Unzureichende Berechtigungen für + </string> + <string name="CompileQueueUnknownFailure"> + Unbekannter Fehler beim Herunterladen + </string> + <string name="CompileNoExperiencePerm"> + Skript „[SCRIPT]“ mit Erlebnis „[EXPERIENCE]“ wird übersprungen. + </string> + <string name="CompileQueueTitle"> + Rekompilierung + </string> + <string name="CompileQueueStart"> + rekompilieren + </string> + <string name="ResetQueueTitle"> + Zurücksetzen + </string> + <string name="ResetQueueStart"> + Zurücksetzen + </string> + <string name="RunQueueTitle"> + Skript ausführen + </string> + <string name="RunQueueStart"> + Skript ausführen + </string> + <string name="NotRunQueueTitle"> + Skript anhalten + </string> + <string name="NotRunQueueStart"> + Skript anhalten + </string> + <string name="CompileSuccessful"> + Kompilieren erfolgreich abgeschlossen! + </string> + <string name="CompileSuccessfulSaving"> + Kompilieren erfolgreich abgeschlossen, speichern... + </string> + <string name="SaveComplete"> + Speichervorgang abgeschlossen. + </string> + <string name="UploadFailed"> + Datei-Upload fehlgeschlagen: + </string> + <string name="ObjectOutOfRange"> + Skript (Objekt außerhalb des Bereichs) + </string> + <string name="ScriptWasDeleted"> + Skript (aus Inventar gelöscht) + </string> + <string name="GodToolsObjectOwnedBy"> + Objekt [OBJECT], Besitzer [OWNER] + </string> + <string name="GroupsNone"> + keine + </string> <string name="Group" value=" (Gruppe)"/> - <string name="Unknown">(unbekannt)</string> + <string name="Unknown"> + (unbekannt) + </string> <string name="SummaryForTheWeek" value="Zusammenfassung für diese Woche, beginnend am "/> <string name="NextStipendDay" value=". Der nächste Stipendium-Tag ist "/> - <string name="GroupPlanningDate">[mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc]</string> + <string name="GroupPlanningDate"> + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + </string> <string name="GroupIndividualShare" value=" Gruppenanteil Einzelanteil"/> <string name="GroupColumn" value="Gruppe"/> - <string name="Balance">Kontostand</string> - <string name="Credits">Danksagung</string> - <string name="Debits">Soll</string> - <string name="Total">Gesamtbetrag</string> - <string name="NoGroupDataFound">Für Gruppe wurden keine Gruppendaten gefunden</string> - <string name="IMParentEstate">parent estate</string> - <string name="IMMainland">Mainland</string> - <string name="IMTeen">Teen</string> - <string name="Anyone">jeder</string> - <string name="RegionInfoError">Fehler</string> - <string name="RegionInfoAllEstatesOwnedBy">alle Grundbesitze gehören [OWNER]</string> - <string name="RegionInfoAllEstatesYouOwn">alle Grundbesitze, die Sie besitzen</string> - <string name="RegionInfoAllEstatesYouManage">alle Grundbesitze, die Sie für [OWNER] verwalten</string> - <string name="RegionInfoAllowedResidents">Immer zulässig: ([ALLOWEDAGENTS], max. [MAXACCESS])</string> - <string name="RegionInfoAllowedGroups">Immer zugelassene Gruppen: ([ALLOWEDGROUPS], max. [MAXACCESS])</string> - <string name="RegionInfoBannedResidents">Immer verbannt: ([BANNEDAGENTS], max. [MAXBANNED])</string> - <string name="RegionInfoListTypeAllowedAgents">Immer zugelassen</string> - <string name="RegionInfoListTypeBannedAgents">Immer verbannt</string> - <string name="RegionInfoAllEstates">alle Grundbesitze</string> - <string name="RegionInfoManagedEstates">verwaltete Grundbesitze</string> - <string name="RegionInfoThisEstate">dieser Grundbesitz</string> - <string name="AndNMore">und [EXTRA_COUNT] weitere</string> - <string name="ScriptLimitsParcelScriptMemory">Parzellenskript-Speicher</string> - <string name="ScriptLimitsParcelsOwned">Aufgeführte Parzellen: [PARCELS]</string> - <string name="ScriptLimitsMemoryUsed">Verwendeter Speicher: [COUNT] KB von [MAX] KB; [AVAILABLE] KB verfügbar</string> - <string name="ScriptLimitsMemoryUsedSimple">Verwendeter Speicher: [COUNT] KB</string> - <string name="ScriptLimitsParcelScriptURLs">Parzelleskript-URLs</string> - <string name="ScriptLimitsURLsUsed">Verwendete URLs: [COUNT] von [MAX]; [AVAILABLE] verfügbar</string> - <string name="ScriptLimitsURLsUsedSimple">Verwendete URLs: [COUNT]</string> - <string name="ScriptLimitsRequestError">Fehler bei Informationsabruf</string> - <string name="ScriptLimitsRequestNoParcelSelected">Keine Parzellen wurden ausgewählt</string> - <string name="ScriptLimitsRequestWrongRegion">Fehler: Skriptinformationen sind nur für Ihre aktuelle Region verfügbar</string> - <string name="ScriptLimitsRequestWaiting">Informationen werden abgerufen...</string> - <string name="ScriptLimitsRequestDontOwnParcel">Sie sind nicht berechtigt, diese Parzelle zu untersuchen.</string> - <string name="SITTING_ON">sitzt auf</string> - <string name="ATTACH_CHEST">Brust</string> - <string name="ATTACH_HEAD">Schädel</string> - <string name="ATTACH_LSHOULDER">Linke Schulter</string> - <string name="ATTACH_RSHOULDER">Rechte Schulter</string> - <string name="ATTACH_LHAND">Linke Hand</string> - <string name="ATTACH_RHAND">Rechte Hand</string> - <string name="ATTACH_LFOOT">Linker Fuß</string> - <string name="ATTACH_RFOOT">Rechter Fuß</string> - <string name="ATTACH_BACK">Wirbelsäule</string> - <string name="ATTACH_PELVIS">Becken</string> - <string name="ATTACH_MOUTH">Mund</string> - <string name="ATTACH_CHIN">Kinn</string> - <string name="ATTACH_LEAR">Linkes Ohr</string> - <string name="ATTACH_REAR">Rechtes Ohr</string> - <string name="ATTACH_LEYE">Linkes Auge</string> - <string name="ATTACH_REYE">Rechtes Auge</string> - <string name="ATTACH_NOSE">Nase</string> - <string name="ATTACH_RUARM">Rechter Oberarm</string> - <string name="ATTACH_RLARM">Rechter Unterarm</string> - <string name="ATTACH_LUARM">Linker Oberarm</string> - <string name="ATTACH_LLARM">Linker Unterarm</string> - <string name="ATTACH_RHIP">Rechte Hüfte</string> - <string name="ATTACH_RULEG">Rechter Oberschenkel</string> - <string name="ATTACH_RLLEG">Rechter Unterschenkel</string> - <string name="ATTACH_LHIP">Linke Hüfte</string> - <string name="ATTACH_LULEG">Linker Oberschenkel</string> - <string name="ATTACH_LLLEG">Linker Unterschenkel</string> - <string name="ATTACH_BELLY">Bauch</string> - <string name="ATTACH_LEFT_PEC">Linke Brust</string> - <string name="ATTACH_RIGHT_PEC">Rechte Brust</string> - <string name="ATTACH_HUD_CENTER_2">HUD Mitte 2</string> - <string name="ATTACH_HUD_TOP_RIGHT">HUD oben rechts</string> - <string name="ATTACH_HUD_TOP_CENTER">HUD oben Mitte</string> - <string name="ATTACH_HUD_TOP_LEFT">HUD oben links</string> - <string name="ATTACH_HUD_CENTER_1">HUD Mitte 1</string> - <string name="ATTACH_HUD_BOTTOM_LEFT">HUD unten links</string> - <string name="ATTACH_HUD_BOTTOM">HUD unten</string> - <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD unten rechts</string> - <string name="ATTACH_NECK">Hals</string> - <string name="ATTACH_AVATAR_CENTER">Avatar-Mitte</string> - <string name="ATTACH_LHAND_RING1">Linker Ringfinger</string> - <string name="ATTACH_RHAND_RING1">Rechter Ringfinger</string> - <string name="ATTACH_TAIL_BASE">Schwanzansatz</string> - <string name="ATTACH_TAIL_TIP">Schwanzspitze</string> - <string name="ATTACH_LWING">Linker Flügel</string> - <string name="ATTACH_RWING">Rechter Flügel</string> - <string name="ATTACH_FACE_JAW">Kiefer</string> - <string name="ATTACH_FACE_LEAR">Alt. linkes Ohr</string> - <string name="ATTACH_FACE_REAR">Alt. rechtes Ohr</string> - <string name="ATTACH_FACE_LEYE">Alt. linkes Auge</string> - <string name="ATTACH_FACE_REYE">Alt. rechtes Auge</string> - <string name="ATTACH_FACE_TONGUE">Zunge</string> - <string name="ATTACH_GROIN">Leiste</string> - <string name="ATTACH_HIND_LFOOT">Linker hinterer Fuß</string> - <string name="ATTACH_HIND_RFOOT">Rechter hinterer Fuß</string> - <string name="CursorPos">Zeile [LINE], Spalte [COLUMN]</string> - <string name="PanelDirCountFound">[COUNT] gefunden</string> - <string name="PanelDirTimeStr">[hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt]</string> - <string name="PanelDirEventsDateText">[mthnum,datetime,slt]/[day,datetime,slt]</string> - <string name="PanelContentsTooltip">Objektinhalt</string> - <string name="PanelContentsNewScript">Neues Skript</string> - <string name="DoNotDisturbModeResponseDefault">Dieser Einwohner hat den Nicht-stören-Modus aktiviert und wird Ihre Nachricht später sehen.</string> - <string name="MuteByName">(Nach Namen)</string> - <string name="MuteAgent">(Einwohner)</string> - <string name="MuteObject">(Objekt)</string> - <string name="MuteGroup">(Gruppe)</string> - <string name="MuteExternal">(Extern)</string> - <string name="RegionNoCovenant">Für diesen Grundbesitz liegt kein Vertrag vor.</string> - <string name="RegionNoCovenantOtherOwner">Für diesen Grundbesitz liegt kein Vertrag vor. Das Land auf diesem Grundbesitz wird vom Grundbesitzer und nicht von Linden Lab verkauft. Für Informationen zum Verkauf setzen Sie sich bitte mit dem Grundbesitzer in Verbindung.</string> + <string name="Balance"> + Kontostand + </string> + <string name="Credits"> + Danksagung + </string> + <string name="Debits"> + Soll + </string> + <string name="Total"> + Gesamtbetrag + </string> + <string name="NoGroupDataFound"> + Für Gruppe wurden keine Gruppendaten gefunden + </string> + <string name="IMParentEstate"> + parent estate + </string> + <string name="IMMainland"> + Mainland + </string> + <string name="IMTeen"> + Teen + </string> + <string name="Anyone"> + jeder + </string> + <string name="RegionInfoError"> + Fehler + </string> + <string name="RegionInfoAllEstatesOwnedBy"> + alle Grundbesitze gehören [OWNER] + </string> + <string name="RegionInfoAllEstatesYouOwn"> + alle Grundbesitze, die Sie besitzen + </string> + <string name="RegionInfoAllEstatesYouManage"> + alle Grundbesitze, die Sie für [OWNER] verwalten + </string> + <string name="RegionInfoAllowedResidents"> + Immer zulässig: ([ALLOWEDAGENTS], max. [MAXACCESS]) + </string> + <string name="RegionInfoAllowedGroups"> + Immer zugelassene Gruppen: ([ALLOWEDGROUPS], max. [MAXACCESS]) + </string> + <string name="RegionInfoBannedResidents"> + Immer verbannt: ([BANNEDAGENTS], max. [MAXBANNED]) + </string> + <string name="RegionInfoListTypeAllowedAgents"> + Immer zugelassen + </string> + <string name="RegionInfoListTypeBannedAgents"> + Immer verbannt + </string> + <string name="RegionInfoAllEstates"> + alle Grundbesitze + </string> + <string name="RegionInfoManagedEstates"> + verwaltete Grundbesitze + </string> + <string name="RegionInfoThisEstate"> + dieser Grundbesitz + </string> + <string name="AndNMore"> + und [EXTRA_COUNT] weitere + </string> + <string name="ScriptLimitsParcelScriptMemory"> + Parzellenskript-Speicher + </string> + <string name="ScriptLimitsParcelsOwned"> + Aufgeführte Parzellen: [PARCELS] + </string> + <string name="ScriptLimitsMemoryUsed"> + Verwendeter Speicher: [COUNT] KB von [MAX] KB; [AVAILABLE] KB verfügbar + </string> + <string name="ScriptLimitsMemoryUsedSimple"> + Verwendeter Speicher: [COUNT] KB + </string> + <string name="ScriptLimitsParcelScriptURLs"> + Parzelleskript-URLs + </string> + <string name="ScriptLimitsURLsUsed"> + Verwendete URLs: [COUNT] von [MAX]; [AVAILABLE] verfügbar + </string> + <string name="ScriptLimitsURLsUsedSimple"> + Verwendete URLs: [COUNT] + </string> + <string name="ScriptLimitsRequestError"> + Fehler bei Informationsabruf + </string> + <string name="ScriptLimitsRequestNoParcelSelected"> + Keine Parzellen wurden ausgewählt + </string> + <string name="ScriptLimitsRequestWrongRegion"> + Fehler: Skriptinformationen sind nur für Ihre aktuelle Region verfügbar + </string> + <string name="ScriptLimitsRequestWaiting"> + Informationen werden abgerufen... + </string> + <string name="ScriptLimitsRequestDontOwnParcel"> + Sie sind nicht berechtigt, diese Parzelle zu untersuchen. + </string> + <string name="SITTING_ON"> + sitzt auf + </string> + <string name="ATTACH_CHEST"> + Brust + </string> + <string name="ATTACH_HEAD"> + Schädel + </string> + <string name="ATTACH_LSHOULDER"> + Linke Schulter + </string> + <string name="ATTACH_RSHOULDER"> + Rechte Schulter + </string> + <string name="ATTACH_LHAND"> + Linke Hand + </string> + <string name="ATTACH_RHAND"> + Rechte Hand + </string> + <string name="ATTACH_LFOOT"> + Linker Fuß + </string> + <string name="ATTACH_RFOOT"> + Rechter Fuß + </string> + <string name="ATTACH_BACK"> + Wirbelsäule + </string> + <string name="ATTACH_PELVIS"> + Becken + </string> + <string name="ATTACH_MOUTH"> + Mund + </string> + <string name="ATTACH_CHIN"> + Kinn + </string> + <string name="ATTACH_LEAR"> + Linkes Ohr + </string> + <string name="ATTACH_REAR"> + Rechtes Ohr + </string> + <string name="ATTACH_LEYE"> + Linkes Auge + </string> + <string name="ATTACH_REYE"> + Rechtes Auge + </string> + <string name="ATTACH_NOSE"> + Nase + </string> + <string name="ATTACH_RUARM"> + Rechter Oberarm + </string> + <string name="ATTACH_RLARM"> + Rechter Unterarm + </string> + <string name="ATTACH_LUARM"> + Linker Oberarm + </string> + <string name="ATTACH_LLARM"> + Linker Unterarm + </string> + <string name="ATTACH_RHIP"> + Rechte Hüfte + </string> + <string name="ATTACH_RULEG"> + Rechter Oberschenkel + </string> + <string name="ATTACH_RLLEG"> + Rechter Unterschenkel + </string> + <string name="ATTACH_LHIP"> + Linke Hüfte + </string> + <string name="ATTACH_LULEG"> + Linker Oberschenkel + </string> + <string name="ATTACH_LLLEG"> + Linker Unterschenkel + </string> + <string name="ATTACH_BELLY"> + Bauch + </string> + <string name="ATTACH_LEFT_PEC"> + Linke Brust + </string> + <string name="ATTACH_RIGHT_PEC"> + Rechte Brust + </string> + <string name="ATTACH_HUD_CENTER_2"> + HUD Mitte 2 + </string> + <string name="ATTACH_HUD_TOP_RIGHT"> + HUD oben rechts + </string> + <string name="ATTACH_HUD_TOP_CENTER"> + HUD oben Mitte + </string> + <string name="ATTACH_HUD_TOP_LEFT"> + HUD oben links + </string> + <string name="ATTACH_HUD_CENTER_1"> + HUD Mitte 1 + </string> + <string name="ATTACH_HUD_BOTTOM_LEFT"> + HUD unten links + </string> + <string name="ATTACH_HUD_BOTTOM"> + HUD unten + </string> + <string name="ATTACH_HUD_BOTTOM_RIGHT"> + HUD unten rechts + </string> + <string name="ATTACH_NECK"> + Hals + </string> + <string name="ATTACH_AVATAR_CENTER"> + Avatar-Mitte + </string> + <string name="ATTACH_LHAND_RING1"> + Linker Ringfinger + </string> + <string name="ATTACH_RHAND_RING1"> + Rechter Ringfinger + </string> + <string name="ATTACH_TAIL_BASE"> + Schwanzansatz + </string> + <string name="ATTACH_TAIL_TIP"> + Schwanzspitze + </string> + <string name="ATTACH_LWING"> + Linker Flügel + </string> + <string name="ATTACH_RWING"> + Rechter Flügel + </string> + <string name="ATTACH_FACE_JAW"> + Kiefer + </string> + <string name="ATTACH_FACE_LEAR"> + Alt. linkes Ohr + </string> + <string name="ATTACH_FACE_REAR"> + Alt. rechtes Ohr + </string> + <string name="ATTACH_FACE_LEYE"> + Alt. linkes Auge + </string> + <string name="ATTACH_FACE_REYE"> + Alt. rechtes Auge + </string> + <string name="ATTACH_FACE_TONGUE"> + Zunge + </string> + <string name="ATTACH_GROIN"> + Leiste + </string> + <string name="ATTACH_HIND_LFOOT"> + Linker hinterer Fuß + </string> + <string name="ATTACH_HIND_RFOOT"> + Rechter hinterer Fuß + </string> + <string name="CursorPos"> + Zeile [LINE], Spalte [COLUMN] + </string> + <string name="PanelDirCountFound"> + [COUNT] gefunden + </string> + <string name="PanelDirTimeStr"> + [hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt] + </string> + <string name="PanelDirEventsDateText"> + [mthnum,datetime,slt]/[day,datetime,slt] + </string> + <string name="PanelContentsTooltip"> + Objektinhalt + </string> + <string name="PanelContentsNewScript"> + Neues Skript + </string> + <string name="DoNotDisturbModeResponseDefault"> + Dieser Einwohner hat den Nicht-stören-Modus aktiviert und wird Ihre Nachricht später sehen. + </string> + <string name="MuteByName"> + (Nach Namen) + </string> + <string name="MuteAgent"> + (Einwohner) + </string> + <string name="MuteObject"> + (Objekt) + </string> + <string name="MuteGroup"> + (Gruppe) + </string> + <string name="MuteExternal"> + (Extern) + </string> + <string name="RegionNoCovenant"> + Für diesen Grundbesitz liegt kein Vertrag vor. + </string> + <string name="RegionNoCovenantOtherOwner"> + Für diesen Grundbesitz liegt kein Vertrag vor. Das Land auf diesem Grundbesitz wird vom Grundbesitzer und nicht von Linden Lab verkauft. Für Informationen zum Verkauf setzen Sie sich bitte mit dem Grundbesitzer in Verbindung. + </string> <string name="covenant_last_modified" value="Zuletzt geändert: "/> <string name="none_text" value=" (keiner) "/> <string name="never_text" value=" (nie) "/> - <string name="GroupOwned">In Gruppenbesitz</string> - <string name="Public">Öffentlich</string> - <string name="LocalSettings">Lokale Einstellungen</string> - <string name="RegionSettings">Regionseinstellungen</string> - <string name="NoEnvironmentSettings">Diese Region unterstützt keine Umgebungseinstellungen.</string> - <string name="EnvironmentSun">Sonne</string> - <string name="EnvironmentMoon">Mond</string> - <string name="EnvironmentBloom">Bloom</string> - <string name="EnvironmentCloudNoise">Wolkenrauschen</string> - <string name="EnvironmentNormalMap">Normal-Map</string> - <string name="EnvironmentTransparent">Transparent</string> - <string name="ClassifiedClicksTxt">Klicks: [TELEPORT] teleportieren, [MAP] Karte, [PROFILE] Profil</string> - <string name="ClassifiedUpdateAfterPublish">(wird nach Veröffentlichung aktualisiert)</string> - <string name="NoPicksClassifiedsText">Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus"-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen.</string> - <string name="NoPicksText">Sie haben keine Auswahl erstellt. Klicken Sie auf die Schaltfläche "Neu", um eine Auswahl zu erstellen.</string> - <string name="NoClassifiedsText">Sie haben keine Anzeigen erstellt. Klicken Sie auf die Schaltfläche "Neu", um eine Anzeige zu erstellen.</string> - <string name="NoAvatarPicksClassifiedsText">Der Einwohner hat keine Auswahl oder Anzeigen</string> - <string name="NoAvatarPicksText">Der Einwohner hat keine Auswahl</string> - <string name="NoAvatarClassifiedsText">Der Einwohner hat keine Anzeigen</string> - <string name="PicksClassifiedsLoadingText">Wird geladen...</string> - <string name="MultiPreviewTitle">Vorschau</string> - <string name="MultiPropertiesTitle">Eigenschaften</string> - <string name="InvOfferAnObjectNamed">Ein Objekt namens</string> - <string name="InvOfferOwnedByGroup">im Besitz der Gruppe</string> - <string name="InvOfferOwnedByUnknownGroup">im Besitz einer unbekannten Gruppe</string> - <string name="InvOfferOwnedBy">im Besitz von</string> - <string name="InvOfferOwnedByUnknownUser">im Besitz eines unbekannten Einwohners</string> - <string name="InvOfferGaveYou">hat Ihnen folgendes übergeben</string> - <string name="InvOfferDecline">Sie lehnen [DESC] von <nolink>[NAME]</nolink> ab.</string> - <string name="GroupMoneyTotal">Gesamtbetrag</string> - <string name="GroupMoneyBought">gekauft</string> - <string name="GroupMoneyPaidYou">bezahlte Ihnen</string> - <string name="GroupMoneyPaidInto">bezahlte an</string> - <string name="GroupMoneyBoughtPassTo">kaufte Pass für</string> - <string name="GroupMoneyPaidFeeForEvent">bezahlte Gebühr für Event</string> - <string name="GroupMoneyPaidPrizeForEvent">bezahlte Preis für Event</string> - <string name="GroupMoneyBalance">Kontostand</string> - <string name="GroupMoneyCredits">Danksagung</string> - <string name="GroupMoneyDebits">Soll</string> - <string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string> - <string name="AcquiredItems">Erworbene Artikel</string> - <string name="Cancel">Abbrechen</string> - <string name="UploadingCosts">Das Hochladen von [NAME] kostet [AMOUNT] L$</string> - <string name="BuyingCosts">Die Kosten betragen: [AMOUNT] L$</string> - <string name="UnknownFileExtension">Unbekanntes Dateiformat .%s -Gültige Formate: .wav, .tga, .bmp, .jpg, .jpeg oder .bvh</string> - <string name="MuteObject2">Ignorieren</string> - <string name="MuteAvatar">Ignorieren</string> - <string name="UnmuteObject">Freischalten</string> - <string name="UnmuteAvatar">Freischalten</string> - <string name="AddLandmarkNavBarMenu">Zu meinen Landmarken hinzufügen...</string> - <string name="EditLandmarkNavBarMenu">Meine Landmarken bearbeiten...</string> - <string name="accel-mac-control">⌃</string> - <string name="accel-mac-command">⌘</string> - <string name="accel-mac-option">⌥</string> - <string name="accel-mac-shift">⇧</string> - <string name="accel-win-control">Strg+</string> - <string name="accel-win-alt">Alt+</string> - <string name="accel-win-shift">Umschalt+</string> - <string name="FileSaved">Datei wurde gespeichert</string> - <string name="Receiving">Daten werden empfangen</string> - <string name="AM">Uhr</string> - <string name="PM">Uhr</string> - <string name="PST">PST</string> - <string name="PDT">PDT</string> - <string name="Direction_Forward">Vorwärts</string> - <string name="Direction_Left">Links</string> - <string name="Direction_Right">Rechts</string> - <string name="Direction_Back">Zurück</string> - <string name="Direction_North">Norden</string> - <string name="Direction_South">Süden</string> - <string name="Direction_West">Westen</string> - <string name="Direction_East">Osten</string> - <string name="Direction_Up">Nach oben</string> - <string name="Direction_Down">Nach unten</string> - <string name="Any Category">Alle Kategorien</string> - <string name="Shopping">Shopping</string> - <string name="Land Rental">Land mieten</string> - <string name="Property Rental">Immobilie mieten</string> - <string name="Special Attraction">Attraktionen</string> - <string name="New Products">Neue Produkte</string> - <string name="Employment">Stellenangebote</string> - <string name="Wanted">Gesucht</string> - <string name="Service">Dienstleistungen</string> - <string name="Personal">Sonstiges</string> - <string name="None">Keiner</string> - <string name="Linden Location">Lindenort</string> - <string name="Adult">Adult</string> - <string name="Arts&Culture">Kunst & Kultur</string> - <string name="Business">Firmen</string> - <string name="Educational">Bildung</string> - <string name="Gaming">Spielen</string> - <string name="Hangout">Treffpunkt</string> - <string name="Newcomer Friendly">Anfängergerecht</string> - <string name="Parks&Nature">Parks und Natur</string> - <string name="Residential">Wohngebiet</string> - <string name="Stage">Phase</string> - <string name="Other">Sonstige</string> - <string name="Rental">Vermietung</string> - <string name="Any">Alle</string> - <string name="You">Sie</string> - <string name=":">:</string> - <string name=",">,</string> - <string name="...">...</string> - <string name="***">***</string> - <string name="(">(</string> - <string name=")">)</string> - <string name=".">.</string> - <string name="'">'</string> - <string name="---">---</string> - <string name="Multiple Media">Mehrere Medien</string> - <string name="Play Media">Medien Abspielen/Pausieren</string> - <string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string> - <string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=de-de</string> - <string name="AMDDriverPage">http://support.amd.com/de/Pages/AMDSupportHub.aspx</string> - <string name="MBCmdLineError">Beim Parsen der Befehlszeile wurde ein Fehler festgestellt. + <string name="GroupOwned"> + In Gruppenbesitz + </string> + <string name="Public"> + Öffentlich + </string> + <string name="LocalSettings"> + Lokale Einstellungen + </string> + <string name="RegionSettings"> + Regionseinstellungen + </string> + <string name="NoEnvironmentSettings"> + Diese Region unterstützt keine Umgebungseinstellungen. + </string> + <string name="EnvironmentSun"> + Sonne + </string> + <string name="EnvironmentMoon"> + Mond + </string> + <string name="EnvironmentBloom"> + Bloom + </string> + <string name="EnvironmentCloudNoise"> + Wolkenrauschen + </string> + <string name="EnvironmentNormalMap"> + Normal-Map + </string> + <string name="EnvironmentTransparent"> + Transparent + </string> + <string name="ClassifiedClicksTxt"> + Klicks: [TELEPORT] teleportieren, [MAP] Karte, [PROFILE] Profil + </string> + <string name="ClassifiedUpdateAfterPublish"> + (wird nach Veröffentlichung aktualisiert) + </string> + <string name="NoPicksClassifiedsText"> + Sie haben keine Auswahl oder Anzeigen erstelllt. Klicken Sie auf die „Plus"-Schaltfläche, um eine Auswahl oder Anzeige zu erstellen. + </string> + <string name="NoPicksText"> + Sie haben keine Auswahl erstellt. Klicken Sie auf die Schaltfläche "Neu", um eine Auswahl zu erstellen. + </string> + <string name="NoClassifiedsText"> + Sie haben keine Anzeigen erstellt. Klicken Sie auf die Schaltfläche "Neu", um eine Anzeige zu erstellen. + </string> + <string name="NoAvatarPicksClassifiedsText"> + Der Einwohner hat keine Auswahl oder Anzeigen + </string> + <string name="NoAvatarPicksText"> + Der Einwohner hat keine Auswahl + </string> + <string name="NoAvatarClassifiedsText"> + Der Einwohner hat keine Anzeigen + </string> + <string name="PicksClassifiedsLoadingText"> + Wird geladen... + </string> + <string name="MultiPreviewTitle"> + Vorschau + </string> + <string name="MultiPropertiesTitle"> + Eigenschaften + </string> + <string name="InvOfferAnObjectNamed"> + Ein Objekt namens + </string> + <string name="InvOfferOwnedByGroup"> + im Besitz der Gruppe + </string> + <string name="InvOfferOwnedByUnknownGroup"> + im Besitz einer unbekannten Gruppe + </string> + <string name="InvOfferOwnedBy"> + im Besitz von + </string> + <string name="InvOfferOwnedByUnknownUser"> + im Besitz eines unbekannten Einwohners + </string> + <string name="InvOfferGaveYou"> + hat Ihnen folgendes übergeben + </string> + <string name="InvOfferDecline"> + Sie lehnen [DESC] von <nolink>[NAME]</nolink> ab. + </string> + <string name="GroupMoneyTotal"> + Gesamtbetrag + </string> + <string name="GroupMoneyBought"> + gekauft + </string> + <string name="GroupMoneyPaidYou"> + bezahlte Ihnen + </string> + <string name="GroupMoneyPaidInto"> + bezahlte an + </string> + <string name="GroupMoneyBoughtPassTo"> + kaufte Pass für + </string> + <string name="GroupMoneyPaidFeeForEvent"> + bezahlte Gebühr für Event + </string> + <string name="GroupMoneyPaidPrizeForEvent"> + bezahlte Preis für Event + </string> + <string name="GroupMoneyBalance"> + Kontostand + </string> + <string name="GroupMoneyCredits"> + Danksagung + </string> + <string name="GroupMoneyDebits"> + Soll + </string> + <string name="GroupMoneyDate"> + [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc] + </string> + <string name="AcquiredItems"> + Erworbene Artikel + </string> + <string name="Cancel"> + Abbrechen + </string> + <string name="UploadingCosts"> + Das Hochladen von [NAME] kostet [AMOUNT] L$ + </string> + <string name="BuyingCosts"> + Die Kosten betragen: [AMOUNT] L$ + </string> + <string name="UnknownFileExtension"> + Unbekanntes Dateiformat .%s +Gültige Formate: .wav, .tga, .bmp, .jpg, .jpeg oder .bvh + </string> + <string name="MuteObject2"> + Ignorieren + </string> + <string name="MuteAvatar"> + Ignorieren + </string> + <string name="UnmuteObject"> + Freischalten + </string> + <string name="UnmuteAvatar"> + Freischalten + </string> + <string name="AddLandmarkNavBarMenu"> + Zu meinen Landmarken hinzufügen... + </string> + <string name="EditLandmarkNavBarMenu"> + Meine Landmarken bearbeiten... + </string> + <string name="accel-mac-control"> + ⌃ + </string> + <string name="accel-mac-command"> + ⌘ + </string> + <string name="accel-mac-option"> + ⌥ + </string> + <string name="accel-mac-shift"> + ⇧ + </string> + <string name="accel-win-control"> + Strg+ + </string> + <string name="accel-win-alt"> + Alt+ + </string> + <string name="accel-win-shift"> + Umschalt+ + </string> + <string name="FileSaved"> + Datei wurde gespeichert + </string> + <string name="Receiving"> + Daten werden empfangen + </string> + <string name="AM"> + Uhr + </string> + <string name="PM"> + Uhr + </string> + <string name="PST"> + PST + </string> + <string name="PDT"> + PDT + </string> + <string name="Direction_Forward"> + Vorwärts + </string> + <string name="Direction_Left"> + Links + </string> + <string name="Direction_Right"> + Rechts + </string> + <string name="Direction_Back"> + Zurück + </string> + <string name="Direction_North"> + Norden + </string> + <string name="Direction_South"> + Süden + </string> + <string name="Direction_West"> + Westen + </string> + <string name="Direction_East"> + Osten + </string> + <string name="Direction_Up"> + Nach oben + </string> + <string name="Direction_Down"> + Nach unten + </string> + <string name="Any Category"> + Alle Kategorien + </string> + <string name="Shopping"> + Shopping + </string> + <string name="Land Rental"> + Land mieten + </string> + <string name="Property Rental"> + Immobilie mieten + </string> + <string name="Special Attraction"> + Attraktionen + </string> + <string name="New Products"> + Neue Produkte + </string> + <string name="Employment"> + Stellenangebote + </string> + <string name="Wanted"> + Gesucht + </string> + <string name="Service"> + Dienstleistungen + </string> + <string name="Personal"> + Sonstiges + </string> + <string name="None"> + Keiner + </string> + <string name="Linden Location"> + Lindenort + </string> + <string name="Adult"> + Adult + </string> + <string name="Arts&Culture"> + Kunst & Kultur + </string> + <string name="Business"> + Firmen + </string> + <string name="Educational"> + Bildung + </string> + <string name="Gaming"> + Spielen + </string> + <string name="Hangout"> + Treffpunkt + </string> + <string name="Newcomer Friendly"> + Anfängergerecht + </string> + <string name="Parks&Nature"> + Parks und Natur + </string> + <string name="Residential"> + Wohngebiet + </string> + <string name="Stage"> + Phase + </string> + <string name="Other"> + Sonstige + </string> + <string name="Rental"> + Vermietung + </string> + <string name="Any"> + Alle + </string> + <string name="You"> + Sie + </string> + <string name=":"> + : + </string> + <string name=","> + , + </string> + <string name="..."> + ... + </string> + <string name="***"> + *** + </string> + <string name="("> + ( + </string> + <string name=")"> + ) + </string> + <string name="."> + . + </string> + <string name="'"> + ' + </string> + <string name="---"> + --- + </string> + <string name="Multiple Media"> + Mehrere Medien + </string> + <string name="Play Media"> + Medien Abspielen/Pausieren + </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=de-de + </string> + <string name="AMDDriverPage"> + http://support.amd.com/de/Pages/AMDSupportHub.aspx + </string> + <string name="MBCmdLineError"> + Beim Parsen der Befehlszeile wurde ein Fehler festgestellt. Weitere Informationen: http://wiki.secondlife.com/wiki/Client_parameters (EN) -Fehler:</string> - <string name="MBCmdLineUsg">[APP_NAME] Verwendung in Befehlszeile:</string> - <string name="MBUnableToAccessFile">[APP_NAME] kann auf die erforderliche Datei nicht zugreifen. +Fehler: + </string> + <string name="MBCmdLineUsg"> + [APP_NAME] Verwendung in Befehlszeile: + </string> + <string name="MBUnableToAccessFile"> + [APP_NAME] kann auf die erforderliche Datei nicht zugreifen. Grund hierfür ist, dass Sie entweder mehrere Instanzen gleichzeitig ausführen oder dass Ihr System denkt, eine Datei sei geöffnet. Falls diese Nachricht erneut angezeigt wird, starten Sie bitte Ihren Computer neu und probieren Sie es noch einmal. -Falls der Fehler dann weiterhin auftritt, müssen Sie [APP_NAME] von Ihrem System de-installieren und erneut installieren.</string> - <string name="MBFatalError">Unbehebbarer Fehler</string> - <string name="MBRequiresAltiVec">[APP_NAME] erfordert einen Prozessor mit AltiVec (G4 oder später).</string> - <string name="MBAlreadyRunning">[APP_NAME] läuft bereits. +Falls der Fehler dann weiterhin auftritt, müssen Sie [APP_NAME] von Ihrem System de-installieren und erneut installieren. + </string> + <string name="MBFatalError"> + Unbehebbarer Fehler + </string> + <string name="MBRequiresAltiVec"> + [APP_NAME] erfordert einen Prozessor mit AltiVec (G4 oder später). + </string> + <string name="MBAlreadyRunning"> + [APP_NAME] läuft bereits. Bitte sehen Sie in Ihrer Menüleiste nach, dort sollte ein Symbol für das Programm angezeigt werden. -Falls diese Nachricht erneut angezeigt wird, starten Sie Ihren Computer bitte neu.</string> - <string name="MBFrozenCrashed">[APP_NAME] scheint eingefroren zu sein oder ist abgestürzt. -Möchten Sie einen Absturz-Bericht einschicken?</string> - <string name="MBAlert">Benachrichtigung</string> - <string name="MBNoDirectX">[APP_NAME] kann DirectX 9.0b oder höher nicht feststellen. +Falls diese Nachricht erneut angezeigt wird, starten Sie Ihren Computer bitte neu. + </string> + <string name="MBFrozenCrashed"> + [APP_NAME] scheint eingefroren zu sein oder ist abgestürzt. +Möchten Sie einen Absturz-Bericht einschicken? + </string> + <string name="MBAlert"> + Benachrichtigung + </string> + <string name="MBNoDirectX"> + [APP_NAME] kann DirectX 9.0b oder höher nicht feststellen. [APP_NAME] verwendet DirectX, um nach Hardware und/oder veralteten Treibern zu suchen, die zu Problemen mit der Stabilität, Leistung und Abstürzen führen können. Sie können [APP_NAME] auch so ausführen, wir empfehlen jedoch, dass DirectX 9.0b vorhanden ist und ausgeführt wird. -Möchten Sie fortfahren?</string> - <string name="MBWarning">Hinweis</string> - <string name="MBNoAutoUpdate">Für Linux ist zur Zeit noch kein automatisches Aktualisieren möglich. -Bitte laden Sie die aktuellste Version von www.secondlife.com herunter.</string> - <string name="MBRegClassFailed">RegisterClass fehlgeschlagen</string> - <string name="MBError">Fehler</string> - <string name="MBFullScreenErr">Vollbildschirm mit [WIDTH] x [HEIGHT] kann nicht ausgeführt werden. -Ausführung erfolgt in Fenster.</string> - <string name="MBDestroyWinFailed">Fehler beim Herunterfahren während Fenster geschlossen wurde (DestroyWindow() fehlgeschlagen)</string> - <string name="MBShutdownErr">Fehler beim Herunterfahren</string> - <string name="MBDevContextErr">Kann keinen Kontext für GL-Gerät erstellen</string> - <string name="MBPixelFmtErr">Passendes Pixelformat wurde nicht gefunden</string> - <string name="MBPixelFmtDescErr">Beschreibung für Pixelformat nicht verfügbar</string> - <string name="MBTrueColorWindow">Um [APP_NAME] auszuführen, ist True Color (32-bit) erforderlich. -Klicken Sie öffnen Sie auf Ihrem Computer die Einstellungen für die Anzeige und stellen Sie den Bildschirm auf 32-bit Farbe ein.</string> - <string name="MBAlpha">[APP_NAME] kann nicht ausgeführt werden, da kein 8-Bit-Alpha-Kanal verfügbar ist. Dies geschieht normalerweise bei Problemen mit dem Treiber der Video-Karte. +Möchten Sie fortfahren? + </string> + <string name="MBWarning"> + Hinweis + </string> + <string name="MBNoAutoUpdate"> + Für Linux ist zur Zeit noch kein automatisches Aktualisieren möglich. +Bitte laden Sie die aktuellste Version von www.secondlife.com herunter. + </string> + <string name="MBRegClassFailed"> + RegisterClass fehlgeschlagen + </string> + <string name="MBError"> + Fehler + </string> + <string name="MBFullScreenErr"> + Vollbildschirm mit [WIDTH] x [HEIGHT] kann nicht ausgeführt werden. +Ausführung erfolgt in Fenster. + </string> + <string name="MBDestroyWinFailed"> + Fehler beim Herunterfahren während Fenster geschlossen wurde (DestroyWindow() fehlgeschlagen) + </string> + <string name="MBShutdownErr"> + Fehler beim Herunterfahren + </string> + <string name="MBDevContextErr"> + Kann keinen Kontext für GL-Gerät erstellen + </string> + <string name="MBPixelFmtErr"> + Passendes Pixelformat wurde nicht gefunden + </string> + <string name="MBPixelFmtDescErr"> + Beschreibung für Pixelformat nicht verfügbar + </string> + <string name="MBTrueColorWindow"> + Um [APP_NAME] auszuführen, ist True Color (32-bit) erforderlich. +Klicken Sie öffnen Sie auf Ihrem Computer die Einstellungen für die Anzeige und stellen Sie den Bildschirm auf 32-bit Farbe ein. + </string> + <string name="MBAlpha"> + [APP_NAME] kann nicht ausgeführt werden, da kein 8-Bit-Alpha-Kanal verfügbar ist. Dies geschieht normalerweise bei Problemen mit dem Treiber der Video-Karte. Bitte vergewissern Sie sich, dass Sie die aktuellsten Treiber für Ihre Videokarte installiert haben. Vergewissern Sie sich außerdem, dass Ihr Bildschirm auf True Color (32-Bit) eingestellt ist (Systemsteuerung > Anzeige > Einstellungen). -Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE].</string> - <string name="MBPixelFmtSetErr">Pixel-Format kann nicht eingestellt werden.</string> - <string name="MBGLContextErr">Kann keinen Kontext für GL-Gerät erstellen</string> - <string name="MBGLContextActErr">Kann keinen Kontext für GL-Gerät aktivieren</string> - <string name="MBVideoDrvErr">[APP_NAME] kann nicht ausgeführt werden, da die Treiber Ihrer Videokarte entweder nicht richtig installiert oder veraltet sind, oder die entsprechende Hardware nicht unterstützt wird. Bitte vergewissern Sie sich, dass Sie die aktuellsten Treiber für die Videokarte installiert haben. Falls Sie die aktuellsten Treiber bereits installiert haben, installieren Sie diese bitte erneut. +Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE]. + </string> + <string name="MBPixelFmtSetErr"> + Pixel-Format kann nicht eingestellt werden. + </string> + <string name="MBGLContextErr"> + Kann keinen Kontext für GL-Gerät erstellen + </string> + <string name="MBGLContextActErr"> + Kann keinen Kontext für GL-Gerät aktivieren + </string> + <string name="MBVideoDrvErr"> + [APP_NAME] kann nicht ausgeführt werden, da die Treiber Ihrer Videokarte entweder nicht richtig installiert oder veraltet sind, oder die entsprechende Hardware nicht unterstützt wird. Bitte vergewissern Sie sich, dass Sie die aktuellsten Treiber für die Videokarte installiert haben. Falls Sie die aktuellsten Treiber bereits installiert haben, installieren Sie diese bitte erneut. -Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE].</string> - <string name="5 O'Clock Shadow">Bartschatten</string> - <string name="All White">Ganz weiß</string> - <string name="Anime Eyes">Anime-Augen</string> - <string name="Arced">Gewölbt</string> - <string name="Arm Length">Armlänge</string> - <string name="Attached">Angewachsen</string> - <string name="Attached Earlobes">Angewachsene Ohrläppchen</string> - <string name="Back Fringe">Nackenfransen</string> - <string name="Baggy">Tränensäcke</string> - <string name="Bangs">Pony</string> - <string name="Beady Eyes">Knopfaugen</string> - <string name="Belly Size">Bauchgröße</string> - <string name="Big">Groß</string> - <string name="Big Butt">Großer Hintern</string> - <string name="Big Hair Back">Volumen: Hinten</string> - <string name="Big Hair Front">Volumen: Vorne</string> - <string name="Big Hair Top">Volumen: Oben</string> - <string name="Big Head">Groß</string> - <string name="Big Pectorals">Große Brustmuskeln</string> - <string name="Big Spikes">Große Stacheln</string> - <string name="Black">Schwarz</string> - <string name="Blonde">Blond</string> - <string name="Blonde Hair">Blondes Haar</string> - <string name="Blush">Rouge</string> - <string name="Blush Color">Rougefarbe</string> - <string name="Blush Opacity">Rouge Deckkraft</string> - <string name="Body Definition">Körperkonturen</string> - <string name="Body Fat">Körperfett</string> - <string name="Body Freckles">Sommersprossen</string> - <string name="Body Thick">breit</string> - <string name="Body Thickness">Körperbreite</string> - <string name="Body Thin">schmal</string> - <string name="Bow Legged">o-beinig</string> - <string name="Breast Buoyancy">Brust, Straffheit</string> - <string name="Breast Cleavage">Dekolleté</string> - <string name="Breast Size">Brustgröße</string> - <string name="Bridge Width">Rückenbreite</string> - <string name="Broad">Breit</string> - <string name="Brow Size">Brauengröße</string> - <string name="Bug Eyes">Glubschaugen</string> - <string name="Bugged Eyes">Hervortretend</string> - <string name="Bulbous">Knollennase</string> - <string name="Bulbous Nose">Knollennase</string> - <string name="Breast Physics Mass">Brust – Masse</string> - <string name="Breast Physics Smoothing">Brust – Glättung</string> - <string name="Breast Physics Gravity">Brust – Schwerkraft</string> - <string name="Breast Physics Drag">Brust – Luftwiderstand</string> - <string name="Breast Physics InOut Max Effect">Max. Effekt</string> - <string name="Breast Physics InOut Spring">Federn</string> - <string name="Breast Physics InOut Gain">Verstärkung</string> - <string name="Breast Physics InOut Damping">Dämpfung</string> - <string name="Breast Physics UpDown Max Effect">Max. Effekt</string> - <string name="Breast Physics UpDown Spring">Federn</string> - <string name="Breast Physics UpDown Gain">Verstärkung</string> - <string name="Breast Physics UpDown Damping">Dämpfung</string> - <string name="Breast Physics LeftRight Max Effect">Max. Effekt</string> - <string name="Breast Physics LeftRight Spring">Federn</string> - <string name="Breast Physics LeftRight Gain">Verstärkung</string> - <string name="Breast Physics LeftRight Damping">Dämpfung</string> - <string name="Belly Physics Mass">Bauch – Masse</string> - <string name="Belly Physics Smoothing">Bauch – Glättung</string> - <string name="Belly Physics Gravity">Bauch – Schwerkraft</string> - <string name="Belly Physics Drag">Bauch – Luftwiderstand</string> - <string name="Belly Physics UpDown Max Effect">Max. Effekt</string> - <string name="Belly Physics UpDown Spring">Federn</string> - <string name="Belly Physics UpDown Gain">Verstärkung</string> - <string name="Belly Physics UpDown Damping">Dämpfung</string> - <string name="Butt Physics Mass">Po – Masse</string> - <string name="Butt Physics Smoothing">Po – Glättung</string> - <string name="Butt Physics Gravity">Po – Schwerkraft</string> - <string name="Butt Physics Drag">Po – Luftwiderstand</string> - <string name="Butt Physics UpDown Max Effect">Max. Effekt</string> - <string name="Butt Physics UpDown Spring">Federn</string> - <string name="Butt Physics UpDown Gain">Verstärkung</string> - <string name="Butt Physics UpDown Damping">Dämpfung</string> - <string name="Butt Physics LeftRight Max Effect">Max. Effekt</string> - <string name="Butt Physics LeftRight Spring">Federn</string> - <string name="Butt Physics LeftRight Gain">Verstärkung</string> - <string name="Butt Physics LeftRight Damping">Dämpfung</string> - <string name="Bushy Eyebrows">Buschige Augenbrauen</string> - <string name="Bushy Hair">Buschiges Haar</string> - <string name="Butt Size">Hintern, Größe</string> - <string name="Butt Gravity">Po – Schwerkraft</string> - <string name="bustle skirt">Tournürenrock</string> - <string name="no bustle">Ohne</string> - <string name="more bustle">Mit</string> - <string name="Chaplin">Chaplin</string> - <string name="Cheek Bones">Wangenknochen</string> - <string name="Chest Size">Brustgröße</string> - <string name="Chin Angle">Kinnwinkel</string> - <string name="Chin Cleft">Kinnspalte</string> - <string name="Chin Curtains">Schifferfräse</string> - <string name="Chin Depth">Kinnlänge</string> - <string name="Chin Heavy">Kinn ausgeprägt</string> - <string name="Chin In">Kinn zurück</string> - <string name="Chin Out">Kinn nach vorne</string> - <string name="Chin-Neck">Kinn-Hals</string> - <string name="Clear">Transparent</string> - <string name="Cleft">Spalte</string> - <string name="Close Set Eyes">Eng stehende Augen</string> - <string name="Closed">Geschlossen</string> - <string name="Closed Back">Hinten geschlossen</string> - <string name="Closed Front">Vorne geschlossen</string> - <string name="Closed Left">Links geschlossen</string> - <string name="Closed Right">Rechts geschlossen</string> - <string name="Coin Purse">Klein</string> - <string name="Collar Back">Kragen hinten</string> - <string name="Collar Front">Kragen vorne</string> - <string name="Corner Down">Nach unten</string> - <string name="Corner Up">Nach oben</string> - <string name="Creased">Schlupflid</string> - <string name="Crooked Nose">Krumme Nase</string> - <string name="Cuff Flare">Hosenaufschlag</string> - <string name="Dark">Dunkel</string> - <string name="Dark Green">Dunkelgrün</string> - <string name="Darker">Dunkler</string> - <string name="Deep">Tief</string> - <string name="Default Heels">Standardabsätze</string> - <string name="Dense">Dicht</string> - <string name="Double Chin">Doppelkinn</string> - <string name="Downturned">Nach unten</string> - <string name="Duffle Bag">Groß</string> - <string name="Ear Angle">Ohrenwinkel</string> - <string name="Ear Size">Ohrengröße</string> - <string name="Ear Tips">Ohrenspitzen</string> - <string name="Egg Head">Eierkopf</string> - <string name="Eye Bags">Augenränder</string> - <string name="Eye Color">Augenfarbe</string> - <string name="Eye Depth">Augentiefe</string> - <string name="Eye Lightness">Helligkeit</string> - <string name="Eye Opening">Öffnung</string> - <string name="Eye Pop">Symmetrie</string> - <string name="Eye Size">Augengröße</string> - <string name="Eye Spacing">Augenstand</string> - <string name="Eyebrow Arc">Brauenbogen</string> - <string name="Eyebrow Density">Brauendichte</string> - <string name="Eyebrow Height">Brauenhöhe</string> - <string name="Eyebrow Points">Brauenenden</string> - <string name="Eyebrow Size">Brauengröße</string> - <string name="Eyelash Length">Wimpernlänge</string> - <string name="Eyeliner">Eyeliner</string> - <string name="Eyeliner Color">Farbe des Eyeliners</string> - <string name="Eyes Bugged">Glubschaugen</string> - <string name="Face Shear">Gesichtsverzerrung</string> - <string name="Facial Definition">Gesichtskonturen</string> - <string name="Far Set Eyes">Weit auseinander</string> - <string name="Fat Lips">Volle Lippen</string> - <string name="Female">weiblich</string> - <string name="Fingerless">Ohne Finger</string> - <string name="Fingers">Finger</string> - <string name="Flared Cuffs">Ausgestellt</string> - <string name="Flat">Flach</string> - <string name="Flat Butt">Flacher Hintern</string> - <string name="Flat Head">Flacher Kopf</string> - <string name="Flat Toe">Flache Spitze</string> - <string name="Foot Size">Fußgröße</string> - <string name="Forehead Angle">Stirnwinkel</string> - <string name="Forehead Heavy">Stirn ausgeprägt</string> - <string name="Freckles">Sommersprossen</string> - <string name="Front Fringe">Fransen, vorne</string> - <string name="Full Back">Hinten volles Haar</string> - <string name="Full Eyeliner">Starker Eyeliner</string> - <string name="Full Front">Vorne volles Haar</string> - <string name="Full Hair Sides">Seitlich volles Haar</string> - <string name="Full Sides">Volle Seiten</string> - <string name="Glossy">Glänzend</string> - <string name="Glove Fingers">Handschuhfinger</string> - <string name="Glove Length">Handschuhlänge</string> - <string name="Hair">Haare</string> - <string name="Hair Back">Haare: Hinten</string> - <string name="Hair Front">Haare: Vorne</string> - <string name="Hair Sides">Haare: Seiten</string> - <string name="Hair Sweep">Haartolle</string> - <string name="Hair Thickess">Haardicke</string> - <string name="Hair Thickness">Haardicke</string> - <string name="Hair Tilt">Haarneigung</string> - <string name="Hair Tilted Left">Nach links</string> - <string name="Hair Tilted Right">Nach rechts</string> - <string name="Hair Volume">Haare: Volumen</string> - <string name="Hand Size">Handgröße</string> - <string name="Handlebars">Zwirbelbart</string> - <string name="Head Length">Kopflänge</string> - <string name="Head Shape">Kopfform</string> - <string name="Head Size">Kopfgröße</string> - <string name="Head Stretch">Kopfstreckung</string> - <string name="Heel Height">Absatzhöhe</string> - <string name="Heel Shape">Absatzform</string> - <string name="Height">Größe</string> - <string name="High">Hoch</string> - <string name="High Heels">Hohe Absätze</string> - <string name="High Jaw">Hoch</string> - <string name="High Platforms">Hohe Plattformsohlen</string> - <string name="High and Tight">Hoch und eng</string> - <string name="Higher">Höhere</string> - <string name="Hip Length">Länge der Hüfte</string> - <string name="Hip Width">Breite der Hüfte</string> - <string name="Hover">Schweben</string> - <string name="In">In</string> - <string name="In Shdw Color">Farbe Innenseite</string> - <string name="In Shdw Opacity">Deckkraft: innen</string> - <string name="Inner Eye Corner">Ecke: Nasenseite</string> - <string name="Inner Eye Shadow">Innenlid</string> - <string name="Inner Shadow">Innenlid</string> - <string name="Jacket Length">Jackenlänge</string> - <string name="Jacket Wrinkles">Jackenfalten</string> - <string name="Jaw Angle">Kinnansatz</string> - <string name="Jaw Jut">Kinnposition</string> - <string name="Jaw Shape">Kinnform</string> - <string name="Join">Zusammen</string> - <string name="Jowls">Hängebacken</string> - <string name="Knee Angle">Kniewinkel</string> - <string name="Knock Kneed">X-beinig</string> - <string name="Large">Groß</string> - <string name="Large Hands">Große Hände</string> - <string name="Left Part">Linksscheitel</string> - <string name="Leg Length">Beinlänge</string> - <string name="Leg Muscles">Beinmuskeln</string> - <string name="Less">Weniger</string> - <string name="Less Body Fat">Weniger Speck</string> - <string name="Less Curtains">Weniger</string> - <string name="Less Freckles">Weniger</string> - <string name="Less Full">Weniger</string> - <string name="Less Gravity">Weniger</string> - <string name="Less Love">Weniger</string> - <string name="Less Muscles">Weniger</string> - <string name="Less Muscular">Weniger</string> - <string name="Less Rosy">Weniger</string> - <string name="Less Round">Weniger</string> - <string name="Less Saddle">Weniger</string> - <string name="Less Square">Weniger</string> - <string name="Less Volume">Weniger</string> - <string name="Less soul">Weniger</string> - <string name="Lighter">Heller</string> - <string name="Lip Cleft">Amorbogen</string> - <string name="Lip Cleft Depth">Tiefe: Amorbogen</string> - <string name="Lip Fullness">Fülle</string> - <string name="Lip Pinkness">Pinkton</string> - <string name="Lip Ratio">Lippenproportionen</string> - <string name="Lip Thickness">Lippendicke</string> - <string name="Lip Width">Mundbreite</string> - <string name="Lipgloss">Lipgloss</string> - <string name="Lipstick">Lippenstift</string> - <string name="Lipstick Color">Farbe</string> - <string name="Long">Lang</string> - <string name="Long Head">Langer Kopf</string> - <string name="Long Hips">Lange Hüften</string> - <string name="Long Legs">Lange Beine</string> - <string name="Long Neck">Langer Hals</string> - <string name="Long Pigtails">Lange Zöpfe</string> - <string name="Long Ponytail">Langer Pferdeschwanz</string> - <string name="Long Torso">Langer Oberkörper</string> - <string name="Long arms">Lange Arme</string> - <string name="Loose Pants">Weite Hosen</string> - <string name="Loose Shirt">Weites Hemd</string> - <string name="Loose Sleeves">Weite Ärmel</string> - <string name="Love Handles">Fettpölsterchen</string> - <string name="Low">Niedrig</string> - <string name="Low Heels">Niedrig</string> - <string name="Low Jaw">Niedrig</string> - <string name="Low Platforms">Niedrig</string> - <string name="Low and Loose">Weit</string> - <string name="Lower">Absenken</string> - <string name="Lower Bridge">Brücke, Unterer Teil</string> - <string name="Lower Cheeks">Wangen, unterer Bereich</string> - <string name="Male">Männlich</string> - <string name="Middle Part">Mittelscheitel</string> - <string name="More">Mehr</string> - <string name="More Blush">Mehr</string> - <string name="More Body Fat">Mehr Speck</string> - <string name="More Curtains">Mehr</string> - <string name="More Eyeshadow">Mehr</string> - <string name="More Freckles">Mehr</string> - <string name="More Full">Voller</string> - <string name="More Gravity">Mehr</string> - <string name="More Lipstick">Mehr</string> - <string name="More Love">Mehr</string> - <string name="More Lower Lip">Größer</string> - <string name="More Muscles">Mehr</string> - <string name="More Muscular">Mehr</string> - <string name="More Rosy">Mehr</string> - <string name="More Round">Runder</string> - <string name="More Saddle">Mehr</string> - <string name="More Sloped">Flach</string> - <string name="More Square">Eckiger</string> - <string name="More Upper Lip">Mehr</string> - <string name="More Vertical">Steil</string> - <string name="More Volume">Mehr</string> - <string name="More soul">Mehr</string> - <string name="Moustache">Schnauzer</string> - <string name="Mouth Corner">Mundwinkel</string> - <string name="Mouth Position">Mundposition</string> - <string name="Mowhawk">Irokese</string> - <string name="Muscular">Muskulös</string> - <string name="Mutton Chops">Koteletten</string> - <string name="Nail Polish">Nagellack</string> - <string name="Nail Polish Color">Farbe</string> - <string name="Narrow">Schmal</string> - <string name="Narrow Back">Wenig</string> - <string name="Narrow Front">Wenig</string> - <string name="Narrow Lips">Schmale Lippen</string> - <string name="Natural">Natürlich</string> - <string name="Neck Length">Halslänge</string> - <string name="Neck Thickness">Halsdicke</string> - <string name="No Blush">Kein Rouge</string> - <string name="No Eyeliner">Kein Eyeliner</string> - <string name="No Eyeshadow">Kein Lidschatten</string> - <string name="No Lipgloss">Kein Lipgloss</string> - <string name="No Lipstick">Kein Lippenstift</string> - <string name="No Part">Kein Scheitel</string> - <string name="No Polish">Kein Nagellack</string> - <string name="No Red">Nicht rot</string> - <string name="No Spikes">Keine Stachel</string> - <string name="No White">Kein Weiß</string> - <string name="No Wrinkles">Keine Falten</string> - <string name="Normal Lower">Normal unten</string> - <string name="Normal Upper">Normal oben</string> - <string name="Nose Left">Links</string> - <string name="Nose Right">Rechts</string> - <string name="Nose Size">Größe</string> - <string name="Nose Thickness">Dicke</string> - <string name="Nose Tip Angle">Nasenspitze</string> - <string name="Nose Tip Shape">Nasenspitze</string> - <string name="Nose Width">Nasenbreite</string> - <string name="Nostril Division">Teilung</string> - <string name="Nostril Width">Größe</string> - <string name="Opaque">Deckend</string> - <string name="Open">Öffnen</string> - <string name="Open Back">Hinten offen</string> - <string name="Open Front">Vorne offen</string> - <string name="Open Left">Links offen</string> - <string name="Open Right">Rechts offen</string> - <string name="Orange">Orange</string> - <string name="Out">Aus</string> - <string name="Out Shdw Color">Farbe: Oben</string> - <string name="Out Shdw Opacity">Deckkraft: Oben</string> - <string name="Outer Eye Corner">Äußerer Augenwinkel</string> - <string name="Outer Eye Shadow">Lidschatten: Oben</string> - <string name="Outer Shadow">Lidschatten: Oben</string> - <string name="Overbite">Überbiss</string> - <string name="Package">Ausbeulung</string> - <string name="Painted Nails">Lackierte Nägel</string> - <string name="Pale">Blass</string> - <string name="Pants Crotch">Schritt</string> - <string name="Pants Fit">Passform</string> - <string name="Pants Length">Hosenlänge</string> - <string name="Pants Waist">Hüfte</string> - <string name="Pants Wrinkles">Falten</string> - <string name="Part">Scheitel</string> - <string name="Part Bangs">Pony scheiteln</string> - <string name="Pectorals">Brustmuskel</string> - <string name="Pigment">Pigmentierung</string> - <string name="Pigtails">Zöpfe</string> - <string name="Pink">Pink</string> - <string name="Pinker">Mehr Pink</string> - <string name="Platform Height">Höhe</string> - <string name="Platform Width">Breite</string> - <string name="Pointy">Spitz</string> - <string name="Pointy Heels">Pfennigabsätze</string> - <string name="Ponytail">Pferdeschwanz</string> - <string name="Poofy Skirt">Weit ausgestellt</string> - <string name="Pop Left Eye">Linkes Auge größer</string> - <string name="Pop Right Eye">Rechtes Auge größer</string> - <string name="Puffy">Geschwollen</string> - <string name="Puffy Eyelids">Geschwollene Lider</string> - <string name="Rainbow Color">Regenbogenfarben</string> - <string name="Red Hair">Rote Haare</string> - <string name="Regular">Normal</string> - <string name="Right Part">Scheitel rechts</string> - <string name="Rosy Complexion">Rosiger Teint</string> - <string name="Round">Rund</string> - <string name="Ruddiness">Röte</string> - <string name="Ruddy">Rötlich</string> - <string name="Rumpled Hair">Zerzauste Haare</string> - <string name="Saddle Bags">Hüftspeck</string> - <string name="Scrawny Leg">Dürres Bein</string> - <string name="Separate">Auseinander</string> - <string name="Shallow">Flach</string> - <string name="Shear Back">Hinterkopf rasiert</string> - <string name="Shear Face">Gesicht verzerren</string> - <string name="Shear Front">Vorne rasiert</string> - <string name="Shear Left Up">Links</string> - <string name="Shear Right Up">Rechts</string> - <string name="Sheared Back">Hinterkopf rasiert</string> - <string name="Sheared Front">Vorne rasiert</string> - <string name="Shift Left">Nach links</string> - <string name="Shift Mouth">Mund verschieben</string> - <string name="Shift Right">Nach rechts</string> - <string name="Shirt Bottom">Hemdlänge</string> - <string name="Shirt Fit">Passform</string> - <string name="Shirt Wrinkles">Falten</string> - <string name="Shoe Height">Schuhart</string> - <string name="Short">Klein</string> - <string name="Short Arms">Kurze Arme</string> - <string name="Short Legs">Kurze Beine</string> - <string name="Short Neck">Kurzer Hals</string> - <string name="Short Pigtails">Kurze Zöpfe</string> - <string name="Short Ponytail">Kurzer Pferdeschwanz</string> - <string name="Short Sideburns">Kurze Koteletten</string> - <string name="Short Torso">Kurzer Oberkörper</string> - <string name="Short hips">Kurze Hüften</string> - <string name="Shoulders">Schultern</string> - <string name="Side Fringe">Seitliche Fransen</string> - <string name="Sideburns">Koteletten</string> - <string name="Sides Hair">Seitliches Haar</string> - <string name="Sides Hair Down">Lang</string> - <string name="Sides Hair Up">Kurz</string> - <string name="Skinny Neck">Dünner Hals</string> - <string name="Skirt Fit">Passform</string> - <string name="Skirt Length">Rocklänge</string> - <string name="Slanted Forehead">Fliehende Stirn</string> - <string name="Sleeve Length">Ärmellänge</string> - <string name="Sleeve Looseness">Passform Ärmel</string> - <string name="Slit Back">Schlitz: Hinten</string> - <string name="Slit Front">Schlitz: Vorne</string> - <string name="Slit Left">Schlitz: Links</string> - <string name="Slit Right">Schlitz: Rechts</string> - <string name="Small">Klein</string> - <string name="Small Hands">Kleine Hände</string> - <string name="Small Head">Klein</string> - <string name="Smooth">Glätten</string> - <string name="Smooth Hair">Glattes Haar</string> - <string name="Socks Length">Strumpflänge</string> - <string name="Soulpatch">Unterlippenbart</string> - <string name="Sparse">Wenig</string> - <string name="Spiked Hair">Stachelhaare</string> - <string name="Square">Rechteck</string> - <string name="Square Toe">Eckig</string> - <string name="Squash Head">Gestaucht</string> - <string name="Stretch Head">Gestreckt</string> - <string name="Sunken">Eingefallen</string> - <string name="Sunken Chest">Trichterbrust</string> - <string name="Sunken Eyes">Eingesunkene Augen</string> - <string name="Sweep Back">Nach hinten</string> - <string name="Sweep Forward">Nach vorne</string> - <string name="Tall">Groß</string> - <string name="Taper Back">Ansatzbreite hinten</string> - <string name="Taper Front">Ansatzbreite vorne</string> - <string name="Thick Heels">Dicke Absätze</string> - <string name="Thick Neck">Dicker Hals</string> - <string name="Thick Toe">Dick</string> - <string name="Thin">Dünn</string> - <string name="Thin Eyebrows">Dünne Augenbrauen</string> - <string name="Thin Lips">Dünne Lippen</string> - <string name="Thin Nose">Dünne Nase</string> - <string name="Tight Chin">Straffes Kinn</string> - <string name="Tight Cuffs">Eng</string> - <string name="Tight Pants">Enge Hosen</string> - <string name="Tight Shirt">Enges Hemd</string> - <string name="Tight Skirt">Enger Rock</string> - <string name="Tight Sleeves">Enge Ärmel</string> - <string name="Toe Shape">Spitze</string> - <string name="Toe Thickness">Dicke</string> - <string name="Torso Length">Länge des Oberkörpers</string> - <string name="Torso Muscles">Muskeln</string> - <string name="Torso Scrawny">Dürr</string> - <string name="Unattached">Frei</string> - <string name="Uncreased">Straffes Lid</string> - <string name="Underbite">Unterbiss</string> - <string name="Unnatural">Unnatürlich</string> - <string name="Upper Bridge">Brücke, oberer Teil</string> - <string name="Upper Cheeks">Obere Wangen</string> - <string name="Upper Chin Cleft">Obere Kinnspalte</string> - <string name="Upper Eyelid Fold">Obere Lidfalte</string> - <string name="Upturned">Stupsnase</string> - <string name="Very Red">Sehr rot</string> - <string name="Waist Height">Bund</string> - <string name="Well-Fed">Gut genährt</string> - <string name="White Hair">Weiße Haare</string> - <string name="Wide">Breit</string> - <string name="Wide Back">Breit</string> - <string name="Wide Front">Breit</string> - <string name="Wide Lips">Breit</string> - <string name="Wild">Wild</string> - <string name="Wrinkles">Falten</string> - <string name="LocationCtrlAddLandmarkTooltip">Zu meinen Landmarken hinzufügen</string> - <string name="LocationCtrlEditLandmarkTooltip">Meine Landmarken bearbeiten</string> - <string name="LocationCtrlInfoBtnTooltip">Weitere Informationen über die aktuelle Position</string> - <string name="LocationCtrlComboBtnTooltip">Mein Reiseverlauf</string> - <string name="LocationCtrlForSaleTooltip">Dieses Land kaufen</string> - <string name="LocationCtrlVoiceTooltip">Voice hier nicht möglich</string> - <string name="LocationCtrlFlyTooltip">Fliegen ist unzulässig</string> - <string name="LocationCtrlPushTooltip">Kein Stoßen</string> - <string name="LocationCtrlBuildTooltip">Bauen/Fallen lassen von Objekten ist verboten</string> - <string name="LocationCtrlScriptsTooltip">Skripte sind unzulässig</string> - <string name="LocationCtrlDamageTooltip">Gesundheit</string> - <string name="LocationCtrlAdultIconTooltip">Adult-Region</string> - <string name="LocationCtrlModerateIconTooltip">Moderate Region</string> - <string name="LocationCtrlGeneralIconTooltip">Generelle Region</string> - <string name="LocationCtrlSeeAVsTooltip">Avatare in dieser Parzelle können von Avataren außerhalb dieser Parzelle weder gesehen noch gehört werden</string> - <string name="LocationCtrlPathfindingDirtyTooltip">Bewegliche Objekte verhalten sich in dieser Region u. U. erst dann korrekt, wenn die Region neu geformt wird.</string> - <string name="LocationCtrlPathfindingDisabledTooltip">Dynamisches Pathfinding ist in dieser Region nicht aktiviert.</string> - <string name="UpdaterWindowTitle">[APP_NAME] Aktualisierung</string> - <string name="UpdaterNowUpdating">[APP_NAME] wird aktualisiert...</string> - <string name="UpdaterNowInstalling">[APP_NAME] wird installiert...</string> - <string name="UpdaterUpdatingDescriptive">Ihr [APP_NAME]-Viewer wird aktualisiert. Dies kann einen Moment dauern. Wir bitten um Ihr Verständnis.</string> - <string name="UpdaterProgressBarTextWithEllipses">Aktualisierung wird heruntergeladen...</string> - <string name="UpdaterProgressBarText">Aktualisierung wird heruntergeladen</string> - <string name="UpdaterFailDownloadTitle">Herunterladen ist fehlgeschlagen</string> - <string name="UpdaterFailUpdateDescriptive">Beim Aktualisieren von [APP_NAME] ist ein Fehler aufgetreten. Bitte laden Sie die aktuellste Version von www.secondlife.com herunter.</string> - <string name="UpdaterFailInstallTitle">Aktualisierung konnte nicht installiert werden</string> - <string name="UpdaterFailStartTitle">Viewer konnte nicht gestartet werden</string> - <string name="ItemsComingInTooFastFrom">[APP_NAME]: Zuviele Objekte auf einmal von [FROM_NAME]. Automaitsche Vorschau ist für [TIME] Sekunden nicht verfügbar.</string> - <string name="ItemsComingInTooFast">[APP_NAME]: Zuviele Objekte auf einmal. Automaitsche Vorschau ist für [TIME] Sekunden nicht verfügbar.</string> - <string name="IM_logging_string">-- Instant-Message-Protokoll aktiviert --</string> - <string name="IM_typing_start_string">[NAME] tippt...</string> - <string name="Unnamed">(Nicht benannt)</string> - <string name="IM_moderated_chat_label">(Moderiert: Stimmen in der Standardeinstellung stummgeschaltet)</string> - <string name="IM_unavailable_text_label">Für diese Verbindung ist kein Text-Chat verfügbar.</string> - <string name="IM_muted_text_label">Ihr Text-Chat wurde von einem Gruppenmoderator deaktiviert.</string> - <string name="IM_default_text_label">Für Instant Message hier klicken.</string> - <string name="IM_to_label">An</string> - <string name="IM_moderator_label">(Moderator)</string> - <string name="Saved_message">(Gespeichert am [LONG_TIMESTAMP])</string> - <string name="IM_unblock_only_groups_friends">Wenn Sie diese Meldung sehen, müssen Sie unter „Einstellungen“ > „Privatsphäre“ die Option „Nur IMs und Anrufe von Freunden oder Gruppen durchstellen“ deaktivieren.</string> - <string name="OnlineStatus">Online</string> - <string name="OfflineStatus">Offline</string> - <string name="not_online_msg">Benutzer nicht online – Nachricht wird gespeichert und später zugestellt.</string> - <string name="not_online_inventory">Benutzer nicht online – Inventar gespeichert.</string> - <string name="answered_call">Ihr Anruf wurde entgegengenommen</string> - <string name="you_started_call">Sie haben einen Voice-Anruf begonnen</string> - <string name="you_joined_call">Sie sind dem Gespräch beigetreten</string> - <string name="you_auto_rejected_call-im">Sie haben den Voice-Anruf automatisch abgelehnt, während der Nicht-stören-Modus aktiviert war.</string> - <string name="name_started_call">[NAME] hat einen Voice-Anruf begonnen</string> - <string name="ringing-im">Verbindung wird hergestellt...</string> - <string name="connected-im">Verbunden. Klicken Sie auf Anruf beenden, um die Verbindung zu trennen</string> - <string name="hang_up-im">Anruf wurde beendet</string> - <string name="answering-im">Wird verbunden...</string> - <string name="conference-title">Chat mit mehreren Personen</string> - <string name="conference-title-incoming">Konferenz mit [AGENT_NAME]</string> - <string name="inventory_item_offered-im">Inventarobjekt „[ITEM_NAME]“ angeboten</string> - <string name="inventory_folder_offered-im">Inventarordner „[ITEM_NAME]“ angeboten</string> - <string name="share_alert">Objekte aus dem Inventar hier her ziehen</string> - <string name="facebook_post_success">Sie haben auf Facebook gepostet.</string> - <string name="flickr_post_success">Sie haben auf Flickr gepostet.</string> - <string name="twitter_post_success">Sie haben auf Twitter gepostet.</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> - <string name="offline_message">[NAME] ist offline.</string> - <string name="invite_message">Klicken Sie auf [BUTTON NAME], um eine Verbindung zu diesem Voice-Chat herzustellen.</string> - <string name="muted_message">Sie haben diesen Einwohner ignoriert. Wenn Sie eine Nachricht senden, wird dieser freigeschaltet.</string> - <string name="generic">Fehler bei Anfrage, bitte versuchen Sie es später.</string> - <string name="generic_request_error">Fehler bei Anfrage, bitte versuchen Sie es später.</string> - <string name="insufficient_perms_error">Sie sind dazu nicht berechtigt.</string> - <string name="session_does_not_exist_error">Die Sitzung ist abgelaufen</string> - <string name="no_ability_error">Sie besitzen diese Fähigkeit nicht.</string> - <string name="no_ability">Sie besitzen diese Fähigkeit nicht.</string> - <string name="not_a_mod_error">Sie sind kein Sitzungsmoderator.</string> - <string name="muted">Ein Gruppenmoderator hat Ihren Text-Chat deaktiviert.</string> - <string name="muted_error">Ein Gruppenmoderator hat Ihren Text-Chat deaktiviert.</string> - <string name="add_session_event">Es konnten keine Benutzer zur Chat-Sitzung mit [RECIPIENT] hinzugefügt werden.</string> - <string name="message">Ihre Nachricht konnte nicht an die Chat-Sitzung mit [RECIPIENT] gesendet werden.</string> - <string name="message_session_event">Ihre Nachricht konnte nicht an die Chat-Sitzung mit [RECIPIENT] gesendet werden.</string> - <string name="mute">Fehler während Moderation.</string> - <string name="removed">Sie wurden von der Gruppe ausgeschlossen.</string> - <string name="removed_from_group">Sie wurden von der Gruppe ausgeschlossen.</string> - <string name="close_on_no_ability">Sie haben nicht mehr die Berechtigung an der Chat-Sitzung teilzunehmen.</string> - <string name="unread_chat_single">[SOURCES] hat etwas Neues gesagt</string> - <string name="unread_chat_multiple">[SOURCES] haben etwas Neues gesagt</string> - <string name="session_initialization_timed_out_error">Die Initialisierung der Sitzung ist fehlgeschlagen</string> - <string name="Home position set.">Position für Zuhause festgelegt.</string> - <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string> - <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string> - <string name="paid_you_ldollars">[NAME] hat Ihnen [REASON] [AMOUNT] L$ bezahlt.</string> - <string name="paid_you_ldollars_gift">[NAME] hat Ihnen [AMOUNT] L$ bezahlt: [REASON]</string> - <string name="paid_you_ldollars_no_reason">[NAME] hat Ihnen [AMOUNT] L$ bezahlt.</string> - <string name="you_paid_ldollars">Sie haben [REASON] [AMOUNT] L$ an [NAME] bezahlt.</string> - <string name="you_paid_ldollars_gift">Sie haben [NAME] [AMOUNT] L$ bezahlt: [REASON]</string> - <string name="you_paid_ldollars_no_info">Sie haben [AMOUNT] L$ bezahlt.</string> - <string name="you_paid_ldollars_no_reason">Sie haben [AMOUNT] L$ an [NAME] bezahlt.</string> - <string name="you_paid_ldollars_no_name">Sie haben [REASON] [AMOUNT] L$ bezahlt.</string> - <string name="you_paid_failure_ldollars">Sie haben [NAME] [AMOUNT] L$ [REASON] nicht bezahlt.</string> - <string name="you_paid_failure_ldollars_gift">Sie haben [NAME] [AMOUNT] L$ nicht bezahlt: [REASON]</string> - <string name="you_paid_failure_ldollars_no_info">Sie haben [AMOUNT] L$ nicht bezahlt.</string> - <string name="you_paid_failure_ldollars_no_reason">Sie haben [NAME] [AMOUNT] L$ nicht bezahlt.</string> - <string name="you_paid_failure_ldollars_no_name">Sie haben [AMOUNT] L$ [REASON] nicht bezahlt.</string> - <string name="for item">für [ITEM]</string> - <string name="for a parcel of land">für eine Landparzelle</string> - <string name="for a land access pass">für einen Pass</string> - <string name="for deeding land">für die Landübertragung</string> - <string name="to create a group">für die Gründung einer Gruppe</string> - <string name="to join a group">für den Beitritt zur Gruppe</string> - <string name="to upload">fürs Hochladen</string> - <string name="to publish a classified ad">um eine Anzeige aufzugeben</string> - <string name="giving">[AMOUNT] L$ werden bezahlt</string> - <string name="uploading_costs">Kosten für Hochladen [AMOUNT] L$</string> - <string name="this_costs">Kosten: [AMOUNT] L$</string> - <string name="buying_selected_land">Ausgewähltes Land wird für [AMOUNT] L$ gekauft.</string> - <string name="this_object_costs">Dieses Objekt kostet [AMOUNT] L$</string> - <string name="group_role_everyone">Jeder</string> - <string name="group_role_officers">Offiziere</string> - <string name="group_role_owners">Eigentümer</string> - <string name="group_member_status_online">Online</string> - <string name="uploading_abuse_report">Hochladen... +Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE]. + </string> + <string name="5 O'Clock Shadow"> + Bartschatten + </string> + <string name="All White"> + Ganz weiß + </string> + <string name="Anime Eyes"> + Anime-Augen + </string> + <string name="Arced"> + Gewölbt + </string> + <string name="Arm Length"> + Armlänge + </string> + <string name="Attached"> + Angewachsen + </string> + <string name="Attached Earlobes"> + Angewachsene Ohrläppchen + </string> + <string name="Back Fringe"> + Nackenfransen + </string> + <string name="Baggy"> + Tränensäcke + </string> + <string name="Bangs"> + Pony + </string> + <string name="Beady Eyes"> + Knopfaugen + </string> + <string name="Belly Size"> + Bauchgröße + </string> + <string name="Big"> + Groß + </string> + <string name="Big Butt"> + Großer Hintern + </string> + <string name="Big Hair Back"> + Volumen: Hinten + </string> + <string name="Big Hair Front"> + Volumen: Vorne + </string> + <string name="Big Hair Top"> + Volumen: Oben + </string> + <string name="Big Head"> + Groß + </string> + <string name="Big Pectorals"> + Große Brustmuskeln + </string> + <string name="Big Spikes"> + Große Stacheln + </string> + <string name="Black"> + Schwarz + </string> + <string name="Blonde"> + Blond + </string> + <string name="Blonde Hair"> + Blondes Haar + </string> + <string name="Blush"> + Rouge + </string> + <string name="Blush Color"> + Rougefarbe + </string> + <string name="Blush Opacity"> + Rouge Deckkraft + </string> + <string name="Body Definition"> + Körperkonturen + </string> + <string name="Body Fat"> + Körperfett + </string> + <string name="Body Freckles"> + Sommersprossen + </string> + <string name="Body Thick"> + breit + </string> + <string name="Body Thickness"> + Körperbreite + </string> + <string name="Body Thin"> + schmal + </string> + <string name="Bow Legged"> + o-beinig + </string> + <string name="Breast Buoyancy"> + Brust, Straffheit + </string> + <string name="Breast Cleavage"> + Dekolleté + </string> + <string name="Breast Size"> + Brustgröße + </string> + <string name="Bridge Width"> + Rückenbreite + </string> + <string name="Broad"> + Breit + </string> + <string name="Brow Size"> + Brauengröße + </string> + <string name="Bug Eyes"> + Glubschaugen + </string> + <string name="Bugged Eyes"> + Hervortretend + </string> + <string name="Bulbous"> + Knollennase + </string> + <string name="Bulbous Nose"> + Knollennase + </string> + <string name="Breast Physics Mass"> + Brust – Masse + </string> + <string name="Breast Physics Smoothing"> + Brust – Glättung + </string> + <string name="Breast Physics Gravity"> + Brust – Schwerkraft + </string> + <string name="Breast Physics Drag"> + Brust – Luftwiderstand + </string> + <string name="Breast Physics InOut Max Effect"> + Max. Effekt + </string> + <string name="Breast Physics InOut Spring"> + Federn + </string> + <string name="Breast Physics InOut Gain"> + Verstärkung + </string> + <string name="Breast Physics InOut Damping"> + Dämpfung + </string> + <string name="Breast Physics UpDown Max Effect"> + Max. Effekt + </string> + <string name="Breast Physics UpDown Spring"> + Federn + </string> + <string name="Breast Physics UpDown Gain"> + Verstärkung + </string> + <string name="Breast Physics UpDown Damping"> + Dämpfung + </string> + <string name="Breast Physics LeftRight Max Effect"> + Max. Effekt + </string> + <string name="Breast Physics LeftRight Spring"> + Federn + </string> + <string name="Breast Physics LeftRight Gain"> + Verstärkung + </string> + <string name="Breast Physics LeftRight Damping"> + Dämpfung + </string> + <string name="Belly Physics Mass"> + Bauch – Masse + </string> + <string name="Belly Physics Smoothing"> + Bauch – Glättung + </string> + <string name="Belly Physics Gravity"> + Bauch – Schwerkraft + </string> + <string name="Belly Physics Drag"> + Bauch – Luftwiderstand + </string> + <string name="Belly Physics UpDown Max Effect"> + Max. Effekt + </string> + <string name="Belly Physics UpDown Spring"> + Federn + </string> + <string name="Belly Physics UpDown Gain"> + Verstärkung + </string> + <string name="Belly Physics UpDown Damping"> + Dämpfung + </string> + <string name="Butt Physics Mass"> + Po – Masse + </string> + <string name="Butt Physics Smoothing"> + Po – Glättung + </string> + <string name="Butt Physics Gravity"> + Po – Schwerkraft + </string> + <string name="Butt Physics Drag"> + Po – Luftwiderstand + </string> + <string name="Butt Physics UpDown Max Effect"> + Max. Effekt + </string> + <string name="Butt Physics UpDown Spring"> + Federn + </string> + <string name="Butt Physics UpDown Gain"> + Verstärkung + </string> + <string name="Butt Physics UpDown Damping"> + Dämpfung + </string> + <string name="Butt Physics LeftRight Max Effect"> + Max. Effekt + </string> + <string name="Butt Physics LeftRight Spring"> + Federn + </string> + <string name="Butt Physics LeftRight Gain"> + Verstärkung + </string> + <string name="Butt Physics LeftRight Damping"> + Dämpfung + </string> + <string name="Bushy Eyebrows"> + Buschige Augenbrauen + </string> + <string name="Bushy Hair"> + Buschiges Haar + </string> + <string name="Butt Size"> + Hintern, Größe + </string> + <string name="Butt Gravity"> + Po – Schwerkraft + </string> + <string name="bustle skirt"> + Tournürenrock + </string> + <string name="no bustle"> + Ohne + </string> + <string name="more bustle"> + Mit + </string> + <string name="Chaplin"> + Chaplin + </string> + <string name="Cheek Bones"> + Wangenknochen + </string> + <string name="Chest Size"> + Brustgröße + </string> + <string name="Chin Angle"> + Kinnwinkel + </string> + <string name="Chin Cleft"> + Kinnspalte + </string> + <string name="Chin Curtains"> + Schifferfräse + </string> + <string name="Chin Depth"> + Kinnlänge + </string> + <string name="Chin Heavy"> + Kinn ausgeprägt + </string> + <string name="Chin In"> + Kinn zurück + </string> + <string name="Chin Out"> + Kinn nach vorne + </string> + <string name="Chin-Neck"> + Kinn-Hals + </string> + <string name="Clear"> + Transparent + </string> + <string name="Cleft"> + Spalte + </string> + <string name="Close Set Eyes"> + Eng stehende Augen + </string> + <string name="Closed"> + Geschlossen + </string> + <string name="Closed Back"> + Hinten geschlossen + </string> + <string name="Closed Front"> + Vorne geschlossen + </string> + <string name="Closed Left"> + Links geschlossen + </string> + <string name="Closed Right"> + Rechts geschlossen + </string> + <string name="Coin Purse"> + Klein + </string> + <string name="Collar Back"> + Kragen hinten + </string> + <string name="Collar Front"> + Kragen vorne + </string> + <string name="Corner Down"> + Nach unten + </string> + <string name="Corner Up"> + Nach oben + </string> + <string name="Creased"> + Schlupflid + </string> + <string name="Crooked Nose"> + Krumme Nase + </string> + <string name="Cuff Flare"> + Hosenaufschlag + </string> + <string name="Dark"> + Dunkel + </string> + <string name="Dark Green"> + Dunkelgrün + </string> + <string name="Darker"> + Dunkler + </string> + <string name="Deep"> + Tief + </string> + <string name="Default Heels"> + Standardabsätze + </string> + <string name="Dense"> + Dicht + </string> + <string name="Double Chin"> + Doppelkinn + </string> + <string name="Downturned"> + Nach unten + </string> + <string name="Duffle Bag"> + Groß + </string> + <string name="Ear Angle"> + Ohrenwinkel + </string> + <string name="Ear Size"> + Ohrengröße + </string> + <string name="Ear Tips"> + Ohrenspitzen + </string> + <string name="Egg Head"> + Eierkopf + </string> + <string name="Eye Bags"> + Augenränder + </string> + <string name="Eye Color"> + Augenfarbe + </string> + <string name="Eye Depth"> + Augentiefe + </string> + <string name="Eye Lightness"> + Helligkeit + </string> + <string name="Eye Opening"> + Öffnung + </string> + <string name="Eye Pop"> + Symmetrie + </string> + <string name="Eye Size"> + Augengröße + </string> + <string name="Eye Spacing"> + Augenstand + </string> + <string name="Eyebrow Arc"> + Brauenbogen + </string> + <string name="Eyebrow Density"> + Brauendichte + </string> + <string name="Eyebrow Height"> + Brauenhöhe + </string> + <string name="Eyebrow Points"> + Brauenenden + </string> + <string name="Eyebrow Size"> + Brauengröße + </string> + <string name="Eyelash Length"> + Wimpernlänge + </string> + <string name="Eyeliner"> + Eyeliner + </string> + <string name="Eyeliner Color"> + Farbe des Eyeliners + </string> + <string name="Eyes Bugged"> + Glubschaugen + </string> + <string name="Face Shear"> + Gesichtsverzerrung + </string> + <string name="Facial Definition"> + Gesichtskonturen + </string> + <string name="Far Set Eyes"> + Weit auseinander + </string> + <string name="Fat Lips"> + Volle Lippen + </string> + <string name="Female"> + weiblich + </string> + <string name="Fingerless"> + Ohne Finger + </string> + <string name="Fingers"> + Finger + </string> + <string name="Flared Cuffs"> + Ausgestellt + </string> + <string name="Flat"> + Flach + </string> + <string name="Flat Butt"> + Flacher Hintern + </string> + <string name="Flat Head"> + Flacher Kopf + </string> + <string name="Flat Toe"> + Flache Spitze + </string> + <string name="Foot Size"> + Fußgröße + </string> + <string name="Forehead Angle"> + Stirnwinkel + </string> + <string name="Forehead Heavy"> + Stirn ausgeprägt + </string> + <string name="Freckles"> + Sommersprossen + </string> + <string name="Front Fringe"> + Fransen, vorne + </string> + <string name="Full Back"> + Hinten volles Haar + </string> + <string name="Full Eyeliner"> + Starker Eyeliner + </string> + <string name="Full Front"> + Vorne volles Haar + </string> + <string name="Full Hair Sides"> + Seitlich volles Haar + </string> + <string name="Full Sides"> + Volle Seiten + </string> + <string name="Glossy"> + Glänzend + </string> + <string name="Glove Fingers"> + Handschuhfinger + </string> + <string name="Glove Length"> + Handschuhlänge + </string> + <string name="Hair"> + Haare + </string> + <string name="Hair Back"> + Haare: Hinten + </string> + <string name="Hair Front"> + Haare: Vorne + </string> + <string name="Hair Sides"> + Haare: Seiten + </string> + <string name="Hair Sweep"> + Haartolle + </string> + <string name="Hair Thickess"> + Haardicke + </string> + <string name="Hair Thickness"> + Haardicke + </string> + <string name="Hair Tilt"> + Haarneigung + </string> + <string name="Hair Tilted Left"> + Nach links + </string> + <string name="Hair Tilted Right"> + Nach rechts + </string> + <string name="Hair Volume"> + Haare: Volumen + </string> + <string name="Hand Size"> + Handgröße + </string> + <string name="Handlebars"> + Zwirbelbart + </string> + <string name="Head Length"> + Kopflänge + </string> + <string name="Head Shape"> + Kopfform + </string> + <string name="Head Size"> + Kopfgröße + </string> + <string name="Head Stretch"> + Kopfstreckung + </string> + <string name="Heel Height"> + Absatzhöhe + </string> + <string name="Heel Shape"> + Absatzform + </string> + <string name="Height"> + Größe + </string> + <string name="High"> + Hoch + </string> + <string name="High Heels"> + Hohe Absätze + </string> + <string name="High Jaw"> + Hoch + </string> + <string name="High Platforms"> + Hohe Plattformsohlen + </string> + <string name="High and Tight"> + Hoch und eng + </string> + <string name="Higher"> + Höhere + </string> + <string name="Hip Length"> + Länge der Hüfte + </string> + <string name="Hip Width"> + Breite der Hüfte + </string> + <string name="Hover"> + Schweben + </string> + <string name="In"> + In + </string> + <string name="In Shdw Color"> + Farbe Innenseite + </string> + <string name="In Shdw Opacity"> + Deckkraft: innen + </string> + <string name="Inner Eye Corner"> + Ecke: Nasenseite + </string> + <string name="Inner Eye Shadow"> + Innenlid + </string> + <string name="Inner Shadow"> + Innenlid + </string> + <string name="Jacket Length"> + Jackenlänge + </string> + <string name="Jacket Wrinkles"> + Jackenfalten + </string> + <string name="Jaw Angle"> + Kinnansatz + </string> + <string name="Jaw Jut"> + Kinnposition + </string> + <string name="Jaw Shape"> + Kinnform + </string> + <string name="Join"> + Zusammen + </string> + <string name="Jowls"> + Hängebacken + </string> + <string name="Knee Angle"> + Kniewinkel + </string> + <string name="Knock Kneed"> + X-beinig + </string> + <string name="Large"> + Groß + </string> + <string name="Large Hands"> + Große Hände + </string> + <string name="Left Part"> + Linksscheitel + </string> + <string name="Leg Length"> + Beinlänge + </string> + <string name="Leg Muscles"> + Beinmuskeln + </string> + <string name="Less"> + Weniger + </string> + <string name="Less Body Fat"> + Weniger Speck + </string> + <string name="Less Curtains"> + Weniger + </string> + <string name="Less Freckles"> + Weniger + </string> + <string name="Less Full"> + Weniger + </string> + <string name="Less Gravity"> + Weniger + </string> + <string name="Less Love"> + Weniger + </string> + <string name="Less Muscles"> + Weniger + </string> + <string name="Less Muscular"> + Weniger + </string> + <string name="Less Rosy"> + Weniger + </string> + <string name="Less Round"> + Weniger + </string> + <string name="Less Saddle"> + Weniger + </string> + <string name="Less Square"> + Weniger + </string> + <string name="Less Volume"> + Weniger + </string> + <string name="Less soul"> + Weniger + </string> + <string name="Lighter"> + Heller + </string> + <string name="Lip Cleft"> + Amorbogen + </string> + <string name="Lip Cleft Depth"> + Tiefe: Amorbogen + </string> + <string name="Lip Fullness"> + Fülle + </string> + <string name="Lip Pinkness"> + Pinkton + </string> + <string name="Lip Ratio"> + Lippenproportionen + </string> + <string name="Lip Thickness"> + Lippendicke + </string> + <string name="Lip Width"> + Mundbreite + </string> + <string name="Lipgloss"> + Lipgloss + </string> + <string name="Lipstick"> + Lippenstift + </string> + <string name="Lipstick Color"> + Farbe + </string> + <string name="Long"> + Lang + </string> + <string name="Long Head"> + Langer Kopf + </string> + <string name="Long Hips"> + Lange Hüften + </string> + <string name="Long Legs"> + Lange Beine + </string> + <string name="Long Neck"> + Langer Hals + </string> + <string name="Long Pigtails"> + Lange Zöpfe + </string> + <string name="Long Ponytail"> + Langer Pferdeschwanz + </string> + <string name="Long Torso"> + Langer Oberkörper + </string> + <string name="Long arms"> + Lange Arme + </string> + <string name="Loose Pants"> + Weite Hosen + </string> + <string name="Loose Shirt"> + Weites Hemd + </string> + <string name="Loose Sleeves"> + Weite Ärmel + </string> + <string name="Love Handles"> + Fettpölsterchen + </string> + <string name="Low"> + Niedrig + </string> + <string name="Low Heels"> + Niedrig + </string> + <string name="Low Jaw"> + Niedrig + </string> + <string name="Low Platforms"> + Niedrig + </string> + <string name="Low and Loose"> + Weit + </string> + <string name="Lower"> + Absenken + </string> + <string name="Lower Bridge"> + Brücke, Unterer Teil + </string> + <string name="Lower Cheeks"> + Wangen, unterer Bereich + </string> + <string name="Male"> + Männlich + </string> + <string name="Middle Part"> + Mittelscheitel + </string> + <string name="More"> + Mehr + </string> + <string name="More Blush"> + Mehr + </string> + <string name="More Body Fat"> + Mehr Speck + </string> + <string name="More Curtains"> + Mehr + </string> + <string name="More Eyeshadow"> + Mehr + </string> + <string name="More Freckles"> + Mehr + </string> + <string name="More Full"> + Voller + </string> + <string name="More Gravity"> + Mehr + </string> + <string name="More Lipstick"> + Mehr + </string> + <string name="More Love"> + Mehr + </string> + <string name="More Lower Lip"> + Größer + </string> + <string name="More Muscles"> + Mehr + </string> + <string name="More Muscular"> + Mehr + </string> + <string name="More Rosy"> + Mehr + </string> + <string name="More Round"> + Runder + </string> + <string name="More Saddle"> + Mehr + </string> + <string name="More Sloped"> + Flach + </string> + <string name="More Square"> + Eckiger + </string> + <string name="More Upper Lip"> + Mehr + </string> + <string name="More Vertical"> + Steil + </string> + <string name="More Volume"> + Mehr + </string> + <string name="More soul"> + Mehr + </string> + <string name="Moustache"> + Schnauzer + </string> + <string name="Mouth Corner"> + Mundwinkel + </string> + <string name="Mouth Position"> + Mundposition + </string> + <string name="Mowhawk"> + Irokese + </string> + <string name="Muscular"> + Muskulös + </string> + <string name="Mutton Chops"> + Koteletten + </string> + <string name="Nail Polish"> + Nagellack + </string> + <string name="Nail Polish Color"> + Farbe + </string> + <string name="Narrow"> + Schmal + </string> + <string name="Narrow Back"> + Wenig + </string> + <string name="Narrow Front"> + Wenig + </string> + <string name="Narrow Lips"> + Schmale Lippen + </string> + <string name="Natural"> + Natürlich + </string> + <string name="Neck Length"> + Halslänge + </string> + <string name="Neck Thickness"> + Halsdicke + </string> + <string name="No Blush"> + Kein Rouge + </string> + <string name="No Eyeliner"> + Kein Eyeliner + </string> + <string name="No Eyeshadow"> + Kein Lidschatten + </string> + <string name="No Lipgloss"> + Kein Lipgloss + </string> + <string name="No Lipstick"> + Kein Lippenstift + </string> + <string name="No Part"> + Kein Scheitel + </string> + <string name="No Polish"> + Kein Nagellack + </string> + <string name="No Red"> + Nicht rot + </string> + <string name="No Spikes"> + Keine Stachel + </string> + <string name="No White"> + Kein Weiß + </string> + <string name="No Wrinkles"> + Keine Falten + </string> + <string name="Normal Lower"> + Normal unten + </string> + <string name="Normal Upper"> + Normal oben + </string> + <string name="Nose Left"> + Links + </string> + <string name="Nose Right"> + Rechts + </string> + <string name="Nose Size"> + Größe + </string> + <string name="Nose Thickness"> + Dicke + </string> + <string name="Nose Tip Angle"> + Nasenspitze + </string> + <string name="Nose Tip Shape"> + Nasenspitze + </string> + <string name="Nose Width"> + Nasenbreite + </string> + <string name="Nostril Division"> + Teilung + </string> + <string name="Nostril Width"> + Größe + </string> + <string name="Opaque"> + Deckend + </string> + <string name="Open"> + Öffnen + </string> + <string name="Open Back"> + Hinten offen + </string> + <string name="Open Front"> + Vorne offen + </string> + <string name="Open Left"> + Links offen + </string> + <string name="Open Right"> + Rechts offen + </string> + <string name="Orange"> + Orange + </string> + <string name="Out"> + Aus + </string> + <string name="Out Shdw Color"> + Farbe: Oben + </string> + <string name="Out Shdw Opacity"> + Deckkraft: Oben + </string> + <string name="Outer Eye Corner"> + Äußerer Augenwinkel + </string> + <string name="Outer Eye Shadow"> + Lidschatten: Oben + </string> + <string name="Outer Shadow"> + Lidschatten: Oben + </string> + <string name="Overbite"> + Überbiss + </string> + <string name="Package"> + Ausbeulung + </string> + <string name="Painted Nails"> + Lackierte Nägel + </string> + <string name="Pale"> + Blass + </string> + <string name="Pants Crotch"> + Schritt + </string> + <string name="Pants Fit"> + Passform + </string> + <string name="Pants Length"> + Hosenlänge + </string> + <string name="Pants Waist"> + Hüfte + </string> + <string name="Pants Wrinkles"> + Falten + </string> + <string name="Part"> + Scheitel + </string> + <string name="Part Bangs"> + Pony scheiteln + </string> + <string name="Pectorals"> + Brustmuskel + </string> + <string name="Pigment"> + Pigmentierung + </string> + <string name="Pigtails"> + Zöpfe + </string> + <string name="Pink"> + Pink + </string> + <string name="Pinker"> + Mehr Pink + </string> + <string name="Platform Height"> + Höhe + </string> + <string name="Platform Width"> + Breite + </string> + <string name="Pointy"> + Spitz + </string> + <string name="Pointy Heels"> + Pfennigabsätze + </string> + <string name="Ponytail"> + Pferdeschwanz + </string> + <string name="Poofy Skirt"> + Weit ausgestellt + </string> + <string name="Pop Left Eye"> + Linkes Auge größer + </string> + <string name="Pop Right Eye"> + Rechtes Auge größer + </string> + <string name="Puffy"> + Geschwollen + </string> + <string name="Puffy Eyelids"> + Geschwollene Lider + </string> + <string name="Rainbow Color"> + Regenbogenfarben + </string> + <string name="Red Hair"> + Rote Haare + </string> + <string name="Regular"> + Normal + </string> + <string name="Right Part"> + Scheitel rechts + </string> + <string name="Rosy Complexion"> + Rosiger Teint + </string> + <string name="Round"> + Rund + </string> + <string name="Ruddiness"> + Röte + </string> + <string name="Ruddy"> + Rötlich + </string> + <string name="Rumpled Hair"> + Zerzauste Haare + </string> + <string name="Saddle Bags"> + Hüftspeck + </string> + <string name="Scrawny Leg"> + Dürres Bein + </string> + <string name="Separate"> + Auseinander + </string> + <string name="Shallow"> + Flach + </string> + <string name="Shear Back"> + Hinterkopf rasiert + </string> + <string name="Shear Face"> + Gesicht verzerren + </string> + <string name="Shear Front"> + Vorne rasiert + </string> + <string name="Shear Left Up"> + Links + </string> + <string name="Shear Right Up"> + Rechts + </string> + <string name="Sheared Back"> + Hinterkopf rasiert + </string> + <string name="Sheared Front"> + Vorne rasiert + </string> + <string name="Shift Left"> + Nach links + </string> + <string name="Shift Mouth"> + Mund verschieben + </string> + <string name="Shift Right"> + Nach rechts + </string> + <string name="Shirt Bottom"> + Hemdlänge + </string> + <string name="Shirt Fit"> + Passform + </string> + <string name="Shirt Wrinkles"> + Falten + </string> + <string name="Shoe Height"> + Schuhart + </string> + <string name="Short"> + Klein + </string> + <string name="Short Arms"> + Kurze Arme + </string> + <string name="Short Legs"> + Kurze Beine + </string> + <string name="Short Neck"> + Kurzer Hals + </string> + <string name="Short Pigtails"> + Kurze Zöpfe + </string> + <string name="Short Ponytail"> + Kurzer Pferdeschwanz + </string> + <string name="Short Sideburns"> + Kurze Koteletten + </string> + <string name="Short Torso"> + Kurzer Oberkörper + </string> + <string name="Short hips"> + Kurze Hüften + </string> + <string name="Shoulders"> + Schultern + </string> + <string name="Side Fringe"> + Seitliche Fransen + </string> + <string name="Sideburns"> + Koteletten + </string> + <string name="Sides Hair"> + Seitliches Haar + </string> + <string name="Sides Hair Down"> + Lang + </string> + <string name="Sides Hair Up"> + Kurz + </string> + <string name="Skinny Neck"> + Dünner Hals + </string> + <string name="Skirt Fit"> + Passform + </string> + <string name="Skirt Length"> + Rocklänge + </string> + <string name="Slanted Forehead"> + Fliehende Stirn + </string> + <string name="Sleeve Length"> + Ärmellänge + </string> + <string name="Sleeve Looseness"> + Passform Ärmel + </string> + <string name="Slit Back"> + Schlitz: Hinten + </string> + <string name="Slit Front"> + Schlitz: Vorne + </string> + <string name="Slit Left"> + Schlitz: Links + </string> + <string name="Slit Right"> + Schlitz: Rechts + </string> + <string name="Small"> + Klein + </string> + <string name="Small Hands"> + Kleine Hände + </string> + <string name="Small Head"> + Klein + </string> + <string name="Smooth"> + Glätten + </string> + <string name="Smooth Hair"> + Glattes Haar + </string> + <string name="Socks Length"> + Strumpflänge + </string> + <string name="Soulpatch"> + Unterlippenbart + </string> + <string name="Sparse"> + Wenig + </string> + <string name="Spiked Hair"> + Stachelhaare + </string> + <string name="Square"> + Rechteck + </string> + <string name="Square Toe"> + Eckig + </string> + <string name="Squash Head"> + Gestaucht + </string> + <string name="Stretch Head"> + Gestreckt + </string> + <string name="Sunken"> + Eingefallen + </string> + <string name="Sunken Chest"> + Trichterbrust + </string> + <string name="Sunken Eyes"> + Eingesunkene Augen + </string> + <string name="Sweep Back"> + Nach hinten + </string> + <string name="Sweep Forward"> + Nach vorne + </string> + <string name="Tall"> + Groß + </string> + <string name="Taper Back"> + Ansatzbreite hinten + </string> + <string name="Taper Front"> + Ansatzbreite vorne + </string> + <string name="Thick Heels"> + Dicke Absätze + </string> + <string name="Thick Neck"> + Dicker Hals + </string> + <string name="Thick Toe"> + Dick + </string> + <string name="Thin"> + Dünn + </string> + <string name="Thin Eyebrows"> + Dünne Augenbrauen + </string> + <string name="Thin Lips"> + Dünne Lippen + </string> + <string name="Thin Nose"> + Dünne Nase + </string> + <string name="Tight Chin"> + Straffes Kinn + </string> + <string name="Tight Cuffs"> + Eng + </string> + <string name="Tight Pants"> + Enge Hosen + </string> + <string name="Tight Shirt"> + Enges Hemd + </string> + <string name="Tight Skirt"> + Enger Rock + </string> + <string name="Tight Sleeves"> + Enge Ärmel + </string> + <string name="Toe Shape"> + Spitze + </string> + <string name="Toe Thickness"> + Dicke + </string> + <string name="Torso Length"> + Länge des Oberkörpers + </string> + <string name="Torso Muscles"> + Muskeln + </string> + <string name="Torso Scrawny"> + Dürr + </string> + <string name="Unattached"> + Frei + </string> + <string name="Uncreased"> + Straffes Lid + </string> + <string name="Underbite"> + Unterbiss + </string> + <string name="Unnatural"> + Unnatürlich + </string> + <string name="Upper Bridge"> + Brücke, oberer Teil + </string> + <string name="Upper Cheeks"> + Obere Wangen + </string> + <string name="Upper Chin Cleft"> + Obere Kinnspalte + </string> + <string name="Upper Eyelid Fold"> + Obere Lidfalte + </string> + <string name="Upturned"> + Stupsnase + </string> + <string name="Very Red"> + Sehr rot + </string> + <string name="Waist Height"> + Bund + </string> + <string name="Well-Fed"> + Gut genährt + </string> + <string name="White Hair"> + Weiße Haare + </string> + <string name="Wide"> + Breit + </string> + <string name="Wide Back"> + Breit + </string> + <string name="Wide Front"> + Breit + </string> + <string name="Wide Lips"> + Breit + </string> + <string name="Wild"> + Wild + </string> + <string name="Wrinkles"> + Falten + </string> + <string name="LocationCtrlAddLandmarkTooltip"> + Zu meinen Landmarken hinzufügen + </string> + <string name="LocationCtrlEditLandmarkTooltip"> + Meine Landmarken bearbeiten + </string> + <string name="LocationCtrlInfoBtnTooltip"> + Weitere Informationen über die aktuelle Position + </string> + <string name="LocationCtrlComboBtnTooltip"> + Mein Reiseverlauf + </string> + <string name="LocationCtrlForSaleTooltip"> + Dieses Land kaufen + </string> + <string name="LocationCtrlVoiceTooltip"> + Voice hier nicht möglich + </string> + <string name="LocationCtrlFlyTooltip"> + Fliegen ist unzulässig + </string> + <string name="LocationCtrlPushTooltip"> + Kein Stoßen + </string> + <string name="LocationCtrlBuildTooltip"> + Bauen/Fallen lassen von Objekten ist verboten + </string> + <string name="LocationCtrlScriptsTooltip"> + Skripte sind unzulässig + </string> + <string name="LocationCtrlDamageTooltip"> + Gesundheit + </string> + <string name="LocationCtrlAdultIconTooltip"> + Adult-Region + </string> + <string name="LocationCtrlModerateIconTooltip"> + Moderate Region + </string> + <string name="LocationCtrlGeneralIconTooltip"> + Generelle Region + </string> + <string name="LocationCtrlSeeAVsTooltip"> + Avatare in dieser Parzelle können von Avataren außerhalb dieser Parzelle weder gesehen noch gehört werden + </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Bewegliche Objekte verhalten sich in dieser Region u. U. erst dann korrekt, wenn die Region neu geformt wird. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Dynamisches Pathfinding ist in dieser Region nicht aktiviert. + </string> + <string name="UpdaterWindowTitle"> + [APP_NAME] Aktualisierung + </string> + <string name="UpdaterNowUpdating"> + [APP_NAME] wird aktualisiert... + </string> + <string name="UpdaterNowInstalling"> + [APP_NAME] wird installiert... + </string> + <string name="UpdaterUpdatingDescriptive"> + Ihr [APP_NAME]-Viewer wird aktualisiert. Dies kann einen Moment dauern. Wir bitten um Ihr Verständnis. + </string> + <string name="UpdaterProgressBarTextWithEllipses"> + Aktualisierung wird heruntergeladen... + </string> + <string name="UpdaterProgressBarText"> + Aktualisierung wird heruntergeladen + </string> + <string name="UpdaterFailDownloadTitle"> + Herunterladen ist fehlgeschlagen + </string> + <string name="UpdaterFailUpdateDescriptive"> + Beim Aktualisieren von [APP_NAME] ist ein Fehler aufgetreten. Bitte laden Sie die aktuellste Version von www.secondlife.com herunter. + </string> + <string name="UpdaterFailInstallTitle"> + Aktualisierung konnte nicht installiert werden + </string> + <string name="UpdaterFailStartTitle"> + Viewer konnte nicht gestartet werden + </string> + <string name="ItemsComingInTooFastFrom"> + [APP_NAME]: Zuviele Objekte auf einmal von [FROM_NAME]. Automaitsche Vorschau ist für [TIME] Sekunden nicht verfügbar. + </string> + <string name="ItemsComingInTooFast"> + [APP_NAME]: Zuviele Objekte auf einmal. Automaitsche Vorschau ist für [TIME] Sekunden nicht verfügbar. + </string> + <string name="IM_logging_string"> + -- Instant-Message-Protokoll aktiviert -- + </string> + <string name="IM_typing_start_string"> + [NAME] tippt... + </string> + <string name="Unnamed"> + (Nicht benannt) + </string> + <string name="IM_moderated_chat_label"> + (Moderiert: Stimmen in der Standardeinstellung stummgeschaltet) + </string> + <string name="IM_unavailable_text_label"> + Für diese Verbindung ist kein Text-Chat verfügbar. + </string> + <string name="IM_muted_text_label"> + Ihr Text-Chat wurde von einem Gruppenmoderator deaktiviert. + </string> + <string name="IM_default_text_label"> + Für Instant Message hier klicken. + </string> + <string name="IM_to_label"> + An + </string> + <string name="IM_moderator_label"> + (Moderator) + </string> + <string name="Saved_message"> + (Gespeichert am [LONG_TIMESTAMP]) + </string> + <string name="IM_unblock_only_groups_friends"> + Wenn Sie diese Meldung sehen, müssen Sie unter „Einstellungen“ > „Privatsphäre“ die Option „Nur IMs und Anrufe von Freunden oder Gruppen durchstellen“ deaktivieren. + </string> + <string name="OnlineStatus"> + Online + </string> + <string name="OfflineStatus"> + Offline + </string> + <string name="not_online_msg"> + Benutzer nicht online – Nachricht wird gespeichert und später zugestellt. + </string> + <string name="not_online_inventory"> + Benutzer nicht online – Inventar gespeichert. + </string> + <string name="answered_call"> + Ihr Anruf wurde entgegengenommen + </string> + <string name="you_started_call"> + Sie haben einen Voice-Anruf begonnen + </string> + <string name="you_joined_call"> + Sie sind dem Gespräch beigetreten + </string> + <string name="you_auto_rejected_call-im"> + Sie haben den Voice-Anruf automatisch abgelehnt, während der Nicht-stören-Modus aktiviert war. + </string> + <string name="name_started_call"> + [NAME] hat einen Voice-Anruf begonnen + </string> + <string name="ringing-im"> + Verbindung wird hergestellt... + </string> + <string name="connected-im"> + Verbunden. Klicken Sie auf Anruf beenden, um die Verbindung zu trennen + </string> + <string name="hang_up-im"> + Anruf wurde beendet + </string> + <string name="answering-im"> + Wird verbunden... + </string> + <string name="conference-title"> + Chat mit mehreren Personen + </string> + <string name="conference-title-incoming"> + Konferenz mit [AGENT_NAME] + </string> + <string name="inventory_item_offered-im"> + Inventarobjekt „[ITEM_NAME]“ angeboten + </string> + <string name="inventory_folder_offered-im"> + Inventarordner „[ITEM_NAME]“ angeboten + </string> + <string name="bot_warning"> + Sie chatten mit einem Bot, [NAME]. Geben Sie keine persönlichen Informationen weiter. +Erfahren Sie mehr unter https://second.life/scripted-agents. + </string> + <string name="share_alert"> + Objekte aus dem Inventar hier her ziehen + </string> + <string name="facebook_post_success"> + Sie haben auf Facebook gepostet. + </string> + <string name="flickr_post_success"> + Sie haben auf Flickr gepostet. + </string> + <string name="twitter_post_success"> + Sie haben auf Twitter gepostet. + </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> + <string name="offline_message"> + [NAME] ist offline. + </string> + <string name="invite_message"> + Klicken Sie auf [BUTTON NAME], um eine Verbindung zu diesem Voice-Chat herzustellen. + </string> + <string name="muted_message"> + Sie haben diesen Einwohner ignoriert. Wenn Sie eine Nachricht senden, wird dieser freigeschaltet. + </string> + <string name="generic"> + Fehler bei Anfrage, bitte versuchen Sie es später. + </string> + <string name="generic_request_error"> + Fehler bei Anfrage, bitte versuchen Sie es später. + </string> + <string name="insufficient_perms_error"> + Sie sind dazu nicht berechtigt. + </string> + <string name="session_does_not_exist_error"> + Die Sitzung ist abgelaufen + </string> + <string name="no_ability_error"> + Sie besitzen diese Fähigkeit nicht. + </string> + <string name="no_ability"> + Sie besitzen diese Fähigkeit nicht. + </string> + <string name="not_a_mod_error"> + Sie sind kein Sitzungsmoderator. + </string> + <string name="muted"> + Ein Gruppenmoderator hat Ihren Text-Chat deaktiviert. + </string> + <string name="muted_error"> + Ein Gruppenmoderator hat Ihren Text-Chat deaktiviert. + </string> + <string name="add_session_event"> + Es konnten keine Benutzer zur Chat-Sitzung mit [RECIPIENT] hinzugefügt werden. + </string> + <string name="message"> + Ihre Nachricht konnte nicht an die Chat-Sitzung mit [RECIPIENT] gesendet werden. + </string> + <string name="message_session_event"> + Ihre Nachricht konnte nicht an die Chat-Sitzung mit [RECIPIENT] gesendet werden. + </string> + <string name="mute"> + Fehler während Moderation. + </string> + <string name="removed"> + Sie wurden von der Gruppe ausgeschlossen. + </string> + <string name="removed_from_group"> + Sie wurden von der Gruppe ausgeschlossen. + </string> + <string name="close_on_no_ability"> + Sie haben nicht mehr die Berechtigung an der Chat-Sitzung teilzunehmen. + </string> + <string name="unread_chat_single"> + [SOURCES] hat etwas Neues gesagt + </string> + <string name="unread_chat_multiple"> + [SOURCES] haben etwas Neues gesagt + </string> + <string name="session_initialization_timed_out_error"> + Die Initialisierung der Sitzung ist fehlgeschlagen + </string> + <string name="Home position set."> + Position für Zuhause festgelegt. + </string> + <string name="voice_morphing_url"> + https://secondlife.com/destination/voice-island + </string> + <string name="premium_voice_morphing_url"> + https://secondlife.com/destination/voice-morphing-premium + </string> + <string name="paid_you_ldollars"> + [NAME] hat Ihnen [REASON] [AMOUNT] L$ bezahlt. + </string> + <string name="paid_you_ldollars_gift"> + [NAME] hat Ihnen [AMOUNT] L$ bezahlt: [REASON] + </string> + <string name="paid_you_ldollars_no_reason"> + [NAME] hat Ihnen [AMOUNT] L$ bezahlt. + </string> + <string name="you_paid_ldollars"> + Sie haben [REASON] [AMOUNT] L$ an [NAME] bezahlt. + </string> + <string name="you_paid_ldollars_gift"> + Sie haben [NAME] [AMOUNT] L$ bezahlt: [REASON] + </string> + <string name="you_paid_ldollars_no_info"> + Sie haben [AMOUNT] L$ bezahlt. + </string> + <string name="you_paid_ldollars_no_reason"> + Sie haben [AMOUNT] L$ an [NAME] bezahlt. + </string> + <string name="you_paid_ldollars_no_name"> + Sie haben [REASON] [AMOUNT] L$ bezahlt. + </string> + <string name="you_paid_failure_ldollars"> + Sie haben [NAME] [AMOUNT] L$ [REASON] nicht bezahlt. + </string> + <string name="you_paid_failure_ldollars_gift"> + Sie haben [NAME] [AMOUNT] L$ nicht bezahlt: [REASON] + </string> + <string name="you_paid_failure_ldollars_no_info"> + Sie haben [AMOUNT] L$ nicht bezahlt. + </string> + <string name="you_paid_failure_ldollars_no_reason"> + Sie haben [NAME] [AMOUNT] L$ nicht bezahlt. + </string> + <string name="you_paid_failure_ldollars_no_name"> + Sie haben [AMOUNT] L$ [REASON] nicht bezahlt. + </string> + <string name="for item"> + für [ITEM] + </string> + <string name="for a parcel of land"> + für eine Landparzelle + </string> + <string name="for a land access pass"> + für einen Pass + </string> + <string name="for deeding land"> + für die Landübertragung + </string> + <string name="to create a group"> + für die Gründung einer Gruppe + </string> + <string name="to join a group"> + für den Beitritt zur Gruppe + </string> + <string name="to upload"> + fürs Hochladen + </string> + <string name="to publish a classified ad"> + um eine Anzeige aufzugeben + </string> + <string name="giving"> + [AMOUNT] L$ werden bezahlt + </string> + <string name="uploading_costs"> + Kosten für Hochladen [AMOUNT] L$ + </string> + <string name="this_costs"> + Kosten: [AMOUNT] L$ + </string> + <string name="buying_selected_land"> + Ausgewähltes Land wird für [AMOUNT] L$ gekauft. + </string> + <string name="this_object_costs"> + Dieses Objekt kostet [AMOUNT] L$ + </string> + <string name="group_role_everyone"> + Jeder + </string> + <string name="group_role_officers"> + Offiziere + </string> + <string name="group_role_owners"> + Eigentümer + </string> + <string name="group_member_status_online"> + Online + </string> + <string name="uploading_abuse_report"> + Hochladen... -Missbrauchsbericht</string> - <string name="New Shape">Neue Form/Gestalt</string> - <string name="New Skin">Neue Haut</string> - <string name="New Hair">Neues Haar</string> - <string name="New Eyes">Neue Augen</string> - <string name="New Shirt">Neues Hemd</string> - <string name="New Pants">Neue Hose</string> - <string name="New Shoes">Neue Schuhe</string> - <string name="New Socks">Neue Socken</string> - <string name="New Jacket">Neue Jacke</string> - <string name="New Gloves">Neue Handschuhe</string> - <string name="New Undershirt">Neues Unterhemd</string> - <string name="New Underpants">Neue Unterhose</string> - <string name="New Skirt">Neuer Rock</string> - <string name="New Alpha">Neues Alpha</string> - <string name="New Tattoo">Neue Tätowierung</string> - <string name="New Universal">Neues Universal</string> - <string name="New Physics">Neue Physik</string> - <string name="Invalid Wearable">Ungültiges Objekt</string> - <string name="New Gesture">Neue Geste</string> - <string name="New Script">Neues Skript</string> - <string name="New Note">Neue Notiz</string> - <string name="New Folder">Neuer Ordner</string> - <string name="Contents">Inhalt</string> - <string name="Gesture">Gesten</string> - <string name="Male Gestures">Männliche Gesten</string> - <string name="Female Gestures">Weibliche Gesten</string> - <string name="Other Gestures">Andere Gesten</string> - <string name="Speech Gestures">Sprachgesten</string> - <string name="Common Gestures">Häufig verwendete Gesten</string> - <string name="Male - Excuse me">Männlich - Excuse me</string> - <string name="Male - Get lost">Männlich - Get lost</string> - <string name="Male - Blow kiss">Männlich - Kusshand</string> - <string name="Male - Boo">Männlich - Buh</string> - <string name="Male - Bored">Männlich - Gelangweilt</string> - <string name="Male - Hey">Männlich - Hey</string> - <string name="Male - Laugh">Männlich - Lachen</string> - <string name="Male - Repulsed">Männlich - Angewidert</string> - <string name="Male - Shrug">Männlich - Achselzucken</string> - <string name="Male - Stick tougue out">Männlich - Zunge herausstrecken</string> - <string name="Male - Wow">Männlich - Wow</string> - <string name="Female - Chuckle">Weiblich - Kichern</string> - <string name="Female - Cry">Weiblich - Weinen</string> - <string name="Female - Embarrassed">Weiblich - Verlegen</string> - <string name="Female - Excuse me">Weiblich - Räuspern</string> - <string name="Female - Get lost">Weiblich - Get lost</string> - <string name="Female - Blow kiss">Weiblich - Kusshand</string> - <string name="Female - Boo">Weiblich - Buh</string> - <string name="Female - Bored">Weiblich - Gelangweilt</string> - <string name="Female - Hey">Weiblich - Hey</string> - <string name="Female - Hey baby">Weiblich - Hey Süße(r)</string> - <string name="Female - Laugh">Weiblich - Lachen</string> - <string name="Female - Looking good">Weiblich - Looking good</string> - <string name="Female - Over here">Weiblich - Over here</string> - <string name="Female - Please">Weiblich - Please</string> - <string name="Female - Repulsed">Weiblich - Angewidert</string> - <string name="Female - Shrug">Weiblich - Achselzucken</string> - <string name="Female - Stick tougue out">Weiblich - Zunge herausstrecken</string> - <string name="Female - Wow">Weiblich - Wow</string> - <string name="New Daycycle">Neuer Tageszyklus</string> - <string name="New Water">Neues Wasser</string> - <string name="New Sky">Neuer Himmel</string> - <string name="/bow">/verbeugen</string> - <string name="/clap">/klatschen</string> - <string name="/count">/zählen</string> - <string name="/extinguish">/löschen</string> - <string name="/kmb">/lmaa</string> - <string name="/muscle">/Muskel</string> - <string name="/no">/nein</string> - <string name="/no!">/nein!</string> - <string name="/paper">/Papier</string> - <string name="/pointme">/auf mich zeigen</string> - <string name="/pointyou">/auf dich zeigen</string> - <string name="/rock">/Stein</string> - <string name="/scissor">/Schere</string> - <string name="/smoke">/rauchen</string> - <string name="/stretch">/dehnen</string> - <string name="/whistle">/pfeifen</string> - <string name="/yes">/ja</string> - <string name="/yes!">/ja!</string> - <string name="afk">afk</string> - <string name="dance1">Tanzen1</string> - <string name="dance2">Tanzen2</string> - <string name="dance3">Tanzen3</string> - <string name="dance4">Tanzen4</string> - <string name="dance5">Tanzen5</string> - <string name="dance6">Tanzen6</string> - <string name="dance7">Tanzen7</string> - <string name="dance8">Tanzen8</string> - <string name="AvatarBirthDateFormat">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string> - <string name="DefaultMimeType">Keine/Keiner</string> - <string name="texture_load_dimensions_error">Bilder, die größer sind als [WIDTH]*[HEIGHT] können nicht geladen werden</string> - <string name="outfit_photo_load_dimensions_error">Max. Fotogröße für Outfit ist [WIDTH]*[HEIGHT]. Bitte verkleinern Sie das Bild oder verwenden Sie ein anderes.</string> - <string name="outfit_photo_select_dimensions_error">Max. Fotogröße für Outfit ist [WIDTH]*[HEIGHT]. Bitte wählen Sie eine andere Textur aus.</string> - <string name="outfit_photo_verify_dimensions_error">Fotoabmessungen können nicht bestätigt werden. Bitte warten Sie, bis die Fotogröße im Auswahlfenster angezeigt wird.</string> +Missbrauchsbericht + </string> + <string name="New Shape"> + Neue Form/Gestalt + </string> + <string name="New Skin"> + Neue Haut + </string> + <string name="New Hair"> + Neues Haar + </string> + <string name="New Eyes"> + Neue Augen + </string> + <string name="New Shirt"> + Neues Hemd + </string> + <string name="New Pants"> + Neue Hose + </string> + <string name="New Shoes"> + Neue Schuhe + </string> + <string name="New Socks"> + Neue Socken + </string> + <string name="New Jacket"> + Neue Jacke + </string> + <string name="New Gloves"> + Neue Handschuhe + </string> + <string name="New Undershirt"> + Neues Unterhemd + </string> + <string name="New Underpants"> + Neue Unterhose + </string> + <string name="New Skirt"> + Neuer Rock + </string> + <string name="New Alpha"> + Neues Alpha + </string> + <string name="New Tattoo"> + Neue Tätowierung + </string> + <string name="New Universal"> + Neues Universal + </string> + <string name="New Physics"> + Neue Physik + </string> + <string name="Invalid Wearable"> + Ungültiges Objekt + </string> + <string name="New Gesture"> + Neue Geste + </string> + <string name="New Script"> + Neues Skript + </string> + <string name="New Note"> + Neue Notiz + </string> + <string name="New Folder"> + Neuer Ordner + </string> + <string name="Contents"> + Inhalt + </string> + <string name="Gesture"> + Gesten + </string> + <string name="Male Gestures"> + Männliche Gesten + </string> + <string name="Female Gestures"> + Weibliche Gesten + </string> + <string name="Other Gestures"> + Andere Gesten + </string> + <string name="Speech Gestures"> + Sprachgesten + </string> + <string name="Common Gestures"> + Häufig verwendete Gesten + </string> + <string name="Male - Excuse me"> + Männlich - Excuse me + </string> + <string name="Male - Get lost"> + Männlich - Get lost + </string> + <string name="Male - Blow kiss"> + Männlich - Kusshand + </string> + <string name="Male - Boo"> + Männlich - Buh + </string> + <string name="Male - Bored"> + Männlich - Gelangweilt + </string> + <string name="Male - Hey"> + Männlich - Hey + </string> + <string name="Male - Laugh"> + Männlich - Lachen + </string> + <string name="Male - Repulsed"> + Männlich - Angewidert + </string> + <string name="Male - Shrug"> + Männlich - Achselzucken + </string> + <string name="Male - Stick tougue out"> + Männlich - Zunge herausstrecken + </string> + <string name="Male - Wow"> + Männlich - Wow + </string> + <string name="Female - Chuckle"> + Weiblich - Kichern + </string> + <string name="Female - Cry"> + Weiblich - Weinen + </string> + <string name="Female - Embarrassed"> + Weiblich - Verlegen + </string> + <string name="Female - Excuse me"> + Weiblich - Räuspern + </string> + <string name="Female - Get lost"> + Weiblich - Get lost + </string> + <string name="Female - Blow kiss"> + Weiblich - Kusshand + </string> + <string name="Female - Boo"> + Weiblich - Buh + </string> + <string name="Female - Bored"> + Weiblich - Gelangweilt + </string> + <string name="Female - Hey"> + Weiblich - Hey + </string> + <string name="Female - Hey baby"> + Weiblich - Hey Süße(r) + </string> + <string name="Female - Laugh"> + Weiblich - Lachen + </string> + <string name="Female - Looking good"> + Weiblich - Looking good + </string> + <string name="Female - Over here"> + Weiblich - Over here + </string> + <string name="Female - Please"> + Weiblich - Please + </string> + <string name="Female - Repulsed"> + Weiblich - Angewidert + </string> + <string name="Female - Shrug"> + Weiblich - Achselzucken + </string> + <string name="Female - Stick tougue out"> + Weiblich - Zunge herausstrecken + </string> + <string name="Female - Wow"> + Weiblich - Wow + </string> + <string name="New Daycycle"> + Neuer Tageszyklus + </string> + <string name="New Water"> + Neues Wasser + </string> + <string name="New Sky"> + Neuer Himmel + </string> + <string name="/bow"> + /verbeugen + </string> + <string name="/clap"> + /klatschen + </string> + <string name="/count"> + /zählen + </string> + <string name="/extinguish"> + /löschen + </string> + <string name="/kmb"> + /lmaa + </string> + <string name="/muscle"> + /Muskel + </string> + <string name="/no"> + /nein + </string> + <string name="/no!"> + /nein! + </string> + <string name="/paper"> + /Papier + </string> + <string name="/pointme"> + /auf mich zeigen + </string> + <string name="/pointyou"> + /auf dich zeigen + </string> + <string name="/rock"> + /Stein + </string> + <string name="/scissor"> + /Schere + </string> + <string name="/smoke"> + /rauchen + </string> + <string name="/stretch"> + /dehnen + </string> + <string name="/whistle"> + /pfeifen + </string> + <string name="/yes"> + /ja + </string> + <string name="/yes!"> + /ja! + </string> + <string name="afk"> + afk + </string> + <string name="dance1"> + Tanzen1 + </string> + <string name="dance2"> + Tanzen2 + </string> + <string name="dance3"> + Tanzen3 + </string> + <string name="dance4"> + Tanzen4 + </string> + <string name="dance5"> + Tanzen5 + </string> + <string name="dance6"> + Tanzen6 + </string> + <string name="dance7"> + Tanzen7 + </string> + <string name="dance8"> + Tanzen8 + </string> + <string name="AvatarBirthDateFormat"> + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] + </string> + <string name="DefaultMimeType"> + Keine/Keiner + </string> + <string name="texture_load_dimensions_error"> + Bilder, die größer sind als [WIDTH]*[HEIGHT] können nicht geladen werden + </string> + <string name="outfit_photo_load_dimensions_error"> + Max. Fotogröße für Outfit ist [WIDTH]*[HEIGHT]. Bitte verkleinern Sie das Bild oder verwenden Sie ein anderes. + </string> + <string name="outfit_photo_select_dimensions_error"> + Max. Fotogröße für Outfit ist [WIDTH]*[HEIGHT]. Bitte wählen Sie eine andere Textur aus. + </string> + <string name="outfit_photo_verify_dimensions_error"> + Fotoabmessungen können nicht bestätigt werden. Bitte warten Sie, bis die Fotogröße im Auswahlfenster angezeigt wird. + </string> <string name="words_separator" value=","/> - <string name="server_is_down">Trotz all unserer Bemühungen ist ein unerwarteter Fehler aufgetreten. + <string name="server_is_down"> + Trotz all unserer Bemühungen ist ein unerwarteter Fehler aufgetreten. Bitte überprüfen Sie http://status.secondlifegrid.net, um herauszufinden, ob ein Problem mit dem Service vorliegt. - Falls Sie weiterhin Problem haben, überprüfen Sie bitte Ihre Netzwerk- und Firewalleinstellungen.</string> - <string name="dateTimeWeekdaysNames">Sonntag:Montag:Dienstag:Mittwoch:Donnerstag:Freitag:Samstag</string> - <string name="dateTimeWeekdaysShortNames">So:Mo:Di:Mi:Do:Fr:Sa</string> - <string name="dateTimeMonthNames">Januar:Februar:März:April:Mai:Juni:Juli:August:September:Oktober:November:Dezember</string> - <string name="dateTimeMonthShortNames">Jan:Feb:Mär:Apr:Mai:Jun:Jul:Aug:Sep:Okt:Nov:Dez</string> - <string name="dateTimeDayFormat">[MDAY]</string> - <string name="dateTimeAM">Uhr</string> - <string name="dateTimePM">Uhr</string> - <string name="LocalEstimateUSD">[AMOUNT] US$</string> - <string name="Group Ban">Gruppenverbannung</string> - <string name="Membership">Mitgliedschaft</string> - <string name="Roles">Rollen</string> - <string name="Group Identity">Gruppenidentität</string> - <string name="Parcel Management">Parzellenverwaltung</string> - <string name="Parcel Identity">Parzellenidentität</string> - <string name="Parcel Settings">Parzelleneinstellungen</string> - <string name="Parcel Powers">Parzellenfähigkeiten</string> - <string name="Parcel Access">Parzellenzugang</string> - <string name="Parcel Content">Parzelleninhalt</string> - <string name="Object Management">Objektmanagement</string> - <string name="Accounting">Kontoführung</string> - <string name="Notices">Mitteilungen</string> - <string name="Chat" value=" Chat:">Chat</string> - <string name="BaseMembership">Basis</string> - <string name="PremiumMembership">Premium</string> - <string name="Premium_PlusMembership">Premium Plus</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> - <string name="ExternalEditorNotSet">Wählen Sie über die Einstellung „ExternalEditor“ einen Editor aus</string> - <string name="ExternalEditorNotFound">Angegebener externer Editor nicht gefunden. + Falls Sie weiterhin Problem haben, überprüfen Sie bitte Ihre Netzwerk- und Firewalleinstellungen. + </string> + <string name="dateTimeWeekdaysNames"> + Sonntag:Montag:Dienstag:Mittwoch:Donnerstag:Freitag:Samstag + </string> + <string name="dateTimeWeekdaysShortNames"> + So:Mo:Di:Mi:Do:Fr:Sa + </string> + <string name="dateTimeMonthNames"> + Januar:Februar:März:April:Mai:Juni:Juli:August:September:Oktober:November:Dezember + </string> + <string name="dateTimeMonthShortNames"> + Jan:Feb:Mär:Apr:Mai:Jun:Jul:Aug:Sep:Okt:Nov:Dez + </string> + <string name="dateTimeDayFormat"> + [MDAY] + </string> + <string name="dateTimeAM"> + Uhr + </string> + <string name="dateTimePM"> + Uhr + </string> + <string name="LocalEstimateUSD"> + [AMOUNT] US$ + </string> + <string name="Group Ban"> + Gruppenverbannung + </string> + <string name="Membership"> + Mitgliedschaft + </string> + <string name="Roles"> + Rollen + </string> + <string name="Group Identity"> + Gruppenidentität + </string> + <string name="Parcel Management"> + Parzellenverwaltung + </string> + <string name="Parcel Identity"> + Parzellenidentität + </string> + <string name="Parcel Settings"> + Parzelleneinstellungen + </string> + <string name="Parcel Powers"> + Parzellenfähigkeiten + </string> + <string name="Parcel Access"> + Parzellenzugang + </string> + <string name="Parcel Content"> + Parzelleninhalt + </string> + <string name="Object Management"> + Objektmanagement + </string> + <string name="Accounting"> + Kontoführung + </string> + <string name="Notices"> + Mitteilungen + </string> + <string name="Chat" value=" Chat:"> + Chat + </string> + <string name="BaseMembership"> + Basis + </string> + <string name="PremiumMembership"> + Premium + </string> + <string name="Premium_PlusMembership"> + Premium Plus + </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> + <string name="ExternalEditorNotSet"> + Wählen Sie über die Einstellung „ExternalEditor“ einen Editor aus + </string> + <string name="ExternalEditorNotFound"> + Angegebener externer Editor nicht gefunden. Setzen Sie den Editorpfad in Anführungszeichen -(z. B. "/pfad/editor" "%s").</string> - <string name="ExternalEditorCommandParseError">Fehler beim Parsen des externen Editorbefehls.</string> - <string name="ExternalEditorFailedToRun">Externer Editor konnte nicht ausgeführt werden.</string> - <string name="TranslationFailed">Übersetzung fehlgeschlagen: [REASON]</string> - <string name="TranslationResponseParseError">Fehler beim Parsen der Übersetzungsantwort.</string> - <string name="Esc">Esc</string> - <string name="Space">Space</string> - <string name="Enter">Enter</string> - <string name="Tab">Tab</string> - <string name="Ins">Ins</string> - <string name="Del">Del</string> - <string name="Backsp">Backsp</string> - <string name="Shift">Shift</string> - <string name="Ctrl">Ctrl</string> - <string name="Alt">Alt</string> - <string name="CapsLock">CapsLock</string> - <string name="Home">Zuhause</string> - <string name="End">End</string> - <string name="PgUp">PgUp</string> - <string name="PgDn">PgDn</string> - <string name="F1">F1</string> - <string name="F2">F2</string> - <string name="F3">F3</string> - <string name="F4">F4</string> - <string name="F5">F5</string> - <string name="F6">F6</string> - <string name="F7">F7</string> - <string name="F8">F8</string> - <string name="F9">F9</string> - <string name="F10">F10</string> - <string name="F11">F11</string> - <string name="F12">F12</string> - <string name="Add">Addieren</string> - <string name="Subtract">Subtrahieren</string> - <string name="Multiply">Multiplizieren</string> - <string name="Divide">Dividieren</string> - <string name="PAD_DIVIDE">PAD_DIVIDE</string> - <string name="PAD_LEFT">PAD_LEFT</string> - <string name="PAD_RIGHT">PAD_RIGHT</string> - <string name="PAD_DOWN">PAD_DOWN</string> - <string name="PAD_UP">PAD_UP</string> - <string name="PAD_HOME">PAD_HOME</string> - <string name="PAD_END">PAD_END</string> - <string name="PAD_PGUP">PAD_PGUP</string> - <string name="PAD_PGDN">PAD_PGDN</string> - <string name="PAD_CENTER">PAD_CENTER</string> - <string name="PAD_INS">PAD_INS</string> - <string name="PAD_DEL">PAD_DEL</string> - <string name="PAD_Enter">PAD_Enter</string> - <string name="PAD_BUTTON0">PAD_BUTTON0</string> - <string name="PAD_BUTTON1">PAD_BUTTON1</string> - <string name="PAD_BUTTON2">PAD_BUTTON2</string> - <string name="PAD_BUTTON3">PAD_BUTTON3</string> - <string name="PAD_BUTTON4">PAD_BUTTON4</string> - <string name="PAD_BUTTON5">PAD_BUTTON5</string> - <string name="PAD_BUTTON6">PAD_BUTTON6</string> - <string name="PAD_BUTTON7">PAD_BUTTON7</string> - <string name="PAD_BUTTON8">PAD_BUTTON8</string> - <string name="PAD_BUTTON9">PAD_BUTTON9</string> - <string name="PAD_BUTTON10">PAD_BUTTON10</string> - <string name="PAD_BUTTON11">PAD_BUTTON11</string> - <string name="PAD_BUTTON12">PAD_BUTTON12</string> - <string name="PAD_BUTTON13">PAD_BUTTON13</string> - <string name="PAD_BUTTON14">PAD_BUTTON14</string> - <string name="PAD_BUTTON15">PAD_BUTTON15</string> - <string name="-">-</string> - <string name="=">=</string> - <string name="`">`</string> - <string name=";">;</string> - <string name="[">[</string> - <string name="]">]</string> - <string name="\">\</string> - <string name="0">0</string> - <string name="1">1</string> - <string name="2">2</string> - <string name="3">3</string> - <string name="4">4</string> - <string name="5">5</string> - <string name="6">6</string> - <string name="7">7</string> - <string name="8">8</string> - <string name="9">9</string> - <string name="A">A</string> - <string name="B">B</string> - <string name="C">C</string> - <string name="D">D</string> - <string name="E">E</string> - <string name="F">F</string> - <string name="G">G</string> - <string name="H">H</string> - <string name="I">I</string> - <string name="J">J</string> - <string name="K">K</string> - <string name="L">L</string> - <string name="M">M</string> - <string name="N">N</string> - <string name="O">O</string> - <string name="P">P</string> - <string name="Q">Q</string> - <string name="R">R</string> - <string name="S">S</string> - <string name="T">T</string> - <string name="U">U</string> - <string name="V">V</string> - <string name="W">W</string> - <string name="X">X</string> - <string name="Y">Y</string> - <string name="Z">Z</string> - <string name="BeaconParticle">Partikel-Beacons werden angezeigt (blau)</string> - <string name="BeaconPhysical">Beacons für physische Objekte werden angezeigt (grün)</string> - <string name="BeaconScripted">Beacons für Skriptobjekte werden angezeigt (rot)</string> - <string name="BeaconScriptedTouch">Beacons für Skriptobjekte mit Berührungsfunktion werden angezeigt (rot)</string> - <string name="BeaconSound">Sound-Beacons werden angezeigt (gelb)</string> - <string name="BeaconMedia">Medien-Beacons werden angezeigt (weiß)</string> - <string name="BeaconSun">Sonnenrichtungs-Beacon ansehen (orange)</string> - <string name="BeaconMoon">Mondrichtungs-Beacon ansehen (lila)</string> - <string name="ParticleHiding">Partikel werden ausgeblendet</string> - <string name="Command_AboutLand_Label">Landinformationen</string> - <string name="Command_Appearance_Label">Aussehen</string> - <string name="Command_Avatar_Label">Avatar</string> - <string name="Command_Build_Label">Bauen</string> - <string name="Command_Chat_Label">Chat</string> - <string name="Command_Conversations_Label">Unterhaltungen</string> - <string name="Command_Compass_Label">Kompass</string> - <string name="Command_Destinations_Label">Ziele</string> - <string name="Command_Environments_Label">Meine Umgebungen</string> - <string name="Command_Facebook_Label">Facebook</string> - <string name="Command_Flickr_Label">Flickr</string> - <string name="Command_Gestures_Label">Gesten</string> - <string name="Command_Grid_Status_Label">Grid-Status</string> - <string name="Command_HowTo_Label">Infos</string> - <string name="Command_Inventory_Label">Inventar</string> - <string name="Command_Map_Label">Karte</string> - <string name="Command_Marketplace_Label">Marktplatz</string> - <string name="Command_MarketplaceListings_Label">Marktplatz</string> - <string name="Command_MiniMap_Label">Minikarte</string> - <string name="Command_Move_Label">Gehen / Rennen / Fliegen</string> - <string name="Command_Outbox_Label">Händler-Outbox</string> - <string name="Command_People_Label">Leute</string> - <string name="Command_Picks_Label">Auswahlen</string> - <string name="Command_Places_Label">Orte</string> - <string name="Command_Preferences_Label">Einstellungen</string> - <string name="Command_Profile_Label">Profil</string> - <string name="Command_Report_Abuse_Label">Missbrauch melden</string> - <string name="Command_Search_Label">Suchen</string> - <string name="Command_Snapshot_Label">Foto</string> - <string name="Command_Speak_Label">Sprechen</string> - <string name="Command_Twitter_Label">Twitter</string> - <string name="Command_View_Label">Kamerasteuerungen</string> - <string name="Command_Voice_Label">Voice-Einstellungen</string> - <string name="Command_AboutLand_Tooltip">Informationen zu dem von Ihnen besuchten Land</string> - <string name="Command_Appearance_Tooltip">Avatar ändern</string> - <string name="Command_Avatar_Tooltip">Kompletten Avatar auswählen</string> - <string name="Command_Build_Tooltip">Objekte bauen und Terrain umformen</string> - <string name="Command_Chat_Tooltip">Mit Leuten in der Nähe chatten</string> - <string name="Command_Conversations_Tooltip">Mit allen unterhalten</string> - <string name="Command_Compass_Tooltip">Kompass</string> - <string name="Command_Destinations_Tooltip">Ziele von Interesse</string> - <string name="Command_Environments_Tooltip">Meine Umgebungen</string> - <string name="Command_Facebook_Tooltip">Auf Facebook posten</string> - <string name="Command_Flickr_Tooltip">Auf Flickr hochladen</string> - <string name="Command_Gestures_Tooltip">Gesten für Ihren Avatar</string> - <string name="Command_Grid_Status_Tooltip">Aktuellen Grid-Status anzeigen</string> - <string name="Command_HowTo_Tooltip">Wie führe ich gängige Aufgaben aus?</string> - <string name="Command_Inventory_Tooltip">Ihr Eigentum anzeigen und benutzen</string> - <string name="Command_Map_Tooltip">Weltkarte</string> - <string name="Command_Marketplace_Tooltip">Einkaufen gehen</string> - <string name="Command_MarketplaceListings_Tooltip">Ihre Kreation verkaufen</string> - <string name="Command_MiniMap_Tooltip">Leute in der Nähe anzeigen</string> - <string name="Command_Move_Tooltip">Ihren Avatar bewegen</string> - <string name="Command_Outbox_Tooltip">Artikel zum Verkauf in den Marktplatz übertragen</string> - <string name="Command_People_Tooltip">Freunde, Gruppen und Leute in der Nähe</string> - <string name="Command_Picks_Tooltip">Orte, die in Ihrem Profil als Favoriten angezeigt werden sollen</string> - <string name="Command_Places_Tooltip">Von Ihnen gespeicherte Orte</string> - <string name="Command_Preferences_Tooltip">Einstellungen</string> - <string name="Command_Profile_Tooltip">Ihr Profil bearbeiten oder anzeigen</string> - <string name="Command_Report_Abuse_Tooltip">Missbrauch melden</string> - <string name="Command_Search_Tooltip">Orte, Veranstaltungen, Leute finden</string> - <string name="Command_Snapshot_Tooltip">Foto aufnehmen</string> - <string name="Command_Speak_Tooltip">Über Ihr Mikrofon mit Leuten in der Nähe sprechen</string> - <string name="Command_Twitter_Tooltip">Twitter</string> - <string name="Command_View_Tooltip">Kamerawinkel ändern</string> - <string name="Command_Voice_Tooltip">Lautstärkeregler für Anrufe und Leute in Ihrer Nähe in SL</string> - <string name="Toolbar_Bottom_Tooltip">gegenwärtig in der unteren Symbolleiste</string> - <string name="Toolbar_Left_Tooltip">gegenwärtig in der linken Symbolleiste</string> - <string name="Toolbar_Right_Tooltip">gegenwärtig in der rechten Symbolleiste</string> - <string name="Retain%">% zurückbehalten</string> - <string name="Detail">Details</string> - <string name="Better Detail">Bessere Details</string> - <string name="Surface">Oberfläche</string> - <string name="Solid">Fest</string> - <string name="Wrap">Wickeln</string> - <string name="Preview">Vorschau</string> - <string name="Normal">Normal</string> - <string name="Pathfinding_Wiki_URL">http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer</string> - <string name="Pathfinding_Object_Attr_None">Keine</string> - <string name="Pathfinding_Object_Attr_Permanent">Wirkt sich auf Navmesh aus</string> - <string name="Pathfinding_Object_Attr_Character">Figur</string> - <string name="Pathfinding_Object_Attr_MultiSelect">(mehrere)</string> - <string name="snapshot_quality_very_low">Sehr niedrig</string> - <string name="snapshot_quality_low">Niedrig</string> - <string name="snapshot_quality_medium">Mittel</string> - <string name="snapshot_quality_high">Hoch</string> - <string name="snapshot_quality_very_high">Sehr hoch</string> - <string name="TeleportMaturityExceeded">Der Einwohner kann diese Region nicht besuchen.</string> - <string name="UserDictionary">[Benutzer]</string> - <string name="experience_tools_experience">Erlebnis</string> - <string name="ExperienceNameNull">(kein Erlebnis)</string> - <string name="ExperienceNameUntitled">(unbenanntes Erlebnis)</string> - <string name="Land-Scope">Landumfang</string> - <string name="Grid-Scope">Gridumfang</string> - <string name="Allowed_Experiences_Tab">ZULäSSIG</string> - <string name="Blocked_Experiences_Tab">BLOCKIERT</string> - <string name="Contrib_Experiences_Tab">CONTRIBUTOR</string> - <string name="Admin_Experiences_Tab">ADMIN</string> - <string name="Recent_Experiences_Tab">AKTUELL</string> - <string name="Owned_Experiences_Tab">EIGENE</string> - <string name="ExperiencesCounter">([EXPERIENCES], max. [MAXEXPERIENCES])</string> - <string name="ExperiencePermission1">Ihre Steuerungen übernehmen</string> - <string name="ExperiencePermission3">Animationen Ihres Avatars auslösen</string> - <string name="ExperiencePermission4">an Ihren Avatar anhängen</string> - <string name="ExperiencePermission9">Ihre Kamera vorfolgen</string> - <string name="ExperiencePermission10">Ihre Kamera steuern</string> - <string name="ExperiencePermission11">Sie teleportieren</string> - <string name="ExperiencePermission12">automatisch Erlebnisberechtigungen akzeptieren</string> - <string name="ExperiencePermission16">ihren Avatar zwingen, sich zu setzen</string> - <string name="ExperiencePermission17">Ändern Ihrer Umgebungseinstellungen</string> - <string name="ExperiencePermissionShortUnknown">unbekannten Vorgang durchführen: [Permission]</string> - <string name="ExperiencePermissionShort1">Steuerungen übernehmen</string> - <string name="ExperiencePermissionShort3">Animationen auslösen</string> - <string name="ExperiencePermissionShort4">Anhängen</string> - <string name="ExperiencePermissionShort9">Kamera verfolgen</string> - <string name="ExperiencePermissionShort10">Kamera steuern</string> - <string name="ExperiencePermissionShort11">Teleportieren</string> - <string name="ExperiencePermissionShort12">Berechtigung</string> - <string name="ExperiencePermissionShort16">Sitzen</string> - <string name="ExperiencePermissionShort17">Umgebung</string> - <string name="logging_calls_disabled_log_empty">Unterhaltungen werden nicht protokolliert. Um ein Protokoll zu starten, wählen Sie „Speichern: nur Protokoll“ oder „Speichern: Protokoll und Transkripte“ unter „Einstellungen“ > „Chat“.</string> - <string name="logging_calls_disabled_log_not_empty">Es werden keine Unterhaltungen mehr protokolliert. Um weiterhin ein Protokoll zu führen, wählen Sie „Speichern: nur Protokoll“ oder „Speichern: Protokoll und Transkripte“ unter „Einstellungen“ > „Chat“.</string> - <string name="logging_calls_enabled_log_empty">Keine protokollierten Unterhaltungen verfügbar. Hier erscheint ein Protokolleintrag, wenn Sie eine Person kontaktieren oder von einer Person kontaktiert werden.</string> - <string name="loading_chat_logs">Laden...</string> - <string name="na">Nicht zutreffend</string> - <string name="preset_combo_label">-Leere Liste-</string> - <string name="Default">Standard</string> - <string name="none_paren_cap">(Keine)</string> - <string name="no_limit">Keine Begrenzung</string> - <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">Die Physikform enthält Dreiecke, die zu klein sind. Versuchen Sie, das Physikmodell zu vereinfachen.</string> - <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH">Die Physikform enthält ungültige Bestätigungsdaten. Versuchen Sie, das Physikmodell zu korrigieren.</string> - <string name="Mav_Details_MAV_UNKNOWN_VERSION">Die Physikform hat keine korrekte Version. Legen Sie die korrekte Version für das Physikmodell fest.</string> - <string name="couldnt_resolve_host">Der DNS konnte den Hostnamen ([HOSTNAME]) nicht auflösen Prüfen +(z. B. "/pfad/editor" "%s"). + </string> + <string name="ExternalEditorCommandParseError"> + Fehler beim Parsen des externen Editorbefehls. + </string> + <string name="ExternalEditorFailedToRun"> + Externer Editor konnte nicht ausgeführt werden. + </string> + <string name="TranslationFailed"> + Übersetzung fehlgeschlagen: [REASON] + </string> + <string name="TranslationResponseParseError"> + Fehler beim Parsen der Übersetzungsantwort. + </string> + <string name="Esc"> + Esc + </string> + <string name="Space"> + Space + </string> + <string name="Enter"> + Enter + </string> + <string name="Tab"> + Tab + </string> + <string name="Ins"> + Ins + </string> + <string name="Del"> + Del + </string> + <string name="Backsp"> + Backsp + </string> + <string name="Shift"> + Shift + </string> + <string name="Ctrl"> + Ctrl + </string> + <string name="Alt"> + Alt + </string> + <string name="CapsLock"> + CapsLock + </string> + <string name="Home"> + Zuhause + </string> + <string name="End"> + End + </string> + <string name="PgUp"> + PgUp + </string> + <string name="PgDn"> + PgDn + </string> + <string name="F1"> + F1 + </string> + <string name="F2"> + F2 + </string> + <string name="F3"> + F3 + </string> + <string name="F4"> + F4 + </string> + <string name="F5"> + F5 + </string> + <string name="F6"> + F6 + </string> + <string name="F7"> + F7 + </string> + <string name="F8"> + F8 + </string> + <string name="F9"> + F9 + </string> + <string name="F10"> + F10 + </string> + <string name="F11"> + F11 + </string> + <string name="F12"> + F12 + </string> + <string name="Add"> + Addieren + </string> + <string name="Subtract"> + Subtrahieren + </string> + <string name="Multiply"> + Multiplizieren + </string> + <string name="Divide"> + Dividieren + </string> + <string name="PAD_DIVIDE"> + PAD_DIVIDE + </string> + <string name="PAD_LEFT"> + PAD_LEFT + </string> + <string name="PAD_RIGHT"> + PAD_RIGHT + </string> + <string name="PAD_DOWN"> + PAD_DOWN + </string> + <string name="PAD_UP"> + PAD_UP + </string> + <string name="PAD_HOME"> + PAD_HOME + </string> + <string name="PAD_END"> + PAD_END + </string> + <string name="PAD_PGUP"> + PAD_PGUP + </string> + <string name="PAD_PGDN"> + PAD_PGDN + </string> + <string name="PAD_CENTER"> + PAD_CENTER + </string> + <string name="PAD_INS"> + PAD_INS + </string> + <string name="PAD_DEL"> + PAD_DEL + </string> + <string name="PAD_Enter"> + PAD_Enter + </string> + <string name="PAD_BUTTON0"> + PAD_BUTTON0 + </string> + <string name="PAD_BUTTON1"> + PAD_BUTTON1 + </string> + <string name="PAD_BUTTON2"> + PAD_BUTTON2 + </string> + <string name="PAD_BUTTON3"> + PAD_BUTTON3 + </string> + <string name="PAD_BUTTON4"> + PAD_BUTTON4 + </string> + <string name="PAD_BUTTON5"> + PAD_BUTTON5 + </string> + <string name="PAD_BUTTON6"> + PAD_BUTTON6 + </string> + <string name="PAD_BUTTON7"> + PAD_BUTTON7 + </string> + <string name="PAD_BUTTON8"> + PAD_BUTTON8 + </string> + <string name="PAD_BUTTON9"> + PAD_BUTTON9 + </string> + <string name="PAD_BUTTON10"> + PAD_BUTTON10 + </string> + <string name="PAD_BUTTON11"> + PAD_BUTTON11 + </string> + <string name="PAD_BUTTON12"> + PAD_BUTTON12 + </string> + <string name="PAD_BUTTON13"> + PAD_BUTTON13 + </string> + <string name="PAD_BUTTON14"> + PAD_BUTTON14 + </string> + <string name="PAD_BUTTON15"> + PAD_BUTTON15 + </string> + <string name="-"> + - + </string> + <string name="="> + = + </string> + <string name="`"> + ` + </string> + <string name=";"> + ; + </string> + <string name="["> + [ + </string> + <string name="]"> + ] + </string> + <string name="\"> + \ + </string> + <string name="0"> + 0 + </string> + <string name="1"> + 1 + </string> + <string name="2"> + 2 + </string> + <string name="3"> + 3 + </string> + <string name="4"> + 4 + </string> + <string name="5"> + 5 + </string> + <string name="6"> + 6 + </string> + <string name="7"> + 7 + </string> + <string name="8"> + 8 + </string> + <string name="9"> + 9 + </string> + <string name="A"> + A + </string> + <string name="B"> + B + </string> + <string name="C"> + C + </string> + <string name="D"> + D + </string> + <string name="E"> + E + </string> + <string name="F"> + F + </string> + <string name="G"> + G + </string> + <string name="H"> + H + </string> + <string name="I"> + I + </string> + <string name="J"> + J + </string> + <string name="K"> + K + </string> + <string name="L"> + L + </string> + <string name="M"> + M + </string> + <string name="N"> + N + </string> + <string name="O"> + O + </string> + <string name="P"> + P + </string> + <string name="Q"> + Q + </string> + <string name="R"> + R + </string> + <string name="S"> + S + </string> + <string name="T"> + T + </string> + <string name="U"> + U + </string> + <string name="V"> + V + </string> + <string name="W"> + W + </string> + <string name="X"> + X + </string> + <string name="Y"> + Y + </string> + <string name="Z"> + Z + </string> + <string name="BeaconParticle"> + Partikel-Beacons werden angezeigt (blau) + </string> + <string name="BeaconPhysical"> + Beacons für physische Objekte werden angezeigt (grün) + </string> + <string name="BeaconScripted"> + Beacons für Skriptobjekte werden angezeigt (rot) + </string> + <string name="BeaconScriptedTouch"> + Beacons für Skriptobjekte mit Berührungsfunktion werden angezeigt (rot) + </string> + <string name="BeaconSound"> + Sound-Beacons werden angezeigt (gelb) + </string> + <string name="BeaconMedia"> + Medien-Beacons werden angezeigt (weiß) + </string> + <string name="BeaconSun"> + Sonnenrichtungs-Beacon ansehen (orange) + </string> + <string name="BeaconMoon"> + Mondrichtungs-Beacon ansehen (lila) + </string> + <string name="ParticleHiding"> + Partikel werden ausgeblendet + </string> + <string name="Command_AboutLand_Label"> + Landinformationen + </string> + <string name="Command_Appearance_Label"> + Aussehen + </string> + <string name="Command_Avatar_Label"> + Avatar + </string> + <string name="Command_Build_Label"> + Bauen + </string> + <string name="Command_Chat_Label"> + Chat + </string> + <string name="Command_Conversations_Label"> + Unterhaltungen + </string> + <string name="Command_Compass_Label"> + Kompass + </string> + <string name="Command_Destinations_Label"> + Ziele + </string> + <string name="Command_Environments_Label"> + Meine Umgebungen + </string> + <string name="Command_Facebook_Label"> + Facebook + </string> + <string name="Command_Flickr_Label"> + Flickr + </string> + <string name="Command_Gestures_Label"> + Gesten + </string> + <string name="Command_Grid_Status_Label"> + Grid-Status + </string> + <string name="Command_HowTo_Label"> + Infos + </string> + <string name="Command_Inventory_Label"> + Inventar + </string> + <string name="Command_Map_Label"> + Karte + </string> + <string name="Command_Marketplace_Label"> + Marktplatz + </string> + <string name="Command_MarketplaceListings_Label"> + Marktplatz + </string> + <string name="Command_MiniMap_Label"> + Minikarte + </string> + <string name="Command_Move_Label"> + Gehen / Rennen / Fliegen + </string> + <string name="Command_Outbox_Label"> + Händler-Outbox + </string> + <string name="Command_People_Label"> + Leute + </string> + <string name="Command_Picks_Label"> + Auswahlen + </string> + <string name="Command_Places_Label"> + Orte + </string> + <string name="Command_Preferences_Label"> + Einstellungen + </string> + <string name="Command_Profile_Label"> + Profil + </string> + <string name="Command_Report_Abuse_Label"> + Missbrauch melden + </string> + <string name="Command_Search_Label"> + Suchen + </string> + <string name="Command_Snapshot_Label"> + Foto + </string> + <string name="Command_Speak_Label"> + Sprechen + </string> + <string name="Command_Twitter_Label"> + Twitter + </string> + <string name="Command_View_Label"> + Kamerasteuerungen + </string> + <string name="Command_Voice_Label"> + Voice-Einstellungen + </string> + <string name="Command_AboutLand_Tooltip"> + Informationen zu dem von Ihnen besuchten Land + </string> + <string name="Command_Appearance_Tooltip"> + Avatar ändern + </string> + <string name="Command_Avatar_Tooltip"> + Kompletten Avatar auswählen + </string> + <string name="Command_Build_Tooltip"> + Objekte bauen und Terrain umformen + </string> + <string name="Command_Chat_Tooltip"> + Mit Leuten in der Nähe chatten + </string> + <string name="Command_Conversations_Tooltip"> + Mit allen unterhalten + </string> + <string name="Command_Compass_Tooltip"> + Kompass + </string> + <string name="Command_Destinations_Tooltip"> + Ziele von Interesse + </string> + <string name="Command_Environments_Tooltip"> + Meine Umgebungen + </string> + <string name="Command_Facebook_Tooltip"> + Auf Facebook posten + </string> + <string name="Command_Flickr_Tooltip"> + Auf Flickr hochladen + </string> + <string name="Command_Gestures_Tooltip"> + Gesten für Ihren Avatar + </string> + <string name="Command_Grid_Status_Tooltip"> + Aktuellen Grid-Status anzeigen + </string> + <string name="Command_HowTo_Tooltip"> + Wie führe ich gängige Aufgaben aus? + </string> + <string name="Command_Inventory_Tooltip"> + Ihr Eigentum anzeigen und benutzen + </string> + <string name="Command_Map_Tooltip"> + Weltkarte + </string> + <string name="Command_Marketplace_Tooltip"> + Einkaufen gehen + </string> + <string name="Command_MarketplaceListings_Tooltip"> + Ihre Kreation verkaufen + </string> + <string name="Command_MiniMap_Tooltip"> + Leute in der Nähe anzeigen + </string> + <string name="Command_Move_Tooltip"> + Ihren Avatar bewegen + </string> + <string name="Command_Outbox_Tooltip"> + Artikel zum Verkauf in den Marktplatz übertragen + </string> + <string name="Command_People_Tooltip"> + Freunde, Gruppen und Leute in der Nähe + </string> + <string name="Command_Picks_Tooltip"> + Orte, die in Ihrem Profil als Favoriten angezeigt werden sollen + </string> + <string name="Command_Places_Tooltip"> + Von Ihnen gespeicherte Orte + </string> + <string name="Command_Preferences_Tooltip"> + Einstellungen + </string> + <string name="Command_Profile_Tooltip"> + Ihr Profil bearbeiten oder anzeigen + </string> + <string name="Command_Report_Abuse_Tooltip"> + Missbrauch melden + </string> + <string name="Command_Search_Tooltip"> + Orte, Veranstaltungen, Leute finden + </string> + <string name="Command_Snapshot_Tooltip"> + Foto aufnehmen + </string> + <string name="Command_Speak_Tooltip"> + Über Ihr Mikrofon mit Leuten in der Nähe sprechen + </string> + <string name="Command_Twitter_Tooltip"> + Twitter + </string> + <string name="Command_View_Tooltip"> + Kamerawinkel ändern + </string> + <string name="Command_Voice_Tooltip"> + Lautstärkeregler für Anrufe und Leute in Ihrer Nähe in SL + </string> + <string name="Toolbar_Bottom_Tooltip"> + gegenwärtig in der unteren Symbolleiste + </string> + <string name="Toolbar_Left_Tooltip"> + gegenwärtig in der linken Symbolleiste + </string> + <string name="Toolbar_Right_Tooltip"> + gegenwärtig in der rechten Symbolleiste + </string> + <string name="Retain%"> + % zurückbehalten + </string> + <string name="Detail"> + Details + </string> + <string name="Better Detail"> + Bessere Details + </string> + <string name="Surface"> + Oberfläche + </string> + <string name="Solid"> + Fest + </string> + <string name="Wrap"> + Wickeln + </string> + <string name="Preview"> + Vorschau + </string> + <string name="Normal"> + Normal + </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Keine + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Wirkt sich auf Navmesh aus + </string> + <string name="Pathfinding_Object_Attr_Character"> + Figur + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (mehrere) + </string> + <string name="snapshot_quality_very_low"> + Sehr niedrig + </string> + <string name="snapshot_quality_low"> + Niedrig + </string> + <string name="snapshot_quality_medium"> + Mittel + </string> + <string name="snapshot_quality_high"> + Hoch + </string> + <string name="snapshot_quality_very_high"> + Sehr hoch + </string> + <string name="TeleportMaturityExceeded"> + Der Einwohner kann diese Region nicht besuchen. + </string> + <string name="UserDictionary"> + [Benutzer] + </string> + <string name="experience_tools_experience"> + Erlebnis + </string> + <string name="ExperienceNameNull"> + (kein Erlebnis) + </string> + <string name="ExperienceNameUntitled"> + (unbenanntes Erlebnis) + </string> + <string name="Land-Scope"> + Landumfang + </string> + <string name="Grid-Scope"> + Gridumfang + </string> + <string name="Allowed_Experiences_Tab"> + ZULäSSIG + </string> + <string name="Blocked_Experiences_Tab"> + BLOCKIERT + </string> + <string name="Contrib_Experiences_Tab"> + CONTRIBUTOR + </string> + <string name="Admin_Experiences_Tab"> + ADMIN + </string> + <string name="Recent_Experiences_Tab"> + AKTUELL + </string> + <string name="Owned_Experiences_Tab"> + EIGENE + </string> + <string name="ExperiencesCounter"> + ([EXPERIENCES], max. [MAXEXPERIENCES]) + </string> + <string name="ExperiencePermission1"> + Ihre Steuerungen übernehmen + </string> + <string name="ExperiencePermission3"> + Animationen Ihres Avatars auslösen + </string> + <string name="ExperiencePermission4"> + an Ihren Avatar anhängen + </string> + <string name="ExperiencePermission9"> + Ihre Kamera vorfolgen + </string> + <string name="ExperiencePermission10"> + Ihre Kamera steuern + </string> + <string name="ExperiencePermission11"> + Sie teleportieren + </string> + <string name="ExperiencePermission12"> + automatisch Erlebnisberechtigungen akzeptieren + </string> + <string name="ExperiencePermission16"> + ihren Avatar zwingen, sich zu setzen + </string> + <string name="ExperiencePermission17"> + Ändern Ihrer Umgebungseinstellungen + </string> + <string name="ExperiencePermissionShortUnknown"> + unbekannten Vorgang durchführen: [Permission] + </string> + <string name="ExperiencePermissionShort1"> + Steuerungen übernehmen + </string> + <string name="ExperiencePermissionShort3"> + Animationen auslösen + </string> + <string name="ExperiencePermissionShort4"> + Anhängen + </string> + <string name="ExperiencePermissionShort9"> + Kamera verfolgen + </string> + <string name="ExperiencePermissionShort10"> + Kamera steuern + </string> + <string name="ExperiencePermissionShort11"> + Teleportieren + </string> + <string name="ExperiencePermissionShort12"> + Berechtigung + </string> + <string name="ExperiencePermissionShort16"> + Sitzen + </string> + <string name="ExperiencePermissionShort17"> + Umgebung + </string> + <string name="logging_calls_disabled_log_empty"> + Unterhaltungen werden nicht protokolliert. Um ein Protokoll zu starten, wählen Sie „Speichern: nur Protokoll“ oder „Speichern: Protokoll und Transkripte“ unter „Einstellungen“ > „Chat“. + </string> + <string name="logging_calls_disabled_log_not_empty"> + Es werden keine Unterhaltungen mehr protokolliert. Um weiterhin ein Protokoll zu führen, wählen Sie „Speichern: nur Protokoll“ oder „Speichern: Protokoll und Transkripte“ unter „Einstellungen“ > „Chat“. + </string> + <string name="logging_calls_enabled_log_empty"> + Keine protokollierten Unterhaltungen verfügbar. Hier erscheint ein Protokolleintrag, wenn Sie eine Person kontaktieren oder von einer Person kontaktiert werden. + </string> + <string name="loading_chat_logs"> + Laden... + </string> + <string name="na"> + Nicht zutreffend + </string> + <string name="preset_combo_label"> + -Leere Liste- + </string> + <string name="Default"> + Standard + </string> + <string name="none_paren_cap"> + (Keine) + </string> + <string name="no_limit"> + Keine Begrenzung + </string> + <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES"> + Die Physikform enthält Dreiecke, die zu klein sind. Versuchen Sie, das Physikmodell zu vereinfachen. + </string> + <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH"> + Die Physikform enthält ungültige Bestätigungsdaten. Versuchen Sie, das Physikmodell zu korrigieren. + </string> + <string name="Mav_Details_MAV_UNKNOWN_VERSION"> + Die Physikform hat keine korrekte Version. Legen Sie die korrekte Version für das Physikmodell fest. + </string> + <string name="couldnt_resolve_host"> + Der DNS konnte den Hostnamen ([HOSTNAME]) nicht auflösen Prüfen Sie bitte, ob Sie die Website www.secondlife.com aufrufen können. Wenn Sie die Website aufrufen können, jedoch weiterhin diese Fehlermeldung erhalten, -besuchen Sie bitte den Support-Bereich und melden Sie das Problem.</string> - <string name="ssl_peer_certificate">Der Anmeldeserver konnte sich nicht per SSL verifizieren. +besuchen Sie bitte den Support-Bereich und melden Sie das Problem. + </string> + <string name="ssl_peer_certificate"> + Der Anmeldeserver konnte sich nicht per SSL verifizieren. Wenn Sie diese Fehlermeldung weiterhin erhalten, besuchen Sie bitte den Support-Bereich der Website Secondlife.com -und melden Sie das Problem.</string> - <string name="ssl_connect_error">Die Ursache hierfür ist häufig eine falsch eingestellte Uhrzeit auf Ihrem Computer. +und melden Sie das Problem. + </string> + <string name="ssl_connect_error"> + Die Ursache hierfür ist häufig eine falsch eingestellte Uhrzeit auf Ihrem Computer. Bitte vergewissern Sie sich, dass Datum und Uhrzeit in der Systemsteuerung korrekt eingestellt sind. Überprüfen Sie außerdem, ob Ihre Netzwerk- und Firewall-Einstellungen korrekt sind. Wenn Sie diese Fehlermeldung weiterhin erhalten, besuchen Sie bitte den Support-Bereich der Website Secondlife.com und melden Sie das Problem. -[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Knowledge-Base]</string> +[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Knowledge-Base] + </string> </strings> diff --git a/indra/newview/skins/default/xui/de/teleport_strings.xml b/indra/newview/skins/default/xui/de/teleport_strings.xml index 9f8a7a8045..1ed09f24b5 100644 --- a/indra/newview/skins/default/xui/de/teleport_strings.xml +++ b/indra/newview/skins/default/xui/de/teleport_strings.xml @@ -1,41 +1,97 @@ <?xml version="1.0" ?> <teleport_messages> <message_set name="errors"> - <message name="invalid_tport">Bei der Bearbeitung Ihrer Teleport-Anfrage ist ein Problem aufgetreten. Sie müssen sich zum Teleportieren eventuell neu anmelden. -Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE].</message> - <message name="invalid_region_handoff">Bei der Bearbeitung Ihres Regionswechsels ist ein Problem aufgetreten. Sie müssen eventuell neu anmelden, um die Region wechseln zu können. -Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE].</message> - <message name="blocked_tport">Teleportieren ist zurzeit leider nicht möglich. Versuchen Sie es später noch einmal. -Wenn der Teleport dann immer noch nicht funktioniert, melden Sie sich bitte ab und wieder an.</message> - <message name="nolandmark_tport">Das System konnte das Landmarken-Ziel nicht finden.</message> - <message name="timeout_tport">Das System konnte keine Teleport-Verbindung herstellen. -Versuchen Sie es später noch einmal.</message> - <message name="NoHelpIslandTP">Sie können nicht zurück nach Welcome Island teleportieren. -Gehen Sie zu „Welcome Island Public“, um das Tutorial zu wiederholen.</message> - <message name="noaccess_tport">Sie haben leider keinen Zugang zu diesem Teleport-Ziel.</message> - <message name="missing_attach_tport">Ihre Anhänge sind noch nicht eingetroffen. Warten Sie kurz oder melden Sie sich ab und wieder an, bevor Sie einen neuen Teleport-Versuch unternehmen.</message> - <message name="too_many_uploads_tport">Die Asset-Warteschlange in dieser Region ist zurzeit überlastet. -Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in einigen Minuten erneut oder besuchen Sie eine weniger überfüllte Region.</message> - <message name="expired_tport">Das System konnte Ihre Teleport-Anfrage nicht rechtzeitig bearbeiten. Versuchen Sie es in einigen Minuten erneut.</message> - <message name="expired_region_handoff">Das System konnte Ihre Anfrage zum Regionswechsel nicht rechtzeitig bearbeiten. Versuchen Sie es in einigen Minuten erneut.</message> - <message name="no_host">Teleport-Ziel wurde nicht gefunden. Das Ziel ist entweder im Moment nicht verfügbar oder existiert nicht mehr. Versuchen Sie es in einigen Minuten erneut.</message> - <message name="no_inventory_host">Das Inventarsystem ist zurzeit nicht verfügbar.</message> - <message name="MustGetAgeRegion">Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können.</message> - <message name="RegionTPSpecialUsageBlocked">Betreten der Region nicht gestattet. „[REGION_NAME]“ ist eine Region für Geschicklichkeitsspiele. Der Zutritt ist Einwohnern vorbehalten, die bestimmte Kriterien erfüllen. Weitere Details finden Sie unter [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ].</message> - <message name="preexisting_tport">Entschuldigung, aber das System konnte deinen Teleport nicht starten. Versuche es bitte in ein paar Minuten noch einmal.</message> + <message name="invalid_tport"> + Bei der Bearbeitung Ihrer Teleport-Anfrage ist ein Problem aufgetreten. Sie müssen sich zum Teleportieren eventuell neu anmelden. +Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE]. + </message> + <message name="invalid_region_handoff"> + Bei der Bearbeitung Ihres Regionswechsels ist ein Problem aufgetreten. Sie müssen eventuell neu anmelden, um die Region wechseln zu können. +Falls diese Meldung weiterhin angezeigt wird, wenden Sie sich bitte an [SUPPORT_SITE]. + </message> + <message name="blocked_tport"> + Teleportieren ist zurzeit leider nicht möglich. Versuchen Sie es später noch einmal. +Wenn der Teleport dann immer noch nicht funktioniert, melden Sie sich bitte ab und wieder an. + </message> + <message name="nolandmark_tport"> + Das System konnte das Landmarken-Ziel nicht finden. + </message> + <message name="timeout_tport"> + Das System konnte keine Teleport-Verbindung herstellen. +Versuchen Sie es später noch einmal. + </message> + <message name="NoHelpIslandTP"> + Sie können nicht zurück nach Welcome Island teleportieren. +Gehen Sie zu „Welcome Island Public“, um das Tutorial zu wiederholen. + </message> + <message name="noaccess_tport"> + Sie haben leider keinen Zugang zu diesem Teleport-Ziel. + </message> + <message name="missing_attach_tport"> + Ihre Anhänge sind noch nicht eingetroffen. Warten Sie kurz oder melden Sie sich ab und wieder an, bevor Sie einen neuen Teleport-Versuch unternehmen. + </message> + <message name="too_many_uploads_tport"> + Die Asset-Warteschlange in dieser Region ist zurzeit überlastet. +Ihre Teleport-Anfrage kann nicht sofort bearbeitet werden. Versuchen Sie es in einigen Minuten erneut oder besuchen Sie eine weniger überfüllte Region. + </message> + <message name="expired_tport"> + Das System konnte Ihre Teleport-Anfrage nicht rechtzeitig bearbeiten. Versuchen Sie es in einigen Minuten erneut. + </message> + <message name="expired_region_handoff"> + Das System konnte Ihre Anfrage zum Regionswechsel nicht rechtzeitig bearbeiten. Versuchen Sie es in einigen Minuten erneut. + </message> + <message name="no_host"> + Teleport-Ziel wurde nicht gefunden. Das Ziel ist entweder im Moment nicht verfügbar oder existiert nicht mehr. Versuchen Sie es in einigen Minuten erneut. + </message> + <message name="no_inventory_host"> + Das Inventarsystem ist zurzeit nicht verfügbar. + </message> + <message name="MustGetAgeRegion"> + Sie müssen mindestens 18 Jahre alt sein, um diese Region betreten zu können. + </message> + <message name="RegionTPSpecialUsageBlocked"> + Betreten der Region nicht gestattet. „[REGION_NAME]“ ist eine Region für Geschicklichkeitsspiele. Der Zutritt ist Einwohnern vorbehalten, die bestimmte Kriterien erfüllen. Weitere Details finden Sie unter [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ]. + </message> + <message name="preexisting_tport"> + Entschuldigung, aber das System konnte deinen Teleport nicht starten. Versuche es bitte in ein paar Minuten noch einmal. + </message> </message_set> <message_set name="progress"> - <message name="sending_dest">Transport zum Ziel.</message> - <message name="redirecting">Weiterleitung an anderes Ziel.</message> - <message name="relaying">Weiterleitung zum Ziel.</message> - <message name="sending_home">Zuhause-Position wird ermittelt.</message> - <message name="sending_landmark">Landmarken-Position wird ermittelt.</message> - <message name="completing">Teleport wird abgeschlossen.</message> - <message name="completed_from">Teleport aus [T_SLURL] wurde erfolgreich abgeschlossen.</message> - <message name="resolving">Ziel wird ermittelt.</message> - <message name="contacting">Verbindung zu neuer Region.</message> - <message name="arriving">Ziel erreicht...</message> - <message name="requesting">Teleport wird initialisiert...</message> - <message name="pending">Anstehender Teleport...</message> + <message name="sending_dest"> + Transport zum Ziel. + </message> + <message name="redirecting"> + Weiterleitung an anderes Ziel. + </message> + <message name="relaying"> + Weiterleitung zum Ziel. + </message> + <message name="sending_home"> + Zuhause-Position wird ermittelt. + </message> + <message name="sending_landmark"> + Landmarken-Position wird ermittelt. + </message> + <message name="completing"> + Teleport wird abgeschlossen. + </message> + <message name="completed_from"> + Teleport aus [T_SLURL] wurde erfolgreich abgeschlossen. + </message> + <message name="resolving"> + Ziel wird ermittelt. + </message> + <message name="contacting"> + Verbindung zu neuer Region. + </message> + <message name="arriving"> + Ziel erreicht... + </message> + <message name="requesting"> + Teleport wird initialisiert... + </message> + <message name="pending"> + Anstehender Teleport... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/en/floater_avatar_welcome_pack.xml b/indra/newview/skins/default/xui/en/floater_avatar_welcome_pack.xml new file mode 100644 index 0000000000..795d642755 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_avatar_welcome_pack.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater + positioning="cascading" + legacy_header_height="225" + can_minimize="true" + can_close="true" + can_resize="false" + min_height="438" + min_width="530" + height="438" + layout="topleft" + name="Avatar Welcome Pack" + single_instance="true" + save_rect="true" + save_visibility="true" + title="AVATAR WELCOME PACK" + width="530"> + <web_browser + top="25" + height="438" + width="530" + follows="all" + name="avatar_picker_contents" + trusted_content="true"/> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_chat_mention_picker.xml b/indra/newview/skins/default/xui/en/floater_chat_mention_picker.xml new file mode 100644 index 0000000000..bbad99f932 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_chat_mention_picker.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + name="chat_mention_picker" + title="CHOOSE RESIDENT" + single_instance="true" + can_minimize="false" + can_tear_off="false" + can_resize="true" + auto_close="true" + layout="topleft" + min_width="250" + chrome="true" + height="125" + width="310"> + <avatar_list + allow_select="true" + follows="all" + height="120" + width="306" + ignore_online_status="true" + layout="topleft" + left="3" + keep_one_selected="true" + multi_select="false" + show_info_btn="false" + show_profile_btn="false" + show_speaking_indicator="false" + name="avatar_list" + right="-1" + top="2" /> +</floater> 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 deleted file mode 100644 index 6c3214a76d..0000000000 --- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml +++ /dev/null @@ -1,421 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater - legacy_header_height="18" - height="340" - layout="topleft" - name="item properties" - help_topic="item_properties" - save_rect="true" - title="INVENTORY ITEM PROPERTIES" - width="350"> - <floater.string - name="unknown"> - (unknown) - </floater.string> - <floater.string - name="public"> - (public) - </floater.string> - <floater.string - name="you_can"> - You can: - </floater.string> - <floater.string - name="owner_can"> - Owner can: - </floater.string> - <floater.string - name="acquiredDate"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] - </floater.string> - <icon - follows="top|right" - height="18" - image_name="Lock" - layout="topleft" - left="276" - mouse_opaque="true" - name="IconLocked" - top="4" - width="18" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="LabelItemNameTitle" - top="25" - width="78"> - Name: - </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top|right" - height="16" - layout="topleft" - left_delta="78" - max_length_bytes="63" - name="LabelItemName" - top_delta="0" - width="252" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="LabelItemDescTitle" - top="45" - width="78"> - Description: - </text> - <line_editor - border_style="line" - border_thickness="1" - follows="left|top|right" - height="16" - layout="topleft" - left_delta="78" - max_length_bytes="127" - name="LabelItemDesc" - top_delta="0" - width="252" /> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="LabelCreatorTitle" - top="65" - width="78"> - Creator: - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left_delta="78" - name="LabelCreatorName" - top_delta="0" - translate="false" - use_ellipses="true" - width="170"> - TestString PleaseIgnore - </text> - <button - follows="top|right" - height="16" - label="Profile..." - layout="topleft" - left_delta="174" - name="BtnCreator" - top_delta="0" - width="78" /> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="LabelOwnerTitle" - top="85" - width="78"> - Owner: - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left_delta="78" - name="LabelOwnerName" - top_delta="0" - translate="false" - use_ellipses="true" - width="170"> - TestString PleaseIgnore - </text> - <button - follows="top|right" - height="16" - label="Profile..." - layout="topleft" - left_delta="174" - name="BtnOwner" - top_delta="0" - width="78" /> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left="10" - name="LabelAcquiredTitle" - top="105" - width="78"> - Acquired: - </text> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - left_delta="78" - name="LabelAcquiredDate" - top_delta="0" - width="252"> - Wed May 24 12:50:46 2006 - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="OwnerLabel" - top="125" - width="78"> - You: - </text> - <check_box - height="16" - label="Edit" - layout="topleft" - left_pad="5" - name="CheckOwnerModify" - top_delta="0" - width="78" /> - <check_box - height="16" - label="Copy" - layout="topleft" - left_delta="0" - name="CheckOwnerCopy" - top_pad="5" - width="88" /> - <check_box - height="16" - label="Resell" - layout="topleft" - left_delta="0" - name="CheckOwnerTransfer" - top_pad="5" - width="106" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="AnyoneLabel" - top_pad="5" - width="78"> - Anyone: - </text> - <check_box - height="16" - label="Copy" - layout="topleft" - left_pad="5" - name="CheckEveryoneCopy" - top_delta="0" - width="130" /> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="GroupLabel" - top_pad="5" - width="78"> - Group: - </text> - <check_box - height="16" - label="Share" - layout="topleft" - left_pad="5" - name="CheckShareWithGroup" - top_delta="5" - width="106" /> - <text - type="string" - length="1" - follows="left|top" - height="25" - layout="topleft" - left="10" - name="NextOwnerLabel" - top_pad="5" - width="78" - word_wrap="true"> - Next owner: - </text> - <check_box - height="16" - label="Edit" - layout="topleft" - left_pad="5" - name="CheckNextOwnerModify" - top_delta="0" - width="78" /> - <check_box - height="16" - label="Copy" - layout="topleft" - left_delta="0" - name="CheckNextOwnerCopy" - top_pad="5" - width="88" /> - <check_box - height="16" - label="Resell" - layout="topleft" - left_delta="0" - name="CheckNextOwnerTransfer" - top_pad="5" - width="106" /> - <check_box - height="16" - label="For Sale" - layout="topleft" - left="10" - name="CheckPurchase" - top_pad="5" - width="78" /> - <combo_box - height="19" - left_pad="5" - layout="topleft" - follows="left|top" - name="ComboBoxSaleType" - width="110"> - <combo_box.item - name="Copy" - label="Copy" - value="2" /> - <combo_box.item - name="Contents" - label="Contents" - value="3" /> - <combo_box.item - name="Original" - label="Original" - value="1" /> - </combo_box> - <spinner - follows="left|top" - decimal_digits="0" - increment="1" - name="Edit Cost" - label="Price:" - label_width="100" - left="10" - width="192" - min_val="1" - height="19" - max_val="999999999" - top_pad="5"/> - <text - type="string" - length="1" - height="15" - follows="left|top" - layout="topleft" - left_delta="82" - name="CurrencySymbol" - top_delta="1" - width="18"> - L$ - </text> - - <!--line_editor - border_style="line" - border_thickness="1" - follows="left|top|right" - height="16" - layout="topleft" - left_pad="5" - max_length_bytes="25" - name="EditPrice" - top_delta="0" - width="242" /--> - - <!--text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left="10" - name="BaseMaskDebug" - top="155" - width="330"> - B: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="OwnerMaskDebug" - top_delta="0" - width="270"> - O: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="GroupMaskDebug" - top_delta="0" - width="210"> - G: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="EveryoneMaskDebug" - top_delta="0" - width="150"> - E: - </text> - <text - type="string" - length="1" - follows="left|top" - height="10" - layout="topleft" - left_delta="60" - name="NextMaskDebug" - top_delta="0" - width="90"> - N: - </text--> - -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_inventory_settings.xml b/indra/newview/skins/default/xui/en/floater_inventory_settings.xml index 156bba6c27..a51e7a844a 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_settings.xml @@ -4,8 +4,8 @@ can_minimize="true" can_resize="false" save_rect="true" - height="370" - width="370" + height="483" + width="483" name="inventory_settings" title="INVENTORY SETTINGS"> <icon @@ -16,7 +16,7 @@ left="18" mouse_opaque="true" name="multi_folder_icon" - top="25" + top="20" width="18" /> <text type="string" @@ -40,10 +40,10 @@ font="SansSerifMedium" left="60" width="300" - height="70" + height="66" name="multi_double_click_setting"> <radio_item - height="20" + height="18" label="Expands & collapses folder" label_text.text_color="White" follows="left|top" @@ -51,24 +51,24 @@ name="0" width="200"/> <radio_item - height="20" + height="18" follows="left|top" label="Opens a new window" label_text.text_color="White" layout="topleft" left_delta="0" name="1" - top_pad ="5" + top_pad ="3" width="200" /> <radio_item - height="20" + height="18" follows="left|top" label="Switches view" label_text.text_color="White" layout="topleft" left_delta="0" name="2" - top_pad ="5" + top_pad ="3" width="200" /> </radio_group> <icon @@ -79,7 +79,7 @@ left="18" mouse_opaque="true" name="single_folder_icon" - top_pad="30" + top_pad="19" width="18" /> <text type="string" @@ -103,10 +103,10 @@ font="SansSerifMedium" left="60" width="300" - height="45" + height="44" name="single_double_click_setting"> <radio_item - height="20" + height="18" label="Stays in current window" label_text.text_color="White" follows="left|top" @@ -114,27 +114,37 @@ name="false" width="200"/> <radio_item - height="20" + height="18" follows="left|top" label="Opens a new window" label_text.text_color="White" layout="topleft" left_delta="0" name="true" - top_pad ="5" + top_pad ="3" width="200" /> </radio_group> + <icon + follows="top|left" + height="15" + image_name="Icon_Pointer" + layout="topleft" + left="20" + mouse_opaque="true" + name="single_folder_icon" + top_pad="20" + width="15" /> <text type="string" length="1" follows="left|top|right" height="13" layout="topleft" - left="48" + left_pad="13" name="find_original_txt" font="SansSerifMedium" text_color="White" - top_pad="30" + top_delta="1" width="300"> Clicking on "Show in inventory" or "Find original" </text> @@ -146,10 +156,10 @@ font="SansSerifMedium" left="60" width="300" - height="45" + height="44" name="find_original_settings"> <radio_item - height="20" + height="18" label="Shows item in main inventory window" label_text.text_color="White" follows="left|top" @@ -157,23 +167,136 @@ name="false" width="200"/> <radio_item - height="20" + height="18" follows="left|top" label="Opens a new single-folder window" label_text.text_color="White" layout="topleft" left_delta="0" name="true" - top_pad ="5" + top_pad ="3" width="200" /> </radio_group> - <button - height="20" - label="OK" - layout="topleft" - left="140" - bottom="-20" - name="ok_btn" - label_color="White" - width="90" /> + <icon + follows="top|left" + height="18" + image_name="Inv_Favorite_Star_Full" + layout="topleft" + left="18" + mouse_opaque="true" + name="favorites_icon" + top_pad="19" + width="18" /> + <text + type="string" + length="1" + layout="topleft" + follows="left|top|right" + height="13" + left_pad="12" + top_delta="2" + name="favorites_txt" + font="SansSerifMedium" + text_color="White" + width="300"> + Favorites + </text> + <check_box + control_name="InventoryFavoritesUseStar" + layout="topleft" + follows="left|top" + top_pad="8" + font="SansSerifMedium" + left="60" + width="300" + height="18" + label="Star on favorite items" + name="favorite_star" + label_text.text_color="White" + initial_value="false"/> + <check_box + control_name="InventoryFavoritesUseHollowStar" + follows="left|top" + top_pad="5" + layout="topleft" + font="SansSerifMedium" + left="60" + width="150" + height="18" + label="Star on folders containing a favorite" + name="favorite_hollow_star" + label_text.text_color="White" + initial_value="false"/> + <check_box + control_name="InventoryFavoritesColorText" + follows="left|top" + top_pad="5" + layout="topleft" + font="SansSerifMedium" + left="60" + width="150" + height="18" + label="Colored text" + name="favorites_color" + label_text.text_color="White" + initial_value="false"/> + <color_swatch + can_apply_immediately="true" + follows="left|top" + layout="topleft" + height="24" + label_height="0" + left_pad="40" + name="favorites_swatch" + top_delta="-6" + width="44" > + <color_swatch.init_callback + function="ScriptPref.getUIColor" + parameter="InventoryFavoriteColor" /> + <color_swatch.commit_callback + function="ScriptPref.applyUIColor" + parameter="InventoryFavoriteColor" /> + </color_swatch> + <icon + follows="top|left" + height="18" + image_name="Inv_Object" + layout="topleft" + left="18" + mouse_opaque="true" + name="obj_icon" + top_pad="19" + width="18" /> + <text + type="string" + length="1" + follows="left|top|right" + height="13" + layout="topleft" + left_pad="12" + top_delta="2" + name="single_folder_txt" + font="SansSerifMedium" + text_color="White" + width="300"> + Pressing enter on an avatar attachment + </text> + <combo_box + control_name="InventoryAddAttachmentBehavior" + layout="topleft" + follows="left|top" + top_pad="8" + height="24" + left="60" + name="attach_combo" + width="300"> + <combo_box.item + label="Adds attachment (recommended)" + name="0" + value="0"/> + <combo_box.item + label="Wear (removes attachment at that point)" + name="1" + value="1"/> + </combo_box> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 90223fcda8..f11d687840 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -14,7 +14,7 @@ legacy_header_height="25"> <string name="status_idle"></string> - <string name="status_parse_error">Error: Dae parsing issue - see log for details.</string> + <string name="status_parse_error">Error: Model parsing issue - see log for details.</string> <string name="status_bind_shape_orientation">Warning: bind shape matrix is not in standard X-forward orientation.</string> <string name="status_material_mismatch">Error: Material of model is not a subset of reference model.</string> <string name="status_reading_file">Loading...</string> @@ -39,12 +39,14 @@ <string name="decomposing">Analyzing...</string> <string name="simplifying">Simplifying...</string> <string name="tbd">TBD</string> + <string name="ModelTextureScaling">One or more textures in this model were scaled to be within the allowed limits.</string> <!-- Warnings and info from model loader--> <string name="TooManyJoint">Skinning disabled due to too many joints: [JOINTS], maximum: [MAX]</string> <string name="UnrecognizedJoint">Rigged to unrecognized joint name [NAME]</string> <string name="UnknownJoints">Skinning disabled due to [COUNT] unknown joints</string> <string name="ModelLoaded">Model [MODEL_NAME] loaded</string> + <string name="InvBindCountMismatch">Bind matrices count mismatch joints count</string> <string name="IncompleteTC">Texture coordinates data is not complete.</string> <string name="PositionNaN">Found NaN while loading position data from DAE-Model, invalid model.</string> @@ -60,6 +62,27 @@ <string name="ParsingErrorNoRoot">Document has no root</string> <string name="ParsingErrorNoScene">Document has no visual_scene</string> <string name="ParsingErrorPositionInvalidModel">Unable to process mesh without position data. Invalid model.</string> + <string name="UnknownException">Importer crashed while processing [FILENAME], if you encounter this and file is valid, please report the issue to Second Life Support. Exception: [EXCEPTION].</string> + + <!-- GLTF specific messages --> + <string name="NoScenesFound">No scenes defined in GLTF file</string> + <string name="InvalidMeshReference">Node [NODE_NAME] references invalid mesh [MESH_INDEX] (total meshes: [TOTAL_MESHES])</string> + <string name="InvalidGeometryNonTriangulated">Mesh [MESH_NAME] primitive [PRIMITIVE_INDEX]: Invalid geometry with [INDEX_COUNT] indices (must be triangulated)</string> + <string name="EmptyVertexArray">Mesh [MESH_NAME] primitive [PRIMITIVE_INDEX]: Empty vertex array</string> + <string name="ErrorIndexLimit">Unable to process mesh [MESH_NAME] due to 65,534 vertex limit. Vertex count: [VERTEX_COUNT]</string> + <string name="TextureFound">Found texture: [TEXTURE_NAME] for material: [MATERIAL_NAME]</string> + <string name="IgnoredExtension">Model uses unsupported extension: [EXT], related material properties are ignored</string> + <string name="UnsupportedExtension">Unable to load model, unsupported extension: [EXT]</string> + <string name="FailedToCreateTempFile">Failed to create temporary file for embedded [TEXTURE_TYPE] texture [TEXTURE_INDEX]: [TEMP_FILE]</string> + <string name="SkinJointsOverLimit">Skin [SKIN_INDEX] defines [JOINT_COUNT] compatible joints, maximum is: [MAX]. Unused joints will be stripped on per model basis.</string> + <string name="SkinUsupportedJoints">Skin [SKIN_INDEX] defines [JOINT_COUNT] joints, but only [LEGAL_COUNT] were recognized and are compatible</string> + <string name="SkinUnusedJoints">Skin [SKIN_INDEX] defines [JOINT_COUNT] compatible joints, of them only [USED_COUNT] were used</string> + <string name="ModelTooManyJoints">Model [MODEL_NAME] uses [JOINT_COUNT], maximum: [MAX], upload might fail</string> + <string name="ModelSplitPrimitive">Too many vertices in primitive [MODEL_NAME], it was split into [FACE_COUNT] faces</string> + <string name="ModelTooManySubmodels">Model [MODEL_NAME] contains [SUBMODEL_COUNT] generated mesh parts, parts were trimmed to [SUBMODEL_LIMIT]</string> + <string name="ParsingErrorMissingBuffer">Buffer is either missing or empty [BUFFER_NAME].</string> + <string name="ParsingErrorMissingBufferBin">Buffer is either missing or empty. Check presence of [BUFFER_URI] file.</string> + <string name="ParsingErrorException">Parser failed to process [FILENAME], file might be corrupt, incomplete or protected from reading. Exception: [EXCEPTION].</string> <panel follows="top|left" @@ -1404,7 +1427,7 @@ word_wrap="true"> </text_editor> <check_box - control_name="ImporterDebug" + control_name="ImporterDebugVerboseLogging" follows="top|left" top_pad="9" left="6" @@ -1706,7 +1729,6 @@ Analysed: height="408"/> <panel follows="right|bottom" - can_resize="false" height="140" layout="topleft" name="right_panel" diff --git a/indra/newview/skins/default/xui/en/floater_my_inventory.xml b/indra/newview/skins/default/xui/en/floater_my_inventory.xml index a9900f05b7..881c1f7469 100644 --- a/indra/newview/skins/default/xui/en/floater_my_inventory.xml +++ b/indra/newview/skins/default/xui/en/floater_my_inventory.xml @@ -12,7 +12,7 @@ save_visibility="true" reuse_instance="true" title="INVENTORY" - width="363" > + width="418" > <panel class="sidepanel_inventory" name="main_panel" diff --git a/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml b/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml index 57b74b360a..9981e5d893 100644 --- a/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml +++ b/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml @@ -17,17 +17,7 @@ New inventory features </floater.string> <floater.string name="description_txt_inventory"> -You can now add preview images to inventory items and view a folder in its own window. -Learn more in this [https://community.secondlife.com/blogs/entry/13637-new-features-inventory-item-preview-and-single-folder-view/ blogpost] - </floater.string> - <floater.string name="title_txt_gltf"> -New GLTF PBR materials support - </floater.string> - <floater.string name="description_txt_gltf"> -You can now use expanded material support with the ability to import and edit GLTF Physically Based Rendering (PBR) Materials. -In order to support the addition of the GLTF format, some areas in the viewer may appear darker than usual. - -Learn more about [https://wiki.secondlife.com/wiki/PBR_Materials Physically Based Rendering (PBR)] +You can now mark items and folders as favorites. Favorited items will appear in the Favorites tab of inventory and by default will be highlighted with a star in the main inventory view. </floater.string> <text type="string" diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml index 5e4b017590..709fbdd27e 100644 --- a/indra/newview/skins/default/xui/en/floater_object_weights.xml +++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml @@ -2,7 +2,7 @@ <floater can_close="true" can_tear_off="false" - height="289" + height="372" help_topic="object_weights" layout="topleft" name="object_weights" @@ -13,6 +13,21 @@ <floater.string name="nothing_selected" value="--"/> + <floater.string + name="lowest_lod" + value="Lowest"/> + <floater.string + name="low_lod" + value="Low"/> + <floater.string + name="medium_lod" + value="Medium"/> + <floater.string + name="high_lod" + value="High"/> + <floater.string + name="multiple_lods" + value="Multiple"/> <text follows="left|top" @@ -320,4 +335,97 @@ top_delta="0" value="Total capacity" width="130" /> + + + <text + follows="left|top" + height="16" + layout="topleft" + left="10" + name="rendering_info_text" + text_color="EmphasisColor" + top_pad="10" + value="RENDERING INFO" + width="180" /> + <text + follows="left|top" + halign="right" + height="16" + layout="topleft" + left="10" + name="lod_level" + top_pad="3" + value="--" + width="40" /> + <loading_indicator + follows="left|top" + height="16" + layout="topleft" + left="34" + name="lod_level_loading_indicator" + top_delta="0" + width="16" /> + <text + follows="left|top" + height="16" + layout="topleft" + left_pad="10" + name="lod_level_label" + top_delta="0" + value="LOD (Level of detail)" + width="130" /> + <text + follows="left|top" + halign="right" + height="16" + layout="topleft" + left="10" + name="triangles_shown" + top_pad="3" + value="--" + width="40" /> + <loading_indicator + follows="left|top" + height="16" + layout="topleft" + left="34" + name="triangles_shown_loading_indicator" + top_delta="0" + width="16" /> + <text + follows="left|top" + height="16" + layout="topleft" + left_pad="10" + name="triangles_shown_label" + top_delta="0" + value="Triangles Shown" + width="130" /> + <text + follows="left|top" + halign="right" + height="16" + layout="topleft" + left="10" + name="pixel_area" + top_pad="3" + value="--" + width="40" /> + <loading_indicator + follows="left|top" + height="16" + layout="topleft" + left="34" + name="pixel_area_loading_indicator" + top_delta="0" + width="16" /> + <text + follows="left|top" + height="16" + layout="topleft" + left_pad="10" + name="pixel_area_label" + top_delta="0" + value="Pixel Area" + width="130" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 6877ce6411..2a18134491 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -931,7 +931,7 @@ layout="topleft" left="420" name="Mirrors" - top_delta="24" + top_delta="22" width="240"> <check_box.commit_callback function="Pref.RenderOptionUpdate" /> @@ -1033,7 +1033,7 @@ max_val="1.0" name="RenderSharpness" show_text="true" - top_delta="24" + top_delta="20" width="260"> </slider> <!-- End of Sharpening Settings--> @@ -1084,7 +1084,7 @@ max_val="1.0" name="TonemapMix" show_text="true" - top_delta="22" + top_delta="20" width="260"> </slider> <!-- End of Tone Mapping Settings--> diff --git a/indra/newview/skins/default/xui/en/floater_preview_trash.xml b/indra/newview/skins/default/xui/en/floater_preview_trash.xml index f1c87c8c5a..ebb5cd9251 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_trash.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_trash.xml @@ -29,6 +29,8 @@ bevel_style="none" scroll.reserve_scroll_corner="false"> <folder folder_arrow_image="Folder_Arrow" + favorite_image="Inv_Favorite_Star_Full" + favorite_content_image="Inv_Favorite_Star_Content" folder_indentation="8" item_height="20" item_top_pad="4" diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml index 6633e25099..1600c422c3 100644 --- a/indra/newview/skins/default/xui/en/floater_stats.xml +++ b/indra/newview/skins/default/xui/en/floater_stats.xml @@ -54,6 +54,27 @@ label="jitter" decimal_digits="1" stat="frametimejitter"/> + <stat_bar name="normalized_cumulative_frametime" + label="normalized sess. jitter" + decimal_digits="4" + stat="normalizedframetimejitter"/> + <stat_bar name="normalized_period_jitter" + label="normalized period jitter" + decimal_digits="4" + stat="normalizedframetimejitterperiod"/> + <stat_bar name="normalized_frametime_variation" + label="normalized frametime variation" + decimal_digits="4" + stat="nftv"/> + <stat_bar name="frame_events_per_minute" + label="frame events/minute" + decimal_digits="2" + stat="frametimeeventspm"/> + <stat_bar name="frame_events_last_minute" + label="frame events last min." + decimal_digits="0" + stat="frametimeeventslastmin"/> + <stat_bar name="bandwidth" label="UDP Data Received" stat="activemessagedatareceived" @@ -74,6 +95,38 @@ <stat_view name="render" label="Render" setting="OpenDebugStatRender"> + <stat_bar name="framet_cumulative" + label="jitter cumulative" + decimal_digits="1" + stat="frametimejitcumulative"/> + <stat_bar name="framet_jitter_99th" + label="jitter 99th percentile" + decimal_digits="1" + stat="frametimejitter99"/> + <stat_bar name="framet_jitter_95th" + label="jitter 95th percentile" + decimal_digits="1" + stat="frametimejitter95"/> + <stat_bar name="framet_jitter_stddev" + label="frametime jitter std dev" + decimal_digits="1" + stat="frametimejitterstddev"/> + <stat_bar name="framet_99th" + label="frametime 99th percentile" + decimal_digits="1" + stat="frametime99"/> + <stat_bar name="framet_95th" + label="frametime 95th percentile" + decimal_digits="1" + stat="frametime95"/> + <stat_bar name="framet_stddev" + label="frametime std dev" + decimal_digits="1" + stat="frametimestddev"/> + <stat_bar name="framet_events" + label="frametime events" + decimal_digits="0" + stat="frametimeevents"/> <stat_bar name="ktrisframe" label="KTris per Frame" unit_label="ktris/fr" diff --git a/indra/newview/skins/default/xui/en/floater_test_slapp.xml b/indra/newview/skins/default/xui/en/floater_test_slapp.xml index dd2720816a..5a13a0147e 100644 --- a/indra/newview/skins/default/xui/en/floater_test_slapp.xml +++ b/indra/newview/skins/default/xui/en/floater_test_slapp.xml @@ -8,7 +8,7 @@ width="500"> <floater.string name="remove_folder_slapp"> - secondlife://app/remove_folder/?folder_id= + secondlife:///app/remove_folder/?folder_id= </floater.string> <text type="string" @@ -42,7 +42,7 @@ width="450" layout="topleft" left="16"> - secondlife://app/wear_folder/?folder_name=Daisy + secondlife:///app/wear_folder/?folder_name=Daisy </text> <text type="string" @@ -63,7 +63,7 @@ width="450" layout="topleft" left="16"> - secondlife://app/add_folder/?folder_name=Cardboard%20Boxbot + secondlife:///app/add_folder/?folder_name=Cardboard%20Boxbot </text> <text type="string" @@ -73,7 +73,7 @@ height="16" width="450" layout="topleft"> - secondlife://app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8 + secondlife:///app/add_folder/?folder_id=59219db2-c260-87d3-213d-bb3bc298a3d8 </text> <text type="string" @@ -118,6 +118,6 @@ name="remove_folder_txt" layout="topleft" left="16"> - secondlife://app/remove_folder/?folder_id= + secondlife:///app/remove_folder/?folder_id= </text> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml index 51809793d3..c0d260ef59 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml @@ -22,7 +22,7 @@ increment="0.025" initial_value="0.5" label="Voice Chat" - label_width="50" + label_width="60" layout="topleft" left="15" top="50" diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index 5ab0177de6..0ce64b7a83 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -455,7 +455,7 @@ <panel follows="right|top|bottom" - height="330" + height="235" top_pad="0" width="238" name="layout_panel_4"> @@ -532,9 +532,9 @@ width="16" /> <search_editor follows="top|right" - search_button_visible="false" + search_button_visible="false" height="22" - text_readonly_color="DkGray" + text_readonly_color="DkGray" label="Regions by Name" layout="topleft" top_delta="-2" @@ -542,10 +542,7 @@ name="location" select_on_focus="true" tool_tip="Type the name of a region" - width="152"> - <search_editor.commit_callback - function="WMap.Location" /> - </search_editor> + width="152"/> <button follows="top|right" height="23" @@ -594,6 +591,13 @@ <scroll_list.commit_callback function="WMap.SearchResult" /> </scroll_list> + </panel> + <panel + follows="right|bottom" + height="95" + top_pad="0" + width="238" + name="layout_panel_7"> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml b/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml index 16907d3577..d8090070bd 100644 --- a/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_gallery_inventory.xml @@ -670,6 +670,22 @@ function="Inventory.DoToSelected" parameter="ungroup_folder_items" /> </menu_item_call> + <menu_item_call + label="Add to Favorites" + layout="topleft" + name="Add to Favorites"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="add_to_favorites" /> + </menu_item_call> + <menu_item_call + label="Remove from Favorites" + layout="topleft" + name="Remove from Favorites"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="remove_from_favorites" /> + </menu_item_call> <menu label="Use as default for" layout="topleft" @@ -715,6 +731,136 @@ function="Inventory.CanSetUploadLocation" /> </menu_item_call> </menu> + <menu + label="Upload to folder" + layout="topleft" + name="upload_options"> + <menu_item_call + label="Image..." + layout="topleft" + name="Upload Image"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_texture" /> + <menu_item_call.on_enable + function="File.EnableUpload" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Upload Image,texture" /> + </menu_item_call> + <menu_item_call + label="Sound (L$[COST])..." + layout="topleft" + name="Upload Sound"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_sound" /> + <menu_item_call.on_enable + function="File.EnableUpload" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Upload Sound,sound" /> + </menu_item_call> + <menu_item_call + label="Animation (L$[COST])..." + layout="topleft" + name="Upload Animation"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_animation" /> + <menu_item_call.on_enable + function="File.EnableUpload" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Upload Animation,animation" /> + </menu_item_call> + <menu_item_call + label="Model..." + layout="topleft" + name="Upload Model"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_model" /> + <menu_item_call.on_enable + function="File.EnableUploadModel" /> + <menu_item_call.on_visible + function="File.VisibleUploadModel"/> + </menu_item_call> + <menu_item_call + label="Material..." + layout="topleft" + name="Upload Material"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_pbr_material" /> + <menu_item_call.on_enable + function="File.EnableUploadMaterial" /> + </menu_item_call> + <menu_item_call + label="Bulk..." + layout="topleft" + name="Bulk Upload"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_bulk" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Bulk Upload,texture" /> + </menu_item_call> + </menu> + <menu + label="Use as default for" + layout="topleft" + name="upload_def"> + <menu_item_call + label="Image uploads" + layout="topleft" + name="Image uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_texture" /> + <menu_item_call.on_visible + function="Inventory.CanSetUploadLocation" /> + </menu_item_call> + <menu_item_call + label="Sound uploads" + layout="topleft" + name="Sound uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_sound" /> + <menu_item_call.on_visible + function="Inventory.CanSetUploadLocation" /> + </menu_item_call> + <menu_item_call + label="Animation uploads" + layout="topleft" + name="Animation uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_animation" /> + <menu_item_call.on_visible + function="Inventory.CanSetUploadLocation" /> + </menu_item_call> + <menu_item_call + label="Model uploads" + layout="topleft" + name="Model uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_model" /> + <menu_item_call.on_visible + function="Inventory.CanSetUploadLocation" /> + </menu_item_call> + <menu_item_call + label="PBR material uploads" + layout="topleft" + name="PBR uploads"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_pbr_material" /> + </menu_item_call> + </menu> <menu_item_separator layout="topleft" name="Marketplace Separator" /> diff --git a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml index 99cee83f4e..fb68193006 100755 --- a/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_gallery_outfit_tab.xml @@ -50,6 +50,26 @@ function="Outfit.Thumbnail" /> </menu_item_call> <menu_item_call + label="Add to favorites" + layout="topleft" + name="favorites_add"> + <on_visible + function="Outfit.OnVisible" + parameter="favorites_add" /> + <on_click + function="Outfit.Favorite" /> + </menu_item_call> + <menu_item_call + label="Remove from favorites" + layout="topleft" + name="favorites_remove"> + <on_visible + function="Outfit.OnVisible" + parameter="favorites_remove" /> + <on_click + function="Outfit.Favorite" /> + </menu_item_call> + <menu_item_call label="Edit outfit" layout="topleft" name="edit"> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index d8c7de0e55..f998aefb29 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -950,7 +950,7 @@ function="Inventory.EnvironmentEnabled" /> </menu_item_call> </menu> - </menu> + </menu> <menu_item_call label="Create folder from selected" layout="topleft" @@ -967,6 +967,99 @@ function="Inventory.DoToSelected" parameter="ungroup_folder_items" /> </menu_item_call> + <menu_item_call + label="Add to Favorites" + layout="topleft" + name="Add to Favorites"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="add_to_favorites" /> + </menu_item_call> + <menu_item_call + label="Remove from Favorites" + layout="topleft" + name="Remove from Favorites"> + <menu_item_call.on_click + function="Inventory.DoToSelected" + parameter="remove_from_favorites" /> + </menu_item_call> + <menu + label="Upload to folder" + layout="topleft" + name="upload_options"> + <menu_item_call + label="Image..." + layout="topleft" + name="Upload Image"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_texture" /> + <menu_item_call.on_enable + function="File.EnableUpload" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Upload Image,texture" /> + </menu_item_call> + <menu_item_call + label="Sound (L$[COST])..." + layout="topleft" + name="Upload Sound"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_sound" /> + <menu_item_call.on_enable + function="File.EnableUpload" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Upload Sound,sound" /> + </menu_item_call> + <menu_item_call + label="Animation (L$[COST])..." + layout="topleft" + name="Upload Animation"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_animation" /> + <menu_item_call.on_enable + function="File.EnableUpload" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Upload Animation,animation" /> + </menu_item_call> + <menu_item_call + label="Model..." + layout="topleft" + name="Upload Model"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_model" /> + <menu_item_call.on_enable + function="File.EnableUploadModel" /> + <menu_item_call.on_visible + function="File.VisibleUploadModel"/> + </menu_item_call> + <menu_item_call + label="Material..." + layout="topleft" + name="Upload Material"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_pbr_material" /> + <menu_item_call.on_enable + function="File.EnableUploadMaterial" /> + </menu_item_call> + <menu_item_call + label="Bulk..." + layout="topleft" + name="Bulk Upload"> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="upload_bulk" /> + <menu_item_call.on_visible + function="Upload.CalculateCosts" + parameter="Bulk Upload,texture" /> + </menu_item_call> + </menu> <menu label="Use as default for" layout="topleft" @@ -977,39 +1070,39 @@ name="Image uploads"> <menu_item_call.on_click function="Inventory.FileUploadLocation" - parameter="texture" /> + parameter="def_texture" /> </menu_item_call> <menu_item_call label="Sound uploads" layout="topleft" name="Sound uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="sound" /> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_sound" /> </menu_item_call> <menu_item_call label="Animation uploads" layout="topleft" name="Animation uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="animation" /> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_animation" /> </menu_item_call> <menu_item_call label="Model uploads" layout="topleft" name="Model uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="model" /> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_model" /> </menu_item_call> <menu_item_call label="PBR material uploads" layout="topleft" name="PBR uploads"> - <menu_item_call.on_click - function="Inventory.FileUploadLocation" - parameter="pbr_material" /> + <menu_item_call.on_click + function="Inventory.FileUploadLocation" + parameter="def_pbr_material" /> </menu_item_call> </menu> <menu_item_separator diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml index e249acaccd..d17fbf84b3 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml @@ -138,4 +138,15 @@ function="Inventory.GearDefault.Visible" parameter="multi_folder_view" /> </menu_item_call> + <menu_item_separator/> + <menu_item_check + label="Inventory settings..." + name="inv_settings"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="inventory_settings" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="inventory_settings" /> + </menu_item_check> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml index 33cf01493d..97f53d3a17 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_view_default.xml @@ -100,15 +100,4 @@ function="Inventory.GearDefault.Visible" parameter="single_folder_view" /> </menu_item_check> - <menu_item_separator/> - <menu_item_check - label="Inventory settings..." - name="inv_settings"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="inventory_settings" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="inventory_settings" /> - </menu_item_check> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_object_icon.xml b/indra/newview/skins/default/xui/en/menu_object_icon.xml index f3e520700b..d43ce26e56 100644 --- a/indra/newview/skins/default/xui/en/menu_object_icon.xml +++ b/indra/newview/skins/default/xui/en/menu_object_icon.xml @@ -41,6 +41,17 @@ <menu_item_separator layout="topleft" /> <menu_item_call + label="Zoom in" + layout="topleft" + name="zoom_in"> + <menu_item_call.on_click + function="ObjectIcon.Action" + parameter="obj_zoom_in" /> + <menu_item_call.on_enable + function="ObjectIcon.Visible" + parameter="obj_zoom_in" /> + </menu_item_call> + <menu_item_call label="Show on Map" layout="topleft" name="show_on_map"> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gallery_sort.xml b/indra/newview/skins/default/xui/en/menu_outfit_gallery_sort.xml new file mode 100644 index 0000000000..aa4cd1483d --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_outfit_gallery_sort.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu + layout="topleft" + visible="false" + name="Sort Outfit"> + <menu_item_check + label="Sort favorites to top" + layout="topleft" + visible="true" + name="sort_favorites_to_top"> + <on_click + function="Sort.OnSort" + parameter="favorites_to_top" /> + <on_check + function="Sort.OnEnable" + parameter="favorites_to_top" /> + </menu_item_check> + <menu_item_check + label="Sort images to top" + layout="topleft" + visible="true" + name="sort_images_to_top"> + <on_click + function="Sort.OnSort" + parameter="images_to_top" /> + <on_check + function="Sort.OnEnable" + parameter="images_to_top" /> + </menu_item_check> + <menu_item_check + label="Sort by name" + layout="topleft" + visible="true" + name="sort_by_name"> + <on_click + function="Sort.OnSort" + parameter="by_name" /> + <on_check + function="Sort.OnEnable" + parameter="by_name" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index 8f36c7a00a..e333b05d3e 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -50,6 +50,26 @@ function="Gear.Thumbnail" /> </menu_item_call> <menu_item_call + label="Add to favorite outfits" + layout="topleft" + name="favorites_add"> + <on_visible + function="Gear.OnVisible" + parameter="favorites_add" /> + <on_click + function="Gear.Favorite" /> + </menu_item_call> + <menu_item_call + label="Remove from favorite outfits" + layout="topleft" + name="favorites_remove"> + <on_visible + function="Gear.OnVisible" + parameter="favorites_remove" /> + <on_click + function="Gear.Favorite" /> + </menu_item_call> + <menu_item_call label="Rename outfit" layout="topleft" name="rename"> @@ -89,34 +109,6 @@ function="Gear.OnVisible" parameter="delete" /> </menu_item_call> - <menu_item_separator> - <on_visible - function="Gear.OnVisible"/> - </menu_item_separator> - <menu_item_check - label="Sort folders always by name" - layout="topleft" - name="sort_folders_by_name"> - <on_click - function="Gear.SortByName" /> - <on_check - function="CheckControl" - parameter="OutfitGallerySortByName" /> - </menu_item_check> - <menu_item_call - label="Expand all folders" - layout="topleft" - name="expand"> - <on_click - function="Gear.Expand" /> - </menu_item_call> - <menu_item_call - label="Collapse all folders" - layout="topleft" - name="collapse"> - <on_click - function="Gear.Collapse" /> - </menu_item_call> <menu_item_separator/> <!-- copied (with minor modifications) from menu_inventory_add.xml --> <!-- *TODO: generate dynamically? --> @@ -277,4 +269,19 @@ </menu_item_call> </menu> <!-- copied from menu_inventory_add.xml --> + + <menu_item_separator/> + + <menu_item_check + label="Inventory settings..." + layout="topleft" + visible="true" + name="inventory_settings"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="inventory_settings" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="inventory_settings" /> + </menu_item_check> </toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_list_sort.xml b/indra/newview/skins/default/xui/en/menu_outfit_list_sort.xml new file mode 100644 index 0000000000..0a4d1ea877 --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_outfit_list_sort.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<toggleable_menu + layout="topleft" + visible="false" + name="Sort Outfit"> + <menu_item_call + label="Expand all folders" + layout="topleft" + name="expand"> + <on_click + function="Sort.Expand" /> + </menu_item_call> + <menu_item_call + label="Collapse all folders" + layout="topleft" + visible="true" + name="collapse"> + <on_click + function="Sort.Collapse" /> + </menu_item_call> + + <menu_item_separator/> + + <menu_item_check + label="Sort favorites to top" + layout="topleft" + name="sort_favorites_to_top"> + <on_click + function="Sort.OnSort" + parameter="favorites_to_top" /> + <on_check + function="Sort.OnEnable" + parameter="favorites_to_top" /> + </menu_item_check> + + <menu_item_separator/> + + <menu_item_check + label="Show entire outfit in search" + layout="topleft" + name="show_entire_outfit_in_search"> + <on_click + function="Sort.OnSort" + parameter="show_entire_outfit" /> + <on_check + function="Sort.OnEnable" + parameter="show_entire_outfit" /> + </menu_item_check> +</toggleable_menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml index c6805edd63..0d45e7c95c 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml @@ -50,6 +50,26 @@ function="Outfit.Thumbnail" /> </menu_item_call> <menu_item_call + label="Add to favorites" + layout="topleft" + name="favorites_add"> + <on_visible + function="Outfit.OnVisible" + parameter="favorites_add" /> + <on_click + function="Outfit.Favorite" /> + </menu_item_call> + <menu_item_call + label="Remove from favorites" + layout="topleft" + name="favorites_remove"> + <on_visible + function="Outfit.OnVisible" + parameter="favorites_remove" /> + <on_click + function="Outfit.Favorite" /> + </menu_item_call> + <menu_item_call label="Edit outfit" layout="topleft" name="edit"> diff --git a/indra/newview/skins/default/xui/en/menu_settings_gear.xml b/indra/newview/skins/default/xui/en/menu_settings_gear.xml index 57f4aa8655..96cbac4478 100644 --- a/indra/newview/skins/default/xui/en/menu_settings_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_settings_gear.xml @@ -24,6 +24,9 @@ <menu_item_call.on_click function="MyEnvironments.DoApply" parameter="local" /> + <menu_item_call.on_enable + function="MyEnvironments.CanApply" + parameter="local"/> </menu_item_call> <menu_item_call name="Settings Apply Parcel" diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml index 1874c01f8d..fb6081e1fb 100644 --- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml @@ -26,6 +26,13 @@ <menu_item_separator layout="topleft" /> <menu_item_call + label="Zoom in" + layout="topleft" + name="zoom_in"> + <menu_item_call.on_click + function="Url.ZoomInObject" /> + </menu_item_call> + <menu_item_call label="Show on Map" layout="topleft" name="show_on_map"> diff --git a/indra/newview/skins/default/xui/en/menu_url_parcel.xml b/indra/newview/skins/default/xui/en/menu_url_parcel.xml index e0f1fcf9c3..95752dab66 100644 --- a/indra/newview/skins/default/xui/en/menu_url_parcel.xml +++ b/indra/newview/skins/default/xui/en/menu_url_parcel.xml @@ -16,7 +16,7 @@ layout="topleft" name="show_on_map"> <menu_item_call.on_click - function="Url.ShowOnMap" /> + function="Url.ShowParcelOnMap" /> </menu_item_call> <menu_item_separator layout="topleft" /> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 343f0c0059..081e5be014 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -411,11 +411,11 @@ </menu_item_call> <menu_item_separator/> <menu_item_call - label="Complete avatars..." - name="Avatar Picker"> + label="Avatar Welcome Pack..." + name="Avatar Welcome Pack"> <menu_item_call.on_click function="Floater.ToggleOrBringToFront" - parameter="avatar" /> + parameter="avatar_welcome_pack" /> </menu_item_call> <menu_item_separator/> @@ -1563,6 +1563,64 @@ function="World.EnvPreset" parameter="RenderDisablePostProcessing" /> </menu_item_check> + + <menu + create_jump_keys="true" + label="Selection level of detail" + name="Selection level of detail" + tear_off="true"> + + <menu_item_check + label="Default" + name="Default lod setting"> + <menu_item_check.on_check + function="Tools.ToolsCheckSelectionLODMode" + parameter="default" /> + <menu_item_check.on_click + function="Tools.SelectionLODMode" + parameter="default" /> + </menu_item_check> + <menu_item_check + label="High" + name="High lod setting"> + <menu_item_check.on_check + function="Tools.ToolsCheckSelectionLODMode" + parameter="high" /> + <menu_item_check.on_click + function="Tools.SelectionLODMode" + parameter="high" /> + </menu_item_check> + <menu_item_check + label="Medium" + name="Medium lod setting"> + <menu_item_check.on_check + function="Tools.ToolsCheckSelectionLODMode" + parameter="medium" /> + <menu_item_check.on_click + function="Tools.SelectionLODMode" + parameter="medium" /> + </menu_item_check> + <menu_item_check + label="Low" + name="Low lod setting"> + <menu_item_check.on_check + function="Tools.ToolsCheckSelectionLODMode" + parameter="low" /> + <menu_item_check.on_click + function="Tools.SelectionLODMode" + parameter="low" /> + </menu_item_check> + <menu_item_check + label="Lowest" + name="Lowest lod setting"> + <menu_item_check.on_check + function="Tools.ToolsCheckSelectionLODMode" + parameter="lowest" /> + <menu_item_check.on_click + function="Tools.SelectionLODMode" + parameter="lowest" /> + </menu_item_check> + </menu> <menu_item_separator/> <menu_item_check @@ -2808,12 +2866,18 @@ function="World.EnvPreset" function="Advanced.ForceErrorWorkQueueCrash" /> </menu_item_call> <menu_item_call - label="Force a Crash in a Thread" - name="Force a Crash in a Thread"> + label="Force an LLError Crash in a Thread" + name="Force an LLError Crash in a Thread"> <menu_item_call.on_click function="Advanced.ForceErrorThreadCrash" /> </menu_item_call> <menu_item_call + label="Force an Exception Crash in a Thread" + name="Force an Exception Crash in a Thread"> + <menu_item_call.on_click + function="Advanced.ForceExceptionThreadCrash" /> + </menu_item_call> + <menu_item_call label="Force Disconnect Viewer" name="Force Disconnect Viewer"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml index ee77ef23f0..63d37edf38 100644 --- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml @@ -80,6 +80,20 @@ function="Attachment.Profile" /> </menu_item_call> <menu_item_call + label="Add to favorites" + layout="topleft" + name="favorites_add"> + <on_click + function="Attachment.Favorite" /> + </menu_item_call> + <menu_item_call + label="Remove from favorites" + layout="topleft" + name="favorites_remove"> + <on_click + function="Attachment.Favorite" /> + </menu_item_call> + <menu_item_call label="Show Original" layout="topleft" visible="false" diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml index 321e8a0831..9a752a1643 100644 --- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml @@ -31,6 +31,20 @@ function="Wearing.Detach" parameter="detach"/> </menu_item_call> + <menu_item_call + label="Add to favorites" + layout="topleft" + name="favorites_add"> + <on_click + function="Wearing.Favorite" /> + </menu_item_call> + <menu_item_call + label="Remove from favorites" + layout="topleft" + name="favorites_remove"> + <on_click + function="Wearing.Favorite" /> + </menu_item_call> <menu_item_separator layout="topleft" name="edit_outfit_separator" /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 1a56d7e3a3..b182a241d8 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1322,6 +1322,14 @@ Error encoding snapshot. <notification icon="alertmodal.tga" + name="ErrorEncodingImage" + type="alertmodal"> + Failed to encode image, reason: [REASON] + <tag>fail</tag> + </notification> + + <notification + icon="alertmodal.tga" name="ErrorTextureCannotAfford" type="alertmodal"> You need L$[COST] to save a texture to your inventory. You may either buy L$ or save the photo to your computer instead. @@ -3139,9 +3147,13 @@ Would you be my friend? <input name="listname" type="text"/> <button default="true" - index="0" + index="1" name="SetName" text="OK"/> + <button + index="0" + name="Cancel" + text="Cancel"/> </form> </notification> @@ -3170,6 +3182,29 @@ Would you be my friend? <notification icon="alertmodal.tga" + label="Rename Auto-Replace List" + name="RemoveAutoReplaceList" + type="alertmodal"> +'[LIST_NAME]' contains [MAP_SIZE] entries. + +Are you sure you want to delete this list? + <tag>confirm</tag> + <form name="form"> + <button + default="true" + index="1" + name="DeleteList" + text="Delete"/> + <button + default="false" + index="0" + name="Cancel" + text="Cancel"/> + </form> + </notification> + + <notification + icon="alertmodal.tga" name="InvalidAutoReplaceEntry" type="alertmodal"> The keyword must be a single word, and the replacement may not be empty. @@ -4628,13 +4663,12 @@ You already have blocked this name. <notification icon="alert.tga" - name="RemoveItemWarn" + name="CantModifyContentInNoModTask" type="alert"> -Though permitted, deleting contents may damage the object. Do you want to delete that item? +You don't have permission to modify content of this object <tag>confirm</tag> <usetemplate - name="okcancelbuttons" - notext="Cancel" + name="okbutton" yestext="OK"/> </notification> @@ -7136,6 +7170,20 @@ You don't have permission to view this notecard. </notification> <notification + icon="alertmodal.tga" + name="MaterialImagesWereScaled" + type="alertmodal"> +One or more textures in this material were scaled to be within the allowed limits. +Textures must have power of two dimensions and must not exceed [MAX_SIZE]x[MAX_SIZE] pixels. + <unique/> + <tag>confirm</tag> + <usetemplate + ignoretext="Warn if textures will be scaled during upload." + name="okignore" + yestext="OK"/> + </notification> + + <notification icon="notifytip.tga" name="RezItemNoPermissions" type="notifytip"> @@ -9453,8 +9501,11 @@ Unable to upload texture: '[NAME]' icon="alertmodal.tga" name="CannotUploadMaterial" type="alertmodal"> -There was a problem uploading the file +Unable to upload material file. The file may be corrupted, in an unsupported format, or contain invalid data. Please check that you're using a valid GLTF/GLB file with proper material definitions. <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> </notification> <notification @@ -12610,4 +12661,24 @@ are wearing now. notext="Cancel" yestext="Continue"/> </notification> + + <notification + icon="notify.tga" + name="WaterExclusionNoMaterial" + persist="true" + type="notify"> + Unable to apply material to the water exclusion surface. + <tag>fail</tag> + </notification> + + <notification + icon="notify.tga" + name="ImageUploadResized" + type="alertmodal"> + The texture you are uploading has been resized from [ORIGINAL_WIDTH]x[ORIGINAL_HEIGHT] to [NEW_WIDTH]x[NEW_HEIGHT] in order to to fit the maximum size of [MAX_WIDTH]x[MAX_HEIGHT] pixels. + <usetemplate + ignoretext="Image Upload Resized" + name="okignore" + yestext="OK"/> + </notification> </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_inventory_gallery_item.xml b/indra/newview/skins/default/xui/en/panel_inventory_gallery_item.xml index 73cb9b080f..f5906c17fd 100644 --- a/indra/newview/skins/default/xui/en/panel_inventory_gallery_item.xml +++ b/indra/newview/skins/default/xui/en/panel_inventory_gallery_item.xml @@ -43,6 +43,16 @@ follows="left|top" visible="false" image_name="Inv_Link"/> + <icon + layout="topleft" + follows="left|top" + name="fav_icon" + left="110" + top_pad="-14" + height="14" + width="14" + visible="true" + image_name="Inv_Favorite_Star_Full"/> <panel background_visible="false" background_opaque="true" diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml deleted file mode 100644 index d6ac71db94..0000000000 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ /dev/null @@ -1,262 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel - follows="all" - height="768" - layout="topleft" - name="panel_login" - focus_root="true" - background_visible="true" - bg_opaque_color="0.16 0.16 0.16 1" - background_opaque="true" - width="1024"> - <panel.string - name="forgot_password_url"> - http://secondlife.com/account/request.php - </panel.string> - <panel.string - name="sign_up_url"> - https://join.secondlife.com/ - </panel.string> - <layout_stack - follows="left|right|top|bottom" - width="1024" - height="768" - left="0" - name="logo_stack" - orientation="vertical" - top="0"> - <layout_panel - height="18" - auto_resize="false" - name="page_top" - width="1024" /> - <!-- start of logo stack --> - <layout_panel - height="130" - min_height="10" - auto_resize="false" - name="parent_panel" - width="1024"> - <layout_stack - follows="left|right|top|bottom" - height="100" - left="0" - name="logo_stack" - orientation="horizontal" - top="0" - width="1024"> - <layout_panel - height="110" - min_height="10" - auto_resize="true" - name="logo_left" - width="300" /> - <layout_panel - auto_resize="false" - follows="left|right|top" - name="logo_container" - width="225" - left="0" - top="0" - height="105"> - <icon - height="94" - image_name="login_sl_logo" - left="0" - name="sl_logo" - top="0" /> - </layout_panel> - <layout_panel - height="100" - name="logo_right" - auto_resize="true" - width="300" /> - </layout_stack> - </layout_panel> - <!-- end of logo stack --> - <!-- start of widget stack --> - <layout_panel - height="100" - min_height="10" - auto_resize="false" - name="parent_panel2" - width="1024"> - <layout_stack - follows="left|right|top|bottom" - height="80" - left="0" - name="widget_stack" - orientation="horizontal" - top="0" - width="1024"> - <layout_panel - height="80" - min_height="10" - auto_resize="true" - name="widget_left" - width="200" /> - <layout_panel - auto_resize="false" - follows="left|right|top" - name="widget_container" - width="730" - left="0" - top="0" - height="80"> - <combo_box - allow_text_entry="true" - follows="left|bottom" - height="32" - left="42" - label="Username" - combo_editor.font="SansSerifLarge" - max_chars="128" - top="0" - combo_editor.prevalidator="ascii" - tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" - name="username_combo" - width="232"> - <combo_box.combo_editor - text_pad_left="8" /> - <combo_box.combo_button - visible ="false"/> - <combo_box.drop_down_button - visible ="false"/> - </combo_box> - <line_editor - follows="left|top" - width="200" - height="32" - left="262" - max_length_chars="16" - name="password_edit" - label="Password" - text_pad_left="8" - font="SansSerifLarge" - is_password="true" - select_on_focus="true" - commit_on_focus_lost="false" - top="0" /> - <button - follows="left|top" - image_unselected="PushButton_Login" - image_pressed="PushButton_Login_Pressed" - image_hover_unselected="PushButton_Login_Over" - label="Log In" - label_color="White" - font="SansSerifLarge" - name="connect_btn" - left_pad="15" - width="120" - height="32" - top="0" /> - <text - follows="left|top" - font="SansSerifLarge" - font.style="BOLD" - text_color="EmphasisColor" - height="34" - name="sign_up_text" - left_pad="10" - top="0" - width="200" - valign="center"> - Sign up - </text> - <check_box - follows="left|top" - font="SansSerifLarge" - left="42" - top="32" - height="24" - label="Remember me" - word_wrap="down" - check_button.bottom="3" - name="remember_name" - tool_tip="Already remembered user can be forgotten from Me > Preferences > Advanced > Remembered Usernames." - width="198" /> - <check_box - control_name="RememberPassword" - follows="left|top" - font="SansSerifLarge" - height="24" - left="262" - bottom_delta="0" - label="Remember password" - word_wrap="down" - check_button.bottom="3" - name="remember_password" - width="198" /> - <text - follows="left|top" - font="SansSerifLarge" - text_color="EmphasisColor" - height="16" - name="forgot_password_text" - left="492" - top="34" - width="200"> - Forgotten password - </text> - </layout_panel> - <layout_panel - height="100" - name="widget_right" - auto_resize="true" - width="200" /> - </layout_stack> - </layout_panel> - <!-- end of widget stack --> - <!-- start of images stack --> - <layout_panel - height="500" - min_height="10" - auto_resize="false" - name="parent_panel3" - width="1024"> - <layout_stack - follows="left|right|top|bottom" - height="500" - left="0" - name="images_stack" - orientation="horizontal" - top="0" - width="1024"> - <layout_panel - height="500" - min_height="10" - auto_resize="true" - name="images_left" - width="96" /> - <layout_panel - auto_resize="false" - follows="left|right|top" - name="images_container" - width="675" - left="0" - top="0" - height="500"> - <icon - height="450" - width="675" - image_name="first_login_image" - left="0" - name="image_left" - top="0" /> - </layout_panel> - <layout_panel - height="100" - name="images_right" - auto_resize="true" - width="96" /> - </layout_stack> - </layout_panel> - <!-- end of images stack --> - <layout_panel - height="400" - min_height="10" - auto_resize="true" - name="page_bottom" - width="1024" /> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index 498dab1ef3..6e1e6facbe 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -269,6 +269,22 @@ scroll.reserve_scroll_corner="false"> <folder double_click_override="true"/> </inventory_panel> + <favorites_inventory_panel + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + follows="all" + label="FAVORITES" + help_topic="recent_inventory_tab" + layout="topleft" + name="Favorites" + show_item_link_overlays="true" + preinitialize_views="false" + scroll.reserve_scroll_corner="false"> + <folder double_click_override="true"/> + </favorites_inventory_panel> </tab_container> </panel> <panel diff --git a/indra/newview/skins/default/xui/en/panel_marketplace_listings_inventory.xml b/indra/newview/skins/default/xui/en/panel_marketplace_listings_inventory.xml index a8a306bea9..9586957694 100644 --- a/indra/newview/skins/default/xui/en/panel_marketplace_listings_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_marketplace_listings_inventory.xml @@ -21,5 +21,5 @@ border="false" bevel_style="none" show_item_link_overlays="true"> - <item allow_wear="false"/> + <item marketplace_item="true"/> </inventory_panel> diff --git a/indra/newview/skins/default/xui/en/panel_marketplace_listings_listed.xml b/indra/newview/skins/default/xui/en/panel_marketplace_listings_listed.xml index 0c665fb07e..5f64a5d47a 100644 --- a/indra/newview/skins/default/xui/en/panel_marketplace_listings_listed.xml +++ b/indra/newview/skins/default/xui/en/panel_marketplace_listings_listed.xml @@ -20,5 +20,5 @@ border="false" bevel_style="none" show_item_link_overlays="true"> - <item allow_wear="false"/> + <item marketplace_item="true"/> </inventory_panel> diff --git a/indra/newview/skins/default/xui/en/panel_marketplace_listings_unassociated.xml b/indra/newview/skins/default/xui/en/panel_marketplace_listings_unassociated.xml index 0be405c5b8..ab4d836ba9 100644 --- a/indra/newview/skins/default/xui/en/panel_marketplace_listings_unassociated.xml +++ b/indra/newview/skins/default/xui/en/panel_marketplace_listings_unassociated.xml @@ -19,5 +19,5 @@ border="false" bevel_style="none" show_item_link_overlays="true"> - <item allow_wear="false"/> + <item marketplace_item="true"/> </inventory_panel> diff --git a/indra/newview/skins/default/xui/en/panel_marketplace_listings_unlisted.xml b/indra/newview/skins/default/xui/en/panel_marketplace_listings_unlisted.xml index 58122db7f4..303601e65b 100644 --- a/indra/newview/skins/default/xui/en/panel_marketplace_listings_unlisted.xml +++ b/indra/newview/skins/default/xui/en/panel_marketplace_listings_unlisted.xml @@ -20,5 +20,5 @@ border="false" bevel_style="none" show_item_link_overlays="true"> - <item allow_wear="false"/> + <item marketplace_item="true"/> </inventory_panel> diff --git a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml index 6bd491f7a3..96624e7aa2 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_gallery.xml @@ -35,7 +35,7 @@ </text> <scroll_container follows="all" - height="400" + height="429" width="312" layout="topleft" left="4" @@ -44,49 +44,5 @@ name="gallery_scroll_panel" opaque="false" top_pad="0"> - </scroll_container> - <panel - background_visible="true" - follows="bottom|left|right" - height="28" - layout="topleft" - left="4" - top_pad="0" - visible="true" - name="bottom_panel" - width="312"> - <menu_button - follows="bottom|left" - tool_tip="Show additional options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="options_gear_btn" - top="1" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="243"/> - <button - follows="bottom|right" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="TrashItem_Off" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="trash_btn" - tool_tip="Delete selected outfit" - width="31"/> - </panel> + </scroll_container> </panel> 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 9281a21fbf..b38e2b2b50 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_list.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_list.xml @@ -16,7 +16,7 @@ bg_opaque_color="DkGray2" follows="all" - height="400" + height="428" layout="topleft" left="3" name="outfits_accordion" @@ -30,48 +30,4 @@ name="no_outfits_msg" value="You don't have any outfits yet. Try [secondlife:///app/search/all/ Search]"/> </accordion> - <panel - background_visible="true" - follows="bottom|left|right" - height="28" - layout="topleft" - left="4" - top_pad="0" - visible="true" - name="bottom_panel" - width="312"> - <menu_button - follows="bottom|left" - tool_tip="Show additional options" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="options_gear_btn" - top="1" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Middle_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="243"/> - <button - follows="bottom|right" - height="25" - image_hover_unselected="Toolbar_Right_Over" - image_overlay="TrashItem_Off" - image_selected="Toolbar_Right_Selected" - image_unselected="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="trash_btn" - tool_tip="Delete selected outfit" - width="31"/> - </panel> </panel> 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 a486c03ac7..ceefe9f6fb 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml @@ -16,7 +16,7 @@ <accordion fit_parent="true" follows="all" - height="400" + height="429" layout="topleft" left="3" single_expansion="true" @@ -62,35 +62,4 @@ </scroll_list> </accordion_tab> </accordion> - <panel - background_visible="true" - follows="bottom|left|right" - height="28" - layout="topleft" - left="4" - name="bottom_panel" - top_pad="0" - width="312"> - <menu_button - follows="bottom|left" - height="25" - image_hover_unselected="Toolbar_Left_Over" - image_overlay="OptionsMenu_Off" - image_selected="Toolbar_Left_Selected" - image_unselected="Toolbar_Left_Off" - layout="topleft" - left="0" - name="options_gear_btn" - tool_tip="Show additional options" - top="1" - width="31" /> - <icon - follows="bottom|left|right" - height="25" - image_name="Toolbar_Right_Off" - layout="topleft" - left_pad="1" - name="dummy_icon" - width="274" /> - </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index c31e6c94ea..1be34550fa 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -177,6 +177,25 @@ Learn about [https://community.secondlife.com/knowledgebase/joining-and-particip function="People.DelFriend" /> </dnd_button> </panel> + <slider + control_name="NearMeRange" + decimal_digits="0" + increment="1" + follows="left|top" + left="5" + min_val="0" + max_val="4096" + label="Range:" + name="near_me_range" + tool_tip="Nearby people range" + width="230"/> + <text + type="string" + follows="left|top" + left_delta="225" + name="near_me_range_text2"> + m + </text> <layout_stack clip="false" follows="all" @@ -216,7 +235,7 @@ Learn about [https://community.secondlife.com/knowledgebase/joining-and-particip <avatar_list allow_select="true" follows="all" - height="211" + height="197" ignore_online_status="true" layout="topleft" left="3" diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index a3a2f7c47e..1bda5c019c 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -19,7 +19,7 @@ background_visible="true" value="VISITED" /> <string name="favorites_tab_title" - value="FAVORITES" /> + value="FAVORITES BAR" /> <string name="tooltip_trash_items" value="Remove selected landmark or folder" /> 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 8051ffa8ec..86999b1afb 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -32,15 +32,15 @@ height="23" increment="64" initial_value="1024" - label="Cache size (256 - 9984MB)" + label="Cache size (896 - 32768MB)" label_width="150" layout="topleft" left="80" - max_val="9984" - min_val="256" + max_val="32768" + min_val="896" top_pad="10" name="cachesizespinner" - width="200" /> + width="210" /> <text type="string" length="1" @@ -59,7 +59,7 @@ label="Clear Cache" label_selected="Clear Cache" layout="topleft" - left_pad="30" + left_pad="20" name="clear_cache" top_delta="0" width="100"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index 88716c7f96..0aa1af7de6 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -409,7 +409,7 @@ layout="topleft" left="0" name="play_sound" - width="100" + width="90" top_pad="8" visible="true"> Play sound: @@ -419,10 +419,10 @@ height="16" label="New conversation" layout="topleft" - left_pad="15" + left_pad="5" top_pad="-10" name="new_conversation" - width="150" /> + width="130" /> <check_box control_name="PlaySoundIncomingVoiceCall" height="16" @@ -430,16 +430,16 @@ layout="topleft" top_pad="6" name="incoming_voice_call" - width="150" /> + width="130" /> <check_box control_name="PlaySoundTeleportOffer" height="16" label="Teleport offer" layout="topleft" - left_pad="35" + left_pad="18" top_pad="-38" name="teleport_offer" - width="150" /> + width="130" /> <check_box control_name="PlaySoundInventoryOffer" height="16" @@ -447,14 +447,23 @@ layout="topleft" top_pad="6" name="inventory_offer" - width="150" /> + width="130" /> + <check_box + control_name="PlaySoundChatMention" + height="16" + label="Chat mention" + layout="topleft" + left_pad="7" + top_pad="-38" + name="chat_mention" + width="130" /> <view_border bevel_style="none" height="0" layout="topleft" left="0" name="cost_text_border" - top_pad="7" + top_pad="29" width="492"/> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml index 44df5354aa..8a09e15396 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml @@ -299,6 +299,107 @@ width="95"> URLs </text> + <color_swatch + can_apply_immediately="true" + color="EmphasisColor" + follows="left|top" + height="24" + label_height="0" + layout="topleft" + left="360" + name="mentions" + top_pad="-15" + width="44" > + <color_swatch.init_callback + function="Pref.getUIColor" + parameter="ChatMentionFont" /> + <color_swatch.commit_callback + function="Pref.applyUIColor" + parameter="ChatMentionFont" /> + </color_swatch> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_pad="5" + mouse_opaque="false" + name="text_mentions" + top_delta="5" + width="95"> + Mentions + </text> + <text + follows="left|top" + layout="topleft" + left="30" + height="12" + name="mentions_colors" + top_pad="20" + width="170"> + Chat mentions highlight colors: + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="24" + label_height="0" + layout="topleft" + left="40" + name="mention_self" + top_pad="10" + width="44" > + <color_swatch.init_callback + function="Pref.getUIColor" + parameter="ChatSelfMentionHighlight" /> + <color_swatch.commit_callback + function="Pref.applyUIColor" + parameter="ChatSelfMentionHighlight" /> + </color_swatch> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_pad="5" + mouse_opaque="false" + name="text_mentions_self" + top_delta="5" + width="95"> + Me + </text> + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="24" + label_height="0" + layout="topleft" + left="190" + name="mention_others" + top_pad="-15" + width="44" > + <color_swatch.init_callback + function="Pref.getUIColor" + parameter="ChatMentionHighlight" /> + <color_swatch.commit_callback + function="Pref.applyUIColor" + parameter="ChatMentionHighlight" /> + </color_swatch> + <text + type="string" + length="1" + follows="left|top" + height="10" + layout="topleft" + left_pad="5" + mouse_opaque="false" + name="text_mentions_others" + top_delta="5" + width="95"> + Others + </text> <text follows="left|top" layout="topleft" 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 7481e10ed2..bf07ae4d68 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -230,40 +230,6 @@ width="128"> m </text> - <slider - control_name="IndirectMaxNonImpostors" - name="IndirectMaxNonImpostors" - decimal_digits="0" - increment="1" - initial_value="12" - show_text="false" - min_val="1" - max_val="66" - label="Maximum number of animated avatars:" - follows="left|top" - layout="topleft" - height="16" - label_width="240" - left="30" - top_delta="40" - width="393"> - <slider.commit_callback - function="Pref.UpdateIndirectMaxNonImpostors" - parameter="IndirectNonImpostorsText" /> - </slider> - <text - type="string" - length="1" - follows="left|top" - height="16" - layout="topleft" - top_delta="0" - left_delta="397" - text_readonly_color="LabelDisabledColor" - name="IndirectMaxNonImpostorsText" - width="65"> - 0 - </text> <button height="23" @@ -347,6 +313,41 @@ 0 </text> + <slider + control_name="IndirectMaxNonImpostors" + name="IndirectMaxNonImpostors" + decimal_digits="0" + increment="1" + initial_value="12" + show_text="false" + min_val="1" + max_val="66" + label="Maximum number of animated avatars:" + follows="left|top" + layout="topleft" + height="16" + label_width="240" + left="30" + top_delta="20" + width="393"> + <slider.commit_callback + function="Pref.UpdateIndirectMaxNonImpostors" + parameter="IndirectNonImpostorsText" /> + </slider> + <text + type="string" + length="1" + follows="left|top" + height="16" + layout="topleft" + top_delta="0" + left_delta="397" + text_readonly_color="LabelDisabledColor" + name="IndirectMaxNonImpostorsText" + width="65"> + 0 + </text> + <button height="23" label="Exceptions..." diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml index 0412466b4f..4aafceb112 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml @@ -113,7 +113,7 @@ control_name="ArrowKeysAlwaysMove" follows="left|top" height="20" - label="Arrow keys always move me" + label="Arrow keys always move me while in chat" layout="topleft" left_delta="5" name="arrow_keys_move_avatar_check" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 5041fb4878..1c00837073 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -1,15 +1,31 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel + <panel border="true" follows="left|top|right|bottom" - height="408" - label="Communication" + height="438" + label="Privacy" layout="topleft" left="102" - name="im" + name="Privacy panel" top="1" width="517"> + <tab_container + top_pad="0" + enabled="true" + follows="left|top" + height="430" + width="517" + left_delta="0" + name="privacy_tab_container" + tab_position="top" + tab_stop="false"> + <panel + label="General" + name="privacy_preferences_general" + layout="topleft" + follows="top|left"> + <panel.string name="log_in_to_change"> log in to change @@ -63,7 +79,7 @@ name="online_visibility" top_pad="30" width="350" /> - + <check_box enabled_control="EnableVoiceChat" control_name="AutoDisengageMic" @@ -74,6 +90,37 @@ name="auto_disengage_mic_check" top_pad="10" width="350" /> + <check_box + control_name="EnableLookAtTarget" + height="16" + label="Enable LookAt" + tool_tip="Enable tracking cursor position with avatar head's rotation" + layout="topleft" + left="30" + name="enable_lookat_target" + top_pad="10" + width="350" /> + <check_box + enabled_control="EnableLookAtTarget" + control_name="LimitLookAtTarget" + height="16" + label="Limit LookAt Distance" + tool_tip="Limit the look at target's distance by restricting it around the avatar's head" + layout="topleft" + left="50" + name="limit_lookat_distance" + top_pad="10" + width="350" /> + <check_box + control_name="EnableSelectionHints" + height="16" + label="Enable Selection Hints" + tool_tip="Enable reporting and tracking current selection using 'beam' particles and character animations" + layout="topleft" + left="30" + name="enable_selection_hints" + top_pad="10" + width="350" /> <button follows="left|top" height="23" @@ -103,3 +150,48 @@ (People and/or Objects you have blocked) </text> </panel> + + <panel + label="Discord" + name="privacy_preferences_discord" + layout="topleft" + follows="top|left"> + + <check_box + control_name="EnableDiscord" + height="16" + enabled="true" + label="Enable Discord integration" + layout="topleft" + left="30" + name="enable_discord" + top_pad="20" + width="350" /> + + <check_box + enabled_control="EnableDiscord" + control_name="ShowDiscordActivityDetails" + height="16" + enabled="true" + label="Show avatar name" + layout="topleft" + left="30" + name="show_name" + top_pad="20" + width="350" /> + + <check_box + enabled_control="EnableDiscord" + control_name="ShowDiscordActivityState" + height="16" + enabled="false" + label="Show location" + layout="topleft" + left="30" + name="show_location" + top_pad="20" + width="350" /> + </panel> + </tab_container> + +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index d909a56733..52413abe74 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -62,20 +62,9 @@ name="mute_when_minimized" top_delta="3" left_pad="5" - width="20" /> - <!-- *HACK - After storm-1109 will be fixed: instead of using this text_box, word_wrap should be applied for "mute_when_minimized" check_box's label.--> - <text - follows="top|left" - height="15" - layout="topleft" - left_pad="0" - name="mute_chb_label" - top_delta="-1" - width="150" - wrap="true"> - Mute when minimized - </text> + width="20" + label="Mute when minimized" + word_wrap="true"/> <slider control_name="AudioLevelUI" disabled_control="MuteAudio" @@ -321,66 +310,45 @@ left_pad="5" name="enable_voice_check" width="110"/> - <!-- --> <text type="string" length="1" follows="left|top" layout="topleft" left="23" - top_delta="22" + top_delta="25" name="Listen media from" height="15" - word_wrap="true" - width="112"> - Hear media and sounds from: + width="165" + halign="right"> + Hear media and sounds from </text> - <radio_group + <combo_box control_name="MediaSoundsEarLocation" follows="left|top" - top_delta="-6" layout="topleft" - left_pad="10" - width="360" - height="40" - name="media_ear_location"> - <radio_item - height="19" - label="Camera position" - follows="left|top" - layout="topleft" - name="0" - width="200"/> - <radio_item - height="19" - follows="left|top" - label="Avatar position" - layout="topleft" - left_delta="0" - name="1" - top_delta ="18" - width="200" /> - </radio_group> - <check_box - name="media_show_on_others_btn" - control_name="MediaShowOnOthers" - value="true" - follows="left|top" - layout="topleft" - height="15" - top_pad="8" - tool_tip="Uncheck this to hide media attached to other avatars nearby" - label="Play media attached to other avatars" - left="20" - width="230"/> + left_pad="5" + width="130" + height="23" + top_delta="-4" + name="media_ear_location_combo"> + <item + label="Camera position" + name="camera_position" + value="0" /> + <item + label="Avatar position" + name="avatar_position" + value="1" /> +</combo_box> <text follows="left|top" layout="topleft" height="15" left="23" - top_pad="8" - width="120" - name="media_autoplay_label"> + width="165" + name="media_autoplay_label" + halign="right"> Auto-play media </text> <combo_box @@ -389,10 +357,10 @@ follows="left|top" layout="topleft" height="23" - left_pad="-15" + left_delta="170" top_delta="-4" name="media_auto_play_combo" - width="115"> + width="130"> <item label="Never" name="autoplay_disabled" @@ -406,23 +374,106 @@ name="autoplay_ask" value="2"/> </combo_box> + <text + follows="left|top" + layout="topleft" + height="15" + left="23" + width="165" + name="media_firstinteract_label" + halign="right"> + Media first-interact + </text> + <combo_box + control_name="MediaFirstClickInteract" + enabled_control="AudioStreamingMedia" + follows="left|top" + layout="topleft" + height="23" + left_delta="170" + top_delta="-4" + width="130" + name="media_first_interact_combo" + tool_tip="This setting controls which media (once loaded) does not require a first click to focus before interaction can begin. This allows clicks to be passed directly to media bypassing the focus click requirement. Each option also inherits the previous ones."> + <item + label="Disabled" + name="media_first_click_none" + value="0"/> + <item + label="Worn HUDs only" + name="media_first_click_hud" + value="1"/> + <item + label="Owned objects" + name="media_first_click_own" + value="3"/> + <item + label="Friends' objects" + name="media_first_click_friend" + value="7"/> + <item + label="Group objects" + name="media_first_click_group" + value="15"/> + <item + label="Landowner objects" + name="media_first_click_land" + value="31"/> + <item + label="Anyone's objects" + name="media_first_interact_any" + value="32767"/> + <item + label="All MOAP" + name="media_first_click_all" + value="65535"/> + </combo_box> + <check_box + name="media_show_on_others_btn" + control_name="MediaShowOnOthers" + enabled_control="AudioStreamingMedia" + value="true" + follows="left|top" + tool_tip="Uncheck this to hide media attached to other avatars nearby" + label="Play media attached to other avatars" + left="23" + width="15" + top_delta="30" + height="15"/> + <check_box + name="media_huds_autoplay" + control_name="MediaAutoPlayHuds" + enabled_control="AudioStreamingMedia" + value="true" + follows="left|top" + layout="topleft" + tool_tip="Uncheck this to make HUDs follow the standard media auto-play setting" + label="Auto-play media attached to your HUD" + left="260" + top_pad="-15" + width="15" + height="15"/> <text layout="topleft" + follows="left" height="15" - left="260" - top_pad="-18" - width="100" - name="noise_suppression_label"> - Noise Suppression + width="165" + name="noise_suppression_label" + left="23" + top_delta="22" + halign="right"> + Microphone Noise Suppression </text> <combo_box control_name="VoiceNoiseSuppressionLevel" + enabled_control="EnableVoiceChat" + follows="left|top" layout="topleft" + left_delta="170" + top_delta="-6" + width="130" height="23" - left_pad="10" - top_pad="-20" - name="noise_suppression_combo" - width="80"> + name="noise_suppression_combo"> <item label="Off" name="noise_suppression_none" @@ -452,48 +503,44 @@ left="23" top_delta="30" name="Listen from" - width="112"> - Hear voice from: + width="165" + height="15" + halign="right"> + Hear voice from </text> - <radio_group + <combo_box enabled_control="EnableVoiceChat" control_name="VoiceEarLocation" follows="left|top" layout="topleft" - left_pad="10" + left_delta="170" top_delta="-6" - width="360" - height="40" - name="ear_location"> - <radio_item - height="19" - label="Camera position" - follows="left|top" - layout="topleft" - name="0" - width="200"/> - <radio_item - height="19" - follows="left|top" - label="Avatar position" - layout="topleft" - left_delta="0" - name="1" - top_delta ="18" - width="200" /> - </radio_group> + width="130" + height="23" + name="ear_location_combo"> + <item + label="Camera position" + name="camera_position" + value="0" /> + <item + label="Avatar position" + name="avatar_position" + value="1" /> +</combo_box> <check_box control_name="LipSyncEnabled" + enabled_control="EnableVoiceChat" follows="left|top" height="15" label="Move avatar lips when speaking" layout="topleft" left="20" name="enable_lip_sync" - top_pad="10" + top_pad="8" width="237"/> <check_box control_name="VoiceEchoCancellation" + enabled_control="EnableVoiceChat" height="15" tool_tip="Check to enable voice echo cancellation" label="Echo Cancellation" @@ -516,6 +563,7 @@ top_pad="5"/> <check_box control_name="VoiceAutomaticGainControl" + enabled_control="EnableVoiceChat" height="15" tool_tip="Check to enable automatic gain control" label="Automatic Gain Control" @@ -537,6 +585,7 @@ left="20"/> <check_box control_name="VoiceVisualizerEnabled" + enabled_control="EnableVoiceChat" height="15" tool_tip="Check to show voice dot indicator above avatars" label="Show voice dot above avatars" @@ -547,6 +596,7 @@ width="200"/> <button control_name="ShowDeviceSettings" + enabled_control="EnableVoiceChat" follows="left|top" height="23" is_toggle="true" diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml index 024120931f..4f441b9b49 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml @@ -200,6 +200,26 @@ <layout_panel follows="all" + layout="bottomleft" + left_pad="2" + name="set_to_curr_location_btn_lp" + auto_resize="false" + width="100"> + <button + name="set_to_curr_location_btn" + label="Set Location" + tool_tip="Set to Current Location" + left="0" + top="0" + height="23" + width="100" + follows="left|top" + layout="topleft" + /> + </layout_panel> + + <layout_panel + follows="all" layout="topleft" name="util_resizer_right" auto_resize="true" diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml index 7687f7cd96..23bbf45e88 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_clouds.xml @@ -139,7 +139,7 @@ max_val_x="30" min_val_y="-30" max_val_y="30" - logarithmic="1"/> + logarithmic="true"/> <text name="cloud_image_label" diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml index bd68434aab..34b48574d5 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml @@ -248,29 +248,13 @@ </layout_panel> <layout_panel - name="moon_layout" - border="false" + border="true" bevel_style="in" + name="moon_layout" auto_resize="true" user_resize="false" visible="true" height="400"> - <layout_stack - name="moon_stack" - left="5" - top="5" - right="-5" - bottom="-5" - follows="left|top|right|bottom" - orientation="vertical"> - <layout_panel - border="true" - bevel_style="in" - auto_resize="true" - user_resize="false" - visible="true" - name="moon_layout" - height="220"> <text name="moon_label" follows="left|top" @@ -423,9 +407,7 @@ name="moonbeacon" top_pad="5" left_delta="-8"/> - - </layout_panel> - </layout_stack> + </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_settings_water.xml b/indra/newview/skins/default/xui/en/panel_settings_water.xml index e062f1710b..ffea470cfc 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_water.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_water.xml @@ -247,7 +247,7 @@ Reflection Wavelet Scale </text> <slider - decimal_digits="1" + decimal_digits="2" follows="left|top" increment="0.01" height="16" @@ -261,7 +261,7 @@ width="150" can_edit_text="true"/> <slider - decimal_digits="1" + decimal_digits="2" follows="left|top" increment="0.01" initial_value="0.7" @@ -274,7 +274,7 @@ width="150" can_edit_text="true"/> <slider - decimal_digits="1" + decimal_digits="2" follows="left|top" increment="0.01" initial_value="0.7" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml index 68878baa0d..0cac1b410f 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_inventory.xml @@ -119,6 +119,8 @@ type="string" word_wrap="true"> To save your image as a texture select one of the square formats. + +Upload cost: L$[UPLOAD_COST] </text> <button follows="right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml index 3a7731d235..2fb02af61c 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml @@ -31,7 +31,7 @@ image_overlay_alignment="left" image_top_pad="-1" imgoverlay_label_space="10" - label="Save to Inventory (L$[AMOUNT])" + label="Save to Inventory" layout="topleft" left_delta="0" name="save_to_inventory_btn" diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 4501e0df3a..cf52916484 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -86,7 +86,7 @@ height="18" left="0" name="balance" - tool_tip="Click to refresh your L$ balance" + tool_tip="L$ [AMT] Click to refresh your L$ balance. Double-click to display or hide your L$ balance." v_pad="4" top="0" wrap="false" diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index af6a9b94d9..1c70383bf9 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -968,8 +968,8 @@ label_width="205" layout="topleft" left="10" - min_val="-100" - max_val="100" + min_val="-10000" + max_val="10000" name="gltfTextureScaleU" top_delta="34" width="265" /> @@ -981,11 +981,24 @@ label_width="205" layout="topleft" left="10" - min_val="-100" - max_val="100" + min_val="-10000" + max_val="10000" name="gltfTextureScaleV" width="265" /> <spinner + decimal_digits="1" + follows="left|top" + height="19" + initial_value="" + label="Repeats per meter" + layout="topleft" + label_width="205" + left="10" + max_val="100" + min_val="-100" + name="gltfRptctrl" + width="265" /> + <spinner follows="left|top" height="19" initial_value="0" diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index c898b0989e..a16b0b58da 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -64,7 +64,7 @@ width="333"> font="SansSerifSmall" text_color="EmphasisColor" width="300" - height="10" + height="13" follows="top|left|right" layout="topleft" left="35" @@ -94,7 +94,7 @@ width="333"> image_overlay="Edit_Wrench" label="" layout="topleft" - left="265" + right="-3" name="edit_outfit_btn" tool_tip="Edit this outfit" top="3" @@ -108,17 +108,100 @@ width="333"> top="6" width="24" /> </panel> - <filter_editor - height="23" - follows="left|top|right" - layout="topleft" - left="10" - label="Filter Outfits" - max_length_chars="300" - name="Filter" - search_button_visible="true" - top_pad="10" - width="307" /> + <layout_stack + animate="false" + border_size="0" + follows="left|top|right" + height="27" + layout="topleft" + orientation="horizontal" + top_pad="6" + left="0" + name="top_menu_panel" + width="320"> + <layout_panel + auto_resize="true" + layout="topleft" + name="filter_panel" + width="193"> + <filter_editor + text_pad_left="10" + follows="left|top|right" + font="SansSerifSmall" + height="23" + layout="topleft" + left="10" + label="Filter Outfits" + max_length_chars="300" + name="Filter" + search_button_visible="true" + tab_group="1" + top="3" + width="181" /> + </layout_panel> + <layout_panel + auto_resize="false" + height="25" + layout="topleft" + name="options_gear_btn_panel" + width="32"> + <menu_button + follows="bottom|left" + tool_tip="Show additional options" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="OptionsMenu_Off" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_position="bottomleft" + layout="topleft" + left="0" + name="options_gear_btn" + top="0" + width="31" /> + </layout_panel> + <layout_panel + auto_resize="false" + height="25" + layout="topleft" + name="options_sort_btn_panel" + width="32"> + <menu_button + follows="bottom|left" + tool_tip="Show sorting options" + height="25" + image_hover_unselected="Toolbar_Middle_Over" + image_overlay="Conv_toolbar_sort" + image_selected="Toolbar_Middle_Selected" + image_unselected="Toolbar_Middle_Off" + menu_position="bottomleft" + layout="topleft" + left="0" + name="sorting_menu_btn" + top="0" + width="31" /> + </layout_panel> + <layout_panel + auto_resize="false" + height="25" + layout="topleft" + name="trash_btn_panel" + width="31"> + <dnd_button + follows="bottom|left" + height="25" + image_hover_unselected="Toolbar_Right_Over" + image_overlay="TrashItem_Off" + image_selected="Toolbar_Right_Selected" + image_unselected="Toolbar_Right_Off" + left="0" + layout="topleft" + name="trash_btn" + tool_tip="Delete selected outfit" + top="0" + width="31"/> + </layout_panel> + </layout_stack> <panel class="panel_outfits_inventory" filename="panel_outfits_inventory.xml" @@ -129,7 +212,7 @@ width="333"> visible="false" left="0" tab_group="1" - top_pad="6" + top_pad="4" follows="all" /> <panel class="panel_outfit_edit" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 7361ad5245..c48ba10cac 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -2321,6 +2321,7 @@ For AI Character: Get the closest navigable point to the point provided. <!-- inventory --> <string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> + <string name="InventoryNoMatchingFavorites">You haven't marked any items as favorites.</string> <string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string> <string name="FavoritesNoMatchingItems">To add a place to your favorites, click the star to the right of the location name, then save the landmark to "Favorites bar".</string> <string name="MarketplaceNoListing">You have no listings yet.</string> @@ -2484,13 +2485,13 @@ If you continue to receive this message, please contact Second Life support for <string name="InvFolder Uncompressed Sounds">Uncompressed Sounds</string> <string name="InvFolder Animations">Animations</string> <string name="InvFolder Gestures">Gestures</string> - <string name="InvFolder Favorite">My Favorites</string> + <string name="InvFolder Favorite">Favorites Bar</string> <!-- historically default name of the Favorites folder can start from either "f" or "F" letter. Also, it can be written as "Favorite" or "Favorites". We should localize all variants of them with the same value --> - <string name="InvFolder favorite">My Favorites</string> - <string name="InvFolder Favorites">My Favorites</string> - <string name="InvFolder favorites">My Favorites</string> + <string name="InvFolder favorite">Favorites Bar</string> + <string name="InvFolder Favorites">Favorites Bar</string> + <string name="InvFolder favorites">Favorites Bar</string> <string name="InvFolder Current Outfit">Current Outfit</string> <string name="InvFolder Initial Outfits">Initial Outfits</string> <string name="InvFolder My Outfits">My Outfits</string> @@ -3717,6 +3718,10 @@ Please reinstall viewer from https://secondlife.com/support/downloads/ and cont <string name="inventory_folder_offered-im"> Inventory folder '[ITEM_NAME]' offered </string> + <string name="bot_warning"> + You are chatting with a bot, [NAME]. Do not share any personal information. +Learn more at https://second.life/scripted-agents. + </string> <string name="share_alert"> Drag items from inventory here </string> @@ -3965,7 +3970,7 @@ Abuse Report</string> <string name="AvatarBirthDateFormatShort">[mthnum,datetime,slt]/[day,datetime,slt]</string> <string name="DefaultMimeType">none/none</string> - <string name="texture_load_dimensions_error">Can't load images larger than [WIDTH]*[HEIGHT]</string> + <string name="texture_load_dimensions_error">Can't load images larger than [PIXELS] pixels</string> <string name="texture_load_format_error">Incorrect image format.</string> <string name="texture_load_empty_file">File is empty.</string> <string name="outfit_photo_load_dimensions_error">Max outfit photo size is [WIDTH]*[HEIGHT]. Please resize or use another image</string> @@ -4182,7 +4187,7 @@ Try enclosing path to the editor with double quotes. name="Command_360_Capture_Label">360 snapshot</string> <string name="Command_AboutLand_Label">About land</string> <string name="Command_Appearance_Label">Outfits</string> - <string name="Command_Avatar_Label">Complete avatars</string> + <string name="Command_Avatar_Label">Avatar Welcome Pack</string> <string name="Command_Build_Label">Build</string> <string name="Command_Chat_Label">Chat</string> <string name="Command_Conversations_Label">Conversations</string> diff --git a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml index b598bbccd8..50c5285e04 100644 --- a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml +++ b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml @@ -1,6 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <folder_view_item folder_arrow_image="Folder_Arrow" + favorite_image="Inv_Favorite_Star_Full" + favorite_content_image="Inv_Favorite_Star_Content" folder_indentation="8" item_height="20" item_top_pad="4" diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml index 27ec6ded81..865c145022 100644 --- a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml +++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml @@ -1,6 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <inbox_folder_view_folder folder_arrow_image="Folder_Arrow" + favorite_image="Inv_Favorite_Star_Full" + favorite_content_image="Inv_Favorite_Star_Content" folder_indentation="8" item_height="20" item_top_pad="4" diff --git a/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml b/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml index cdeff6ab05..f246ff764a 100644 --- a/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml +++ b/indra/newview/skins/default/xui/en/widgets/sun_moon_trackball.xml @@ -3,7 +3,6 @@ name="virtualtrackball" width="150" height="150" - user_resize="false" increment_angle_mouse="1.5f" increment_angle_btn="1.0f" image_sphere="VirtualTrackball_Sphere" diff --git a/indra/newview/skins/default/xui/en/widgets/xy_vector.xml b/indra/newview/skins/default/xui/en/widgets/xy_vector.xml index 23cde55f30..923895be5e 100644 --- a/indra/newview/skins/default/xui/en/widgets/xy_vector.xml +++ b/indra/newview/skins/default/xui/en/widgets/xy_vector.xml @@ -3,11 +3,9 @@ name="xyvector" width="120" height="140" - decimal_digits="1" label_width="16" padding="4" - edit_bar_height="18" - user_resize="false"> + edit_bar_height="18"> <xy_vector.border visible="true"/> diff --git a/indra/newview/skins/default/xui/es/panel_login_first.xml b/indra/newview/skins/default/xui/es/panel_login_first.xml deleted file mode 100644 index ccb6858351..0000000000 --- a/indra/newview/skins/default/xui/es/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php?lang=es - </panel.string> - <panel.string name="sign_up_url"> - https://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Nombre de usuario" name="username_combo" tool_tip="El nombre de usuario que elegiste al registrarte, como bobsmith12 o Steller Sunshine"/> - <line_editor label="Contraseña" name="password_edit"/> - <button label="Iniciar sesión" name="connect_btn"/> - <check_box label="Recordarme" name="remember_check"/> - <text name="forgot_password_text"> - Contraseña olvidada - </text> - <text name="sign_up_text"> - Regístrate - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Tu primer destino es la Isla de aprendizaje. ¡Encuentra el portal de salida! - </text> - <text name="image_caption_right"> - A continuación, puedes explorar la Isla social y hablar con otros residentes nuevos. - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/es/panel_snapshot_options.xml b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml index 4eb9ecf28f..f3119c739e 100644 --- a/indra/newview/skins/default/xui/es/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/es/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="Guardar en disco" name="save_to_computer_btn"/> - <button label="Guardar en inventario (L$[AMOUNT])" name="save_to_inventory_btn"/> + <button label="Guardar en inventario" name="save_to_inventory_btn"/> <button label="Compartir en los comentarios de Mi perfil" name="save_to_profile_btn"/> <button label="Compartir en Facebook" name="send_to_facebook_btn"/> <button label="Compartir en Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index ff1200e2b3..86e454b83e 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -1,608 +1,1660 @@ <?xml version="1.0" ?> <strings> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> - <string name="SUPPORT_SITE">Portal de Soporte de Second Life</string> - <string name="StartupDetectingHardware">Identificando el hardware...</string> - <string name="StartupLoading">Instalando [APP_NAME]...</string> - <string name="StartupClearingCache">Limpiando la caché...</string> - <string name="StartupInitializingTextureCache">Iniciando la caché de las texturas...</string> - <string name="StartupRequireDriverUpdate">Error de inicialización de gráficos. Actualiza tu controlador de gráficos.</string> - <string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) -[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string> - <string name="BuildConfig">Configuración de constitución [BUILD_CONFIG]</string> - <string name="AboutPosition">Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> + <string name="CAPITALIZED_APP_NAME"> + SECOND LIFE + </string> + <string name="SUPPORT_SITE"> + Portal de Soporte de Second Life + </string> + <string name="StartupDetectingHardware"> + Identificando el hardware... + </string> + <string name="StartupLoading"> + Instalando [APP_NAME]... + </string> + <string name="StartupClearingCache"> + Limpiando la caché... + </string> + <string name="StartupInitializingTextureCache"> + Iniciando la caché de las texturas... + </string> + <string name="StartupRequireDriverUpdate"> + Error de inicialización de gráficos. Actualiza tu controlador de gráficos. + </string> + <string name="AboutHeader"> + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Configuración de constitución [BUILD_CONFIG] + </string> + <string name="AboutPosition"> + Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en <nolink>[HOSTNAME]</nolink> SLURL: <nolink>[SLURL]</nolink> (coordenadas globales [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] -[SERVER_RELEASE_NOTES_URL]</string> - <string name="AboutSystem">CPU: [CPU] +[SERVER_RELEASE_NOTES_URL] + </string> + <string name="AboutSystem"> + CPU: [CPU] Memoria: [MEMORY_MB] MB Versión del Sistema Operativo: [OS_VERSION] Fabricante de la tarjeta gráfica: [GRAPHICS_CARD_VENDOR] -Tarjeta gráfica: [GRAPHICS_CARD]</string> - <string name="AboutDriver">Versión de Windows Graphics Driver: [GRAPHICS_DRIVER_VERSION]</string> - <string name="AboutOGL">Versión de OpenGL: [OPENGL_VERSION]</string> - <string name="AboutSettings">Tamaño de la ventana: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Tarjeta gráfica: [GRAPHICS_CARD] + </string> + <string name="AboutDriver"> + Versión de Windows Graphics Driver: [GRAPHICS_DRIVER_VERSION] + </string> + <string name="AboutOGL"> + Versión de OpenGL: [OPENGL_VERSION] + </string> + <string name="AboutSettings"> + Tamaño de la ventana: [WINDOW_WIDTH]x[WINDOW_HEIGHT] Ajuste del tamaño de fuente: [FONT_SIZE_ADJUSTMENT]pt Escala UI: [UI_SCALE] Distancia de dibujo: [DRAW_DISTANCE]m Ancho de banda: [NET_BANDWITH]kbit/s Factor LOD: [LOD_FACTOR] Calidad de renderización: [RENDER_QUALITY] -Memoria de textura: [TEXTURE_MEMORY]MB</string> - <string name="AboutOSXHiDPI">Modo de visualización HiDPi: [HIDPI]</string> - <string name="AboutLibs">Versión de descodificador J2C: [J2C_VERSION] +Memoria de textura: [TEXTURE_MEMORY]MB + </string> + <string name="AboutOSXHiDPI"> + Modo de visualización HiDPi: [HIDPI] + </string> + <string name="AboutLibs"> + Versión de descodificador J2C: [J2C_VERSION] Versión del controlador audio: [AUDIO_DRIVER_VERSION] [LIBCEF_VERSION] Versión LibVLC: [LIBVLC_VERSION] -Versión del servidor de voz: [VOICE_VERSION]</string> - <string name="AboutTraffic">Paquetes perdidos: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string> - <string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string> - <string name="ErrorFetchingServerReleaseNotesURL">Error al obtener la URL de las notas de la versión del servidor.</string> - <string name="BuildConfiguration">Configuración de constitución</string> - <string name="ProgressRestoring">Restaurando...</string> - <string name="ProgressChangingResolution">Cambiando la resolución...</string> - <string name="Fullbright">Brillo al máximo (antiguo)</string> - <string name="LoginInProgress">Iniciando la sesión. [APP_NAME] debe de aparecer congelado. Por favor, espere.</string> - <string name="LoginInProgressNoFrozen">Iniciando la sesión...</string> - <string name="LoginAuthenticating">Autenticando</string> - <string name="LoginMaintenance">Realizando el mantenimiento de la cuenta...</string> - <string name="LoginAttempt">Ha fallado el intento previo de iniciar sesión. Iniciando sesión, intento [NUMBER]</string> - <string name="LoginPrecaching">Cargando el mundo...</string> - <string name="LoginInitializingBrowser">Iniciando el navegador web incorporado...</string> - <string name="LoginInitializingMultimedia">Iniciando multimedia...</string> - <string name="LoginInitializingFonts">Cargando las fuentes...</string> - <string name="LoginVerifyingCache">Comprobando los archivos de la caché (puede tardar entre 60 y 90 segundos)...</string> - <string name="LoginProcessingResponse">Procesando la respuesta...</string> - <string name="LoginInitializingWorld">Iniciando el mundo...</string> - <string name="LoginDecodingImages">Decodificando las imágenes...</string> - <string name="LoginInitializingQuicktime">Iniciando QuickTime...</string> - <string name="LoginQuicktimeNotFound">No se ha encontrado QuickTime. Imposible iniciarlo.</string> - <string name="LoginQuicktimeOK">QuickTime se ha iniciado adecuadamente.</string> - <string name="LoginRequestSeedCapGrant">Solicitando capacidades de la región...</string> - <string name="LoginRetrySeedCapGrant">Solicitando capacidades de la región, intento [NUMBER]...</string> - <string name="LoginWaitingForRegionHandshake">Esperando la conexión con la región...</string> - <string name="LoginConnectingToRegion">Conectando con la región...</string> - <string name="LoginDownloadingClothing">Descargando la ropa...</string> - <string name="InvalidCertificate">El servidor devolvió un certificado no válido o dañado. Ponte en contacto con el administrador de la cuadrícula.</string> - <string name="CertInvalidHostname">El nombre de host utilizado para acceder al servidor no es válido. Comprueba tu SLURL o el nombre de host de la cuadrícula.</string> - <string name="CertExpired">Parece que el certificado que devolvió la cuadrícula está caducado. Comprueba el reloj del sistema o consulta al administrador de la cuadrícula.</string> - <string name="CertKeyUsage">El certificado que devolvió el servidor no puede utilizarse para SSL. Ponte en contacto con el administrador de la cuadrícula.</string> - <string name="CertBasicConstraints">La cadena de certificado del servidor contenía demasiados certificados. Ponte en contacto con el administrador de la cuadrícula.</string> - <string name="CertInvalidSignature">No se pudo verificar la firma del certificado devuelta por el servidor de la cuadrícula. Ponte en contacto con el administrador de la cuadrícula.</string> - <string name="LoginFailedNoNetwork">Error de red: no se ha podido conectar; por favor, revisa tu conexión a internet.</string> - <string name="LoginFailedHeader">Error en el inicio de sesión.</string> - <string name="Quit">Salir</string> - <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - <string name="AgniGridLabel">Grid principal de Second Life (Agni)</string> - <string name="AditiGridLabel">Grid de prueba beta de Second Life (Aditi)</string> - <string name="ViewerDownloadURL">http://secondlife.com/download.</string> - <string name="LoginFailedViewerNotPermitted">Ya no puedes acceder a Second Life con el visor que estás utilizando. Visita la siguiente página para descargar un nuevo visor: +Versión del servidor de voz: [VOICE_VERSION] + </string> + <string name="AboutTraffic"> + Paquetes perdidos: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) + </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> + <string name="ErrorFetchingServerReleaseNotesURL"> + Error al obtener la URL de las notas de la versión del servidor. + </string> + <string name="BuildConfiguration"> + Configuración de constitución + </string> + <string name="ProgressRestoring"> + Restaurando... + </string> + <string name="ProgressChangingResolution"> + Cambiando la resolución... + </string> + <string name="Fullbright"> + Brillo al máximo (antiguo) + </string> + <string name="LoginInProgress"> + Iniciando la sesión. [APP_NAME] debe de aparecer congelado. Por favor, espere. + </string> + <string name="LoginInProgressNoFrozen"> + Iniciando la sesión... + </string> + <string name="LoginAuthenticating"> + Autenticando + </string> + <string name="LoginMaintenance"> + Realizando el mantenimiento de la cuenta... + </string> + <string name="LoginAttempt"> + Ha fallado el intento previo de iniciar sesión. Iniciando sesión, intento [NUMBER] + </string> + <string name="LoginPrecaching"> + Cargando el mundo... + </string> + <string name="LoginInitializingBrowser"> + Iniciando el navegador web incorporado... + </string> + <string name="LoginInitializingMultimedia"> + Iniciando multimedia... + </string> + <string name="LoginInitializingFonts"> + Cargando las fuentes... + </string> + <string name="LoginVerifyingCache"> + Comprobando los archivos de la caché (puede tardar entre 60 y 90 segundos)... + </string> + <string name="LoginProcessingResponse"> + Procesando la respuesta... + </string> + <string name="LoginInitializingWorld"> + Iniciando el mundo... + </string> + <string name="LoginDecodingImages"> + Decodificando las imágenes... + </string> + <string name="LoginInitializingQuicktime"> + Iniciando QuickTime... + </string> + <string name="LoginQuicktimeNotFound"> + No se ha encontrado QuickTime. Imposible iniciarlo. + </string> + <string name="LoginQuicktimeOK"> + QuickTime se ha iniciado adecuadamente. + </string> + <string name="LoginRequestSeedCapGrant"> + Solicitando capacidades de la región... + </string> + <string name="LoginRetrySeedCapGrant"> + Solicitando capacidades de la región, intento [NUMBER]... + </string> + <string name="LoginWaitingForRegionHandshake"> + Esperando la conexión con la región... + </string> + <string name="LoginConnectingToRegion"> + Conectando con la región... + </string> + <string name="LoginDownloadingClothing"> + Descargando la ropa... + </string> + <string name="InvalidCertificate"> + El servidor devolvió un certificado no válido o dañado. Ponte en contacto con el administrador de la cuadrícula. + </string> + <string name="CertInvalidHostname"> + El nombre de host utilizado para acceder al servidor no es válido. Comprueba tu SLURL o el nombre de host de la cuadrícula. + </string> + <string name="CertExpired"> + Parece que el certificado que devolvió la cuadrícula está caducado. Comprueba el reloj del sistema o consulta al administrador de la cuadrícula. + </string> + <string name="CertKeyUsage"> + El certificado que devolvió el servidor no puede utilizarse para SSL. Ponte en contacto con el administrador de la cuadrícula. + </string> + <string name="CertBasicConstraints"> + La cadena de certificado del servidor contenía demasiados certificados. Ponte en contacto con el administrador de la cuadrícula. + </string> + <string name="CertInvalidSignature"> + No se pudo verificar la firma del certificado devuelta por el servidor de la cuadrícula. Ponte en contacto con el administrador de la cuadrícula. + </string> + <string name="LoginFailedNoNetwork"> + Error de red: no se ha podido conectar; por favor, revisa tu conexión a internet. + </string> + <string name="LoginFailedHeader"> + Error en el inicio de sesión. + </string> + <string name="Quit"> + Salir + </string> + <string name="create_account_url"> + http://join.secondlife.com/?sourceid=[sourceid] + </string> + <string name="AgniGridLabel"> + Grid principal de Second Life (Agni) + </string> + <string name="AditiGridLabel"> + Grid de prueba beta de Second Life (Aditi) + </string> + <string name="ViewerDownloadURL"> + http://secondlife.com/download. + </string> + <string name="LoginFailedViewerNotPermitted"> + Ya no puedes acceder a Second Life con el visor que estás utilizando. Visita la siguiente página para descargar un nuevo visor: http://secondlife.com/download. Si deseas obtener más información, consulta las preguntas frecuentes que aparecen a continuación: -http://secondlife.com/viewer-access-faq</string> - <string name="LoginIntermediateOptionalUpdateAvailable">Actualización opcional del visor disponible: [VERSION]</string> - <string name="LoginFailedRequiredUpdate">Actualización necesaria del visor: [VERSION]</string> - <string name="LoginFailedAlreadyLoggedIn">El agente ya ha iniciado sesión.</string> - <string name="LoginFailedAuthenticationFailed">Lo sentimos. No ha sido posible iniciar sesión. +http://secondlife.com/viewer-access-faq + </string> + <string name="LoginIntermediateOptionalUpdateAvailable"> + Actualización opcional del visor disponible: [VERSION] + </string> + <string name="LoginFailedRequiredUpdate"> + Actualización necesaria del visor: [VERSION] + </string> + <string name="LoginFailedAlreadyLoggedIn"> + El agente ya ha iniciado sesión. + </string> + <string name="LoginFailedAuthenticationFailed"> + Lo sentimos. No ha sido posible iniciar sesión. Comprueba si has introducido correctamente * El nombre de usuario (como juangarcia12 o estrella.polar) * Contraseña -Asimismo, asegúrate de que la tecla Mayús esté desactivada.</string> - <string name="LoginFailedPasswordChanged">Como precaución de seguridad, se ha modificado tu contraseña. +Asimismo, asegúrate de que la tecla Mayús esté desactivada. + </string> + <string name="LoginFailedPasswordChanged"> + Como precaución de seguridad, se ha modificado tu contraseña. Dirígete a la página de tu cuenta en http://secondlife.com/password y responde a la pregunta de seguridad para restablecer la contraseña. -Lamentamos las molestias.</string> - <string name="LoginFailedPasswordReset">Hemos realizado unos cambios en nuestro sistema, por lo que deberás restablecer la contraseña. +Lamentamos las molestias. + </string> + <string name="LoginFailedPasswordReset"> + Hemos realizado unos cambios en nuestro sistema, por lo que deberás restablecer la contraseña. Dirígete a la página de tu cuenta en http://secondlife.com/password y responde a la pregunta de seguridad para restablecer la contraseña. -Lamentamos las molestias.</string> - <string name="LoginFailedEmployeesOnly">Second Life no está disponible temporalmente debido a tareas de mantenimiento. +Lamentamos las molestias. + </string> + <string name="LoginFailedEmployeesOnly"> + Second Life no está disponible temporalmente debido a tareas de mantenimiento. Actualmente, solo se permite iniciar sesión a los empleados. -Consulta www.secondlife.com/status si deseas obtener actualizaciones.</string> - <string name="LoginFailedPremiumOnly">Las conexiones a Second Life se han restringido provisionalmente para garantizar que los usuarios que ya están conectados tengan la mejor experiencia posible. +Consulta www.secondlife.com/status si deseas obtener actualizaciones. + </string> + <string name="LoginFailedPremiumOnly"> + Las conexiones a Second Life se han restringido provisionalmente para garantizar que los usuarios que ya están conectados tengan la mejor experiencia posible. -Durante este tiempo, las personas con cuentas gratuitas no podrán acceder a Second Life, ya que tienen prioridad los usuarios con una cuenta de pago.</string> - <string name="LoginFailedComputerProhibited">No se puede acceder a Second Life desde este ordenador. +Durante este tiempo, las personas con cuentas gratuitas no podrán acceder a Second Life, ya que tienen prioridad los usuarios con una cuenta de pago. + </string> + <string name="LoginFailedComputerProhibited"> + No se puede acceder a Second Life desde este ordenador. Si crees que se trata de un error, ponte en contacto con -support@secondlife.com.</string> - <string name="LoginFailedAcountSuspended">No se podrá acceder a tu cuenta hasta las -[TIME] (horario de la costa del Pacífico).</string> - <string name="LoginFailedAccountDisabled">En este momento no podemos completar la solicitud. -Por favor solicita ayuda al personal de asistencia de Second Life en http://support.secondlife.com.</string> - <string name="LoginFailedTransformError">Se han detectado datos incorrectos en el inicio de sesión. -Ponte en contacto con support@secondlife.com.</string> - <string name="LoginFailedAccountMaintenance">Se están realizando tareas rutinarias de mantenimiento en tu cuenta. +support@secondlife.com. + </string> + <string name="LoginFailedAcountSuspended"> + No se podrá acceder a tu cuenta hasta las +[TIME] (horario de la costa del Pacífico). + </string> + <string name="LoginFailedAccountDisabled"> + En este momento no podemos completar la solicitud. +Por favor solicita ayuda al personal de asistencia de Second Life en http://support.secondlife.com. + </string> + <string name="LoginFailedTransformError"> + Se han detectado datos incorrectos en el inicio de sesión. +Ponte en contacto con support@secondlife.com. + </string> + <string name="LoginFailedAccountMaintenance"> + Se están realizando tareas rutinarias de mantenimiento en tu cuenta. No se podrá acceder a tu cuenta hasta las [TIME] (horario de la costa del Pacífico). -Si crees que se trata de un error, ponte en contacto con support@secondlife.com.</string> - <string name="LoginFailedPendingLogoutFault">La solicitud de cierre de sesión ha obtenido como resultado un error del simulador.</string> - <string name="LoginFailedPendingLogout">El sistema te desconectará. -Por favor, aguarda un momento antes de intentar conectarte nuevamente.</string> - <string name="LoginFailedUnableToCreateSession">No se ha podido crear una sesión válida.</string> - <string name="LoginFailedUnableToConnectToSimulator">No se ha podido establecer la conexión con un simulador.</string> - <string name="LoginFailedRestrictedHours">Tu cuenta solo puede acceder a Second Life +Si crees que se trata de un error, ponte en contacto con support@secondlife.com. + </string> + <string name="LoginFailedPendingLogoutFault"> + La solicitud de cierre de sesión ha obtenido como resultado un error del simulador. + </string> + <string name="LoginFailedPendingLogout"> + El sistema te desconectará. +Por favor, aguarda un momento antes de intentar conectarte nuevamente. + </string> + <string name="LoginFailedUnableToCreateSession"> + No se ha podido crear una sesión válida. + </string> + <string name="LoginFailedUnableToConnectToSimulator"> + No se ha podido establecer la conexión con un simulador. + </string> + <string name="LoginFailedRestrictedHours"> + Tu cuenta solo puede acceder a Second Life entre las [START] y las [END] (horario de la costa del Pacífico). Inténtalo de nuevo durante ese horario. -Si crees que se trata de un error, ponte en contacto con support@secondlife.com.</string> - <string name="LoginFailedIncorrectParameters">Parámetros incorrectos. -Si crees que se trata de un error, ponte en contacto con support@secondlife.com.</string> - <string name="LoginFailedFirstNameNotAlphanumeric">El parámetro correspondiente al nombre debe contener caracteres alfanuméricos. -Si crees que se trata de un error, ponte en contacto con support@secondlife.com.</string> - <string name="LoginFailedLastNameNotAlphanumeric">El parámetro correspondiente al apellido debe contener caracteres alfanuméricos. -Si crees que se trata de un error, ponte en contacto con support@secondlife.com.</string> - <string name="LogoutFailedRegionGoingOffline">La región se está desconectando. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="LogoutFailedAgentNotInRegion">El agente no se encuentra en la región. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="LogoutFailedPendingLogin">A esta región ya se ha accedido en otra sesión. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="LogoutFailedLoggingOut">Se ha salido de la región en la sesión anterior. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="LogoutFailedStillLoggingOut">La región aún está cerrando la sesión anterior. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="LogoutSucceeded">Se ha salido de la región en la última sesión. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="LogoutFailedLogoutBegun">La región ha comenzado el proceso de cierre de sesión. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="LoginFailedLoggingOutSession">El sistema ha comenzado a cerrar la última sesión. -Intenta iniciar sesión de nuevo en unos instantes.</string> - <string name="AgentLostConnection">Esta región puede estar teniendo problemas. Por favor, comprueba tu conexión a Internet.</string> - <string name="SavingSettings">Guardando tus configuraciones...</string> - <string name="LoggingOut">Cerrando sesión...</string> - <string name="ShuttingDown">Cerrando...</string> - <string name="YouHaveBeenDisconnected">Has sido desconectado de la región en la que estabas.</string> - <string name="SentToInvalidRegion">Has sido enviado a una región no válida.</string> - <string name="TestingDisconnect">Probando la desconexión del visor</string> - <string name="SocialFacebookConnecting">Conectando con Facebook...</string> - <string name="SocialFacebookPosting">Publicando...</string> - <string name="SocialFacebookDisconnecting">Desconectando de Facebook...</string> - <string name="SocialFacebookErrorConnecting">Problema al conectar con Facebook</string> - <string name="SocialFacebookErrorPosting">Problema al publicar en Facebook</string> - <string name="SocialFacebookErrorDisconnecting">Problema al desconectar de Facebook</string> - <string name="SocialFlickrConnecting">Conectándose a Flickr...</string> - <string name="SocialFlickrPosting">Publicando...</string> - <string name="SocialFlickrDisconnecting">Desconectándose de Flickr...</string> - <string name="SocialFlickrErrorConnecting">Problema con la conexión a Flickr</string> - <string name="SocialFlickrErrorPosting">Problema al publicar en Flickr</string> - <string name="SocialFlickrErrorDisconnecting">Problema con la desconexión de Flickr</string> - <string name="SocialTwitterConnecting">Conectándose a Twitter...</string> - <string name="SocialTwitterPosting">Publicando...</string> - <string name="SocialTwitterDisconnecting">Desconectándose de Twitter...</string> - <string name="SocialTwitterErrorConnecting">Problema con la conexión a Twitter</string> - <string name="SocialTwitterErrorPosting">Problema al publicar en Twitter</string> - <string name="SocialTwitterErrorDisconnecting">Problema con la desconexión de Twitter</string> - <string name="BlackAndWhite">Blanco y negro</string> - <string name="Colors1970">Colores de los 70</string> - <string name="Intense">Intenso</string> - <string name="Newspaper">Periódico</string> - <string name="Sepia">Sepia</string> - <string name="Spotlight">Foco</string> - <string name="Video">Vídeo</string> - <string name="Autocontrast">Contraste automático</string> - <string name="LensFlare">Destello de lente</string> - <string name="Miniature">Miniatura</string> - <string name="Toycamera">Cámara de juguete</string> - <string name="TooltipPerson">Persona</string> - <string name="TooltipNoName">(sin nombre)</string> - <string name="TooltipOwner">Propietario:</string> - <string name="TooltipPublic">Público</string> - <string name="TooltipIsGroup">(Grupo)</string> - <string name="TooltipForSaleL$">En venta: [AMOUNT] L$</string> - <string name="TooltipFlagGroupBuild">Construir el grupo</string> - <string name="TooltipFlagNoBuild">No construir</string> - <string name="TooltipFlagNoEdit">Construir el grupo</string> - <string name="TooltipFlagNotSafe">No seguro</string> - <string name="TooltipFlagNoFly">No volar</string> - <string name="TooltipFlagGroupScripts">Scripts el grupo</string> - <string name="TooltipFlagNoScripts">No scripts</string> - <string name="TooltipLand">Terreno:</string> - <string name="TooltipMustSingleDrop">Aquí se puede arrastrar sólo un ítem</string> - <string name="TooltipTooManyWearables">No puedes tener una carpeta de prendas que contenga más de [AMOUNT] elementos. Puedes cambiar este límite en Avanzado > Mostrar las configuraciones del depurador > WearFolderLimit.</string> +Si crees que se trata de un error, ponte en contacto con support@secondlife.com. + </string> + <string name="LoginFailedIncorrectParameters"> + Parámetros incorrectos. +Si crees que se trata de un error, ponte en contacto con support@secondlife.com. + </string> + <string name="LoginFailedFirstNameNotAlphanumeric"> + El parámetro correspondiente al nombre debe contener caracteres alfanuméricos. +Si crees que se trata de un error, ponte en contacto con support@secondlife.com. + </string> + <string name="LoginFailedLastNameNotAlphanumeric"> + El parámetro correspondiente al apellido debe contener caracteres alfanuméricos. +Si crees que se trata de un error, ponte en contacto con support@secondlife.com. + </string> + <string name="LogoutFailedRegionGoingOffline"> + La región se está desconectando. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="LogoutFailedAgentNotInRegion"> + El agente no se encuentra en la región. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="LogoutFailedPendingLogin"> + A esta región ya se ha accedido en otra sesión. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="LogoutFailedLoggingOut"> + Se ha salido de la región en la sesión anterior. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="LogoutFailedStillLoggingOut"> + La región aún está cerrando la sesión anterior. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="LogoutSucceeded"> + Se ha salido de la región en la última sesión. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="LogoutFailedLogoutBegun"> + La región ha comenzado el proceso de cierre de sesión. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="LoginFailedLoggingOutSession"> + El sistema ha comenzado a cerrar la última sesión. +Intenta iniciar sesión de nuevo en unos instantes. + </string> + <string name="AgentLostConnection"> + Esta región puede estar teniendo problemas. Por favor, comprueba tu conexión a Internet. + </string> + <string name="SavingSettings"> + Guardando tus configuraciones... + </string> + <string name="LoggingOut"> + Cerrando sesión... + </string> + <string name="ShuttingDown"> + Cerrando... + </string> + <string name="YouHaveBeenDisconnected"> + Has sido desconectado de la región en la que estabas. + </string> + <string name="SentToInvalidRegion"> + Has sido enviado a una región no válida. + </string> + <string name="TestingDisconnect"> + Probando la desconexión del visor + </string> + <string name="SocialFacebookConnecting"> + Conectando con Facebook... + </string> + <string name="SocialFacebookPosting"> + Publicando... + </string> + <string name="SocialFacebookDisconnecting"> + Desconectando de Facebook... + </string> + <string name="SocialFacebookErrorConnecting"> + Problema al conectar con Facebook + </string> + <string name="SocialFacebookErrorPosting"> + Problema al publicar en Facebook + </string> + <string name="SocialFacebookErrorDisconnecting"> + Problema al desconectar de Facebook + </string> + <string name="SocialFlickrConnecting"> + Conectándose a Flickr... + </string> + <string name="SocialFlickrPosting"> + Publicando... + </string> + <string name="SocialFlickrDisconnecting"> + Desconectándose de Flickr... + </string> + <string name="SocialFlickrErrorConnecting"> + Problema con la conexión a Flickr + </string> + <string name="SocialFlickrErrorPosting"> + Problema al publicar en Flickr + </string> + <string name="SocialFlickrErrorDisconnecting"> + Problema con la desconexión de Flickr + </string> + <string name="SocialTwitterConnecting"> + Conectándose a Twitter... + </string> + <string name="SocialTwitterPosting"> + Publicando... + </string> + <string name="SocialTwitterDisconnecting"> + Desconectándose de Twitter... + </string> + <string name="SocialTwitterErrorConnecting"> + Problema con la conexión a Twitter + </string> + <string name="SocialTwitterErrorPosting"> + Problema al publicar en Twitter + </string> + <string name="SocialTwitterErrorDisconnecting"> + Problema con la desconexión de Twitter + </string> + <string name="BlackAndWhite"> + Blanco y negro + </string> + <string name="Colors1970"> + Colores de los 70 + </string> + <string name="Intense"> + Intenso + </string> + <string name="Newspaper"> + Periódico + </string> + <string name="Sepia"> + Sepia + </string> + <string name="Spotlight"> + Foco + </string> + <string name="Video"> + Vídeo + </string> + <string name="Autocontrast"> + Contraste automático + </string> + <string name="LensFlare"> + Destello de lente + </string> + <string name="Miniature"> + Miniatura + </string> + <string name="Toycamera"> + Cámara de juguete + </string> + <string name="TooltipPerson"> + Persona + </string> + <string name="TooltipNoName"> + (sin nombre) + </string> + <string name="TooltipOwner"> + Propietario: + </string> + <string name="TooltipPublic"> + Público + </string> + <string name="TooltipIsGroup"> + (Grupo) + </string> + <string name="TooltipForSaleL$"> + En venta: [AMOUNT] L$ + </string> + <string name="TooltipFlagGroupBuild"> + Construir el grupo + </string> + <string name="TooltipFlagNoBuild"> + No construir + </string> + <string name="TooltipFlagNoEdit"> + Construir el grupo + </string> + <string name="TooltipFlagNotSafe"> + No seguro + </string> + <string name="TooltipFlagNoFly"> + No volar + </string> + <string name="TooltipFlagGroupScripts"> + Scripts el grupo + </string> + <string name="TooltipFlagNoScripts"> + No scripts + </string> + <string name="TooltipLand"> + Terreno: + </string> + <string name="TooltipMustSingleDrop"> + Aquí se puede arrastrar sólo un ítem + </string> + <string name="TooltipTooManyWearables"> + No puedes tener una carpeta de prendas que contenga más de [AMOUNT] elementos. Puedes cambiar este límite en Avanzado > Mostrar las configuraciones del depurador > WearFolderLimit. + </string> <string name="TooltipPrice" value="[AMOUNT] L$:"/> - <string name="TooltipSLIcon">Esto crea un vínculo a una página del dominio oficial SecondLife.com o LindenLab.com.</string> - <string name="TooltipOutboxDragToWorld">No se pueden mostrar artículos desde la carpeta Artículos del mercado</string> - <string name="TooltipOutboxWorn">Los artículos que tienes puestos no se pueden colocar en la carpeta Artículos del mercado</string> - <string name="TooltipOutboxFolderLevels">La profundidad de carpetas anidadas excede de [AMOUNT]. Disminuye la profundidad de las carpetas anidadas; si es necesario, agrupa los artículos.</string> - <string name="TooltipOutboxTooManyFolders">La cantidad de subcarpetas excede de [AMOUNT]. Disminuye la cantidad de carpetas de tu lista de artículos; si es necesario, agrupa los artículos.</string> - <string name="TooltipOutboxTooManyObjects">La cantidad de artículos excede de [AMOUNT]. Para vender más de [AMOUNT] artículos en la misma lista, debes agrupar algunos.</string> - <string name="TooltipOutboxTooManyStockItems">La cantidad de artículos en stock excede de [AMOUNT].</string> - <string name="TooltipOutboxCannotDropOnRoot">Solo se pueden soltar artículos o carpetas en las pestañas TODOS o SIN ASOCIAR. Selecciona una de estas pestañas y mueve otra vez los artículos o carpetas.</string> - <string name="TooltipOutboxNoTransfer">Uno o varios de estos objetos no se pueden vender o transferir</string> - <string name="TooltipOutboxNotInInventory">Solo puedes colocar en el mercado artículos de tu inventario</string> - <string name="TooltipOutboxLinked">No puedes poner carpetas o artículos vinculados en el Mercado</string> - <string name="TooltipOutboxCallingCard">No puedes colocar tarjetas de visita en el Mercado</string> - <string name="TooltipOutboxDragActive">No se puede mover una lista de artículos publicada</string> - <string name="TooltipOutboxCannotMoveRoot">No se puede mover la carpeta raíz de artículos del Mercado</string> - <string name="TooltipOutboxMixedStock">Todos los artículos de una carpeta de stock deben tener el mismo tipo y permiso</string> - <string name="TooltipDragOntoOwnChild">No puedes mover una carpeta a su carpeta secundaria</string> - <string name="TooltipDragOntoSelf">No puedes mover una carpeta dentro de sí misma</string> - <string name="TooltipHttpUrl">Pulsa para ver esta página web</string> - <string name="TooltipSLURL">Pulsa para ver la información de este lugar</string> - <string name="TooltipAgentUrl">Pulsa para ver el perfil del Residente</string> - <string name="TooltipAgentInspect">Obtén más información acerca de este residente.</string> - <string name="TooltipAgentMute">Pulsa para silenciar a este Residente</string> - <string name="TooltipAgentUnmute">Pulsa para quitar el silencio a este Residente</string> - <string name="TooltipAgentIM">Pulsa para enviar un MI a este Residente</string> - <string name="TooltipAgentPay">Pulsa para pagar a este Residente</string> - <string name="TooltipAgentOfferTeleport">Pulsa para enviar una petición de teleporte a este Residente</string> - <string name="TooltipAgentRequestFriend">Pulsa para enviar una petición de amistad a este Residente</string> - <string name="TooltipGroupUrl">Pulsa para ver la descripción de este grupo</string> - <string name="TooltipEventUrl">Pulsa para ver la descripción de este evento</string> - <string name="TooltipClassifiedUrl">Pulsa para ver este clasificado</string> - <string name="TooltipParcelUrl">Pulsa para ver la descripción de esta parcela</string> - <string name="TooltipTeleportUrl">Pulsa para teleportarte a esta posición</string> - <string name="TooltipObjectIMUrl">Pulsa para ver la descripción de este objeto</string> - <string name="TooltipMapUrl">Pulsa para ver en el mapa esta localización</string> - <string name="TooltipSLAPP">Pulsa para ejecutar el comando secondlife://</string> + <string name="TooltipSLIcon"> + Esto crea un vínculo a una página del dominio oficial SecondLife.com o LindenLab.com. + </string> + <string name="TooltipOutboxDragToWorld"> + No se pueden mostrar artículos desde la carpeta Artículos del mercado + </string> + <string name="TooltipOutboxWorn"> + Los artículos que tienes puestos no se pueden colocar en la carpeta Artículos del mercado + </string> + <string name="TooltipOutboxFolderLevels"> + La profundidad de carpetas anidadas excede de [AMOUNT]. Disminuye la profundidad de las carpetas anidadas; si es necesario, agrupa los artículos. + </string> + <string name="TooltipOutboxTooManyFolders"> + La cantidad de subcarpetas excede de [AMOUNT]. Disminuye la cantidad de carpetas de tu lista de artículos; si es necesario, agrupa los artículos. + </string> + <string name="TooltipOutboxTooManyObjects"> + La cantidad de artículos excede de [AMOUNT]. Para vender más de [AMOUNT] artículos en la misma lista, debes agrupar algunos. + </string> + <string name="TooltipOutboxTooManyStockItems"> + La cantidad de artículos en stock excede de [AMOUNT]. + </string> + <string name="TooltipOutboxCannotDropOnRoot"> + Solo se pueden soltar artículos o carpetas en las pestañas TODOS o SIN ASOCIAR. Selecciona una de estas pestañas y mueve otra vez los artículos o carpetas. + </string> + <string name="TooltipOutboxNoTransfer"> + Uno o varios de estos objetos no se pueden vender o transferir + </string> + <string name="TooltipOutboxNotInInventory"> + Solo puedes colocar en el mercado artículos de tu inventario + </string> + <string name="TooltipOutboxLinked"> + No puedes poner carpetas o artículos vinculados en el Mercado + </string> + <string name="TooltipOutboxCallingCard"> + No puedes colocar tarjetas de visita en el Mercado + </string> + <string name="TooltipOutboxDragActive"> + No se puede mover una lista de artículos publicada + </string> + <string name="TooltipOutboxCannotMoveRoot"> + No se puede mover la carpeta raíz de artículos del Mercado + </string> + <string name="TooltipOutboxMixedStock"> + Todos los artículos de una carpeta de stock deben tener el mismo tipo y permiso + </string> + <string name="TooltipDragOntoOwnChild"> + No puedes mover una carpeta a su carpeta secundaria + </string> + <string name="TooltipDragOntoSelf"> + No puedes mover una carpeta dentro de sí misma + </string> + <string name="TooltipHttpUrl"> + Pulsa para ver esta página web + </string> + <string name="TooltipSLURL"> + Pulsa para ver la información de este lugar + </string> + <string name="TooltipAgentUrl"> + Pulsa para ver el perfil del Residente + </string> + <string name="TooltipAgentInspect"> + Obtén más información acerca de este residente. + </string> + <string name="TooltipAgentMute"> + Pulsa para silenciar a este Residente + </string> + <string name="TooltipAgentUnmute"> + Pulsa para quitar el silencio a este Residente + </string> + <string name="TooltipAgentIM"> + Pulsa para enviar un MI a este Residente + </string> + <string name="TooltipAgentPay"> + Pulsa para pagar a este Residente + </string> + <string name="TooltipAgentOfferTeleport"> + Pulsa para enviar una petición de teleporte a este Residente + </string> + <string name="TooltipAgentRequestFriend"> + Pulsa para enviar una petición de amistad a este Residente + </string> + <string name="TooltipGroupUrl"> + Pulsa para ver la descripción de este grupo + </string> + <string name="TooltipEventUrl"> + Pulsa para ver la descripción de este evento + </string> + <string name="TooltipClassifiedUrl"> + Pulsa para ver este clasificado + </string> + <string name="TooltipParcelUrl"> + Pulsa para ver la descripción de esta parcela + </string> + <string name="TooltipTeleportUrl"> + Pulsa para teleportarte a esta posición + </string> + <string name="TooltipObjectIMUrl"> + Pulsa para ver la descripción de este objeto + </string> + <string name="TooltipMapUrl"> + Pulsa para ver en el mapa esta localización + </string> + <string name="TooltipSLAPP"> + Pulsa para ejecutar el comando secondlife:// + </string> <string name="CurrentURL" value="URL actual: [CurrentURL]"/> - <string name="TooltipEmail">Haz clic para redactar un correo electrónico</string> - <string name="SLurlLabelTeleport">Teleportarse a</string> - <string name="SLurlLabelShowOnMap">Mostrarla en el mapa</string> - <string name="SLappAgentMute">Silenciar</string> - <string name="SLappAgentUnmute">Quitar el silencio</string> - <string name="SLappAgentIM">MI</string> - <string name="SLappAgentPay">Pagar</string> - <string name="SLappAgentOfferTeleport">Ofrecer teleporte a</string> - <string name="SLappAgentRequestFriend">Petición de amistad</string> - <string name="SLappAgentRemoveFriend">Eliminación de amigos</string> - <string name="BUTTON_CLOSE_DARWIN">Cerrar (⌘W)</string> - <string name="BUTTON_CLOSE_WIN">Cerrar (Ctrl+W)</string> - <string name="BUTTON_CLOSE_CHROME">Cerrar</string> - <string name="BUTTON_RESTORE">Maximizar</string> - <string name="BUTTON_MINIMIZE">Minimizar</string> - <string name="BUTTON_TEAR_OFF">Separar la ventana</string> - <string name="BUTTON_DOCK">Fijar</string> - <string name="BUTTON_HELP">Ver la Ayuda</string> - <string name="TooltipNotecardNotAllowedTypeDrop">Los objetos de este tipo no se pueden adjuntar -a las notas de esta región.</string> - <string name="TooltipNotecardOwnerRestrictedDrop">Sólo los objetos con permisos + <string name="TooltipEmail"> + Haz clic para redactar un correo electrónico + </string> + <string name="SLurlLabelTeleport"> + Teleportarse a + </string> + <string name="SLurlLabelShowOnMap"> + Mostrarla en el mapa + </string> + <string name="SLappAgentMute"> + Silenciar + </string> + <string name="SLappAgentUnmute"> + Quitar el silencio + </string> + <string name="SLappAgentIM"> + MI + </string> + <string name="SLappAgentPay"> + Pagar + </string> + <string name="SLappAgentOfferTeleport"> + Ofrecer teleporte a + </string> + <string name="SLappAgentRequestFriend"> + Petición de amistad + </string> + <string name="SLappAgentRemoveFriend"> + Eliminación de amigos + </string> + <string name="BUTTON_CLOSE_DARWIN"> + Cerrar (⌘W) + </string> + <string name="BUTTON_CLOSE_WIN"> + Cerrar (Ctrl+W) + </string> + <string name="BUTTON_CLOSE_CHROME"> + Cerrar + </string> + <string name="BUTTON_RESTORE"> + Maximizar + </string> + <string name="BUTTON_MINIMIZE"> + Minimizar + </string> + <string name="BUTTON_TEAR_OFF"> + Separar la ventana + </string> + <string name="BUTTON_DOCK"> + Fijar + </string> + <string name="BUTTON_HELP"> + Ver la Ayuda + </string> + <string name="TooltipNotecardNotAllowedTypeDrop"> + Los objetos de este tipo no se pueden adjuntar +a las notas de esta región. + </string> + <string name="TooltipNotecardOwnerRestrictedDrop"> + Sólo los objetos con permisos «próximo propietario» sin restricciones -pueden adjuntarse a las notas.</string> - <string name="Searching">Buscando...</string> - <string name="NoneFound">No se ha encontrado.</string> - <string name="RetrievingData">Reintentando...</string> - <string name="ReleaseNotes">Notas de la versión</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> - <string name="LoadingData">Cargando...</string> - <string name="AvatarNameNobody">(nadie)</string> - <string name="AvatarNameWaiting">(esperando)</string> - <string name="GroupNameNone">(ninguno)</string> - <string name="AssetErrorNone">No hay ningún error</string> - <string name="AssetErrorRequestFailed">Petición de asset: fallida</string> - <string name="AssetErrorNonexistentFile">Petición de asset: el archivo no existe</string> - <string name="AssetErrorNotInDatabase">Petición de asset: no se encontró el asset en la base de datos</string> - <string name="AssetErrorEOF">Fin del archivo</string> - <string name="AssetErrorCannotOpenFile">No puede abrirse el archivo</string> - <string name="AssetErrorFileNotFound">No se ha encontrado el archivo</string> - <string name="AssetErrorTCPTimeout">Tiempo de transferencia del archivo</string> - <string name="AssetErrorCircuitGone">Circuito desconectado</string> - <string name="AssetErrorPriceMismatch">No concuerda el precio en el visor y en el servidor</string> - <string name="AssetErrorUnknownStatus">Estado desconocido</string> - <string name="AssetUploadServerUnreacheble">El servicio no está disponible.</string> - <string name="AssetUploadServerDifficulties">Se detectaron errores inesperados en el servidor.</string> - <string name="AssetUploadServerUnavaliable">El servicio no está disponible o se alcanzó el tiempo de carga máxima.</string> - <string name="AssetUploadRequestInvalid">Error en la solicitud de carga. Por favor, ingresa a -http://secondlife.com/support para obtener ayuda sobre cómo solucionar este problema.</string> - <string name="SettingValidationError">Error en la validación para importar los parámetros [NAME]</string> - <string name="SettingImportFileError">No se pudo abrir el archivo [FILE]</string> - <string name="SettingParseFileError">No se pudo abrir el archivo [FILE]</string> - <string name="SettingTranslateError">No se pudo traducir el Viento de luz legado [NAME]</string> - <string name="texture">la textura</string> - <string name="sound">el sonido</string> - <string name="calling card">la tarjeta de visita</string> - <string name="landmark">el hito</string> - <string name="legacy script">el script antiguo</string> - <string name="clothing">esa ropa</string> - <string name="object">el objeto</string> - <string name="note card">la nota</string> - <string name="folder">la carpeta</string> - <string name="root">la ruta</string> - <string name="lsl2 script">ese script de LSL2</string> - <string name="lsl bytecode">el código intermedio de LSL</string> - <string name="tga texture">esa textura tga</string> - <string name="body part">esa parte del cuerpo</string> - <string name="snapshot">la foto</string> - <string name="lost and found">Objetos Perdidos</string> - <string name="targa image">esa imagen targa</string> - <string name="trash">la Papelera</string> - <string name="jpeg image">esa imagen jpeg</string> - <string name="animation">la animación</string> - <string name="gesture">el gesto</string> - <string name="simstate">simstate</string> - <string name="favorite">ese favorito</string> - <string name="symbolic link">el enlace</string> - <string name="symbolic folder link">enlace de la carpeta</string> - <string name="settings blob">opciones</string> - <string name="mesh">red</string> - <string name="AvatarEditingAppearance">(Edición de Apariencia)</string> - <string name="AvatarAway">Ausente</string> - <string name="AvatarDoNotDisturb">No molestar</string> - <string name="AvatarMuted">Ignorado</string> - <string name="anim_express_afraid">Susto</string> - <string name="anim_express_anger">Enfado</string> - <string name="anim_away">Ausente</string> - <string name="anim_backflip">Salto mortal atrás</string> - <string name="anim_express_laugh">Carcajada</string> - <string name="anim_express_toothsmile">Gran sonrisa</string> - <string name="anim_blowkiss">Mandar un beso</string> - <string name="anim_express_bored">Aburrimiento</string> - <string name="anim_bow">Reverencia</string> - <string name="anim_clap">Aplauso</string> - <string name="anim_courtbow">Reverencia floreada</string> - <string name="anim_express_cry">Llanto</string> - <string name="anim_dance1">Baile 1</string> - <string name="anim_dance2">Baile 2</string> - <string name="anim_dance3">Baile 3</string> - <string name="anim_dance4">Baile 4</string> - <string name="anim_dance5">Baile 5</string> - <string name="anim_dance6">Baile 6</string> - <string name="anim_dance7">Baile 7</string> - <string name="anim_dance8">Baile 8</string> - <string name="anim_express_disdain">Desdén</string> - <string name="anim_drink">Beber</string> - <string name="anim_express_embarrased">Azorarse</string> - <string name="anim_angry_fingerwag">Negar con el dedo</string> - <string name="anim_fist_pump">Éxito con el puño</string> - <string name="anim_yoga_float">Yoga flotando</string> - <string name="anim_express_frown">Fruncir el ceño</string> - <string name="anim_impatient">Impaciente</string> - <string name="anim_jumpforjoy">Salto de alegría</string> - <string name="anim_kissmybutt">Bésame el culo</string> - <string name="anim_express_kiss">Besar</string> - <string name="anim_laugh_short">Reír</string> - <string name="anim_musclebeach">Sacar músculo</string> - <string name="anim_no_unhappy">No (con enfado)</string> - <string name="anim_no_head">No</string> - <string name="anim_nyanya">Ña-Ña-Ña</string> - <string name="anim_punch_onetwo">Puñetazo uno-dos</string> - <string name="anim_express_open_mouth">Abrir la boca</string> - <string name="anim_peace">'V' con los dedos</string> - <string name="anim_point_you">Señalar a otro/a</string> - <string name="anim_point_me">Señalarse</string> - <string name="anim_punch_l">Puñetazo izquierdo</string> - <string name="anim_punch_r">Puñetazo derecho</string> - <string name="anim_rps_countdown">PPT cuenta</string> - <string name="anim_rps_paper">PPT papel</string> - <string name="anim_rps_rock">PPT piedra</string> - <string name="anim_rps_scissors">PPT tijera</string> - <string name="anim_express_repulsed">Repulsa</string> - <string name="anim_kick_roundhouse_r">Patada circular</string> - <string name="anim_express_sad">Triste</string> - <string name="anim_salute">Saludo militar</string> - <string name="anim_shout">Gritar</string> - <string name="anim_express_shrug">Encogerse de hombros</string> - <string name="anim_express_smile">Sonreír</string> - <string name="anim_smoke_idle">Fumar: en la mano</string> - <string name="anim_smoke_inhale">Fumar</string> - <string name="anim_smoke_throw_down">Fumar: tirar el cigarro</string> - <string name="anim_express_surprise">Sorpresa</string> - <string name="anim_sword_strike_r">Estocadas</string> - <string name="anim_angry_tantrum">Berrinche</string> - <string name="anim_express_tongue_out">Sacar la lengua</string> - <string name="anim_hello">Agitar la mano</string> - <string name="anim_whisper">Cuchichear</string> - <string name="anim_whistle">Pitar</string> - <string name="anim_express_wink">Guiño</string> - <string name="anim_wink_hollywood">Guiño (Hollywood)</string> - <string name="anim_express_worry">Preocuparse</string> - <string name="anim_yes_happy">Sí (contento)</string> - <string name="anim_yes_head">Sí</string> - <string name="use_texture">Usar textura</string> - <string name="manip_hint1">Pasa el cursor del ratón sobre la regla</string> - <string name="manip_hint2">para ajustar a la cuadrícula</string> - <string name="texture_loading">Cargando...</string> - <string name="worldmap_offline">Sin conexión</string> - <string name="worldmap_item_tooltip_format">[PRICE] L$ por [AREA] m²</string> - <string name="worldmap_results_none_found">No se ha encontrado.</string> - <string name="Ok">OK</string> - <string name="Premature end of file">Fin prematuro del archivo</string> - <string name="ST_NO_JOINT">No se puede encontrar ROOT o JOINT.</string> - <string name="NearbyChatTitle">Chat</string> - <string name="NearbyChatLabel">(Chat)</string> - <string name="whisper">susurra:</string> - <string name="shout">grita:</string> - <string name="ringing">Conectando al chat de voz...</string> - <string name="connected">Conectado</string> - <string name="unavailable">La voz no está disponible en su localización actual</string> - <string name="hang_up">Desconectado del chat de voz</string> - <string name="reconnect_nearby">Vas a ser reconectado al chat de voz con los cercanos</string> - <string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', un objeto propiedad de '[OWNERNAME]', localizado en [REGIONNAME] con la posición [REGIONPOS], ha recibido permiso para: [PERMISSIONS].</string> - <string name="ScriptQuestionCautionChatDenied">A '[OBJECTNAME]', un objeto propiedad de '[OWNERNAME]', localizado en [REGIONNAME] con la posición [REGIONPOS], se le ha denegado el permiso para: [PERMISSIONS].</string> - <string name="AdditionalPermissionsRequestHeader">Si autorizas el acceso a tu cuenta, también permitirás al objeto:</string> - <string name="ScriptTakeMoney">Cogerle a usted dólares Linden (L$)</string> - <string name="ActOnControlInputs">Actuar en sus controles de entrada</string> - <string name="RemapControlInputs">Reconfigurar sus controles de entrada</string> - <string name="AnimateYourAvatar">Ejecutar animaciones en su avatar</string> - <string name="AttachToYourAvatar">Anexarse a su avatar</string> - <string name="ReleaseOwnership">Anular la propiedad y que pase a ser público</string> - <string name="LinkAndDelink">Enlazar y desenlazar de otros objetos</string> - <string name="AddAndRemoveJoints">Añadir y quitar uniones con otros objetos</string> - <string name="ChangePermissions">Cambiar sus permisos</string> - <string name="TrackYourCamera">Seguir su cámara</string> - <string name="ControlYourCamera">Controlar su cámara</string> - <string name="TeleportYourAgent">Teleportarte</string> - <string name="ForceSitAvatar">Forzar que el avatar se siente</string> - <string name="ChangeEnvSettings">Cambiar tu configuración del entorno</string> - <string name="AgentNameSubst">(Tú)</string> +pueden adjuntarse a las notas. + </string> + <string name="Searching"> + Buscando... + </string> + <string name="NoneFound"> + No se ha encontrado. + </string> + <string name="RetrievingData"> + Reintentando... + </string> + <string name="ReleaseNotes"> + Notas de la versión + </string> + <string name="RELEASE_NOTES_BASE_URL"> + https://releasenotes.secondlife.com/viewer/ + </string> + <string name="LoadingData"> + Cargando... + </string> + <string name="AvatarNameNobody"> + (nadie) + </string> + <string name="AvatarNameWaiting"> + (esperando) + </string> + <string name="GroupNameNone"> + (ninguno) + </string> + <string name="AssetErrorNone"> + No hay ningún error + </string> + <string name="AssetErrorRequestFailed"> + Petición de asset: fallida + </string> + <string name="AssetErrorNonexistentFile"> + Petición de asset: el archivo no existe + </string> + <string name="AssetErrorNotInDatabase"> + Petición de asset: no se encontró el asset en la base de datos + </string> + <string name="AssetErrorEOF"> + Fin del archivo + </string> + <string name="AssetErrorCannotOpenFile"> + No puede abrirse el archivo + </string> + <string name="AssetErrorFileNotFound"> + No se ha encontrado el archivo + </string> + <string name="AssetErrorTCPTimeout"> + Tiempo de transferencia del archivo + </string> + <string name="AssetErrorCircuitGone"> + Circuito desconectado + </string> + <string name="AssetErrorPriceMismatch"> + No concuerda el precio en el visor y en el servidor + </string> + <string name="AssetErrorUnknownStatus"> + Estado desconocido + </string> + <string name="AssetUploadServerUnreacheble"> + El servicio no está disponible. + </string> + <string name="AssetUploadServerDifficulties"> + Se detectaron errores inesperados en el servidor. + </string> + <string name="AssetUploadServerUnavaliable"> + El servicio no está disponible o se alcanzó el tiempo de carga máxima. + </string> + <string name="AssetUploadRequestInvalid"> + Error en la solicitud de carga. Por favor, ingresa a +http://secondlife.com/support para obtener ayuda sobre cómo solucionar este problema. + </string> + <string name="SettingValidationError"> + Error en la validación para importar los parámetros [NAME] + </string> + <string name="SettingImportFileError"> + No se pudo abrir el archivo [FILE] + </string> + <string name="SettingParseFileError"> + No se pudo abrir el archivo [FILE] + </string> + <string name="SettingTranslateError"> + No se pudo traducir el Viento de luz legado [NAME] + </string> + <string name="texture"> + la textura + </string> + <string name="sound"> + el sonido + </string> + <string name="calling card"> + la tarjeta de visita + </string> + <string name="landmark"> + el hito + </string> + <string name="legacy script"> + el script antiguo + </string> + <string name="clothing"> + esa ropa + </string> + <string name="object"> + el objeto + </string> + <string name="note card"> + la nota + </string> + <string name="folder"> + la carpeta + </string> + <string name="root"> + la ruta + </string> + <string name="lsl2 script"> + ese script de LSL2 + </string> + <string name="lsl bytecode"> + el código intermedio de LSL + </string> + <string name="tga texture"> + esa textura tga + </string> + <string name="body part"> + esa parte del cuerpo + </string> + <string name="snapshot"> + la foto + </string> + <string name="lost and found"> + Objetos Perdidos + </string> + <string name="targa image"> + esa imagen targa + </string> + <string name="trash"> + la Papelera + </string> + <string name="jpeg image"> + esa imagen jpeg + </string> + <string name="animation"> + la animación + </string> + <string name="gesture"> + el gesto + </string> + <string name="simstate"> + simstate + </string> + <string name="favorite"> + ese favorito + </string> + <string name="symbolic link"> + el enlace + </string> + <string name="symbolic folder link"> + enlace de la carpeta + </string> + <string name="settings blob"> + opciones + </string> + <string name="mesh"> + red + </string> + <string name="AvatarEditingAppearance"> + (Edición de Apariencia) + </string> + <string name="AvatarAway"> + Ausente + </string> + <string name="AvatarDoNotDisturb"> + No molestar + </string> + <string name="AvatarMuted"> + Ignorado + </string> + <string name="anim_express_afraid"> + Susto + </string> + <string name="anim_express_anger"> + Enfado + </string> + <string name="anim_away"> + Ausente + </string> + <string name="anim_backflip"> + Salto mortal atrás + </string> + <string name="anim_express_laugh"> + Carcajada + </string> + <string name="anim_express_toothsmile"> + Gran sonrisa + </string> + <string name="anim_blowkiss"> + Mandar un beso + </string> + <string name="anim_express_bored"> + Aburrimiento + </string> + <string name="anim_bow"> + Reverencia + </string> + <string name="anim_clap"> + Aplauso + </string> + <string name="anim_courtbow"> + Reverencia floreada + </string> + <string name="anim_express_cry"> + Llanto + </string> + <string name="anim_dance1"> + Baile 1 + </string> + <string name="anim_dance2"> + Baile 2 + </string> + <string name="anim_dance3"> + Baile 3 + </string> + <string name="anim_dance4"> + Baile 4 + </string> + <string name="anim_dance5"> + Baile 5 + </string> + <string name="anim_dance6"> + Baile 6 + </string> + <string name="anim_dance7"> + Baile 7 + </string> + <string name="anim_dance8"> + Baile 8 + </string> + <string name="anim_express_disdain"> + Desdén + </string> + <string name="anim_drink"> + Beber + </string> + <string name="anim_express_embarrased"> + Azorarse + </string> + <string name="anim_angry_fingerwag"> + Negar con el dedo + </string> + <string name="anim_fist_pump"> + Éxito con el puño + </string> + <string name="anim_yoga_float"> + Yoga flotando + </string> + <string name="anim_express_frown"> + Fruncir el ceño + </string> + <string name="anim_impatient"> + Impaciente + </string> + <string name="anim_jumpforjoy"> + Salto de alegría + </string> + <string name="anim_kissmybutt"> + Bésame el culo + </string> + <string name="anim_express_kiss"> + Besar + </string> + <string name="anim_laugh_short"> + Reír + </string> + <string name="anim_musclebeach"> + Sacar músculo + </string> + <string name="anim_no_unhappy"> + No (con enfado) + </string> + <string name="anim_no_head"> + No + </string> + <string name="anim_nyanya"> + Ña-Ña-Ña + </string> + <string name="anim_punch_onetwo"> + Puñetazo uno-dos + </string> + <string name="anim_express_open_mouth"> + Abrir la boca + </string> + <string name="anim_peace"> + 'V' con los dedos + </string> + <string name="anim_point_you"> + Señalar a otro/a + </string> + <string name="anim_point_me"> + Señalarse + </string> + <string name="anim_punch_l"> + Puñetazo izquierdo + </string> + <string name="anim_punch_r"> + Puñetazo derecho + </string> + <string name="anim_rps_countdown"> + PPT cuenta + </string> + <string name="anim_rps_paper"> + PPT papel + </string> + <string name="anim_rps_rock"> + PPT piedra + </string> + <string name="anim_rps_scissors"> + PPT tijera + </string> + <string name="anim_express_repulsed"> + Repulsa + </string> + <string name="anim_kick_roundhouse_r"> + Patada circular + </string> + <string name="anim_express_sad"> + Triste + </string> + <string name="anim_salute"> + Saludo militar + </string> + <string name="anim_shout"> + Gritar + </string> + <string name="anim_express_shrug"> + Encogerse de hombros + </string> + <string name="anim_express_smile"> + Sonreír + </string> + <string name="anim_smoke_idle"> + Fumar: en la mano + </string> + <string name="anim_smoke_inhale"> + Fumar + </string> + <string name="anim_smoke_throw_down"> + Fumar: tirar el cigarro + </string> + <string name="anim_express_surprise"> + Sorpresa + </string> + <string name="anim_sword_strike_r"> + Estocadas + </string> + <string name="anim_angry_tantrum"> + Berrinche + </string> + <string name="anim_express_tongue_out"> + Sacar la lengua + </string> + <string name="anim_hello"> + Agitar la mano + </string> + <string name="anim_whisper"> + Cuchichear + </string> + <string name="anim_whistle"> + Pitar + </string> + <string name="anim_express_wink"> + Guiño + </string> + <string name="anim_wink_hollywood"> + Guiño (Hollywood) + </string> + <string name="anim_express_worry"> + Preocuparse + </string> + <string name="anim_yes_happy"> + Sí (contento) + </string> + <string name="anim_yes_head"> + Sí + </string> + <string name="use_texture"> + Usar textura + </string> + <string name="manip_hint1"> + Pasa el cursor del ratón sobre la regla + </string> + <string name="manip_hint2"> + para ajustar a la cuadrícula + </string> + <string name="texture_loading"> + Cargando... + </string> + <string name="worldmap_offline"> + Sin conexión + </string> + <string name="worldmap_item_tooltip_format"> + [PRICE] L$ por [AREA] m² + </string> + <string name="worldmap_results_none_found"> + No se ha encontrado. + </string> + <string name="Ok"> + OK + </string> + <string name="Premature end of file"> + Fin prematuro del archivo + </string> + <string name="ST_NO_JOINT"> + No se puede encontrar ROOT o JOINT. + </string> + <string name="NearbyChatTitle"> + Chat + </string> + <string name="NearbyChatLabel"> + (Chat) + </string> + <string name="whisper"> + susurra: + </string> + <string name="shout"> + grita: + </string> + <string name="ringing"> + Conectando al chat de voz... + </string> + <string name="connected"> + Conectado + </string> + <string name="unavailable"> + La voz no está disponible en su localización actual + </string> + <string name="hang_up"> + Desconectado del chat de voz + </string> + <string name="reconnect_nearby"> + Vas a ser reconectado al chat de voz con los cercanos + </string> + <string name="ScriptQuestionCautionChatGranted"> + '[OBJECTNAME]', un objeto propiedad de '[OWNERNAME]', localizado en [REGIONNAME] con la posición [REGIONPOS], ha recibido permiso para: [PERMISSIONS]. + </string> + <string name="ScriptQuestionCautionChatDenied"> + A '[OBJECTNAME]', un objeto propiedad de '[OWNERNAME]', localizado en [REGIONNAME] con la posición [REGIONPOS], se le ha denegado el permiso para: [PERMISSIONS]. + </string> + <string name="AdditionalPermissionsRequestHeader"> + Si autorizas el acceso a tu cuenta, también permitirás al objeto: + </string> + <string name="ScriptTakeMoney"> + Cogerle a usted dólares Linden (L$) + </string> + <string name="ActOnControlInputs"> + Actuar en sus controles de entrada + </string> + <string name="RemapControlInputs"> + Reconfigurar sus controles de entrada + </string> + <string name="AnimateYourAvatar"> + Ejecutar animaciones en su avatar + </string> + <string name="AttachToYourAvatar"> + Anexarse a su avatar + </string> + <string name="ReleaseOwnership"> + Anular la propiedad y que pase a ser público + </string> + <string name="LinkAndDelink"> + Enlazar y desenlazar de otros objetos + </string> + <string name="AddAndRemoveJoints"> + Añadir y quitar uniones con otros objetos + </string> + <string name="ChangePermissions"> + Cambiar sus permisos + </string> + <string name="TrackYourCamera"> + Seguir su cámara + </string> + <string name="ControlYourCamera"> + Controlar su cámara + </string> + <string name="TeleportYourAgent"> + Teleportarte + </string> + <string name="ForceSitAvatar"> + Forzar que el avatar se siente + </string> + <string name="ChangeEnvSettings"> + Cambiar tu configuración del entorno + </string> + <string name="AgentNameSubst"> + (Tú) + </string> <string name="JoinAnExperience"/> - <string name="SilentlyManageEstateAccess">Suprimir alertas al gestionar las listas de acceso a un estado</string> - <string name="OverrideYourAnimations">Reemplazar tus animaciones predeterminadas</string> - <string name="ScriptReturnObjects">Devolver objetos en tu nombre</string> - <string name="UnknownScriptPermission">(desconocido)</string> - <string name="SIM_ACCESS_PG">General</string> - <string name="SIM_ACCESS_MATURE">Moderado</string> - <string name="SIM_ACCESS_ADULT">Adulto</string> - <string name="SIM_ACCESS_DOWN">Desconectado</string> - <string name="SIM_ACCESS_MIN">Desconocido</string> - <string name="land_type_unknown">(desconocido)</string> - <string name="Estate / Full Region">Estado /Región completa</string> - <string name="Estate / Homestead">Estado / Homestead</string> - <string name="Mainland / Homestead">Continente / Homestead</string> - <string name="Mainland / Full Region">Continente / Región completa</string> - <string name="all_files">Todos los archivos</string> - <string name="sound_files">Sonidos</string> - <string name="animation_files">Animaciones</string> - <string name="image_files">Imágenes</string> - <string name="save_file_verb">Guardar</string> - <string name="load_file_verb">Cargar</string> - <string name="targa_image_files">Imágenes Targa</string> - <string name="bitmap_image_files">Imágenes de mapa de bits</string> - <string name="png_image_files">Imágenes PNG</string> - <string name="save_texture_image_files">Imágenes Targa o PNG</string> - <string name="avi_movie_file">Archivo de película AVI</string> - <string name="xaf_animation_file">Archivo de anim. XAF</string> - <string name="xml_file">Archivo XML</string> - <string name="raw_file">Archivo RAW</string> - <string name="compressed_image_files">Imágenes comprimidas</string> - <string name="load_files">Cargar archivos</string> - <string name="choose_the_directory">Elegir directorio</string> - <string name="script_files">Scripts</string> - <string name="dictionary_files">Diccionarios</string> - <string name="shape">Forma</string> - <string name="skin">Piel</string> - <string name="hair">Pelo</string> - <string name="eyes">Ojos</string> - <string name="shirt">Camisa</string> - <string name="pants">Pantalón</string> - <string name="shoes">Zapatos</string> - <string name="socks">Calcetines</string> - <string name="jacket">Chaqueta</string> - <string name="gloves">Guantes</string> - <string name="undershirt">Camiseta</string> - <string name="underpants">Ropa interior</string> - <string name="skirt">Falda</string> - <string name="alpha">Alfa</string> - <string name="tattoo">Tatuaje</string> - <string name="universal">Universal</string> - <string name="physics">Física</string> - <string name="invalid">inválido/a</string> - <string name="none">ninguno</string> - <string name="shirt_not_worn">Camisa no puesta</string> - <string name="pants_not_worn">Pantalones no puestos</string> - <string name="shoes_not_worn">Zapatos no puestos</string> - <string name="socks_not_worn">Calcetines no puestos</string> - <string name="jacket_not_worn">Chaqueta no puesta</string> - <string name="gloves_not_worn">Guantes no puestos</string> - <string name="undershirt_not_worn">Camiseta no puesta</string> - <string name="underpants_not_worn">Ropa interior no puesta</string> - <string name="skirt_not_worn">Falda no puesta</string> - <string name="alpha_not_worn">Alfa no puesta</string> - <string name="tattoo_not_worn">Tatuaje no puesto</string> - <string name="universal_not_worn">Universal no puesto</string> - <string name="physics_not_worn">Física no puesta</string> - <string name="invalid_not_worn">no válido/a</string> - <string name="create_new_shape">Crear una anatomía nueva</string> - <string name="create_new_skin">Crear una piel nueva</string> - <string name="create_new_hair">Crear pelo nuevo</string> - <string name="create_new_eyes">Crear ojos nuevos</string> - <string name="create_new_shirt">Crear una camisa nueva</string> - <string name="create_new_pants">Crear unos pantalones nuevos</string> - <string name="create_new_shoes">Crear unos zapatos nuevos</string> - <string name="create_new_socks">Crear unos calcetines nuevos</string> - <string name="create_new_jacket">Crear una chaqueta nueva</string> - <string name="create_new_gloves">Crear unos guantes nuevos</string> - <string name="create_new_undershirt">Crear una camiseta nueva</string> - <string name="create_new_underpants">Crear ropa interior nueva</string> - <string name="create_new_skirt">Crear una falda nueva</string> - <string name="create_new_alpha">Crear una capa alfa nueva</string> - <string name="create_new_tattoo">Crear un tatuaje nuevo</string> - <string name="create_new_universal">Crear unos guantes nuevos</string> - <string name="create_new_physics">Crear nueva física</string> - <string name="create_new_invalid">no válido/a</string> - <string name="NewWearable">Nuevo [WEARABLE_ITEM]</string> - <string name="next">Siguiente</string> - <string name="ok">OK</string> - <string name="GroupNotifyGroupNotice">Aviso de grupo</string> - <string name="GroupNotifyGroupNotices">Avisos del grupo</string> - <string name="GroupNotifySentBy">Enviado por</string> - <string name="GroupNotifyAttached">Adjunto:</string> - <string name="GroupNotifyViewPastNotices">Ver los avisos pasados u optar por dejar de recibir aquí estos mensajes.</string> - <string name="GroupNotifyOpenAttachment">Abrir el adjunto</string> - <string name="GroupNotifySaveAttachment">Guardar el adjunto</string> - <string name="TeleportOffer">Ofrecimiento de teleporte</string> - <string name="StartUpNotifications">Llegaron avisos nuevos mientras estabas ausente...</string> - <string name="OverflowInfoChannelString">Tienes [%d] aviso/s más</string> - <string name="BodyPartsRightArm">Brazo der.</string> - <string name="BodyPartsHead">Cabeza</string> - <string name="BodyPartsLeftArm">Brazo izq.</string> - <string name="BodyPartsLeftLeg">Pierna izq.</string> - <string name="BodyPartsTorso">Torso</string> - <string name="BodyPartsRightLeg">Pierna der.</string> - <string name="BodyPartsEnhancedSkeleton">Esqueleto mejorado</string> - <string name="GraphicsQualityLow">Bajo</string> - <string name="GraphicsQualityMid">Medio</string> - <string name="GraphicsQualityHigh">Alto</string> - <string name="LeaveMouselook">Pulsa ESC para salir de la vista subjetiva</string> - <string name="InventoryNoMatchingItems">¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/all/[SEARCH_TERM] Buscar].</string> - <string name="InventoryNoMatchingRecentItems">¿No encuentras lo que buscas? Intenta [secondlife:///app/inventory/filters Show filters].</string> - <string name="PlacesNoMatchingItems">¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/places/[SEARCH_TERM] Buscar].</string> - <string name="FavoritesNoMatchingItems">Arrastra aquí un hito para tenerlo en tus favoritos.</string> - <string name="MarketplaceNoMatchingItems">No se han encontrado artículos. Comprueba si has escrito correctamente la cadena de búsqueda y vuelve a intentarlo.</string> - <string name="InventoryNoTexture">No tienes en tu inventario una copia de esta textura</string> - <string name="InventoryInboxNoItems">Aquí aparecerán algunos de los objetos que recibas, como los regalos Premium. Después puedes arrastrarlos a tu inventario.</string> - <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> - <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3</string> - <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string> - <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string> - <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string> - <string name="InventoryPlayAnimationTooltip">Abrir la ventana con las opciones del Juego</string> - <string name="InventoryPlayGestureTooltip">Realizar gesto seleccionado en el mundo.</string> - <string name="InventoryPlaySoundTooltip">Abrir la ventana con las opciones del Juego</string> - <string name="InventoryOutboxNotMerchantTitle">Cualquier usuario puede vender objetos en el mercado.</string> + <string name="SilentlyManageEstateAccess"> + Suprimir alertas al gestionar las listas de acceso a un estado + </string> + <string name="OverrideYourAnimations"> + Reemplazar tus animaciones predeterminadas + </string> + <string name="ScriptReturnObjects"> + Devolver objetos en tu nombre + </string> + <string name="UnknownScriptPermission"> + (desconocido) + </string> + <string name="SIM_ACCESS_PG"> + General + </string> + <string name="SIM_ACCESS_MATURE"> + Moderado + </string> + <string name="SIM_ACCESS_ADULT"> + Adulto + </string> + <string name="SIM_ACCESS_DOWN"> + Desconectado + </string> + <string name="SIM_ACCESS_MIN"> + Desconocido + </string> + <string name="land_type_unknown"> + (desconocido) + </string> + <string name="Estate / Full Region"> + Estado /Región completa + </string> + <string name="Estate / Homestead"> + Estado / Homestead + </string> + <string name="Mainland / Homestead"> + Continente / Homestead + </string> + <string name="Mainland / Full Region"> + Continente / Región completa + </string> + <string name="all_files"> + Todos los archivos + </string> + <string name="sound_files"> + Sonidos + </string> + <string name="animation_files"> + Animaciones + </string> + <string name="image_files"> + Imágenes + </string> + <string name="save_file_verb"> + Guardar + </string> + <string name="load_file_verb"> + Cargar + </string> + <string name="targa_image_files"> + Imágenes Targa + </string> + <string name="bitmap_image_files"> + Imágenes de mapa de bits + </string> + <string name="png_image_files"> + Imágenes PNG + </string> + <string name="save_texture_image_files"> + Imágenes Targa o PNG + </string> + <string name="avi_movie_file"> + Archivo de película AVI + </string> + <string name="xaf_animation_file"> + Archivo de anim. XAF + </string> + <string name="xml_file"> + Archivo XML + </string> + <string name="raw_file"> + Archivo RAW + </string> + <string name="compressed_image_files"> + Imágenes comprimidas + </string> + <string name="load_files"> + Cargar archivos + </string> + <string name="choose_the_directory"> + Elegir directorio + </string> + <string name="script_files"> + Scripts + </string> + <string name="dictionary_files"> + Diccionarios + </string> + <string name="shape"> + Forma + </string> + <string name="skin"> + Piel + </string> + <string name="hair"> + Pelo + </string> + <string name="eyes"> + Ojos + </string> + <string name="shirt"> + Camisa + </string> + <string name="pants"> + Pantalón + </string> + <string name="shoes"> + Zapatos + </string> + <string name="socks"> + Calcetines + </string> + <string name="jacket"> + Chaqueta + </string> + <string name="gloves"> + Guantes + </string> + <string name="undershirt"> + Camiseta + </string> + <string name="underpants"> + Ropa interior + </string> + <string name="skirt"> + Falda + </string> + <string name="alpha"> + Alfa + </string> + <string name="tattoo"> + Tatuaje + </string> + <string name="universal"> + Universal + </string> + <string name="physics"> + Física + </string> + <string name="invalid"> + inválido/a + </string> + <string name="none"> + ninguno + </string> + <string name="shirt_not_worn"> + Camisa no puesta + </string> + <string name="pants_not_worn"> + Pantalones no puestos + </string> + <string name="shoes_not_worn"> + Zapatos no puestos + </string> + <string name="socks_not_worn"> + Calcetines no puestos + </string> + <string name="jacket_not_worn"> + Chaqueta no puesta + </string> + <string name="gloves_not_worn"> + Guantes no puestos + </string> + <string name="undershirt_not_worn"> + Camiseta no puesta + </string> + <string name="underpants_not_worn"> + Ropa interior no puesta + </string> + <string name="skirt_not_worn"> + Falda no puesta + </string> + <string name="alpha_not_worn"> + Alfa no puesta + </string> + <string name="tattoo_not_worn"> + Tatuaje no puesto + </string> + <string name="universal_not_worn"> + Universal no puesto + </string> + <string name="physics_not_worn"> + Física no puesta + </string> + <string name="invalid_not_worn"> + no válido/a + </string> + <string name="create_new_shape"> + Crear una anatomía nueva + </string> + <string name="create_new_skin"> + Crear una piel nueva + </string> + <string name="create_new_hair"> + Crear pelo nuevo + </string> + <string name="create_new_eyes"> + Crear ojos nuevos + </string> + <string name="create_new_shirt"> + Crear una camisa nueva + </string> + <string name="create_new_pants"> + Crear unos pantalones nuevos + </string> + <string name="create_new_shoes"> + Crear unos zapatos nuevos + </string> + <string name="create_new_socks"> + Crear unos calcetines nuevos + </string> + <string name="create_new_jacket"> + Crear una chaqueta nueva + </string> + <string name="create_new_gloves"> + Crear unos guantes nuevos + </string> + <string name="create_new_undershirt"> + Crear una camiseta nueva + </string> + <string name="create_new_underpants"> + Crear ropa interior nueva + </string> + <string name="create_new_skirt"> + Crear una falda nueva + </string> + <string name="create_new_alpha"> + Crear una capa alfa nueva + </string> + <string name="create_new_tattoo"> + Crear un tatuaje nuevo + </string> + <string name="create_new_universal"> + Crear unos guantes nuevos + </string> + <string name="create_new_physics"> + Crear nueva física + </string> + <string name="create_new_invalid"> + no válido/a + </string> + <string name="NewWearable"> + Nuevo [WEARABLE_ITEM] + </string> + <string name="next"> + Siguiente + </string> + <string name="ok"> + OK + </string> + <string name="GroupNotifyGroupNotice"> + Aviso de grupo + </string> + <string name="GroupNotifyGroupNotices"> + Avisos del grupo + </string> + <string name="GroupNotifySentBy"> + Enviado por + </string> + <string name="GroupNotifyAttached"> + Adjunto: + </string> + <string name="GroupNotifyViewPastNotices"> + Ver los avisos pasados u optar por dejar de recibir aquí estos mensajes. + </string> + <string name="GroupNotifyOpenAttachment"> + Abrir el adjunto + </string> + <string name="GroupNotifySaveAttachment"> + Guardar el adjunto + </string> + <string name="TeleportOffer"> + Ofrecimiento de teleporte + </string> + <string name="StartUpNotifications"> + Llegaron avisos nuevos mientras estabas ausente... + </string> + <string name="OverflowInfoChannelString"> + Tienes [%d] aviso/s más + </string> + <string name="BodyPartsRightArm"> + Brazo der. + </string> + <string name="BodyPartsHead"> + Cabeza + </string> + <string name="BodyPartsLeftArm"> + Brazo izq. + </string> + <string name="BodyPartsLeftLeg"> + Pierna izq. + </string> + <string name="BodyPartsTorso"> + Torso + </string> + <string name="BodyPartsRightLeg"> + Pierna der. + </string> + <string name="BodyPartsEnhancedSkeleton"> + Esqueleto mejorado + </string> + <string name="GraphicsQualityLow"> + Bajo + </string> + <string name="GraphicsQualityMid"> + Medio + </string> + <string name="GraphicsQualityHigh"> + Alto + </string> + <string name="LeaveMouselook"> + Pulsa ESC para salir de la vista subjetiva + </string> + <string name="InventoryNoMatchingItems"> + ¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/all/[SEARCH_TERM] Buscar]. + </string> + <string name="InventoryNoMatchingRecentItems"> + ¿No encuentras lo que buscas? Intenta [secondlife:///app/inventory/filters Show filters]. + </string> + <string name="PlacesNoMatchingItems"> + ¿No encuentras lo que buscas? Prueba con [secondlife:///app/search/places/[SEARCH_TERM] Buscar]. + </string> + <string name="FavoritesNoMatchingItems"> + Arrastra aquí un hito para tenerlo en tus favoritos. + </string> + <string name="MarketplaceNoMatchingItems"> + No se han encontrado artículos. Comprueba si has escrito correctamente la cadena de búsqueda y vuelve a intentarlo. + </string> + <string name="InventoryNoTexture"> + No tienes en tu inventario una copia de esta textura + </string> + <string name="InventoryInboxNoItems"> + Aquí aparecerán algunos de los objetos que recibas, como los regalos Premium. Después puedes arrastrarlos a tu inventario. + </string> + <string name="MarketplaceURL"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ + </string> + <string name="MarketplaceURL_CreateStore"> + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3 + </string> + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard + </string> + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports + </string> + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more + </string> + <string name="InventoryPlayAnimationTooltip"> + Abrir la ventana con las opciones del Juego + </string> + <string name="InventoryPlayGestureTooltip"> + Realizar gesto seleccionado en el mundo. + </string> + <string name="InventoryPlaySoundTooltip"> + Abrir la ventana con las opciones del Juego + </string> + <string name="InventoryOutboxNotMerchantTitle"> + Cualquier usuario puede vender objetos en el mercado. + </string> <string name="InventoryOutboxNotMerchantTooltip"/> - <string name="InventoryOutboxNotMerchant">Para hacerte comerciante debes [[MARKETPLACE_CREATE_STORE_URL] crear una tienda del Mercado].</string> - <string name="InventoryOutboxNoItemsTitle">El buzón de salida está vacío.</string> + <string name="InventoryOutboxNotMerchant"> + Para hacerte comerciante debes [[MARKETPLACE_CREATE_STORE_URL] crear una tienda del Mercado]. + </string> + <string name="InventoryOutboxNoItemsTitle"> + El buzón de salida está vacío. + </string> <string name="InventoryOutboxNoItemsTooltip"/> - <string name="InventoryOutboxNoItems">Arrastra carpetas a esta sección y pulsa en "Enviar al Mercado" para incluirlas en la lista de venta del [[MARKETPLACE_DASHBOARD_URL] Mercado].</string> - <string name="InventoryOutboxInitializingTitle">Inicializando el Mercado.</string> - <string name="InventoryOutboxInitializing">Estamos accediendo a tu cuenta de la [[MARKETPLACE_CREATE_STORE_URL] tienda del Mercado].</string> - <string name="InventoryOutboxErrorTitle">Errores del Mercado.</string> - <string name="InventoryOutboxError">La [[MARKETPLACE_CREATE_STORE_URL] tienda del Mercado] devuelve errores.</string> - <string name="InventoryMarketplaceError">Se ha producido un error al abrir Artículos del Mercado. -Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia de Second Life en http://support.secondlife.com</string> - <string name="InventoryMarketplaceListingsNoItemsTitle">Tu carpeta Artículos del mercado está vacía.</string> - <string name="InventoryMarketplaceListingsNoItems">Arrastra carpetas a esta sección para incluirlas en la lista de venta del [[MARKETPLACE_DASHBOARD_URL] Mercado].</string> - <string name="InventoryItemsCount">( [ITEMS_COUNT] Objetos)</string> - <string name="Marketplace Validation Warning Stock">La carpeta de stock debe estar contenida en una carpeta de versión</string> - <string name="Marketplace Validation Error Mixed Stock">: Error: todos los artículos de una carpeta de stock deben ser del mismo tipo y que no se puedan copiar</string> - <string name="Marketplace Validation Error Subfolder In Stock">: Error: la carpeta de stock no puede contener subcarpetas</string> - <string name="Marketplace Validation Warning Empty">: Atención: la carpeta no contiene ningún artículo</string> - <string name="Marketplace Validation Warning Create Stock">: Atención: creando carpeta de stock</string> - <string name="Marketplace Validation Warning Create Version">: Atención: creando la carpeta de versión</string> - <string name="Marketplace Validation Warning Move">: Atención: moviendo artículos</string> - <string name="Marketplace Validation Warning Delete">: Atención: se ha transferido el contenido de la carpeta a la carpeta de stock, y se eliminará la carpeta vacía</string> - <string name="Marketplace Validation Error Stock Item">: Error: los artículos que no se pueden copiar deben estar contenidos en una carpeta de stock</string> - <string name="Marketplace Validation Warning Unwrapped Item">: Atención: los artículos deben estar contenidos en una carpeta de versión</string> - <string name="Marketplace Validation Error">: Error:</string> - <string name="Marketplace Validation Warning">: Atención:</string> - <string name="Marketplace Validation Error Empty Version">: Atención: la carpeta de versión debe contener al menos un artículo</string> - <string name="Marketplace Validation Error Empty Stock">: Atención: la carpeta de stock debe contener al menos un artículo</string> - <string name="Marketplace Validation No Error">No se han producido errores ni advertencias</string> - <string name="Marketplace Error None">Sin errores</string> - <string name="Marketplace Error Prefix">Error:</string> - <string name="Marketplace Error Not Merchant">Para poder enviar objetos al mercado, debes registrarte como comerciante (es gratis).</string> - <string name="Marketplace Error Not Accepted">No se puede mover el artículo a esa carpeta.</string> - <string name="Marketplace Error Unsellable Item">Este artículo no se puede vender en el Mercado.</string> - <string name="MarketplaceNoID">no Mkt ID</string> - <string name="MarketplaceLive">en la lista</string> - <string name="MarketplaceActive">activa</string> - <string name="MarketplaceMax">máx.</string> - <string name="MarketplaceStock">stock</string> - <string name="MarketplaceNoStock">existencias agotadas</string> - <string name="MarketplaceUpdating">actualizando...</string> - <string name="UploadFeeInfo">Las cuotas se basan en tu nivel de suscripcion. Niveles más altos tienen cuotas más bajas visita [https://secondlife.com/my/account/membership.php? para saber más]</string> - <string name="Open landmarks">Abrir puntos destacados</string> - <string name="Unconstrained">Sin Restricciones</string> + <string name="InventoryOutboxNoItems"> + Arrastra carpetas a esta sección y pulsa en "Enviar al Mercado" para incluirlas en la lista de venta del [[MARKETPLACE_DASHBOARD_URL] Mercado]. + </string> + <string name="InventoryOutboxInitializingTitle"> + Inicializando el Mercado. + </string> + <string name="InventoryOutboxInitializing"> + Estamos accediendo a tu cuenta de la [[MARKETPLACE_CREATE_STORE_URL] tienda del Mercado]. + </string> + <string name="InventoryOutboxErrorTitle"> + Errores del Mercado. + </string> + <string name="InventoryOutboxError"> + La [[MARKETPLACE_CREATE_STORE_URL] tienda del Mercado] devuelve errores. + </string> + <string name="InventoryMarketplaceError"> + Se ha producido un error al abrir Artículos del Mercado. +Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia de Second Life en http://support.secondlife.com + </string> + <string name="InventoryMarketplaceListingsNoItemsTitle"> + Tu carpeta Artículos del mercado está vacía. + </string> + <string name="InventoryMarketplaceListingsNoItems"> + Arrastra carpetas a esta sección para incluirlas en la lista de venta del [[MARKETPLACE_DASHBOARD_URL] Mercado]. + </string> + <string name="InventoryItemsCount"> + ( [ITEMS_COUNT] Objetos) + </string> + <string name="Marketplace Validation Warning Stock"> + La carpeta de stock debe estar contenida en una carpeta de versión + </string> + <string name="Marketplace Validation Error Mixed Stock"> + : Error: todos los artículos de una carpeta de stock deben ser del mismo tipo y que no se puedan copiar + </string> + <string name="Marketplace Validation Error Subfolder In Stock"> + : Error: la carpeta de stock no puede contener subcarpetas + </string> + <string name="Marketplace Validation Warning Empty"> + : Atención: la carpeta no contiene ningún artículo + </string> + <string name="Marketplace Validation Warning Create Stock"> + : Atención: creando carpeta de stock + </string> + <string name="Marketplace Validation Warning Create Version"> + : Atención: creando la carpeta de versión + </string> + <string name="Marketplace Validation Warning Move"> + : Atención: moviendo artículos + </string> + <string name="Marketplace Validation Warning Delete"> + : Atención: se ha transferido el contenido de la carpeta a la carpeta de stock, y se eliminará la carpeta vacía + </string> + <string name="Marketplace Validation Error Stock Item"> + : Error: los artículos que no se pueden copiar deben estar contenidos en una carpeta de stock + </string> + <string name="Marketplace Validation Warning Unwrapped Item"> + : Atención: los artículos deben estar contenidos en una carpeta de versión + </string> + <string name="Marketplace Validation Error"> + : Error: + </string> + <string name="Marketplace Validation Warning"> + : Atención: + </string> + <string name="Marketplace Validation Error Empty Version"> + : Atención: la carpeta de versión debe contener al menos un artículo + </string> + <string name="Marketplace Validation Error Empty Stock"> + : Atención: la carpeta de stock debe contener al menos un artículo + </string> + <string name="Marketplace Validation No Error"> + No se han producido errores ni advertencias + </string> + <string name="Marketplace Error None"> + Sin errores + </string> + <string name="Marketplace Error Prefix"> + Error: + </string> + <string name="Marketplace Error Not Merchant"> + Para poder enviar objetos al mercado, debes registrarte como comerciante (es gratis). + </string> + <string name="Marketplace Error Not Accepted"> + No se puede mover el artículo a esa carpeta. + </string> + <string name="Marketplace Error Unsellable Item"> + Este artículo no se puede vender en el Mercado. + </string> + <string name="MarketplaceNoID"> + no Mkt ID + </string> + <string name="MarketplaceLive"> + en la lista + </string> + <string name="MarketplaceActive"> + activa + </string> + <string name="MarketplaceMax"> + máx. + </string> + <string name="MarketplaceStock"> + stock + </string> + <string name="MarketplaceNoStock"> + existencias agotadas + </string> + <string name="MarketplaceUpdating"> + actualizando... + </string> + <string name="UploadFeeInfo"> + Las cuotas se basan en tu nivel de suscripcion. Niveles más altos tienen cuotas más bajas visita [https://secondlife.com/my/account/membership.php? para saber más] + </string> + <string name="Open landmarks"> + Abrir puntos destacados + </string> + <string name="Unconstrained"> + Sin Restricciones + </string> <string name="no_transfer" value="(no transferible)"/> <string name="no_modify" value="(no modificable)"/> <string name="no_copy" value="(no copiable)"/> <string name="worn" value="(puesto)"/> <string name="link" value="(enlace)"/> <string name="broken_link" value="(enlace roto)""/> - <string name="LoadingContents">Cargando el contenido...</string> - <string name="NoContents">No hay contenido</string> + <string name="LoadingContents"> + Cargando el contenido... + </string> + <string name="NoContents"> + No hay contenido + </string> <string name="WornOnAttachmentPoint" value="(lo llevas en: [ATTACHMENT_POINT])"/> <string name="AttachmentErrorMessage" value="([ATTACHMENT_ERROR])"/> <string name="ActiveGesture" value="[GESLABEL] (activo)"/> @@ -629,1414 +1681,4140 @@ Si sigues recibiendo el mismo mensaje, solicita ayuda al personal de asistencia <string name="Snapshots" value="Fotos,"/> <string name="No Filters" value="No"/> <string name="Since Logoff" value="- Desde la desconexión"/> - <string name="InvFolder My Inventory">Mi Inventario</string> - <string name="InvFolder Library">Biblioteca</string> - <string name="InvFolder Textures">Texturas</string> - <string name="InvFolder Sounds">Sonidos</string> - <string name="InvFolder Calling Cards">Tarjetas de visita</string> - <string name="InvFolder Landmarks">Hitos</string> - <string name="InvFolder Scripts">Scripts</string> - <string name="InvFolder Clothing">Ropa</string> - <string name="InvFolder Objects">Objetos</string> - <string name="InvFolder Notecards">Notas</string> - <string name="InvFolder New Folder">Carpeta nueva</string> - <string name="InvFolder Inventory">Inventario</string> - <string name="InvFolder Uncompressed Images">Imágenes sin comprimir</string> - <string name="InvFolder Body Parts">Partes del cuerpo</string> - <string name="InvFolder Trash">Papelera</string> - <string name="InvFolder Photo Album">Álbum de fotos</string> - <string name="InvFolder Lost And Found">Objetos Perdidos</string> - <string name="InvFolder Uncompressed Sounds">Sonidos sin comprimir</string> - <string name="InvFolder Animations">Animaciones</string> - <string name="InvFolder Gestures">Gestos</string> - <string name="InvFolder Favorite">Mis Favoritos</string> - <string name="InvFolder favorite">Mis Favoritos</string> - <string name="InvFolder Favorites">Mis Favoritos</string> - <string name="InvFolder favorites">Mis Favoritos</string> - <string name="InvFolder Current Outfit">Vestuario actual</string> - <string name="InvFolder Initial Outfits">Vestuario inicial</string> - <string name="InvFolder My Outfits">Mis vestuarios</string> - <string name="InvFolder Accessories">Accesorios</string> - <string name="InvFolder Meshes">Redes</string> - <string name="InvFolder Received Items">Objetos recibidos</string> - <string name="InvFolder Merchant Outbox">Buzón de salida de comerciante</string> - <string name="InvFolder Friends">Amigos</string> - <string name="InvFolder All">Todas</string> - <string name="no_attachments">No tienes puestos anexos</string> - <string name="Attachments remain">Anexos (quedan [COUNT] ranuras)</string> - <string name="Buy">Comprar</string> - <string name="BuyforL$">Comprar por L$</string> - <string name="Stone">Piedra</string> - <string name="Metal">Metal</string> - <string name="Glass">Cristal</string> - <string name="Wood">Madera</string> - <string name="Flesh">Carne</string> - <string name="Plastic">Plástico</string> - <string name="Rubber">Goma</string> - <string name="Light">Claridad</string> - <string name="KBShift">Mayúsculas</string> - <string name="KBCtrl">Ctrl</string> - <string name="Chest">Tórax</string> - <string name="Skull">Cráneo</string> - <string name="Left Shoulder">Hombro izquierdo</string> - <string name="Right Shoulder">Hombro derecho</string> - <string name="Left Hand">Mano izq.</string> - <string name="Right Hand">Mano der.</string> - <string name="Left Foot">Pie izq.</string> - <string name="Right Foot">Pie der.</string> - <string name="Spine">Columna</string> - <string name="Pelvis">Pelvis</string> - <string name="Mouth">Boca</string> - <string name="Chin">Barbilla</string> - <string name="Left Ear">Oreja izq.</string> - <string name="Right Ear">Oreja der.</string> - <string name="Left Eyeball">Ojo izq.</string> - <string name="Right Eyeball">Ojo der.</string> - <string name="Nose">Nariz</string> - <string name="R Upper Arm">Brazo der.</string> - <string name="R Forearm">Antebrazo der.</string> - <string name="L Upper Arm">Brazo izq.</string> - <string name="L Forearm">Antebrazo izq.</string> - <string name="Right Hip">Cadera der.</string> - <string name="R Upper Leg">Muslo der.</string> - <string name="R Lower Leg">Pantorrilla der.</string> - <string name="Left Hip">Cadera izq.</string> - <string name="L Upper Leg">Muslo izq.</string> - <string name="L Lower Leg">Pantorrilla izq.</string> - <string name="Stomach">Abdomen</string> - <string name="Left Pec">Pecho izquierdo</string> - <string name="Right Pec">Pecho derecho</string> - <string name="Neck">Cuello</string> - <string name="Avatar Center">Centro del avatar</string> - <string name="Left Ring Finger">Dedo anular izquierdo</string> - <string name="Right Ring Finger">Dedo anular derecho</string> - <string name="Tail Base">Base de la cola</string> - <string name="Tail Tip">Extremo de la cola</string> - <string name="Left Wing">Ala izquierda</string> - <string name="Right Wing">Ala derecha</string> - <string name="Jaw">Mandíbula</string> - <string name="Alt Left Ear">Oreja izquierda alternativa</string> - <string name="Alt Right Ear">Oreja derecha alternativa</string> - <string name="Alt Left Eye">Ojo izquierdo alternativo</string> - <string name="Alt Right Eye">Ojo derecho alternativo</string> - <string name="Tongue">Lengua</string> - <string name="Groin">Ingle</string> - <string name="Left Hind Foot">Pata trasera izquierda</string> - <string name="Right Hind Foot">Pata trasera derecha</string> - <string name="Invalid Attachment">Punto de colocación no válido</string> - <string name="ATTACHMENT_MISSING_ITEM">Error: falta un artículo</string> - <string name="ATTACHMENT_MISSING_BASE_ITEM">Error: falta el artículo de base</string> - <string name="ATTACHMENT_NOT_ATTACHED">Error: el objeto se encuentra en el vestuario actual, pero no está anexado</string> - <string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS] de edad</string> - <string name="YearsOld">[AGEYEARS] de edad</string> - <string name="MonthsOld">[AGEMONTHS] de edad</string> - <string name="WeeksOld">[AGEWEEKS] de edad</string> - <string name="DaysOld">[AGEDAYS] de edad</string> - <string name="TodayOld">Registrado hoy</string> - <string name="av_render_everyone_now">Ahora todos pueden verte.</string> - <string name="av_render_not_everyone">Es posible que no todos los que están próximos puedan renderizarte.</string> - <string name="av_render_over_half">Es posible que más de la mitad de los que están próximos no puedan renderizarte.</string> - <string name="av_render_most_of">Es posible que la mayoría de los que están próximos no puedan renderizarte.</string> - <string name="av_render_anyone">Es posible que ninguno de los que están próximos pueda renderizarte.</string> - <string name="hud_description_total">Tu HUD</string> - <string name="hud_name_with_joint">[OBJ_NAME] (lo llevas en [JNT_NAME])</string> - <string name="hud_render_memory_warning">[HUD_DETAILS] usa mucha memoria de textura</string> - <string name="hud_render_cost_warning">[HUD_DETAILS] contiene muchas texturas y objetos complicados</string> - <string name="hud_render_heavy_textures_warning">[HUD_DETAILS] contiene muchas texturas grandes</string> - <string name="hud_render_cramped_warning">[HUD_DETAILS] contiene demasiados objetos</string> - <string name="hud_render_textures_warning">[HUD_DETAILS] contiene demasiadas texturas</string> - <string name="AgeYearsA">[COUNT] año</string> - <string name="AgeYearsB">[COUNT] años</string> - <string name="AgeYearsC">[COUNT] años</string> - <string name="AgeMonthsA">[COUNT] mes</string> - <string name="AgeMonthsB">[COUNT] meses</string> - <string name="AgeMonthsC">[COUNT] meses</string> - <string name="AgeWeeksA">[COUNT] semana</string> - <string name="AgeWeeksB">[COUNT] semanas</string> - <string name="AgeWeeksC">[COUNT] semanas</string> - <string name="AgeDaysA">[COUNT] día</string> - <string name="AgeDaysB">[COUNT] días</string> - <string name="AgeDaysC">[COUNT] días</string> - <string name="GroupMembersA">[COUNT] miembro</string> - <string name="GroupMembersB">[COUNT] miembros</string> - <string name="GroupMembersC">[COUNT] miembros</string> - <string name="AcctTypeResident">Residente</string> - <string name="AcctTypeTrial">Prueba</string> - <string name="AcctTypeCharterMember">Miembro fundador</string> - <string name="AcctTypeEmployee">Empleado de Linden Lab</string> - <string name="PaymentInfoUsed">Ha usado información sobre la forma de pago</string> - <string name="PaymentInfoOnFile">Hay información archivada sobre la forma de pago</string> - <string name="NoPaymentInfoOnFile">No hay información archivada sobre la forma de pago</string> - <string name="AgeVerified">Edad verificada</string> - <string name="NotAgeVerified">Edad no verificada</string> - <string name="Center 2">Centro 2</string> - <string name="Top Right">Arriba der.</string> - <string name="Top">Arriba</string> - <string name="Top Left">Arriba izq.</string> - <string name="Center">Centro</string> - <string name="Bottom Left">Abajo izq.</string> - <string name="Bottom">Abajo</string> - <string name="Bottom Right">Abajo der.</string> - <string name="CompileQueueDownloadedCompiling">Descargado, compilándolo</string> - <string name="CompileQueueServiceUnavailable">El servicio de compilación de scripts no está disponible</string> - <string name="CompileQueueScriptNotFound">No se encuentra el script en el servidor.</string> - <string name="CompileQueueProblemDownloading">Problema al descargar</string> - <string name="CompileQueueInsufficientPermDownload">Permisos insuficientes para descargar un script.</string> - <string name="CompileQueueInsufficientPermFor">Permisos insuficientes para</string> - <string name="CompileQueueUnknownFailure">Fallo desconocido en la descarga</string> - <string name="CompileNoExperiencePerm">Omitiendo el script [SCRIPT] con la experiencia [EXPERIENCE].</string> - <string name="CompileQueueTitle">Recompilando</string> - <string name="CompileQueueStart">recompilar</string> - <string name="ResetQueueTitle">Progreso del reinicio</string> - <string name="ResetQueueStart">restaurar</string> - <string name="RunQueueTitle">Configurar según se ejecuta</string> - <string name="RunQueueStart">Configurando según se ejecuta</string> - <string name="NotRunQueueTitle">Configurar sin ejecutar</string> - <string name="NotRunQueueStart">Configurando sin ejecutarlo</string> - <string name="CompileSuccessful">¡Compilación correcta!</string> - <string name="CompileSuccessfulSaving">Compilación correcta, guardando...</string> - <string name="SaveComplete">Guardado.</string> - <string name="UploadFailed">Error al subir el archivo:</string> - <string name="ObjectOutOfRange">Script (objeto fuera de rango)</string> - <string name="ScriptWasDeleted">Script (eliminado del inventario)</string> - <string name="GodToolsObjectOwnedBy">El objeto [OBJECT] es propiedad de [OWNER]</string> - <string name="GroupsNone">ninguno</string> + <string name="InvFolder My Inventory"> + Mi Inventario + </string> + <string name="InvFolder Library"> + Biblioteca + </string> + <string name="InvFolder Textures"> + Texturas + </string> + <string name="InvFolder Sounds"> + Sonidos + </string> + <string name="InvFolder Calling Cards"> + Tarjetas de visita + </string> + <string name="InvFolder Landmarks"> + Hitos + </string> + <string name="InvFolder Scripts"> + Scripts + </string> + <string name="InvFolder Clothing"> + Ropa + </string> + <string name="InvFolder Objects"> + Objetos + </string> + <string name="InvFolder Notecards"> + Notas + </string> + <string name="InvFolder New Folder"> + Carpeta nueva + </string> + <string name="InvFolder Inventory"> + Inventario + </string> + <string name="InvFolder Uncompressed Images"> + Imágenes sin comprimir + </string> + <string name="InvFolder Body Parts"> + Partes del cuerpo + </string> + <string name="InvFolder Trash"> + Papelera + </string> + <string name="InvFolder Photo Album"> + Álbum de fotos + </string> + <string name="InvFolder Lost And Found"> + Objetos Perdidos + </string> + <string name="InvFolder Uncompressed Sounds"> + Sonidos sin comprimir + </string> + <string name="InvFolder Animations"> + Animaciones + </string> + <string name="InvFolder Gestures"> + Gestos + </string> + <string name="InvFolder Favorite"> + Mis Favoritos + </string> + <string name="InvFolder favorite"> + Mis Favoritos + </string> + <string name="InvFolder Favorites"> + Mis Favoritos + </string> + <string name="InvFolder favorites"> + Mis Favoritos + </string> + <string name="InvFolder Current Outfit"> + Vestuario actual + </string> + <string name="InvFolder Initial Outfits"> + Vestuario inicial + </string> + <string name="InvFolder My Outfits"> + Mis vestuarios + </string> + <string name="InvFolder Accessories"> + Accesorios + </string> + <string name="InvFolder Meshes"> + Redes + </string> + <string name="InvFolder Received Items"> + Objetos recibidos + </string> + <string name="InvFolder Merchant Outbox"> + Buzón de salida de comerciante + </string> + <string name="InvFolder Friends"> + Amigos + </string> + <string name="InvFolder All"> + Todas + </string> + <string name="no_attachments"> + No tienes puestos anexos + </string> + <string name="Attachments remain"> + Anexos (quedan [COUNT] ranuras) + </string> + <string name="Buy"> + Comprar + </string> + <string name="BuyforL$"> + Comprar por L$ + </string> + <string name="Stone"> + Piedra + </string> + <string name="Metal"> + Metal + </string> + <string name="Glass"> + Cristal + </string> + <string name="Wood"> + Madera + </string> + <string name="Flesh"> + Carne + </string> + <string name="Plastic"> + Plástico + </string> + <string name="Rubber"> + Goma + </string> + <string name="Light"> + Claridad + </string> + <string name="KBShift"> + Mayúsculas + </string> + <string name="KBCtrl"> + Ctrl + </string> + <string name="Chest"> + Tórax + </string> + <string name="Skull"> + Cráneo + </string> + <string name="Left Shoulder"> + Hombro izquierdo + </string> + <string name="Right Shoulder"> + Hombro derecho + </string> + <string name="Left Hand"> + Mano izq. + </string> + <string name="Right Hand"> + Mano der. + </string> + <string name="Left Foot"> + Pie izq. + </string> + <string name="Right Foot"> + Pie der. + </string> + <string name="Spine"> + Columna + </string> + <string name="Pelvis"> + Pelvis + </string> + <string name="Mouth"> + Boca + </string> + <string name="Chin"> + Barbilla + </string> + <string name="Left Ear"> + Oreja izq. + </string> + <string name="Right Ear"> + Oreja der. + </string> + <string name="Left Eyeball"> + Ojo izq. + </string> + <string name="Right Eyeball"> + Ojo der. + </string> + <string name="Nose"> + Nariz + </string> + <string name="R Upper Arm"> + Brazo der. + </string> + <string name="R Forearm"> + Antebrazo der. + </string> + <string name="L Upper Arm"> + Brazo izq. + </string> + <string name="L Forearm"> + Antebrazo izq. + </string> + <string name="Right Hip"> + Cadera der. + </string> + <string name="R Upper Leg"> + Muslo der. + </string> + <string name="R Lower Leg"> + Pantorrilla der. + </string> + <string name="Left Hip"> + Cadera izq. + </string> + <string name="L Upper Leg"> + Muslo izq. + </string> + <string name="L Lower Leg"> + Pantorrilla izq. + </string> + <string name="Stomach"> + Abdomen + </string> + <string name="Left Pec"> + Pecho izquierdo + </string> + <string name="Right Pec"> + Pecho derecho + </string> + <string name="Neck"> + Cuello + </string> + <string name="Avatar Center"> + Centro del avatar + </string> + <string name="Left Ring Finger"> + Dedo anular izquierdo + </string> + <string name="Right Ring Finger"> + Dedo anular derecho + </string> + <string name="Tail Base"> + Base de la cola + </string> + <string name="Tail Tip"> + Extremo de la cola + </string> + <string name="Left Wing"> + Ala izquierda + </string> + <string name="Right Wing"> + Ala derecha + </string> + <string name="Jaw"> + Mandíbula + </string> + <string name="Alt Left Ear"> + Oreja izquierda alternativa + </string> + <string name="Alt Right Ear"> + Oreja derecha alternativa + </string> + <string name="Alt Left Eye"> + Ojo izquierdo alternativo + </string> + <string name="Alt Right Eye"> + Ojo derecho alternativo + </string> + <string name="Tongue"> + Lengua + </string> + <string name="Groin"> + Ingle + </string> + <string name="Left Hind Foot"> + Pata trasera izquierda + </string> + <string name="Right Hind Foot"> + Pata trasera derecha + </string> + <string name="Invalid Attachment"> + Punto de colocación no válido + </string> + <string name="ATTACHMENT_MISSING_ITEM"> + Error: falta un artículo + </string> + <string name="ATTACHMENT_MISSING_BASE_ITEM"> + Error: falta el artículo de base + </string> + <string name="ATTACHMENT_NOT_ATTACHED"> + Error: el objeto se encuentra en el vestuario actual, pero no está anexado + </string> + <string name="YearsMonthsOld"> + [AGEYEARS] [AGEMONTHS] de edad + </string> + <string name="YearsOld"> + [AGEYEARS] de edad + </string> + <string name="MonthsOld"> + [AGEMONTHS] de edad + </string> + <string name="WeeksOld"> + [AGEWEEKS] de edad + </string> + <string name="DaysOld"> + [AGEDAYS] de edad + </string> + <string name="TodayOld"> + Registrado hoy + </string> + <string name="av_render_everyone_now"> + Ahora todos pueden verte. + </string> + <string name="av_render_not_everyone"> + Es posible que no todos los que están próximos puedan renderizarte. + </string> + <string name="av_render_over_half"> + Es posible que más de la mitad de los que están próximos no puedan renderizarte. + </string> + <string name="av_render_most_of"> + Es posible que la mayoría de los que están próximos no puedan renderizarte. + </string> + <string name="av_render_anyone"> + Es posible que ninguno de los que están próximos pueda renderizarte. + </string> + <string name="hud_description_total"> + Tu HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (lo llevas en [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] usa mucha memoria de textura + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contiene muchas texturas y objetos complicados + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contiene muchas texturas grandes + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contiene demasiados objetos + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contiene demasiadas texturas + </string> + <string name="AgeYearsA"> + [COUNT] año + </string> + <string name="AgeYearsB"> + [COUNT] años + </string> + <string name="AgeYearsC"> + [COUNT] años + </string> + <string name="AgeMonthsA"> + [COUNT] mes + </string> + <string name="AgeMonthsB"> + [COUNT] meses + </string> + <string name="AgeMonthsC"> + [COUNT] meses + </string> + <string name="AgeWeeksA"> + [COUNT] semana + </string> + <string name="AgeWeeksB"> + [COUNT] semanas + </string> + <string name="AgeWeeksC"> + [COUNT] semanas + </string> + <string name="AgeDaysA"> + [COUNT] día + </string> + <string name="AgeDaysB"> + [COUNT] días + </string> + <string name="AgeDaysC"> + [COUNT] días + </string> + <string name="GroupMembersA"> + [COUNT] miembro + </string> + <string name="GroupMembersB"> + [COUNT] miembros + </string> + <string name="GroupMembersC"> + [COUNT] miembros + </string> + <string name="AcctTypeResident"> + Residente + </string> + <string name="AcctTypeTrial"> + Prueba + </string> + <string name="AcctTypeCharterMember"> + Miembro fundador + </string> + <string name="AcctTypeEmployee"> + Empleado de Linden Lab + </string> + <string name="PaymentInfoUsed"> + Ha usado información sobre la forma de pago + </string> + <string name="PaymentInfoOnFile"> + Hay información archivada sobre la forma de pago + </string> + <string name="NoPaymentInfoOnFile"> + No hay información archivada sobre la forma de pago + </string> + <string name="AgeVerified"> + Edad verificada + </string> + <string name="NotAgeVerified"> + Edad no verificada + </string> + <string name="Center 2"> + Centro 2 + </string> + <string name="Top Right"> + Arriba der. + </string> + <string name="Top"> + Arriba + </string> + <string name="Top Left"> + Arriba izq. + </string> + <string name="Center"> + Centro + </string> + <string name="Bottom Left"> + Abajo izq. + </string> + <string name="Bottom"> + Abajo + </string> + <string name="Bottom Right"> + Abajo der. + </string> + <string name="CompileQueueDownloadedCompiling"> + Descargado, compilándolo + </string> + <string name="CompileQueueServiceUnavailable"> + El servicio de compilación de scripts no está disponible + </string> + <string name="CompileQueueScriptNotFound"> + No se encuentra el script en el servidor. + </string> + <string name="CompileQueueProblemDownloading"> + Problema al descargar + </string> + <string name="CompileQueueInsufficientPermDownload"> + Permisos insuficientes para descargar un script. + </string> + <string name="CompileQueueInsufficientPermFor"> + Permisos insuficientes para + </string> + <string name="CompileQueueUnknownFailure"> + Fallo desconocido en la descarga + </string> + <string name="CompileNoExperiencePerm"> + Omitiendo el script [SCRIPT] con la experiencia [EXPERIENCE]. + </string> + <string name="CompileQueueTitle"> + Recompilando + </string> + <string name="CompileQueueStart"> + recompilar + </string> + <string name="ResetQueueTitle"> + Progreso del reinicio + </string> + <string name="ResetQueueStart"> + restaurar + </string> + <string name="RunQueueTitle"> + Configurar según se ejecuta + </string> + <string name="RunQueueStart"> + Configurando según se ejecuta + </string> + <string name="NotRunQueueTitle"> + Configurar sin ejecutar + </string> + <string name="NotRunQueueStart"> + Configurando sin ejecutarlo + </string> + <string name="CompileSuccessful"> + ¡Compilación correcta! + </string> + <string name="CompileSuccessfulSaving"> + Compilación correcta, guardando... + </string> + <string name="SaveComplete"> + Guardado. + </string> + <string name="UploadFailed"> + Error al subir el archivo: + </string> + <string name="ObjectOutOfRange"> + Script (objeto fuera de rango) + </string> + <string name="ScriptWasDeleted"> + Script (eliminado del inventario) + </string> + <string name="GodToolsObjectOwnedBy"> + El objeto [OBJECT] es propiedad de [OWNER] + </string> + <string name="GroupsNone"> + ninguno + </string> <string name="Group" value="(grupo)"/> - <string name="Unknown">(Desconocido)</string> + <string name="Unknown"> + (Desconocido) + </string> <string name="SummaryForTheWeek" value="Resumen de esta semana, empezando el "/> <string name="NextStipendDay" value=". El próximo día de pago es el "/> - <string name="GroupPlanningDate">[mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc]</string> + <string name="GroupPlanningDate"> + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + </string> <string name="GroupIndividualShare" value="Grupo Aportaciones individuales"/> <string name="GroupColumn" value="Grupo"/> - <string name="Balance">Saldo</string> - <string name="Credits">Créditos</string> - <string name="Debits">Débitos</string> - <string name="Total">Total</string> - <string name="NoGroupDataFound">No se encontraron datos del grupo</string> - <string name="IMParentEstate">parent estate</string> - <string name="IMMainland">continente</string> - <string name="IMTeen">teen</string> - <string name="Anyone">cualquiera</string> - <string name="RegionInfoError">error</string> - <string name="RegionInfoAllEstatesOwnedBy">todos los estados propiedad de [OWNER]</string> - <string name="RegionInfoAllEstatesYouOwn">todos los estados que posees</string> - <string name="RegionInfoAllEstatesYouManage">todos los estados que administras para [OWNER]</string> - <string name="RegionInfoAllowedResidents">Siempre permitido: ([ALLOWEDAGENTS], de un máx. de [MAXACCESS])</string> - <string name="RegionInfoAllowedGroups">Grupos siempre permitidos: ([ALLOWEDGROUPS], de un máx. de [MAXACCESS])</string> - <string name="RegionInfoBannedResidents">Siempre prohibido: ([BANNEDAGENTS], de un máx. de [MAXBANNED])</string> - <string name="RegionInfoListTypeAllowedAgents">Siempre permitido</string> - <string name="RegionInfoListTypeBannedAgents">Siempre prohibido</string> - <string name="RegionInfoAllEstates">todos los estados</string> - <string name="RegionInfoManagedEstates">estados administrados</string> - <string name="RegionInfoThisEstate">este estado</string> - <string name="AndNMore">y [EXTRA_COUNT] más</string> - <string name="ScriptLimitsParcelScriptMemory">Memoria de los scripts de la parcela</string> - <string name="ScriptLimitsParcelsOwned">Parcelas listadas: [PARCELS]</string> - <string name="ScriptLimitsMemoryUsed">Memoria usada: [COUNT] kb de un máx de [MAX] kb; [AVAILABLE] kb disponibles</string> - <string name="ScriptLimitsMemoryUsedSimple">Memoria usada: [COUNT] kb</string> - <string name="ScriptLimitsParcelScriptURLs">URLs de los scripts de la parcela</string> - <string name="ScriptLimitsURLsUsed">URLs usadas: [COUNT] de un máx. de [MAX]; [AVAILABLE] disponibles</string> - <string name="ScriptLimitsURLsUsedSimple">URLs usadas: [COUNT]</string> - <string name="ScriptLimitsRequestError">Error al obtener la información</string> - <string name="ScriptLimitsRequestNoParcelSelected">No hay una parcela seleccionada</string> - <string name="ScriptLimitsRequestWrongRegion">Error: la información del script sólo está disponible en tu región actual</string> - <string name="ScriptLimitsRequestWaiting">Obteniendo la información...</string> - <string name="ScriptLimitsRequestDontOwnParcel">No tienes permiso para examinar esta parcela</string> - <string name="SITTING_ON">Sentado en</string> - <string name="ATTACH_CHEST">Tórax</string> - <string name="ATTACH_HEAD">Cráneo</string> - <string name="ATTACH_LSHOULDER">Hombro izquierdo</string> - <string name="ATTACH_RSHOULDER">Hombro derecho</string> - <string name="ATTACH_LHAND">Mano izq.</string> - <string name="ATTACH_RHAND">Mano der.</string> - <string name="ATTACH_LFOOT">Pie izq.</string> - <string name="ATTACH_RFOOT">Pie der.</string> - <string name="ATTACH_BACK">Columna</string> - <string name="ATTACH_PELVIS">Pelvis</string> - <string name="ATTACH_MOUTH">Boca</string> - <string name="ATTACH_CHIN">Barbilla</string> - <string name="ATTACH_LEAR">Oreja izq.</string> - <string name="ATTACH_REAR">Oreja der.</string> - <string name="ATTACH_LEYE">Ojo izq.</string> - <string name="ATTACH_REYE">Ojo der.</string> - <string name="ATTACH_NOSE">Nariz</string> - <string name="ATTACH_RUARM">Brazo der.</string> - <string name="ATTACH_RLARM">Antebrazo derecho</string> - <string name="ATTACH_LUARM">Brazo izq.</string> - <string name="ATTACH_LLARM">Antebrazo izquierdo</string> - <string name="ATTACH_RHIP">Cadera der.</string> - <string name="ATTACH_RULEG">Muslo der.</string> - <string name="ATTACH_RLLEG">Pantorrilla der.</string> - <string name="ATTACH_LHIP">Cadera izq.</string> - <string name="ATTACH_LULEG">Muslo izq.</string> - <string name="ATTACH_LLLEG">Pantorrilla izq.</string> - <string name="ATTACH_BELLY">Abdomen</string> - <string name="ATTACH_LEFT_PEC">Pectoral izquierdo</string> - <string name="ATTACH_RIGHT_PEC">Pectoral derecho</string> - <string name="ATTACH_HUD_CENTER_2">HUD: Centro 2</string> - <string name="ATTACH_HUD_TOP_RIGHT">HUD: arriba der.</string> - <string name="ATTACH_HUD_TOP_CENTER">HUD: arriba centro</string> - <string name="ATTACH_HUD_TOP_LEFT">HUD: arriba izq.</string> - <string name="ATTACH_HUD_CENTER_1">HUD: Centro 1</string> - <string name="ATTACH_HUD_BOTTOM_LEFT">HUD: abajo izq.</string> - <string name="ATTACH_HUD_BOTTOM">HUD: abajo</string> - <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD: abajo der.</string> - <string name="ATTACH_NECK">Cuello</string> - <string name="ATTACH_AVATAR_CENTER">Centro del avatar</string> - <string name="ATTACH_LHAND_RING1">Dedo anular izquierdo</string> - <string name="ATTACH_RHAND_RING1">Dedo anular derecho</string> - <string name="ATTACH_TAIL_BASE">Base de la cola</string> - <string name="ATTACH_TAIL_TIP">Extremo de la cola</string> - <string name="ATTACH_LWING">Ala izquierda</string> - <string name="ATTACH_RWING">Ala derecha</string> - <string name="ATTACH_FACE_JAW">Mandíbula</string> - <string name="ATTACH_FACE_LEAR">Oreja izquierda alternativa</string> - <string name="ATTACH_FACE_REAR">Oreja derecha alternativa</string> - <string name="ATTACH_FACE_LEYE">Ojo izquierdo alternativo</string> - <string name="ATTACH_FACE_REYE">Ojo derecho alternativo</string> - <string name="ATTACH_FACE_TONGUE">Lengua</string> - <string name="ATTACH_GROIN">Ingle</string> - <string name="ATTACH_HIND_LFOOT">Pata trasera izquierda</string> - <string name="ATTACH_HIND_RFOOT">Pata trasera derecha</string> - <string name="CursorPos">Línea [LINE], Columna [COLUMN]</string> - <string name="PanelDirCountFound">[COUNT] resultados</string> - <string name="PanelContentsTooltip">Contenido del objeto</string> - <string name="PanelContentsNewScript">Script nuevo</string> - <string name="DoNotDisturbModeResponseDefault">Este residente tiene activado 'No molestar' y verá tu mensaje más tarde.</string> - <string name="MuteByName">(Por el nombre)</string> - <string name="MuteAgent">(Residente)</string> - <string name="MuteObject">(Objeto)</string> - <string name="MuteGroup">(Grupo)</string> - <string name="MuteExternal">(Externo)</string> - <string name="RegionNoCovenant">No se ha aportado un contrato para este estado.</string> - <string name="RegionNoCovenantOtherOwner">No se ha aportado un contrato para este estado. El terreno de este estado lo vende el propietario del estado, no Linden Lab. Por favor, contacta con ese propietario para informarte sobre la venta.</string> + <string name="Balance"> + Saldo + </string> + <string name="Credits"> + Créditos + </string> + <string name="Debits"> + Débitos + </string> + <string name="Total"> + Total + </string> + <string name="NoGroupDataFound"> + No se encontraron datos del grupo + </string> + <string name="IMParentEstate"> + parent estate + </string> + <string name="IMMainland"> + continente + </string> + <string name="IMTeen"> + teen + </string> + <string name="Anyone"> + cualquiera + </string> + <string name="RegionInfoError"> + error + </string> + <string name="RegionInfoAllEstatesOwnedBy"> + todos los estados propiedad de [OWNER] + </string> + <string name="RegionInfoAllEstatesYouOwn"> + todos los estados que posees + </string> + <string name="RegionInfoAllEstatesYouManage"> + todos los estados que administras para [OWNER] + </string> + <string name="RegionInfoAllowedResidents"> + Siempre permitido: ([ALLOWEDAGENTS], de un máx. de [MAXACCESS]) + </string> + <string name="RegionInfoAllowedGroups"> + Grupos siempre permitidos: ([ALLOWEDGROUPS], de un máx. de [MAXACCESS]) + </string> + <string name="RegionInfoBannedResidents"> + Siempre prohibido: ([BANNEDAGENTS], de un máx. de [MAXBANNED]) + </string> + <string name="RegionInfoListTypeAllowedAgents"> + Siempre permitido + </string> + <string name="RegionInfoListTypeBannedAgents"> + Siempre prohibido + </string> + <string name="RegionInfoAllEstates"> + todos los estados + </string> + <string name="RegionInfoManagedEstates"> + estados administrados + </string> + <string name="RegionInfoThisEstate"> + este estado + </string> + <string name="AndNMore"> + y [EXTRA_COUNT] más + </string> + <string name="ScriptLimitsParcelScriptMemory"> + Memoria de los scripts de la parcela + </string> + <string name="ScriptLimitsParcelsOwned"> + Parcelas listadas: [PARCELS] + </string> + <string name="ScriptLimitsMemoryUsed"> + Memoria usada: [COUNT] kb de un máx de [MAX] kb; [AVAILABLE] kb disponibles + </string> + <string name="ScriptLimitsMemoryUsedSimple"> + Memoria usada: [COUNT] kb + </string> + <string name="ScriptLimitsParcelScriptURLs"> + URLs de los scripts de la parcela + </string> + <string name="ScriptLimitsURLsUsed"> + URLs usadas: [COUNT] de un máx. de [MAX]; [AVAILABLE] disponibles + </string> + <string name="ScriptLimitsURLsUsedSimple"> + URLs usadas: [COUNT] + </string> + <string name="ScriptLimitsRequestError"> + Error al obtener la información + </string> + <string name="ScriptLimitsRequestNoParcelSelected"> + No hay una parcela seleccionada + </string> + <string name="ScriptLimitsRequestWrongRegion"> + Error: la información del script sólo está disponible en tu región actual + </string> + <string name="ScriptLimitsRequestWaiting"> + Obteniendo la información... + </string> + <string name="ScriptLimitsRequestDontOwnParcel"> + No tienes permiso para examinar esta parcela + </string> + <string name="SITTING_ON"> + Sentado en + </string> + <string name="ATTACH_CHEST"> + Tórax + </string> + <string name="ATTACH_HEAD"> + Cráneo + </string> + <string name="ATTACH_LSHOULDER"> + Hombro izquierdo + </string> + <string name="ATTACH_RSHOULDER"> + Hombro derecho + </string> + <string name="ATTACH_LHAND"> + Mano izq. + </string> + <string name="ATTACH_RHAND"> + Mano der. + </string> + <string name="ATTACH_LFOOT"> + Pie izq. + </string> + <string name="ATTACH_RFOOT"> + Pie der. + </string> + <string name="ATTACH_BACK"> + Columna + </string> + <string name="ATTACH_PELVIS"> + Pelvis + </string> + <string name="ATTACH_MOUTH"> + Boca + </string> + <string name="ATTACH_CHIN"> + Barbilla + </string> + <string name="ATTACH_LEAR"> + Oreja izq. + </string> + <string name="ATTACH_REAR"> + Oreja der. + </string> + <string name="ATTACH_LEYE"> + Ojo izq. + </string> + <string name="ATTACH_REYE"> + Ojo der. + </string> + <string name="ATTACH_NOSE"> + Nariz + </string> + <string name="ATTACH_RUARM"> + Brazo der. + </string> + <string name="ATTACH_RLARM"> + Antebrazo derecho + </string> + <string name="ATTACH_LUARM"> + Brazo izq. + </string> + <string name="ATTACH_LLARM"> + Antebrazo izquierdo + </string> + <string name="ATTACH_RHIP"> + Cadera der. + </string> + <string name="ATTACH_RULEG"> + Muslo der. + </string> + <string name="ATTACH_RLLEG"> + Pantorrilla der. + </string> + <string name="ATTACH_LHIP"> + Cadera izq. + </string> + <string name="ATTACH_LULEG"> + Muslo izq. + </string> + <string name="ATTACH_LLLEG"> + Pantorrilla izq. + </string> + <string name="ATTACH_BELLY"> + Abdomen + </string> + <string name="ATTACH_LEFT_PEC"> + Pectoral izquierdo + </string> + <string name="ATTACH_RIGHT_PEC"> + Pectoral derecho + </string> + <string name="ATTACH_HUD_CENTER_2"> + HUD: Centro 2 + </string> + <string name="ATTACH_HUD_TOP_RIGHT"> + HUD: arriba der. + </string> + <string name="ATTACH_HUD_TOP_CENTER"> + HUD: arriba centro + </string> + <string name="ATTACH_HUD_TOP_LEFT"> + HUD: arriba izq. + </string> + <string name="ATTACH_HUD_CENTER_1"> + HUD: Centro 1 + </string> + <string name="ATTACH_HUD_BOTTOM_LEFT"> + HUD: abajo izq. + </string> + <string name="ATTACH_HUD_BOTTOM"> + HUD: abajo + </string> + <string name="ATTACH_HUD_BOTTOM_RIGHT"> + HUD: abajo der. + </string> + <string name="ATTACH_NECK"> + Cuello + </string> + <string name="ATTACH_AVATAR_CENTER"> + Centro del avatar + </string> + <string name="ATTACH_LHAND_RING1"> + Dedo anular izquierdo + </string> + <string name="ATTACH_RHAND_RING1"> + Dedo anular derecho + </string> + <string name="ATTACH_TAIL_BASE"> + Base de la cola + </string> + <string name="ATTACH_TAIL_TIP"> + Extremo de la cola + </string> + <string name="ATTACH_LWING"> + Ala izquierda + </string> + <string name="ATTACH_RWING"> + Ala derecha + </string> + <string name="ATTACH_FACE_JAW"> + Mandíbula + </string> + <string name="ATTACH_FACE_LEAR"> + Oreja izquierda alternativa + </string> + <string name="ATTACH_FACE_REAR"> + Oreja derecha alternativa + </string> + <string name="ATTACH_FACE_LEYE"> + Ojo izquierdo alternativo + </string> + <string name="ATTACH_FACE_REYE"> + Ojo derecho alternativo + </string> + <string name="ATTACH_FACE_TONGUE"> + Lengua + </string> + <string name="ATTACH_GROIN"> + Ingle + </string> + <string name="ATTACH_HIND_LFOOT"> + Pata trasera izquierda + </string> + <string name="ATTACH_HIND_RFOOT"> + Pata trasera derecha + </string> + <string name="CursorPos"> + Línea [LINE], Columna [COLUMN] + </string> + <string name="PanelDirCountFound"> + [COUNT] resultados + </string> + <string name="PanelContentsTooltip"> + Contenido del objeto + </string> + <string name="PanelContentsNewScript"> + Script nuevo + </string> + <string name="DoNotDisturbModeResponseDefault"> + Este residente tiene activado 'No molestar' y verá tu mensaje más tarde. + </string> + <string name="MuteByName"> + (Por el nombre) + </string> + <string name="MuteAgent"> + (Residente) + </string> + <string name="MuteObject"> + (Objeto) + </string> + <string name="MuteGroup"> + (Grupo) + </string> + <string name="MuteExternal"> + (Externo) + </string> + <string name="RegionNoCovenant"> + No se ha aportado un contrato para este estado. + </string> + <string name="RegionNoCovenantOtherOwner"> + No se ha aportado un contrato para este estado. El terreno de este estado lo vende el propietario del estado, no Linden Lab. Por favor, contacta con ese propietario para informarte sobre la venta. + </string> <string name="covenant_last_modified" value="Última modificación: "/> <string name="none_text" value="(no hay)"/> <string name="never_text" value=" (nunca)"/> - <string name="GroupOwned">Propiedad del grupo</string> - <string name="Public">Público</string> - <string name="LocalSettings">Configuración local</string> - <string name="RegionSettings">Configuración de la región</string> - <string name="NoEnvironmentSettings">Esta región no es compatible con las opciones de entorno.</string> - <string name="EnvironmentSun">Sol</string> - <string name="EnvironmentMoon">Luna</string> - <string name="EnvironmentBloom">Florecimiento</string> - <string name="EnvironmentCloudNoise">Ruido de nubes</string> - <string name="EnvironmentNormalMap">Vista Normal</string> - <string name="EnvironmentTransparent">Transparente</string> - <string name="ClassifiedClicksTxt">Clics: [TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil</string> - <string name="ClassifiedUpdateAfterPublish">(se actualizará tras la publicación)</string> - <string name="NoPicksClassifiedsText">No has creado destacados ni clasificados. Pulsa el botón Más para crear uno.</string> - <string name="NoPicksText">No has creado destacados. Haz clic en el botón Más para crear uno.</string> - <string name="NoClassifiedsText">No has creado clasificados. Haz clic en el botón Nuevo para crear un anuncio clasificado.</string> - <string name="NoAvatarPicksClassifiedsText">El usuario no tiene clasificados ni destacados</string> - <string name="NoAvatarPicksText">El usuario no tiene destacados</string> - <string name="NoAvatarClassifiedsText">El usuario no tiene clasificados</string> - <string name="PicksClassifiedsLoadingText">Cargando...</string> - <string name="MultiPreviewTitle">Vista previa</string> - <string name="MultiPropertiesTitle">Propiedades</string> - <string name="InvOfferAnObjectNamed">Un objeto de nombre</string> - <string name="InvOfferOwnedByGroup">propiedad del grupo</string> - <string name="InvOfferOwnedByUnknownGroup">propiedad de un grupo desconocido</string> - <string name="InvOfferOwnedBy">propiedad de</string> - <string name="InvOfferOwnedByUnknownUser">propiedad de un usuario desconocido</string> - <string name="InvOfferGaveYou">te ha dado</string> - <string name="InvOfferDecline">Rechazas [DESC] de <nolink>[NAME]</nolink>.</string> - <string name="GroupMoneyTotal">Total</string> - <string name="GroupMoneyBought">comprado</string> - <string name="GroupMoneyPaidYou">pagado a ti</string> - <string name="GroupMoneyPaidInto">pagado en</string> - <string name="GroupMoneyBoughtPassTo">pase comprado a</string> - <string name="GroupMoneyPaidFeeForEvent">cuotas pagadas para el evento</string> - <string name="GroupMoneyPaidPrizeForEvent">precio pagado por el evento</string> - <string name="GroupMoneyBalance">Saldo</string> - <string name="GroupMoneyCredits">Créditos</string> - <string name="GroupMoneyDebits">Débitos</string> - <string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string> - <string name="AcquiredItems">Artículos adquiridos</string> - <string name="Cancel">Cancelar</string> - <string name="UploadingCosts">Subir [NAME] cuesta [AMOUNT] L$</string> - <string name="BuyingCosts">Comprar esto cuesta [AMOUNT] L$</string> - <string name="UnknownFileExtension">Extensión de archivo desconocida [.%s] -Se esperaba .wav, .tga, .bmp, .jpg, .jpeg, o .bvh</string> - <string name="MuteObject2">Ignorar</string> - <string name="AddLandmarkNavBarMenu">Guardarme este hito...</string> - <string name="EditLandmarkNavBarMenu">Editar este hito...</string> - <string name="accel-mac-control">⌃</string> - <string name="accel-mac-command">⌘</string> - <string name="accel-mac-option">⌥</string> - <string name="accel-mac-shift">⇧</string> - <string name="accel-win-control">Ctrl+</string> - <string name="accel-win-alt">Alt+</string> - <string name="accel-win-shift">Mayús+</string> - <string name="FileSaved">Archivo guardado</string> - <string name="Receiving">Recibiendo</string> - <string name="AM">AM</string> - <string name="PM">PM</string> - <string name="PST">PST</string> - <string name="PDT">PDT</string> - <string name="Direction_Forward">Adelante</string> - <string name="Direction_Left">Izquierda</string> - <string name="Direction_Right">Derecha</string> - <string name="Direction_Back">Atrás</string> - <string name="Direction_North">Norte</string> - <string name="Direction_South">Sur</string> - <string name="Direction_West">Oeste</string> - <string name="Direction_East">Este</string> - <string name="Direction_Up">Arriba</string> - <string name="Direction_Down">Abajo</string> - <string name="Any Category">Cualquier categoría</string> - <string name="Shopping">Compras</string> - <string name="Land Rental">Terreno en alquiler</string> - <string name="Property Rental">Propiedad en alquiler</string> - <string name="Special Attraction">Atracción especial</string> - <string name="New Products">Nuevos productos</string> - <string name="Employment">Empleo</string> - <string name="Wanted">Se busca</string> - <string name="Service">Servicios</string> - <string name="Personal">Personal</string> - <string name="None">Ninguno</string> - <string name="Linden Location">Localización Linden</string> - <string name="Adult">Adulto</string> - <string name="Arts&Culture">Arte y Cultura</string> - <string name="Business">Negocios</string> - <string name="Educational">Educativo</string> - <string name="Gaming">Juegos de azar</string> - <string name="Hangout">Entretenimiento</string> - <string name="Newcomer Friendly">Para recién llegados</string> - <string name="Parks&Nature">Parques y Naturaleza</string> - <string name="Residential">Residencial</string> - <string name="Stage">Artes escénicas</string> - <string name="Other">Otra</string> - <string name="Rental">Terreno en alquiler</string> - <string name="Any">Cualquiera</string> - <string name="You">Tú</string> - <string name="Multiple Media">Múltiples medias</string> - <string name="Play Media">Play/Pausa los media</string> - <string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string> - <string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=es</string> - <string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string> - <string name="MBCmdLineError">Ha habido un error analizando la línea de comando. + <string name="GroupOwned"> + Propiedad del grupo + </string> + <string name="Public"> + Público + </string> + <string name="LocalSettings"> + Configuración local + </string> + <string name="RegionSettings"> + Configuración de la región + </string> + <string name="NoEnvironmentSettings"> + Esta región no es compatible con las opciones de entorno. + </string> + <string name="EnvironmentSun"> + Sol + </string> + <string name="EnvironmentMoon"> + Luna + </string> + <string name="EnvironmentBloom"> + Florecimiento + </string> + <string name="EnvironmentCloudNoise"> + Ruido de nubes + </string> + <string name="EnvironmentNormalMap"> + Vista Normal + </string> + <string name="EnvironmentTransparent"> + Transparente + </string> + <string name="ClassifiedClicksTxt"> + Clics: [TELEPORT] teleportes, [MAP] mapa, [PROFILE] perfil + </string> + <string name="ClassifiedUpdateAfterPublish"> + (se actualizará tras la publicación) + </string> + <string name="NoPicksClassifiedsText"> + No has creado destacados ni clasificados. Pulsa el botón Más para crear uno. + </string> + <string name="NoPicksText"> + No has creado destacados. Haz clic en el botón Más para crear uno. + </string> + <string name="NoClassifiedsText"> + No has creado clasificados. Haz clic en el botón Nuevo para crear un anuncio clasificado. + </string> + <string name="NoAvatarPicksClassifiedsText"> + El usuario no tiene clasificados ni destacados + </string> + <string name="NoAvatarPicksText"> + El usuario no tiene destacados + </string> + <string name="NoAvatarClassifiedsText"> + El usuario no tiene clasificados + </string> + <string name="PicksClassifiedsLoadingText"> + Cargando... + </string> + <string name="MultiPreviewTitle"> + Vista previa + </string> + <string name="MultiPropertiesTitle"> + Propiedades + </string> + <string name="InvOfferAnObjectNamed"> + Un objeto de nombre + </string> + <string name="InvOfferOwnedByGroup"> + propiedad del grupo + </string> + <string name="InvOfferOwnedByUnknownGroup"> + propiedad de un grupo desconocido + </string> + <string name="InvOfferOwnedBy"> + propiedad de + </string> + <string name="InvOfferOwnedByUnknownUser"> + propiedad de un usuario desconocido + </string> + <string name="InvOfferGaveYou"> + te ha dado + </string> + <string name="InvOfferDecline"> + Rechazas [DESC] de <nolink>[NAME]</nolink>. + </string> + <string name="GroupMoneyTotal"> + Total + </string> + <string name="GroupMoneyBought"> + comprado + </string> + <string name="GroupMoneyPaidYou"> + pagado a ti + </string> + <string name="GroupMoneyPaidInto"> + pagado en + </string> + <string name="GroupMoneyBoughtPassTo"> + pase comprado a + </string> + <string name="GroupMoneyPaidFeeForEvent"> + cuotas pagadas para el evento + </string> + <string name="GroupMoneyPaidPrizeForEvent"> + precio pagado por el evento + </string> + <string name="GroupMoneyBalance"> + Saldo + </string> + <string name="GroupMoneyCredits"> + Créditos + </string> + <string name="GroupMoneyDebits"> + Débitos + </string> + <string name="GroupMoneyDate"> + [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc] + </string> + <string name="AcquiredItems"> + Artículos adquiridos + </string> + <string name="Cancel"> + Cancelar + </string> + <string name="UploadingCosts"> + Subir [NAME] cuesta [AMOUNT] L$ + </string> + <string name="BuyingCosts"> + Comprar esto cuesta [AMOUNT] L$ + </string> + <string name="UnknownFileExtension"> + Extensión de archivo desconocida [.%s] +Se esperaba .wav, .tga, .bmp, .jpg, .jpeg, o .bvh + </string> + <string name="MuteObject2"> + Ignorar + </string> + <string name="AddLandmarkNavBarMenu"> + Guardarme este hito... + </string> + <string name="EditLandmarkNavBarMenu"> + Editar este hito... + </string> + <string name="accel-mac-control"> + ⌃ + </string> + <string name="accel-mac-command"> + ⌘ + </string> + <string name="accel-mac-option"> + ⌥ + </string> + <string name="accel-mac-shift"> + ⇧ + </string> + <string name="accel-win-control"> + Ctrl+ + </string> + <string name="accel-win-alt"> + Alt+ + </string> + <string name="accel-win-shift"> + Mayús+ + </string> + <string name="FileSaved"> + Archivo guardado + </string> + <string name="Receiving"> + Recibiendo + </string> + <string name="AM"> + AM + </string> + <string name="PM"> + PM + </string> + <string name="PST"> + PST + </string> + <string name="PDT"> + PDT + </string> + <string name="Direction_Forward"> + Adelante + </string> + <string name="Direction_Left"> + Izquierda + </string> + <string name="Direction_Right"> + Derecha + </string> + <string name="Direction_Back"> + Atrás + </string> + <string name="Direction_North"> + Norte + </string> + <string name="Direction_South"> + Sur + </string> + <string name="Direction_West"> + Oeste + </string> + <string name="Direction_East"> + Este + </string> + <string name="Direction_Up"> + Arriba + </string> + <string name="Direction_Down"> + Abajo + </string> + <string name="Any Category"> + Cualquier categoría + </string> + <string name="Shopping"> + Compras + </string> + <string name="Land Rental"> + Terreno en alquiler + </string> + <string name="Property Rental"> + Propiedad en alquiler + </string> + <string name="Special Attraction"> + Atracción especial + </string> + <string name="New Products"> + Nuevos productos + </string> + <string name="Employment"> + Empleo + </string> + <string name="Wanted"> + Se busca + </string> + <string name="Service"> + Servicios + </string> + <string name="Personal"> + Personal + </string> + <string name="None"> + Ninguno + </string> + <string name="Linden Location"> + Localización Linden + </string> + <string name="Adult"> + Adulto + </string> + <string name="Arts&Culture"> + Arte y Cultura + </string> + <string name="Business"> + Negocios + </string> + <string name="Educational"> + Educativo + </string> + <string name="Gaming"> + Juegos de azar + </string> + <string name="Hangout"> + Entretenimiento + </string> + <string name="Newcomer Friendly"> + Para recién llegados + </string> + <string name="Parks&Nature"> + Parques y Naturaleza + </string> + <string name="Residential"> + Residencial + </string> + <string name="Stage"> + Artes escénicas + </string> + <string name="Other"> + Otra + </string> + <string name="Rental"> + Terreno en alquiler + </string> + <string name="Any"> + Cualquiera + </string> + <string name="You"> + Tú + </string> + <string name="Multiple Media"> + Múltiples medias + </string> + <string name="Play Media"> + Play/Pausa los media + </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=es + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> + <string name="MBCmdLineError"> + Ha habido un error analizando la línea de comando. Por favor, consulta: http://wiki.secondlife.com/wiki/Client_parameters -Error:</string> - <string name="MBCmdLineUsg">[APP_NAME] Uso de línea de comando:</string> - <string name="MBUnableToAccessFile">[APP_NAME] no puede acceder a un archivo que necesita. +Error: + </string> + <string name="MBCmdLineUsg"> + [APP_NAME] Uso de línea de comando: + </string> + <string name="MBUnableToAccessFile"> + [APP_NAME] no puede acceder a un archivo que necesita. Puede ser porque estés ejecutando varias copias, o porque tu sistema crea -equivocadamente- que el archivo está abierto. Si este mensaje persiste, reinicia tu ordenador y vuelve a intentarlo. -Si aun así sigue apareciendo el mensaje, debes desinstalar completamente [APP_NAME] y reinstalarlo.</string> - <string name="MBFatalError">Error fatal</string> - <string name="MBRequiresAltiVec">[APP_NAME] requiere un procesador con AltiVec (G4 o posterior).</string> - <string name="MBAlreadyRunning">[APP_NAME] ya se está ejecutando. +Si aun así sigue apareciendo el mensaje, debes desinstalar completamente [APP_NAME] y reinstalarlo. + </string> + <string name="MBFatalError"> + Error fatal + </string> + <string name="MBRequiresAltiVec"> + [APP_NAME] requiere un procesador con AltiVec (G4 o posterior). + </string> + <string name="MBAlreadyRunning"> + [APP_NAME] ya se está ejecutando. Revisa tu barra de tareas para encontrar una copia minimizada del programa. -Si este mensaje persiste, reinicia tu ordenador.</string> - <string name="MBFrozenCrashed">En su anterior ejecución, [APP_NAME] se congeló o se cayó. -¿Quieres enviar un informe de caída?</string> - <string name="MBAlert">Alerta</string> - <string name="MBNoDirectX">[APP_NAME] no encuentra DirectX 9.0b o superior. +Si este mensaje persiste, reinicia tu ordenador. + </string> + <string name="MBFrozenCrashed"> + En su anterior ejecución, [APP_NAME] se congeló o se cayó. +¿Quieres enviar un informe de caída? + </string> + <string name="MBAlert"> + Alerta + </string> + <string name="MBNoDirectX"> + [APP_NAME] no encuentra DirectX 9.0b o superior. [APP_NAME] usa DirectX para detectar el hardware o los drivers no actualizados que pueden provocar problemas de estabilidad, ejecución pobre y caídas. Aunque puedes ejecutar [APP_NAME] sin él, recomendamos encarecidamente hacerlo con DirectX 9.0b. -¿Quieres continuar?</string> - <string name="MBWarning">¡Atención!</string> - <string name="MBNoAutoUpdate">Las actualizaciones automáticas no están todavía implementadas para Linux. -Por favor, descarga la última versión desde www.secondlife.com.</string> - <string name="MBRegClassFailed">Fallo en RegisterClass</string> - <string name="MBError">Error</string> - <string name="MBFullScreenErr">No puede ejecutarse a pantalla completa de [WIDTH] x [HEIGHT]. -Ejecutándose en una ventana.</string> - <string name="MBDestroyWinFailed">Error Shutdown destruyendo la ventana (DestroyWindow() failed)</string> - <string name="MBShutdownErr">Error Shutdown</string> - <string name="MBDevContextErr">No se puede construir el 'GL device context'</string> - <string name="MBPixelFmtErr">No se puede encontrar un formato adecuado de píxel</string> - <string name="MBPixelFmtDescErr">No se puede conseguir la descripción del formato de píxel</string> - <string name="MBTrueColorWindow">Para ejecutarse, [APP_NAME] necesita True Color (32-bit). -Por favor, en las configuraciones de tu ordenador ajusta el modo de color a 32-bit.</string> - <string name="MBAlpha">[APP_NAME] no puede ejecutarse porque no puede obtener un canal alpha de 8 bit. Generalmente, se debe a alguna cuestión de los drivers de la tarjeta de vídeo. +¿Quieres continuar? + </string> + <string name="MBWarning"> + ¡Atención! + </string> + <string name="MBNoAutoUpdate"> + Las actualizaciones automáticas no están todavía implementadas para Linux. +Por favor, descarga la última versión desde www.secondlife.com. + </string> + <string name="MBRegClassFailed"> + Fallo en RegisterClass + </string> + <string name="MBError"> + Error + </string> + <string name="MBFullScreenErr"> + No puede ejecutarse a pantalla completa de [WIDTH] x [HEIGHT]. +Ejecutándose en una ventana. + </string> + <string name="MBDestroyWinFailed"> + Error Shutdown destruyendo la ventana (DestroyWindow() failed) + </string> + <string name="MBShutdownErr"> + Error Shutdown + </string> + <string name="MBDevContextErr"> + No se puede construir el 'GL device context' + </string> + <string name="MBPixelFmtErr"> + No se puede encontrar un formato adecuado de píxel + </string> + <string name="MBPixelFmtDescErr"> + No se puede conseguir la descripción del formato de píxel + </string> + <string name="MBTrueColorWindow"> + Para ejecutarse, [APP_NAME] necesita True Color (32-bit). +Por favor, en las configuraciones de tu ordenador ajusta el modo de color a 32-bit. + </string> + <string name="MBAlpha"> + [APP_NAME] no puede ejecutarse porque no puede obtener un canal alpha de 8 bit. Generalmente, se debe a alguna cuestión de los drivers de la tarjeta de vídeo. Por favor, comprueba que tienes instalados los últimos drivers para tu tarjeta de vídeo. Comprueba también que tu monitor esta configurado para True Color (32-bit) en Panel de Control > Apariencia y temas > Pantalla. -Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].</string> - <string name="MBPixelFmtSetErr">No se puede configurar el formato de píxel</string> - <string name="MBGLContextErr">No se puede crear el 'GL rendering context'</string> - <string name="MBGLContextActErr">No se puede activar el 'GL rendering context'</string> - <string name="MBVideoDrvErr">[APP_NAME] no puede ejecutarse porque los drivers de tu tarjeta de vídeo o no están bien instalados, o no están actualizados, o son para hardware no admitido. Por favor, comprueba que tienes los drivers más actuales para tu tarjeta de vídeo, y, aunque los tengas, intenta reinstalarlos. +Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. + </string> + <string name="MBPixelFmtSetErr"> + No se puede configurar el formato de píxel + </string> + <string name="MBGLContextErr"> + No se puede crear el 'GL rendering context' + </string> + <string name="MBGLContextActErr"> + No se puede activar el 'GL rendering context' + </string> + <string name="MBVideoDrvErr"> + [APP_NAME] no puede ejecutarse porque los drivers de tu tarjeta de vídeo o no están bien instalados, o no están actualizados, o son para hardware no admitido. Por favor, comprueba que tienes los drivers más actuales para tu tarjeta de vídeo, y, aunque los tengas, intenta reinstalarlos. -Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].</string> - <string name="5 O'Clock Shadow">Barba del día</string> - <string name="All White">Blanco del todo</string> - <string name="Anime Eyes">Ojos de cómic</string> - <string name="Arced">Arqueadas</string> - <string name="Arm Length">Brazos: longitud</string> - <string name="Attached">Cortos</string> - <string name="Attached Earlobes">Lóbulos</string> - <string name="Back Fringe">Nuca: largo</string> - <string name="Baggy">Marcadas</string> - <string name="Bangs">Bangs</string> - <string name="Beady Eyes">Ojos pequeños</string> - <string name="Belly Size">Barriga: tamaño</string> - <string name="Big">Grande</string> - <string name="Big Butt">Culo grande</string> - <string name="Big Hair Back">Pelo: moño</string> - <string name="Big Hair Front">Pelo: tupé</string> - <string name="Big Hair Top">Pelo: melena alta</string> - <string name="Big Head">Cabeza grande</string> - <string name="Big Pectorals">Grandes pectorales</string> - <string name="Big Spikes">Crestas grandes</string> - <string name="Black">Negro</string> - <string name="Blonde">Rubio</string> - <string name="Blonde Hair">Pelo rubio</string> - <string name="Blush">Colorete</string> - <string name="Blush Color">Color del colorete</string> - <string name="Blush Opacity">Opacidad del colorete</string> - <string name="Body Definition">Definición del cuerpo</string> - <string name="Body Fat">Cuerpo: gordura</string> - <string name="Body Freckles">Pecas del cuerpo</string> - <string name="Body Thick">Cuerpo grueso</string> - <string name="Body Thickness">Cuerpo: grosor</string> - <string name="Body Thin">Cuerpo delgado</string> - <string name="Bow Legged">Abiertas</string> - <string name="Breast Buoyancy">Busto: firmeza</string> - <string name="Breast Cleavage">Busto: canalillo</string> - <string name="Breast Size">Busto: tamaño</string> - <string name="Bridge Width">Puente: ancho</string> - <string name="Broad">Aumentar</string> - <string name="Brow Size">Arco ciliar</string> - <string name="Bug Eyes">Bug Eyes</string> - <string name="Bugged Eyes">Ojos saltones</string> - <string name="Bulbous">Bulbosa</string> - <string name="Bulbous Nose">Nariz de porra</string> - <string name="Breast Physics Mass">Masa del busto</string> - <string name="Breast Physics Smoothing">Suavizado del busto</string> - <string name="Breast Physics Gravity">Gravedad del busto</string> - <string name="Breast Physics Drag">Aerodinámica del busto</string> - <string name="Breast Physics InOut Max Effect">Efecto máx.</string> - <string name="Breast Physics InOut Spring">Elasticidad</string> - <string name="Breast Physics InOut Gain">Ganancia</string> - <string name="Breast Physics InOut Damping">Amortiguación</string> - <string name="Breast Physics UpDown Max Effect">Efecto máx.</string> - <string name="Breast Physics UpDown Spring">Elasticidad</string> - <string name="Breast Physics UpDown Gain">Ganancia</string> - <string name="Breast Physics UpDown Damping">Amortiguación</string> - <string name="Breast Physics LeftRight Max Effect">Efecto máx.</string> - <string name="Breast Physics LeftRight Spring">Elasticidad</string> - <string name="Breast Physics LeftRight Gain">Ganancia</string> - <string name="Breast Physics LeftRight Damping">Amortiguación</string> - <string name="Belly Physics Mass">Masa de la barriga</string> - <string name="Belly Physics Smoothing">Suavizado de la barriga</string> - <string name="Belly Physics Gravity">Gravedad de la barriga</string> - <string name="Belly Physics Drag">Aerodinámica de la barriga</string> - <string name="Belly Physics UpDown Max Effect">Efecto máx.</string> - <string name="Belly Physics UpDown Spring">Elasticidad</string> - <string name="Belly Physics UpDown Gain">Ganancia</string> - <string name="Belly Physics UpDown Damping">Amortiguación</string> - <string name="Butt Physics Mass">Masa del culo</string> - <string name="Butt Physics Smoothing">Suavizado del culo</string> - <string name="Butt Physics Gravity">Gravedad del culo</string> - <string name="Butt Physics Drag">Aerodinámica del culo</string> - <string name="Butt Physics UpDown Max Effect">Efecto máx.</string> - <string name="Butt Physics UpDown Spring">Elasticidad</string> - <string name="Butt Physics UpDown Gain">Ganancia</string> - <string name="Butt Physics UpDown Damping">Amortiguación</string> - <string name="Butt Physics LeftRight Max Effect">Efecto máx.</string> - <string name="Butt Physics LeftRight Spring">Elasticidad</string> - <string name="Butt Physics LeftRight Gain">Ganancia</string> - <string name="Butt Physics LeftRight Damping">Amortiguación</string> - <string name="Bushy Eyebrows">Cejijuntas</string> - <string name="Bushy Hair">Pelo tupido</string> - <string name="Butt Size">Culo: tamaño</string> - <string name="Butt Gravity">Gravedad del culo</string> - <string name="bustle skirt">Polisón</string> - <string name="no bustle">Sin polisón</string> - <string name="more bustle">Con polisón</string> - <string name="Chaplin">Cortito</string> - <string name="Cheek Bones">Pómulos</string> - <string name="Chest Size">Tórax: tamaño</string> - <string name="Chin Angle">Barbilla: ángulo</string> - <string name="Chin Cleft">Barbilla: contorno</string> - <string name="Chin Curtains">Barba en collar</string> - <string name="Chin Depth">Barbilla: largo</string> - <string name="Chin Heavy">Hacia la barbilla</string> - <string name="Chin In">Barbilla retraída</string> - <string name="Chin Out">Barbilla prominente</string> - <string name="Chin-Neck">Papada</string> - <string name="Clear">Transparente</string> - <string name="Cleft">Remarcar</string> - <string name="Close Set Eyes">Ojos juntos</string> - <string name="Closed">Cerrar</string> - <string name="Closed Back">Trasera cerrada</string> - <string name="Closed Front">Frontal cerrado</string> - <string name="Closed Left">Cerrada</string> - <string name="Closed Right">Cerrada</string> - <string name="Coin Purse">Poco abultada</string> - <string name="Collar Back">Espalda</string> - <string name="Collar Front">Escote</string> - <string name="Corner Down">Hacia abajo</string> - <string name="Corner Up">Hacia arriba</string> - <string name="Creased">Caídos</string> - <string name="Crooked Nose">Nariz torcida</string> - <string name="Cuff Flare">Acampanado</string> - <string name="Dark">Oscuridad</string> - <string name="Dark Green">Verde oscuro</string> - <string name="Darker">Más oscuros</string> - <string name="Deep">Remarcar</string> - <string name="Default Heels">Tacones por defecto</string> - <string name="Dense">Densas</string> - <string name="Double Chin">Mucha papada</string> - <string name="Downturned">Poco</string> - <string name="Duffle Bag">Muy abultada</string> - <string name="Ear Angle">Orejas: ángulo</string> - <string name="Ear Size">Orejas: tamaño</string> - <string name="Ear Tips">Orejas: forma</string> - <string name="Egg Head">Cabeza: ahuevada</string> - <string name="Eye Bags">Ojos: bolsas</string> - <string name="Eye Color">Ojos: color</string> - <string name="Eye Depth">Ojos: profundidad</string> - <string name="Eye Lightness">Ojos: brillo</string> - <string name="Eye Opening">Ojos: apertura</string> - <string name="Eye Pop">Ojos: simetría</string> - <string name="Eye Size">Ojos: tamaño</string> - <string name="Eye Spacing">Ojos: separación</string> - <string name="Eyebrow Arc">Cejas: arco</string> - <string name="Eyebrow Density">Cejas: densidad</string> - <string name="Eyebrow Height">Cejas: altura</string> - <string name="Eyebrow Points">Cejas: en V</string> - <string name="Eyebrow Size">Cejas: tamaño</string> - <string name="Eyelash Length">Pestañas: longitud</string> - <string name="Eyeliner">Contorno de ojos</string> - <string name="Eyeliner Color">Contorno de ojos: color</string> - <string name="Eyes Bugged">Eyes Bugged</string> - <string name="Face Shear">Cara: simetría</string> - <string name="Facial Definition">Rasgos marcados</string> - <string name="Far Set Eyes">Ojos separados</string> - <string name="Fat Lips">Prominentes</string> - <string name="Female">Mujer</string> - <string name="Fingerless">Sin dedos</string> - <string name="Fingers">Con dedos</string> - <string name="Flared Cuffs">Campana</string> - <string name="Flat">Redondeadas</string> - <string name="Flat Butt">Culo plano</string> - <string name="Flat Head">Cabeza plana</string> - <string name="Flat Toe">Empeine bajo</string> - <string name="Foot Size">Pie: tamaño</string> - <string name="Forehead Angle">Frente: ángulo</string> - <string name="Forehead Heavy">Hacia la frente</string> - <string name="Freckles">Pecas</string> - <string name="Front Fringe">Flequillo</string> - <string name="Full Back">Sin cortar</string> - <string name="Full Eyeliner">Contorno completo</string> - <string name="Full Front">Sin cortar</string> - <string name="Full Hair Sides">Pelo: volumen a los lados</string> - <string name="Full Sides">Volumen total</string> - <string name="Glossy">Con brillo</string> - <string name="Glove Fingers">Guantes: dedos</string> - <string name="Glove Length">Guantes: largo</string> - <string name="Hair">Pelo</string> - <string name="Hair Back">Pelo: nuca</string> - <string name="Hair Front">Pelo: delante</string> - <string name="Hair Sides">Pelo: lados</string> - <string name="Hair Sweep">Peinado: dirección</string> - <string name="Hair Thickess">Pelo: espesor</string> - <string name="Hair Thickness">Pelo: espesor</string> - <string name="Hair Tilt">Pelo: inclinación</string> - <string name="Hair Tilted Left">A la izq.</string> - <string name="Hair Tilted Right">A la der.</string> - <string name="Hair Volume">Pelo: volumen</string> - <string name="Hand Size">Manos: tamaño</string> - <string name="Handlebars">Muy largo</string> - <string name="Head Length">Cabeza: longitud</string> - <string name="Head Shape">Cabeza: forma</string> - <string name="Head Size">Cabeza: tamaño</string> - <string name="Head Stretch">Cabeza: estiramiento</string> - <string name="Heel Height">Tacón: altura</string> - <string name="Heel Shape">Tacón: forma</string> - <string name="Height">Altura</string> - <string name="High">Subir</string> - <string name="High Heels">Tacones altos</string> - <string name="High Jaw">Mandíbula alta</string> - <string name="High Platforms">Suela gorda</string> - <string name="High and Tight">Pegada</string> - <string name="Higher">Arrriba</string> - <string name="Hip Length">Cadera: altura</string> - <string name="Hip Width">Cadera: ancho</string> - <string name="Hover">Pasa el cursor</string> - <string name="In">Pegadas</string> - <string name="In Shdw Color">Línea de ojos: color</string> - <string name="In Shdw Opacity">Línea de ojos: opacidad</string> - <string name="Inner Eye Corner">Ojos: lagrimal</string> - <string name="Inner Eye Shadow">Inner Eye Shadow</string> - <string name="Inner Shadow">Línea de ojos</string> - <string name="Jacket Length">Chaqueta: largo</string> - <string name="Jacket Wrinkles">Chaqueta: arrugas</string> - <string name="Jaw Angle">Mandíbula: ángulo</string> - <string name="Jaw Jut">Maxilar inferior</string> - <string name="Jaw Shape">Mandíbula: forma</string> - <string name="Join">Más junto</string> - <string name="Jowls">Mofletes</string> - <string name="Knee Angle">Rodillas: ángulo</string> - <string name="Knock Kneed">Zambas</string> - <string name="Large">Aumentar</string> - <string name="Large Hands">Manos grandes</string> - <string name="Left Part">Raya: izq.</string> - <string name="Leg Length">Piernas: longitud</string> - <string name="Leg Muscles">Piernas: musculatura</string> - <string name="Less">Menos</string> - <string name="Less Body Fat">Menos gordura</string> - <string name="Less Curtains">Menos tupida</string> - <string name="Less Freckles">Menos pecas</string> - <string name="Less Full">Menos grosor</string> - <string name="Less Gravity">Más levantado</string> - <string name="Less Love">Menos michelines</string> - <string name="Less Muscles">Pocos músculos</string> - <string name="Less Muscular">Poca musculatura</string> - <string name="Less Rosy">Menos sonrosada</string> - <string name="Less Round">Menos redondeada</string> - <string name="Less Saddle">Menos cartucheras</string> - <string name="Less Square">Menos cuadrada</string> - <string name="Less Volume">Menos volumen</string> - <string name="Less soul">Pequeña</string> - <string name="Lighter">Más luminosos</string> - <string name="Lip Cleft">Labio: hoyuelo</string> - <string name="Lip Cleft Depth">Hoyuelo marcado</string> - <string name="Lip Fullness">Labios: grosor</string> - <string name="Lip Pinkness">Labios sonrosados</string> - <string name="Lip Ratio">Labios: ratio</string> - <string name="Lip Thickness">Labios: prominencia</string> - <string name="Lip Width">Labios: ancho</string> - <string name="Lipgloss">Brillo de labios</string> - <string name="Lipstick">Barra de labios</string> - <string name="Lipstick Color">Barra de labios: color</string> - <string name="Long">Más</string> - <string name="Long Head">Cabeza alargada</string> - <string name="Long Hips">Cadera larga</string> - <string name="Long Legs">Piernas largas</string> - <string name="Long Neck">Cuello largo</string> - <string name="Long Pigtails">Coletas largas</string> - <string name="Long Ponytail">Cola de caballo larga</string> - <string name="Long Torso">Torso largo</string> - <string name="Long arms">Brazos largos</string> - <string name="Loose Pants">Pantalón suelto</string> - <string name="Loose Shirt">Camiseta suelta</string> - <string name="Loose Sleeves">Puños anchos</string> - <string name="Love Handles">Michelines</string> - <string name="Low">Bajar</string> - <string name="Low Heels">Tacones bajos</string> - <string name="Low Jaw">Mandíbula baja</string> - <string name="Low Platforms">Suela fina</string> - <string name="Low and Loose">Suelta</string> - <string name="Lower">Abajo</string> - <string name="Lower Bridge">Puente: abajo</string> - <string name="Lower Cheeks">Mejillas: abajo</string> - <string name="Male">Varón</string> - <string name="Middle Part">Raya: en medio</string> - <string name="More">Más</string> - <string name="More Blush">Más colorete</string> - <string name="More Body Fat">Más gordura</string> - <string name="More Curtains">Más tupida</string> - <string name="More Eyeshadow">Más</string> - <string name="More Freckles">Más pecas</string> - <string name="More Full">Más grosor</string> - <string name="More Gravity">Menos levantado</string> - <string name="More Lipstick">Más barra de labios</string> - <string name="More Love">Más michelines</string> - <string name="More Lower Lip">Más el inferior</string> - <string name="More Muscles">Más músculos</string> - <string name="More Muscular">Más musculatura</string> - <string name="More Rosy">Más sonrosada</string> - <string name="More Round">Más redondeada</string> - <string name="More Saddle">Más cartucheras</string> - <string name="More Sloped">Más inclinada</string> - <string name="More Square">Más cuadrada</string> - <string name="More Upper Lip">Más el superior</string> - <string name="More Vertical">Más recta</string> - <string name="More Volume">Más volumen</string> - <string name="More soul">Grande</string> - <string name="Moustache">Bigote</string> - <string name="Mouth Corner">Comisuras</string> - <string name="Mouth Position">Boca: posición</string> - <string name="Mowhawk">Rapado</string> - <string name="Muscular">Muscular</string> - <string name="Mutton Chops">Patillas largas</string> - <string name="Nail Polish">Uñas pintadas</string> - <string name="Nail Polish Color">Uñas pintadas: color</string> - <string name="Narrow">Disminuir</string> - <string name="Narrow Back">Rapada</string> - <string name="Narrow Front">Entradas</string> - <string name="Narrow Lips">Labios estrechos</string> - <string name="Natural">Natural</string> - <string name="Neck Length">Cuello: longitud</string> - <string name="Neck Thickness">Cuello: grosor</string> - <string name="No Blush">Sin colorete</string> - <string name="No Eyeliner">Sin contorno</string> - <string name="No Eyeshadow">Menos</string> - <string name="No Lipgloss">Sin brillo</string> - <string name="No Lipstick">Sin barra de labios</string> - <string name="No Part">Sin raya</string> - <string name="No Polish">Sin pintar</string> - <string name="No Red">Nada</string> - <string name="No Spikes">Sin crestas</string> - <string name="No White">Sin blanco</string> - <string name="No Wrinkles">Sin arrugas</string> - <string name="Normal Lower">Normal Lower</string> - <string name="Normal Upper">Normal Upper</string> - <string name="Nose Left">Nariz a la izq.</string> - <string name="Nose Right">Nariz a la der.</string> - <string name="Nose Size">Nariz: tamaño</string> - <string name="Nose Thickness">Nariz: grosor</string> - <string name="Nose Tip Angle">Nariz: respingona</string> - <string name="Nose Tip Shape">Nariz: punta</string> - <string name="Nose Width">Nariz: ancho</string> - <string name="Nostril Division">Ventana: altura</string> - <string name="Nostril Width">Ventana: ancho</string> - <string name="Opaque">Opaco</string> - <string name="Open">Abrir</string> - <string name="Open Back">Apertura trasera</string> - <string name="Open Front">Apertura frontal</string> - <string name="Open Left">Abierta</string> - <string name="Open Right">Abierta</string> - <string name="Orange">Anaranjado</string> - <string name="Out">De soplillo</string> - <string name="Out Shdw Color">Sombra de ojos: color</string> - <string name="Out Shdw Opacity">Sombra de ojos: opacidad</string> - <string name="Outer Eye Corner">Ojos: comisura</string> - <string name="Outer Eye Shadow">Outer Eye Shadow</string> - <string name="Outer Shadow">Sombra de ojos</string> - <string name="Overbite">Retraído</string> - <string name="Package">Pubis</string> - <string name="Painted Nails">Pintadas</string> - <string name="Pale">Pálida</string> - <string name="Pants Crotch">Pantalón: cruz</string> - <string name="Pants Fit">Ceñido</string> - <string name="Pants Length">Pernera: largo</string> - <string name="Pants Waist">Caja</string> - <string name="Pants Wrinkles">Pantalón: arrugas</string> - <string name="Part">Raya</string> - <string name="Part Bangs">Flequillo partido</string> - <string name="Pectorals">Pectorales</string> - <string name="Pigment">Tono</string> - <string name="Pigtails">Coletas</string> - <string name="Pink">Rosa</string> - <string name="Pinker">Más sonrosados</string> - <string name="Platform Height">Suela: altura</string> - <string name="Platform Width">Suela: ancho</string> - <string name="Pointy">En punta</string> - <string name="Pointy Heels">De aguja</string> - <string name="Ponytail">Cola de caballo</string> - <string name="Poofy Skirt">Con vuelo</string> - <string name="Pop Left Eye">Izquierdo más grande</string> - <string name="Pop Right Eye">Derecho más grande</string> - <string name="Puffy">Hinchadas</string> - <string name="Puffy Eyelids">Ojeras</string> - <string name="Rainbow Color">Irisación</string> - <string name="Red Hair">Pelirrojo</string> - <string name="Regular">Regular</string> - <string name="Right Part">Raya: der.</string> - <string name="Rosy Complexion">Tez sonrosada</string> - <string name="Round">Redondear</string> - <string name="Ruddiness">Rubicundez</string> - <string name="Ruddy">Rojiza</string> - <string name="Rumpled Hair">Pelo encrespado</string> - <string name="Saddle Bags">Cartucheras</string> - <string name="Scrawny Leg">Piernas flacas</string> - <string name="Separate">Más ancho</string> - <string name="Shallow">Sin marcar</string> - <string name="Shear Back">Nuca: corte</string> - <string name="Shear Face">Shear Face</string> - <string name="Shear Front">Shear Front</string> - <string name="Shear Left Up">Arriba - izq.</string> - <string name="Shear Right Up">Arriba - der.</string> - <string name="Sheared Back">Rapada</string> - <string name="Sheared Front">Rapada</string> - <string name="Shift Left">A la izq.</string> - <string name="Shift Mouth">Boca: ladeada</string> - <string name="Shift Right">A la der.</string> - <string name="Shirt Bottom">Alto de cintura</string> - <string name="Shirt Fit">Ceñido</string> - <string name="Shirt Wrinkles">Camisa: arrugas</string> - <string name="Shoe Height">Caña: altura</string> - <string name="Short">Menos</string> - <string name="Short Arms">Brazos cortos</string> - <string name="Short Legs">Piernas cortas</string> - <string name="Short Neck">Cuello corto</string> - <string name="Short Pigtails">Coletas cortas</string> - <string name="Short Ponytail">Cola de caballo corta</string> - <string name="Short Sideburns">Patillas cortas</string> - <string name="Short Torso">Torso corto</string> - <string name="Short hips">Cadera corta</string> - <string name="Shoulders">Hombros</string> - <string name="Side Fringe">Lados: franja</string> - <string name="Sideburns">Patillas</string> - <string name="Sides Hair">Pelo: lados</string> - <string name="Sides Hair Down">Bajar lados del pelo</string> - <string name="Sides Hair Up">Subir lados del pelo</string> - <string name="Skinny Neck">Cuello estrecho</string> - <string name="Skirt Fit">Falda: vuelo</string> - <string name="Skirt Length">Falda: largo</string> - <string name="Slanted Forehead">Slanted Forehead</string> - <string name="Sleeve Length">Largo de manga</string> - <string name="Sleeve Looseness">Ancho de puños</string> - <string name="Slit Back">Raja trasera</string> - <string name="Slit Front">Raja frontal</string> - <string name="Slit Left">Raja a la izq.</string> - <string name="Slit Right">Raja a la der.</string> - <string name="Small">Disminuir</string> - <string name="Small Hands">Manos pequeñas</string> - <string name="Small Head">Cabeza pequeña</string> - <string name="Smooth">Leves</string> - <string name="Smooth Hair">Pelo liso</string> - <string name="Socks Length">Calcetines: largo</string> - <string name="Soulpatch">Perilla</string> - <string name="Sparse">Depiladas</string> - <string name="Spiked Hair">Crestas</string> - <string name="Square">Cuadrada</string> - <string name="Square Toe">Punta cuadrada</string> - <string name="Squash Head">Cabeza aplastada</string> - <string name="Stretch Head">Cabeza estirada</string> - <string name="Sunken">Chupadas</string> - <string name="Sunken Chest">Estrecho de pecho</string> - <string name="Sunken Eyes">Ojos hundidos</string> - <string name="Sweep Back">Sweep Back</string> - <string name="Sweep Forward">Sweep Forward</string> - <string name="Tall">Más</string> - <string name="Taper Back">Cubierta trasera</string> - <string name="Taper Front">Cubierta frontal</string> - <string name="Thick Heels">Tacones grandes</string> - <string name="Thick Neck">Cuello ancho</string> - <string name="Thick Toe">Empeine alto</string> - <string name="Thin">Delgadas</string> - <string name="Thin Eyebrows">Cejas finas</string> - <string name="Thin Lips">Hacia dentro</string> - <string name="Thin Nose">Nariz fina</string> - <string name="Tight Chin">Poca papada</string> - <string name="Tight Cuffs">Sin campana</string> - <string name="Tight Pants">Pantalón ceñido</string> - <string name="Tight Shirt">Camisa ceñida</string> - <string name="Tight Skirt">Falda ceñida</string> - <string name="Tight Sleeves">Puños ceñidos</string> - <string name="Toe Shape">Punta: forma</string> - <string name="Toe Thickness">Empeine</string> - <string name="Torso Length">Torso: longitud</string> - <string name="Torso Muscles">Torso: musculatura</string> - <string name="Torso Scrawny">Torso flacucho</string> - <string name="Unattached">Largos</string> - <string name="Uncreased">Abiertos</string> - <string name="Underbite">Prognatismo</string> - <string name="Unnatural">No natural</string> - <string name="Upper Bridge">Puente: arriba</string> - <string name="Upper Cheeks">Mejillas: arriba</string> - <string name="Upper Chin Cleft">Barbilla: prominencia</string> - <string name="Upper Eyelid Fold">Párpados</string> - <string name="Upturned">Mucho</string> - <string name="Very Red">Del todo</string> - <string name="Waist Height">Cintura</string> - <string name="Well-Fed">Mofletes</string> - <string name="White Hair">Pelo blanco</string> - <string name="Wide">Aumentar</string> - <string name="Wide Back">Completa</string> - <string name="Wide Front">Completa</string> - <string name="Wide Lips">Labios anchos</string> - <string name="Wild">Total</string> - <string name="Wrinkles">Arrugas</string> - <string name="LocationCtrlAddLandmarkTooltip">Añadir a mis hitos</string> - <string name="LocationCtrlEditLandmarkTooltip">Editar mis hitos</string> - <string name="LocationCtrlInfoBtnTooltip">Ver más información de esta localización</string> - <string name="LocationCtrlComboBtnTooltip">Historial de mis localizaciones</string> - <string name="LocationCtrlForSaleTooltip">Comprar este terreno</string> - <string name="LocationCtrlAdultIconTooltip">Región Adulta</string> - <string name="LocationCtrlModerateIconTooltip">Región Moderada</string> - <string name="LocationCtrlGeneralIconTooltip">Región General</string> - <string name="LocationCtrlSeeAVsTooltip">Los avatares que están en esta parcela no pueden ser vistos ni escuchados por los que están fuera de ella</string> - <string name="LocationCtrlPathfindingDirtyTooltip">Los objetos que se mueven pueden presentar un comportamiento incorrecto en la región hasta que ésta se recargue.</string> - <string name="LocationCtrlPathfindingDisabledTooltip">Esta región no tiene activado el pathfinding dinámico.</string> - <string name="UpdaterWindowTitle">Actualizar [APP_NAME]</string> - <string name="UpdaterNowUpdating">Actualizando [APP_NAME]...</string> - <string name="UpdaterNowInstalling">Instalando [APP_NAME]...</string> - <string name="UpdaterUpdatingDescriptive">Tu visor [APP_NAME] se está actualizando a la última versión. Llevará algún tiempo, paciencia.</string> - <string name="UpdaterProgressBarTextWithEllipses">Descargando la actualización...</string> - <string name="UpdaterProgressBarText">Descargando la actualización</string> - <string name="UpdaterFailDownloadTitle">Fallo en la descarga de la actualización</string> - <string name="UpdaterFailUpdateDescriptive">Ha habido un error actualizando [APP_NAME]. Por favor, descarga la última versión desde www.secondlife.com.</string> - <string name="UpdaterFailInstallTitle">Fallo al instalar la actualización</string> - <string name="UpdaterFailStartTitle">Fallo al iniciar el visor</string> - <string name="ItemsComingInTooFastFrom">[APP_NAME]: Los ítems se reciben muy rápido de [FROM_NAME]; desactivada la vista previa automática durante [TIME] sgs.</string> - <string name="ItemsComingInTooFast">[APP_NAME]: Los ítems se reciben muy rápido; desactivada la vista previa automática durante [TIME] sgs.</string> - <string name="IM_logging_string">-- Activado el registro de los mensajes instantáneos --</string> - <string name="IM_typing_start_string">[NAME] está escribiendo...</string> - <string name="Unnamed">(sin nombre)</string> - <string name="IM_moderated_chat_label">(Moderado: por defecto, desactivada la voz)</string> - <string name="IM_unavailable_text_label">Para esta llamada no está disponible el chat de texto.</string> - <string name="IM_muted_text_label">Un moderador del grupo ha desactivado tu chat de texto.</string> - <string name="IM_default_text_label">Pulsa aquí para enviar un mensaje instantáneo.</string> - <string name="IM_to_label">A</string> - <string name="IM_moderator_label">(Moderador)</string> - <string name="Saved_message">(Guardado [LONG_TIMESTAMP])</string> - <string name="OnlineStatus">Conectado/a</string> - <string name="OfflineStatus">Desconectado/a</string> - <string name="not_online_msg">El usuario no está conectado: el mensaje se almacenará para entregárselo más tarde.</string> - <string name="not_online_inventory">El usuario no está conectado: el inventario se ha guardado.</string> - <string name="answered_call">Han respondido a tu llamada</string> - <string name="you_started_call">Has iniciado una llamada de voz</string> - <string name="you_joined_call">Has entrado en la llamada de voz</string> - <string name="you_auto_rejected_call-im">Rechazaste la llamada de voz automáticamente porque estaba activado 'No molestar'.</string> - <string name="name_started_call">[NAME] inició una llamada de voz</string> - <string name="ringing-im">Haciendo la llamada de voz...</string> - <string name="connected-im">Conectado, pulsa Colgar para salir</string> - <string name="hang_up-im">Se colgó la llamada de voz</string> - <string name="conference-title">Chat multi-persona</string> - <string name="conference-title-incoming">Conferencia con [AGENT_NAME]</string> - <string name="inventory_item_offered-im">Ítem del inventario '[ITEM_NAME]' ofrecido</string> - <string name="inventory_folder_offered-im">Carpeta del inventario '[ITEM_NAME]' ofrecida</string> - <string name="share_alert">Arrastra los ítems desde el invenbtario hasta aquí</string> - <string name="facebook_post_success">Has publicado en Facebook.</string> - <string name="flickr_post_success">Has publicado en Flickr.</string> - <string name="twitter_post_success">Has publicado en Twitter.</string> - <string name="no_session_message">(La sesión de MI no existe)</string> - <string name="only_user_message">Usted es el único usuario en esta sesión.</string> - <string name="offline_message">[NAME] está desconectado.</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">Error en lo solicitado, por favor, inténtalo más tarde.</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="no_ability">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">Un moderador del grupo ha desactivado tu chat de texto.</string> - <string name="muted_error">Un moderador del grupo le ha desactivado el chat de texto.</string> - <string name="add_session_event">No se ha podido añadir usuarios a la sesión de chat con [RECIPIENT].</string> - <string name="message">No se ha podido enviar tu mensaje 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="mute">Error moderando.</string> - <string name="removed">Se te ha sacado del grupo.</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> - <string name="unread_chat_single">[SOURCES] ha dicho algo nuevo</string> - <string name="unread_chat_multiple">[SOURCES] ha dicho algo nuevo</string> - <string name="session_initialization_timed_out_error">Se ha agotado el tiempo del inicio de sesión</string> - <string name="Home position set.">Posición inicial establecida.</string> - <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string> - <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string> - <string name="paid_you_ldollars">[NAME] te ha pagado [AMOUNT] L$ [REASON].</string> - <string name="paid_you_ldollars_gift">[NAME] te ha pagado [AMOUNT] L$: [REASON]</string> - <string name="paid_you_ldollars_no_reason">[NAME] te ha pagado [AMOUNT] L$.</string> - <string name="you_paid_ldollars">Has pagado [AMOUNT] L$ a [NAME] por [REASON].</string> - <string name="you_paid_ldollars_gift">Has pagado [AMOUNT] L$ a [NAME]: [REASON]</string> - <string name="you_paid_ldollars_no_info">Has pagado[AMOUNT] L$</string> - <string name="you_paid_ldollars_no_reason">Has pagado [AMOUNT] L$ a [NAME].</string> - <string name="you_paid_ldollars_no_name">Has pagado [AMOUNT] L$ por [REASON].</string> - <string name="you_paid_failure_ldollars">No has pagado a [NAME] [AMOUNT] L$ [REASON].</string> - <string name="you_paid_failure_ldollars_gift">No has pagado a [NAME] [AMOUNT] L$: [REASON]</string> - <string name="you_paid_failure_ldollars_no_info">No has pagado [AMOUNT] L$.</string> - <string name="you_paid_failure_ldollars_no_reason">No has pagado a [NAME] [AMOUNT] L$.</string> - <string name="you_paid_failure_ldollars_no_name">No has pagado [AMOUNT] L$ [REASON].</string> - <string name="for item">para [ITEM]</string> - <string name="for a parcel of land">para una parcela de terreno</string> - <string name="for a land access pass">para un pase de acceso a terrenos</string> - <string name="for deeding land">for deeding land</string> - <string name="to create a group">para crear un grupo</string> - <string name="to join a group">para entrar a un grupo</string> - <string name="to upload">to upload</string> - <string name="to publish a classified ad">para publicar un anuncio clasificado</string> - <string name="giving">Dando [AMOUNT] L$</string> - <string name="uploading_costs">Subir esto cuesta [AMOUNT] L$</string> - <string name="this_costs">Esto cuesta [AMOUNT] L$</string> - <string name="buying_selected_land">Compra del terreno seleccionado por [AMOUNT] L$</string> - <string name="this_object_costs">Este objeto cuesta [AMOUNT] L$</string> - <string name="group_role_everyone">Todos</string> - <string name="group_role_officers">Oficiales</string> - <string name="group_role_owners">Propietarios</string> - <string name="group_member_status_online">Conectado/a</string> - <string name="uploading_abuse_report">Subiendo... +Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE]. + </string> + <string name="5 O'Clock Shadow"> + Barba del día + </string> + <string name="All White"> + Blanco del todo + </string> + <string name="Anime Eyes"> + Ojos de cómic + </string> + <string name="Arced"> + Arqueadas + </string> + <string name="Arm Length"> + Brazos: longitud + </string> + <string name="Attached"> + Cortos + </string> + <string name="Attached Earlobes"> + Lóbulos + </string> + <string name="Back Fringe"> + Nuca: largo + </string> + <string name="Baggy"> + Marcadas + </string> + <string name="Bangs"> + Bangs + </string> + <string name="Beady Eyes"> + Ojos pequeños + </string> + <string name="Belly Size"> + Barriga: tamaño + </string> + <string name="Big"> + Grande + </string> + <string name="Big Butt"> + Culo grande + </string> + <string name="Big Hair Back"> + Pelo: moño + </string> + <string name="Big Hair Front"> + Pelo: tupé + </string> + <string name="Big Hair Top"> + Pelo: melena alta + </string> + <string name="Big Head"> + Cabeza grande + </string> + <string name="Big Pectorals"> + Grandes pectorales + </string> + <string name="Big Spikes"> + Crestas grandes + </string> + <string name="Black"> + Negro + </string> + <string name="Blonde"> + Rubio + </string> + <string name="Blonde Hair"> + Pelo rubio + </string> + <string name="Blush"> + Colorete + </string> + <string name="Blush Color"> + Color del colorete + </string> + <string name="Blush Opacity"> + Opacidad del colorete + </string> + <string name="Body Definition"> + Definición del cuerpo + </string> + <string name="Body Fat"> + Cuerpo: gordura + </string> + <string name="Body Freckles"> + Pecas del cuerpo + </string> + <string name="Body Thick"> + Cuerpo grueso + </string> + <string name="Body Thickness"> + Cuerpo: grosor + </string> + <string name="Body Thin"> + Cuerpo delgado + </string> + <string name="Bow Legged"> + Abiertas + </string> + <string name="Breast Buoyancy"> + Busto: firmeza + </string> + <string name="Breast Cleavage"> + Busto: canalillo + </string> + <string name="Breast Size"> + Busto: tamaño + </string> + <string name="Bridge Width"> + Puente: ancho + </string> + <string name="Broad"> + Aumentar + </string> + <string name="Brow Size"> + Arco ciliar + </string> + <string name="Bug Eyes"> + Bug Eyes + </string> + <string name="Bugged Eyes"> + Ojos saltones + </string> + <string name="Bulbous"> + Bulbosa + </string> + <string name="Bulbous Nose"> + Nariz de porra + </string> + <string name="Breast Physics Mass"> + Masa del busto + </string> + <string name="Breast Physics Smoothing"> + Suavizado del busto + </string> + <string name="Breast Physics Gravity"> + Gravedad del busto + </string> + <string name="Breast Physics Drag"> + Aerodinámica del busto + </string> + <string name="Breast Physics InOut Max Effect"> + Efecto máx. + </string> + <string name="Breast Physics InOut Spring"> + Elasticidad + </string> + <string name="Breast Physics InOut Gain"> + Ganancia + </string> + <string name="Breast Physics InOut Damping"> + Amortiguación + </string> + <string name="Breast Physics UpDown Max Effect"> + Efecto máx. + </string> + <string name="Breast Physics UpDown Spring"> + Elasticidad + </string> + <string name="Breast Physics UpDown Gain"> + Ganancia + </string> + <string name="Breast Physics UpDown Damping"> + Amortiguación + </string> + <string name="Breast Physics LeftRight Max Effect"> + Efecto máx. + </string> + <string name="Breast Physics LeftRight Spring"> + Elasticidad + </string> + <string name="Breast Physics LeftRight Gain"> + Ganancia + </string> + <string name="Breast Physics LeftRight Damping"> + Amortiguación + </string> + <string name="Belly Physics Mass"> + Masa de la barriga + </string> + <string name="Belly Physics Smoothing"> + Suavizado de la barriga + </string> + <string name="Belly Physics Gravity"> + Gravedad de la barriga + </string> + <string name="Belly Physics Drag"> + Aerodinámica de la barriga + </string> + <string name="Belly Physics UpDown Max Effect"> + Efecto máx. + </string> + <string name="Belly Physics UpDown Spring"> + Elasticidad + </string> + <string name="Belly Physics UpDown Gain"> + Ganancia + </string> + <string name="Belly Physics UpDown Damping"> + Amortiguación + </string> + <string name="Butt Physics Mass"> + Masa del culo + </string> + <string name="Butt Physics Smoothing"> + Suavizado del culo + </string> + <string name="Butt Physics Gravity"> + Gravedad del culo + </string> + <string name="Butt Physics Drag"> + Aerodinámica del culo + </string> + <string name="Butt Physics UpDown Max Effect"> + Efecto máx. + </string> + <string name="Butt Physics UpDown Spring"> + Elasticidad + </string> + <string name="Butt Physics UpDown Gain"> + Ganancia + </string> + <string name="Butt Physics UpDown Damping"> + Amortiguación + </string> + <string name="Butt Physics LeftRight Max Effect"> + Efecto máx. + </string> + <string name="Butt Physics LeftRight Spring"> + Elasticidad + </string> + <string name="Butt Physics LeftRight Gain"> + Ganancia + </string> + <string name="Butt Physics LeftRight Damping"> + Amortiguación + </string> + <string name="Bushy Eyebrows"> + Cejijuntas + </string> + <string name="Bushy Hair"> + Pelo tupido + </string> + <string name="Butt Size"> + Culo: tamaño + </string> + <string name="Butt Gravity"> + Gravedad del culo + </string> + <string name="bustle skirt"> + Polisón + </string> + <string name="no bustle"> + Sin polisón + </string> + <string name="more bustle"> + Con polisón + </string> + <string name="Chaplin"> + Cortito + </string> + <string name="Cheek Bones"> + Pómulos + </string> + <string name="Chest Size"> + Tórax: tamaño + </string> + <string name="Chin Angle"> + Barbilla: ángulo + </string> + <string name="Chin Cleft"> + Barbilla: contorno + </string> + <string name="Chin Curtains"> + Barba en collar + </string> + <string name="Chin Depth"> + Barbilla: largo + </string> + <string name="Chin Heavy"> + Hacia la barbilla + </string> + <string name="Chin In"> + Barbilla retraída + </string> + <string name="Chin Out"> + Barbilla prominente + </string> + <string name="Chin-Neck"> + Papada + </string> + <string name="Clear"> + Transparente + </string> + <string name="Cleft"> + Remarcar + </string> + <string name="Close Set Eyes"> + Ojos juntos + </string> + <string name="Closed"> + Cerrar + </string> + <string name="Closed Back"> + Trasera cerrada + </string> + <string name="Closed Front"> + Frontal cerrado + </string> + <string name="Closed Left"> + Cerrada + </string> + <string name="Closed Right"> + Cerrada + </string> + <string name="Coin Purse"> + Poco abultada + </string> + <string name="Collar Back"> + Espalda + </string> + <string name="Collar Front"> + Escote + </string> + <string name="Corner Down"> + Hacia abajo + </string> + <string name="Corner Up"> + Hacia arriba + </string> + <string name="Creased"> + Caídos + </string> + <string name="Crooked Nose"> + Nariz torcida + </string> + <string name="Cuff Flare"> + Acampanado + </string> + <string name="Dark"> + Oscuridad + </string> + <string name="Dark Green"> + Verde oscuro + </string> + <string name="Darker"> + Más oscuros + </string> + <string name="Deep"> + Remarcar + </string> + <string name="Default Heels"> + Tacones por defecto + </string> + <string name="Dense"> + Densas + </string> + <string name="Double Chin"> + Mucha papada + </string> + <string name="Downturned"> + Poco + </string> + <string name="Duffle Bag"> + Muy abultada + </string> + <string name="Ear Angle"> + Orejas: ángulo + </string> + <string name="Ear Size"> + Orejas: tamaño + </string> + <string name="Ear Tips"> + Orejas: forma + </string> + <string name="Egg Head"> + Cabeza: ahuevada + </string> + <string name="Eye Bags"> + Ojos: bolsas + </string> + <string name="Eye Color"> + Ojos: color + </string> + <string name="Eye Depth"> + Ojos: profundidad + </string> + <string name="Eye Lightness"> + Ojos: brillo + </string> + <string name="Eye Opening"> + Ojos: apertura + </string> + <string name="Eye Pop"> + Ojos: simetría + </string> + <string name="Eye Size"> + Ojos: tamaño + </string> + <string name="Eye Spacing"> + Ojos: separación + </string> + <string name="Eyebrow Arc"> + Cejas: arco + </string> + <string name="Eyebrow Density"> + Cejas: densidad + </string> + <string name="Eyebrow Height"> + Cejas: altura + </string> + <string name="Eyebrow Points"> + Cejas: en V + </string> + <string name="Eyebrow Size"> + Cejas: tamaño + </string> + <string name="Eyelash Length"> + Pestañas: longitud + </string> + <string name="Eyeliner"> + Contorno de ojos + </string> + <string name="Eyeliner Color"> + Contorno de ojos: color + </string> + <string name="Eyes Bugged"> + Eyes Bugged + </string> + <string name="Face Shear"> + Cara: simetría + </string> + <string name="Facial Definition"> + Rasgos marcados + </string> + <string name="Far Set Eyes"> + Ojos separados + </string> + <string name="Fat Lips"> + Prominentes + </string> + <string name="Female"> + Mujer + </string> + <string name="Fingerless"> + Sin dedos + </string> + <string name="Fingers"> + Con dedos + </string> + <string name="Flared Cuffs"> + Campana + </string> + <string name="Flat"> + Redondeadas + </string> + <string name="Flat Butt"> + Culo plano + </string> + <string name="Flat Head"> + Cabeza plana + </string> + <string name="Flat Toe"> + Empeine bajo + </string> + <string name="Foot Size"> + Pie: tamaño + </string> + <string name="Forehead Angle"> + Frente: ángulo + </string> + <string name="Forehead Heavy"> + Hacia la frente + </string> + <string name="Freckles"> + Pecas + </string> + <string name="Front Fringe"> + Flequillo + </string> + <string name="Full Back"> + Sin cortar + </string> + <string name="Full Eyeliner"> + Contorno completo + </string> + <string name="Full Front"> + Sin cortar + </string> + <string name="Full Hair Sides"> + Pelo: volumen a los lados + </string> + <string name="Full Sides"> + Volumen total + </string> + <string name="Glossy"> + Con brillo + </string> + <string name="Glove Fingers"> + Guantes: dedos + </string> + <string name="Glove Length"> + Guantes: largo + </string> + <string name="Hair"> + Pelo + </string> + <string name="Hair Back"> + Pelo: nuca + </string> + <string name="Hair Front"> + Pelo: delante + </string> + <string name="Hair Sides"> + Pelo: lados + </string> + <string name="Hair Sweep"> + Peinado: dirección + </string> + <string name="Hair Thickess"> + Pelo: espesor + </string> + <string name="Hair Thickness"> + Pelo: espesor + </string> + <string name="Hair Tilt"> + Pelo: inclinación + </string> + <string name="Hair Tilted Left"> + A la izq. + </string> + <string name="Hair Tilted Right"> + A la der. + </string> + <string name="Hair Volume"> + Pelo: volumen + </string> + <string name="Hand Size"> + Manos: tamaño + </string> + <string name="Handlebars"> + Muy largo + </string> + <string name="Head Length"> + Cabeza: longitud + </string> + <string name="Head Shape"> + Cabeza: forma + </string> + <string name="Head Size"> + Cabeza: tamaño + </string> + <string name="Head Stretch"> + Cabeza: estiramiento + </string> + <string name="Heel Height"> + Tacón: altura + </string> + <string name="Heel Shape"> + Tacón: forma + </string> + <string name="Height"> + Altura + </string> + <string name="High"> + Subir + </string> + <string name="High Heels"> + Tacones altos + </string> + <string name="High Jaw"> + Mandíbula alta + </string> + <string name="High Platforms"> + Suela gorda + </string> + <string name="High and Tight"> + Pegada + </string> + <string name="Higher"> + Arrriba + </string> + <string name="Hip Length"> + Cadera: altura + </string> + <string name="Hip Width"> + Cadera: ancho + </string> + <string name="Hover"> + Pasa el cursor + </string> + <string name="In"> + Pegadas + </string> + <string name="In Shdw Color"> + Línea de ojos: color + </string> + <string name="In Shdw Opacity"> + Línea de ojos: opacidad + </string> + <string name="Inner Eye Corner"> + Ojos: lagrimal + </string> + <string name="Inner Eye Shadow"> + Inner Eye Shadow + </string> + <string name="Inner Shadow"> + Línea de ojos + </string> + <string name="Jacket Length"> + Chaqueta: largo + </string> + <string name="Jacket Wrinkles"> + Chaqueta: arrugas + </string> + <string name="Jaw Angle"> + Mandíbula: ángulo + </string> + <string name="Jaw Jut"> + Maxilar inferior + </string> + <string name="Jaw Shape"> + Mandíbula: forma + </string> + <string name="Join"> + Más junto + </string> + <string name="Jowls"> + Mofletes + </string> + <string name="Knee Angle"> + Rodillas: ángulo + </string> + <string name="Knock Kneed"> + Zambas + </string> + <string name="Large"> + Aumentar + </string> + <string name="Large Hands"> + Manos grandes + </string> + <string name="Left Part"> + Raya: izq. + </string> + <string name="Leg Length"> + Piernas: longitud + </string> + <string name="Leg Muscles"> + Piernas: musculatura + </string> + <string name="Less"> + Menos + </string> + <string name="Less Body Fat"> + Menos gordura + </string> + <string name="Less Curtains"> + Menos tupida + </string> + <string name="Less Freckles"> + Menos pecas + </string> + <string name="Less Full"> + Menos grosor + </string> + <string name="Less Gravity"> + Más levantado + </string> + <string name="Less Love"> + Menos michelines + </string> + <string name="Less Muscles"> + Pocos músculos + </string> + <string name="Less Muscular"> + Poca musculatura + </string> + <string name="Less Rosy"> + Menos sonrosada + </string> + <string name="Less Round"> + Menos redondeada + </string> + <string name="Less Saddle"> + Menos cartucheras + </string> + <string name="Less Square"> + Menos cuadrada + </string> + <string name="Less Volume"> + Menos volumen + </string> + <string name="Less soul"> + Pequeña + </string> + <string name="Lighter"> + Más luminosos + </string> + <string name="Lip Cleft"> + Labio: hoyuelo + </string> + <string name="Lip Cleft Depth"> + Hoyuelo marcado + </string> + <string name="Lip Fullness"> + Labios: grosor + </string> + <string name="Lip Pinkness"> + Labios sonrosados + </string> + <string name="Lip Ratio"> + Labios: ratio + </string> + <string name="Lip Thickness"> + Labios: prominencia + </string> + <string name="Lip Width"> + Labios: ancho + </string> + <string name="Lipgloss"> + Brillo de labios + </string> + <string name="Lipstick"> + Barra de labios + </string> + <string name="Lipstick Color"> + Barra de labios: color + </string> + <string name="Long"> + Más + </string> + <string name="Long Head"> + Cabeza alargada + </string> + <string name="Long Hips"> + Cadera larga + </string> + <string name="Long Legs"> + Piernas largas + </string> + <string name="Long Neck"> + Cuello largo + </string> + <string name="Long Pigtails"> + Coletas largas + </string> + <string name="Long Ponytail"> + Cola de caballo larga + </string> + <string name="Long Torso"> + Torso largo + </string> + <string name="Long arms"> + Brazos largos + </string> + <string name="Loose Pants"> + Pantalón suelto + </string> + <string name="Loose Shirt"> + Camiseta suelta + </string> + <string name="Loose Sleeves"> + Puños anchos + </string> + <string name="Love Handles"> + Michelines + </string> + <string name="Low"> + Bajar + </string> + <string name="Low Heels"> + Tacones bajos + </string> + <string name="Low Jaw"> + Mandíbula baja + </string> + <string name="Low Platforms"> + Suela fina + </string> + <string name="Low and Loose"> + Suelta + </string> + <string name="Lower"> + Abajo + </string> + <string name="Lower Bridge"> + Puente: abajo + </string> + <string name="Lower Cheeks"> + Mejillas: abajo + </string> + <string name="Male"> + Varón + </string> + <string name="Middle Part"> + Raya: en medio + </string> + <string name="More"> + Más + </string> + <string name="More Blush"> + Más colorete + </string> + <string name="More Body Fat"> + Más gordura + </string> + <string name="More Curtains"> + Más tupida + </string> + <string name="More Eyeshadow"> + Más + </string> + <string name="More Freckles"> + Más pecas + </string> + <string name="More Full"> + Más grosor + </string> + <string name="More Gravity"> + Menos levantado + </string> + <string name="More Lipstick"> + Más barra de labios + </string> + <string name="More Love"> + Más michelines + </string> + <string name="More Lower Lip"> + Más el inferior + </string> + <string name="More Muscles"> + Más músculos + </string> + <string name="More Muscular"> + Más musculatura + </string> + <string name="More Rosy"> + Más sonrosada + </string> + <string name="More Round"> + Más redondeada + </string> + <string name="More Saddle"> + Más cartucheras + </string> + <string name="More Sloped"> + Más inclinada + </string> + <string name="More Square"> + Más cuadrada + </string> + <string name="More Upper Lip"> + Más el superior + </string> + <string name="More Vertical"> + Más recta + </string> + <string name="More Volume"> + Más volumen + </string> + <string name="More soul"> + Grande + </string> + <string name="Moustache"> + Bigote + </string> + <string name="Mouth Corner"> + Comisuras + </string> + <string name="Mouth Position"> + Boca: posición + </string> + <string name="Mowhawk"> + Rapado + </string> + <string name="Muscular"> + Muscular + </string> + <string name="Mutton Chops"> + Patillas largas + </string> + <string name="Nail Polish"> + Uñas pintadas + </string> + <string name="Nail Polish Color"> + Uñas pintadas: color + </string> + <string name="Narrow"> + Disminuir + </string> + <string name="Narrow Back"> + Rapada + </string> + <string name="Narrow Front"> + Entradas + </string> + <string name="Narrow Lips"> + Labios estrechos + </string> + <string name="Natural"> + Natural + </string> + <string name="Neck Length"> + Cuello: longitud + </string> + <string name="Neck Thickness"> + Cuello: grosor + </string> + <string name="No Blush"> + Sin colorete + </string> + <string name="No Eyeliner"> + Sin contorno + </string> + <string name="No Eyeshadow"> + Menos + </string> + <string name="No Lipgloss"> + Sin brillo + </string> + <string name="No Lipstick"> + Sin barra de labios + </string> + <string name="No Part"> + Sin raya + </string> + <string name="No Polish"> + Sin pintar + </string> + <string name="No Red"> + Nada + </string> + <string name="No Spikes"> + Sin crestas + </string> + <string name="No White"> + Sin blanco + </string> + <string name="No Wrinkles"> + Sin arrugas + </string> + <string name="Normal Lower"> + Normal Lower + </string> + <string name="Normal Upper"> + Normal Upper + </string> + <string name="Nose Left"> + Nariz a la izq. + </string> + <string name="Nose Right"> + Nariz a la der. + </string> + <string name="Nose Size"> + Nariz: tamaño + </string> + <string name="Nose Thickness"> + Nariz: grosor + </string> + <string name="Nose Tip Angle"> + Nariz: respingona + </string> + <string name="Nose Tip Shape"> + Nariz: punta + </string> + <string name="Nose Width"> + Nariz: ancho + </string> + <string name="Nostril Division"> + Ventana: altura + </string> + <string name="Nostril Width"> + Ventana: ancho + </string> + <string name="Opaque"> + Opaco + </string> + <string name="Open"> + Abrir + </string> + <string name="Open Back"> + Apertura trasera + </string> + <string name="Open Front"> + Apertura frontal + </string> + <string name="Open Left"> + Abierta + </string> + <string name="Open Right"> + Abierta + </string> + <string name="Orange"> + Anaranjado + </string> + <string name="Out"> + De soplillo + </string> + <string name="Out Shdw Color"> + Sombra de ojos: color + </string> + <string name="Out Shdw Opacity"> + Sombra de ojos: opacidad + </string> + <string name="Outer Eye Corner"> + Ojos: comisura + </string> + <string name="Outer Eye Shadow"> + Outer Eye Shadow + </string> + <string name="Outer Shadow"> + Sombra de ojos + </string> + <string name="Overbite"> + Retraído + </string> + <string name="Package"> + Pubis + </string> + <string name="Painted Nails"> + Pintadas + </string> + <string name="Pale"> + Pálida + </string> + <string name="Pants Crotch"> + Pantalón: cruz + </string> + <string name="Pants Fit"> + Ceñido + </string> + <string name="Pants Length"> + Pernera: largo + </string> + <string name="Pants Waist"> + Caja + </string> + <string name="Pants Wrinkles"> + Pantalón: arrugas + </string> + <string name="Part"> + Raya + </string> + <string name="Part Bangs"> + Flequillo partido + </string> + <string name="Pectorals"> + Pectorales + </string> + <string name="Pigment"> + Tono + </string> + <string name="Pigtails"> + Coletas + </string> + <string name="Pink"> + Rosa + </string> + <string name="Pinker"> + Más sonrosados + </string> + <string name="Platform Height"> + Suela: altura + </string> + <string name="Platform Width"> + Suela: ancho + </string> + <string name="Pointy"> + En punta + </string> + <string name="Pointy Heels"> + De aguja + </string> + <string name="Ponytail"> + Cola de caballo + </string> + <string name="Poofy Skirt"> + Con vuelo + </string> + <string name="Pop Left Eye"> + Izquierdo más grande + </string> + <string name="Pop Right Eye"> + Derecho más grande + </string> + <string name="Puffy"> + Hinchadas + </string> + <string name="Puffy Eyelids"> + Ojeras + </string> + <string name="Rainbow Color"> + Irisación + </string> + <string name="Red Hair"> + Pelirrojo + </string> + <string name="Regular"> + Regular + </string> + <string name="Right Part"> + Raya: der. + </string> + <string name="Rosy Complexion"> + Tez sonrosada + </string> + <string name="Round"> + Redondear + </string> + <string name="Ruddiness"> + Rubicundez + </string> + <string name="Ruddy"> + Rojiza + </string> + <string name="Rumpled Hair"> + Pelo encrespado + </string> + <string name="Saddle Bags"> + Cartucheras + </string> + <string name="Scrawny Leg"> + Piernas flacas + </string> + <string name="Separate"> + Más ancho + </string> + <string name="Shallow"> + Sin marcar + </string> + <string name="Shear Back"> + Nuca: corte + </string> + <string name="Shear Face"> + Shear Face + </string> + <string name="Shear Front"> + Shear Front + </string> + <string name="Shear Left Up"> + Arriba - izq. + </string> + <string name="Shear Right Up"> + Arriba - der. + </string> + <string name="Sheared Back"> + Rapada + </string> + <string name="Sheared Front"> + Rapada + </string> + <string name="Shift Left"> + A la izq. + </string> + <string name="Shift Mouth"> + Boca: ladeada + </string> + <string name="Shift Right"> + A la der. + </string> + <string name="Shirt Bottom"> + Alto de cintura + </string> + <string name="Shirt Fit"> + Ceñido + </string> + <string name="Shirt Wrinkles"> + Camisa: arrugas + </string> + <string name="Shoe Height"> + Caña: altura + </string> + <string name="Short"> + Menos + </string> + <string name="Short Arms"> + Brazos cortos + </string> + <string name="Short Legs"> + Piernas cortas + </string> + <string name="Short Neck"> + Cuello corto + </string> + <string name="Short Pigtails"> + Coletas cortas + </string> + <string name="Short Ponytail"> + Cola de caballo corta + </string> + <string name="Short Sideburns"> + Patillas cortas + </string> + <string name="Short Torso"> + Torso corto + </string> + <string name="Short hips"> + Cadera corta + </string> + <string name="Shoulders"> + Hombros + </string> + <string name="Side Fringe"> + Lados: franja + </string> + <string name="Sideburns"> + Patillas + </string> + <string name="Sides Hair"> + Pelo: lados + </string> + <string name="Sides Hair Down"> + Bajar lados del pelo + </string> + <string name="Sides Hair Up"> + Subir lados del pelo + </string> + <string name="Skinny Neck"> + Cuello estrecho + </string> + <string name="Skirt Fit"> + Falda: vuelo + </string> + <string name="Skirt Length"> + Falda: largo + </string> + <string name="Slanted Forehead"> + Slanted Forehead + </string> + <string name="Sleeve Length"> + Largo de manga + </string> + <string name="Sleeve Looseness"> + Ancho de puños + </string> + <string name="Slit Back"> + Raja trasera + </string> + <string name="Slit Front"> + Raja frontal + </string> + <string name="Slit Left"> + Raja a la izq. + </string> + <string name="Slit Right"> + Raja a la der. + </string> + <string name="Small"> + Disminuir + </string> + <string name="Small Hands"> + Manos pequeñas + </string> + <string name="Small Head"> + Cabeza pequeña + </string> + <string name="Smooth"> + Leves + </string> + <string name="Smooth Hair"> + Pelo liso + </string> + <string name="Socks Length"> + Calcetines: largo + </string> + <string name="Soulpatch"> + Perilla + </string> + <string name="Sparse"> + Depiladas + </string> + <string name="Spiked Hair"> + Crestas + </string> + <string name="Square"> + Cuadrada + </string> + <string name="Square Toe"> + Punta cuadrada + </string> + <string name="Squash Head"> + Cabeza aplastada + </string> + <string name="Stretch Head"> + Cabeza estirada + </string> + <string name="Sunken"> + Chupadas + </string> + <string name="Sunken Chest"> + Estrecho de pecho + </string> + <string name="Sunken Eyes"> + Ojos hundidos + </string> + <string name="Sweep Back"> + Sweep Back + </string> + <string name="Sweep Forward"> + Sweep Forward + </string> + <string name="Tall"> + Más + </string> + <string name="Taper Back"> + Cubierta trasera + </string> + <string name="Taper Front"> + Cubierta frontal + </string> + <string name="Thick Heels"> + Tacones grandes + </string> + <string name="Thick Neck"> + Cuello ancho + </string> + <string name="Thick Toe"> + Empeine alto + </string> + <string name="Thin"> + Delgadas + </string> + <string name="Thin Eyebrows"> + Cejas finas + </string> + <string name="Thin Lips"> + Hacia dentro + </string> + <string name="Thin Nose"> + Nariz fina + </string> + <string name="Tight Chin"> + Poca papada + </string> + <string name="Tight Cuffs"> + Sin campana + </string> + <string name="Tight Pants"> + Pantalón ceñido + </string> + <string name="Tight Shirt"> + Camisa ceñida + </string> + <string name="Tight Skirt"> + Falda ceñida + </string> + <string name="Tight Sleeves"> + Puños ceñidos + </string> + <string name="Toe Shape"> + Punta: forma + </string> + <string name="Toe Thickness"> + Empeine + </string> + <string name="Torso Length"> + Torso: longitud + </string> + <string name="Torso Muscles"> + Torso: musculatura + </string> + <string name="Torso Scrawny"> + Torso flacucho + </string> + <string name="Unattached"> + Largos + </string> + <string name="Uncreased"> + Abiertos + </string> + <string name="Underbite"> + Prognatismo + </string> + <string name="Unnatural"> + No natural + </string> + <string name="Upper Bridge"> + Puente: arriba + </string> + <string name="Upper Cheeks"> + Mejillas: arriba + </string> + <string name="Upper Chin Cleft"> + Barbilla: prominencia + </string> + <string name="Upper Eyelid Fold"> + Párpados + </string> + <string name="Upturned"> + Mucho + </string> + <string name="Very Red"> + Del todo + </string> + <string name="Waist Height"> + Cintura + </string> + <string name="Well-Fed"> + Mofletes + </string> + <string name="White Hair"> + Pelo blanco + </string> + <string name="Wide"> + Aumentar + </string> + <string name="Wide Back"> + Completa + </string> + <string name="Wide Front"> + Completa + </string> + <string name="Wide Lips"> + Labios anchos + </string> + <string name="Wild"> + Total + </string> + <string name="Wrinkles"> + Arrugas + </string> + <string name="LocationCtrlAddLandmarkTooltip"> + Añadir a mis hitos + </string> + <string name="LocationCtrlEditLandmarkTooltip"> + Editar mis hitos + </string> + <string name="LocationCtrlInfoBtnTooltip"> + Ver más información de esta localización + </string> + <string name="LocationCtrlComboBtnTooltip"> + Historial de mis localizaciones + </string> + <string name="LocationCtrlForSaleTooltip"> + Comprar este terreno + </string> + <string name="LocationCtrlAdultIconTooltip"> + Región Adulta + </string> + <string name="LocationCtrlModerateIconTooltip"> + Región Moderada + </string> + <string name="LocationCtrlGeneralIconTooltip"> + Región General + </string> + <string name="LocationCtrlSeeAVsTooltip"> + Los avatares que están en esta parcela no pueden ser vistos ni escuchados por los que están fuera de ella + </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Los objetos que se mueven pueden presentar un comportamiento incorrecto en la región hasta que ésta se recargue. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Esta región no tiene activado el pathfinding dinámico. + </string> + <string name="UpdaterWindowTitle"> + Actualizar [APP_NAME] + </string> + <string name="UpdaterNowUpdating"> + Actualizando [APP_NAME]... + </string> + <string name="UpdaterNowInstalling"> + Instalando [APP_NAME]... + </string> + <string name="UpdaterUpdatingDescriptive"> + Tu visor [APP_NAME] se está actualizando a la última versión. Llevará algún tiempo, paciencia. + </string> + <string name="UpdaterProgressBarTextWithEllipses"> + Descargando la actualización... + </string> + <string name="UpdaterProgressBarText"> + Descargando la actualización + </string> + <string name="UpdaterFailDownloadTitle"> + Fallo en la descarga de la actualización + </string> + <string name="UpdaterFailUpdateDescriptive"> + Ha habido un error actualizando [APP_NAME]. Por favor, descarga la última versión desde www.secondlife.com. + </string> + <string name="UpdaterFailInstallTitle"> + Fallo al instalar la actualización + </string> + <string name="UpdaterFailStartTitle"> + Fallo al iniciar el visor + </string> + <string name="ItemsComingInTooFastFrom"> + [APP_NAME]: Los ítems se reciben muy rápido de [FROM_NAME]; desactivada la vista previa automática durante [TIME] sgs. + </string> + <string name="ItemsComingInTooFast"> + [APP_NAME]: Los ítems se reciben muy rápido; desactivada la vista previa automática durante [TIME] sgs. + </string> + <string name="IM_logging_string"> + -- Activado el registro de los mensajes instantáneos -- + </string> + <string name="IM_typing_start_string"> + [NAME] está escribiendo... + </string> + <string name="Unnamed"> + (sin nombre) + </string> + <string name="IM_moderated_chat_label"> + (Moderado: por defecto, desactivada la voz) + </string> + <string name="IM_unavailable_text_label"> + Para esta llamada no está disponible el chat de texto. + </string> + <string name="IM_muted_text_label"> + Un moderador del grupo ha desactivado tu chat de texto. + </string> + <string name="IM_default_text_label"> + Pulsa aquí para enviar un mensaje instantáneo. + </string> + <string name="IM_to_label"> + A + </string> + <string name="IM_moderator_label"> + (Moderador) + </string> + <string name="Saved_message"> + (Guardado [LONG_TIMESTAMP]) + </string> + <string name="OnlineStatus"> + Conectado/a + </string> + <string name="OfflineStatus"> + Desconectado/a + </string> + <string name="not_online_msg"> + El usuario no está conectado: el mensaje se almacenará para entregárselo más tarde. + </string> + <string name="not_online_inventory"> + El usuario no está conectado: el inventario se ha guardado. + </string> + <string name="answered_call"> + Han respondido a tu llamada + </string> + <string name="you_started_call"> + Has iniciado una llamada de voz + </string> + <string name="you_joined_call"> + Has entrado en la llamada de voz + </string> + <string name="you_auto_rejected_call-im"> + Rechazaste la llamada de voz automáticamente porque estaba activado 'No molestar'. + </string> + <string name="name_started_call"> + [NAME] inició una llamada de voz + </string> + <string name="ringing-im"> + Haciendo la llamada de voz... + </string> + <string name="connected-im"> + Conectado, pulsa Colgar para salir + </string> + <string name="hang_up-im"> + Se colgó la llamada de voz + </string> + <string name="conference-title"> + Chat multi-persona + </string> + <string name="conference-title-incoming"> + Conferencia con [AGENT_NAME] + </string> + <string name="inventory_item_offered-im"> + Ítem del inventario '[ITEM_NAME]' ofrecido + </string> + <string name="inventory_folder_offered-im"> + Carpeta del inventario '[ITEM_NAME]' ofrecida + </string> + <string name="bot_warning"> + Estás conversando con un bot, [NAME]. No compartas información personal. +Más información en https://second.life/scripted-agents. + </string> + <string name="share_alert"> + Arrastra los ítems desde el invenbtario hasta aquí + </string> + <string name="facebook_post_success"> + Has publicado en Facebook. + </string> + <string name="flickr_post_success"> + Has publicado en Flickr. + </string> + <string name="twitter_post_success"> + Has publicado en Twitter. + </string> + <string name="no_session_message"> + (La sesión de MI no existe) + </string> + <string name="only_user_message"> + Usted es el único usuario en esta sesión. + </string> + <string name="offline_message"> + [NAME] está desconectado. + </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"> + Error en lo solicitado, por favor, inténtalo más tarde. + </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="no_ability"> + 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"> + Un moderador del grupo ha desactivado tu chat de texto. + </string> + <string name="muted_error"> + Un moderador del grupo le ha desactivado el chat de texto. + </string> + <string name="add_session_event"> + No se ha podido añadir usuarios a la sesión de chat con [RECIPIENT]. + </string> + <string name="message"> + No se ha podido enviar tu mensaje 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="mute"> + Error moderando. + </string> + <string name="removed"> + Se te ha sacado del grupo. + </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> + <string name="unread_chat_single"> + [SOURCES] ha dicho algo nuevo + </string> + <string name="unread_chat_multiple"> + [SOURCES] ha dicho algo nuevo + </string> + <string name="session_initialization_timed_out_error"> + Se ha agotado el tiempo del inicio de sesión + </string> + <string name="Home position set."> + Posición inicial establecida. + </string> + <string name="voice_morphing_url"> + https://secondlife.com/destination/voice-island + </string> + <string name="premium_voice_morphing_url"> + https://secondlife.com/destination/voice-morphing-premium + </string> + <string name="paid_you_ldollars"> + [NAME] te ha pagado [AMOUNT] L$ [REASON]. + </string> + <string name="paid_you_ldollars_gift"> + [NAME] te ha pagado [AMOUNT] L$: [REASON] + </string> + <string name="paid_you_ldollars_no_reason"> + [NAME] te ha pagado [AMOUNT] L$. + </string> + <string name="you_paid_ldollars"> + Has pagado [AMOUNT] L$ a [NAME] por [REASON]. + </string> + <string name="you_paid_ldollars_gift"> + Has pagado [AMOUNT] L$ a [NAME]: [REASON] + </string> + <string name="you_paid_ldollars_no_info"> + Has pagado[AMOUNT] L$ + </string> + <string name="you_paid_ldollars_no_reason"> + Has pagado [AMOUNT] L$ a [NAME]. + </string> + <string name="you_paid_ldollars_no_name"> + Has pagado [AMOUNT] L$ por [REASON]. + </string> + <string name="you_paid_failure_ldollars"> + No has pagado a [NAME] [AMOUNT] L$ [REASON]. + </string> + <string name="you_paid_failure_ldollars_gift"> + No has pagado a [NAME] [AMOUNT] L$: [REASON] + </string> + <string name="you_paid_failure_ldollars_no_info"> + No has pagado [AMOUNT] L$. + </string> + <string name="you_paid_failure_ldollars_no_reason"> + No has pagado a [NAME] [AMOUNT] L$. + </string> + <string name="you_paid_failure_ldollars_no_name"> + No has pagado [AMOUNT] L$ [REASON]. + </string> + <string name="for item"> + para [ITEM] + </string> + <string name="for a parcel of land"> + para una parcela de terreno + </string> + <string name="for a land access pass"> + para un pase de acceso a terrenos + </string> + <string name="for deeding land"> + for deeding land + </string> + <string name="to create a group"> + para crear un grupo + </string> + <string name="to join a group"> + para entrar a un grupo + </string> + <string name="to upload"> + to upload + </string> + <string name="to publish a classified ad"> + para publicar un anuncio clasificado + </string> + <string name="giving"> + Dando [AMOUNT] L$ + </string> + <string name="uploading_costs"> + Subir esto cuesta [AMOUNT] L$ + </string> + <string name="this_costs"> + Esto cuesta [AMOUNT] L$ + </string> + <string name="buying_selected_land"> + Compra del terreno seleccionado por [AMOUNT] L$ + </string> + <string name="this_object_costs"> + Este objeto cuesta [AMOUNT] L$ + </string> + <string name="group_role_everyone"> + Todos + </string> + <string name="group_role_officers"> + Oficiales + </string> + <string name="group_role_owners"> + Propietarios + </string> + <string name="group_member_status_online"> + Conectado/a + </string> + <string name="uploading_abuse_report"> + Subiendo... -Denuncia de infracción</string> - <string name="New Shape">Anatomía nueva</string> - <string name="New Skin">Piel nueva</string> - <string name="New Hair">Pelo nuevo</string> - <string name="New Eyes">Ojos nuevos</string> - <string name="New Shirt">Camisa nueva</string> - <string name="New Pants">Pantalón nuevo</string> - <string name="New Shoes">Zapatos nuevos</string> - <string name="New Socks">Calcetines nuevos</string> - <string name="New Jacket">Chaqueta nueva</string> - <string name="New Gloves">Guantes nuevos</string> - <string name="New Undershirt">Camiseta nueva</string> - <string name="New Underpants">Ropa interior nueva</string> - <string name="New Skirt">Falda nueva</string> - <string name="New Alpha">Nueva Alfa</string> - <string name="New Tattoo">Tatuaje nuevo</string> - <string name="New Universal">Nuevo Universal</string> - <string name="New Physics">Nueva física</string> - <string name="Invalid Wearable">No se puede poner</string> - <string name="New Gesture">Gesto nuevo</string> - <string name="New Script">Script nuevo</string> - <string name="New Note">Nota nueva</string> - <string name="New Folder">Carpeta nueva</string> - <string name="Contents">Contenidos</string> - <string name="Gesture">Gestos</string> - <string name="Male Gestures">Gestos de hombre</string> - <string name="Female Gestures">Gestos de mujer</string> - <string name="Other Gestures">Otros gestos</string> - <string name="Speech Gestures">Gestos al hablar</string> - <string name="Common Gestures">Gestos corrientes</string> - <string name="Male - Excuse me">Varón - Disculpa</string> - <string name="Male - Get lost">Varón – Déjame en paz</string> - <string name="Male - Blow kiss">Varón - Lanzar un beso</string> - <string name="Male - Boo">Varón - Abucheo</string> - <string name="Male - Bored">Varón - Aburrido</string> - <string name="Male - Hey">Varón – ¡Eh!</string> - <string name="Male - Laugh">Varón - Risa</string> - <string name="Male - Repulsed">Varón - Rechazo</string> - <string name="Male - Shrug">Varón - Encogimiento de hombros</string> - <string name="Male - Stick tougue out">Hombre - Sacando la lengua</string> - <string name="Male - Wow">Varón - Admiración</string> - <string name="Female - Chuckle">Mujer - Risa suave</string> - <string name="Female - Cry">Mujer - Llorar</string> - <string name="Female - Embarrassed">Mujer - Ruborizada</string> - <string name="Female - Excuse me">Mujer - Disculpa</string> - <string name="Female - Get lost">Mujer – Déjame en paz</string> - <string name="Female - Blow kiss">Mujer - Lanzar un beso</string> - <string name="Female - Boo">Mujer - Abucheo</string> - <string name="Female - Bored">Mujer - Aburrida</string> - <string name="Female - Hey">Mujer - ¡Eh!</string> - <string name="Female - Hey baby">Mujer - ¡Eh, encanto!</string> - <string name="Female - Laugh">Mujer - Risa</string> - <string name="Female - Looking good">Mujer - Buen aspecto</string> - <string name="Female - Over here">Mujer - Por aquí</string> - <string name="Female - Please">Mujer - Por favor</string> - <string name="Female - Repulsed">Mujer - Rechazo</string> - <string name="Female - Shrug">Mujer - Encogimiento de hombros</string> - <string name="Female - Stick tougue out">Mujer - Sacando la lengua</string> - <string name="Female - Wow">Mujer - Admiración</string> - <string name="New Daycycle">Nuevo Ciclo del día</string> - <string name="New Water">Nueva Agua</string> - <string name="New Sky">Nuevo Cielo</string> - <string name="/bow">/reverencia</string> - <string name="/clap">/aplaudir</string> - <string name="/count">/contar</string> - <string name="/extinguish">/apagar</string> - <string name="/kmb">/bmc</string> - <string name="/muscle">/músculo</string> - <string name="/no">/no</string> - <string name="/no!">/¡no!</string> - <string name="/paper">/papel</string> - <string name="/pointme">/señalarme</string> - <string name="/pointyou">/señalarte</string> - <string name="/rock">/piedra</string> - <string name="/scissor">/tijera</string> - <string name="/smoke">/fumar</string> - <string name="/stretch">/estirar</string> - <string name="/whistle">/silbar</string> - <string name="/yes">/sí</string> - <string name="/yes!">/¡sí!</string> - <string name="afk">ausente</string> - <string name="dance1">baile1</string> - <string name="dance2">baile2</string> - <string name="dance3">baile3</string> - <string name="dance4">baile4</string> - <string name="dance5">baile5</string> - <string name="dance6">baile6</string> - <string name="dance7">baile7</string> - <string name="dance8">baile8</string> - <string name="AvatarBirthDateFormat">[day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt]</string> - <string name="DefaultMimeType">ninguno/ninguno</string> - <string name="texture_load_dimensions_error">No se puede subir imágenes mayores de [WIDTH]*[HEIGHT]</string> - <string name="outfit_photo_load_dimensions_error">La foto del vestuario puede tener como máx. un tamaño de [WIDTH]*[HEIGHT]. Cambia el tamaño o utiliza otra imagen</string> - <string name="outfit_photo_select_dimensions_error">La foto del vestuario puede tener como máx. un tamaño de [WIDTH]*[HEIGHT]. Selecciona otra textura</string> - <string name="outfit_photo_verify_dimensions_error">No se pueden verificar las dimensiones de la foto. Espera hasta que aparezca el tamaño de la foto en el selector</string> +Denuncia de infracción + </string> + <string name="New Shape"> + Anatomía nueva + </string> + <string name="New Skin"> + Piel nueva + </string> + <string name="New Hair"> + Pelo nuevo + </string> + <string name="New Eyes"> + Ojos nuevos + </string> + <string name="New Shirt"> + Camisa nueva + </string> + <string name="New Pants"> + Pantalón nuevo + </string> + <string name="New Shoes"> + Zapatos nuevos + </string> + <string name="New Socks"> + Calcetines nuevos + </string> + <string name="New Jacket"> + Chaqueta nueva + </string> + <string name="New Gloves"> + Guantes nuevos + </string> + <string name="New Undershirt"> + Camiseta nueva + </string> + <string name="New Underpants"> + Ropa interior nueva + </string> + <string name="New Skirt"> + Falda nueva + </string> + <string name="New Alpha"> + Nueva Alfa + </string> + <string name="New Tattoo"> + Tatuaje nuevo + </string> + <string name="New Universal"> + Nuevo Universal + </string> + <string name="New Physics"> + Nueva física + </string> + <string name="Invalid Wearable"> + No se puede poner + </string> + <string name="New Gesture"> + Gesto nuevo + </string> + <string name="New Script"> + Script nuevo + </string> + <string name="New Note"> + Nota nueva + </string> + <string name="New Folder"> + Carpeta nueva + </string> + <string name="Contents"> + Contenidos + </string> + <string name="Gesture"> + Gestos + </string> + <string name="Male Gestures"> + Gestos de hombre + </string> + <string name="Female Gestures"> + Gestos de mujer + </string> + <string name="Other Gestures"> + Otros gestos + </string> + <string name="Speech Gestures"> + Gestos al hablar + </string> + <string name="Common Gestures"> + Gestos corrientes + </string> + <string name="Male - Excuse me"> + Varón - Disculpa + </string> + <string name="Male - Get lost"> + Varón – Déjame en paz + </string> + <string name="Male - Blow kiss"> + Varón - Lanzar un beso + </string> + <string name="Male - Boo"> + Varón - Abucheo + </string> + <string name="Male - Bored"> + Varón - Aburrido + </string> + <string name="Male - Hey"> + Varón – ¡Eh! + </string> + <string name="Male - Laugh"> + Varón - Risa + </string> + <string name="Male - Repulsed"> + Varón - Rechazo + </string> + <string name="Male - Shrug"> + Varón - Encogimiento de hombros + </string> + <string name="Male - Stick tougue out"> + Hombre - Sacando la lengua + </string> + <string name="Male - Wow"> + Varón - Admiración + </string> + <string name="Female - Chuckle"> + Mujer - Risa suave + </string> + <string name="Female - Cry"> + Mujer - Llorar + </string> + <string name="Female - Embarrassed"> + Mujer - Ruborizada + </string> + <string name="Female - Excuse me"> + Mujer - Disculpa + </string> + <string name="Female - Get lost"> + Mujer – Déjame en paz + </string> + <string name="Female - Blow kiss"> + Mujer - Lanzar un beso + </string> + <string name="Female - Boo"> + Mujer - Abucheo + </string> + <string name="Female - Bored"> + Mujer - Aburrida + </string> + <string name="Female - Hey"> + Mujer - ¡Eh! + </string> + <string name="Female - Hey baby"> + Mujer - ¡Eh, encanto! + </string> + <string name="Female - Laugh"> + Mujer - Risa + </string> + <string name="Female - Looking good"> + Mujer - Buen aspecto + </string> + <string name="Female - Over here"> + Mujer - Por aquí + </string> + <string name="Female - Please"> + Mujer - Por favor + </string> + <string name="Female - Repulsed"> + Mujer - Rechazo + </string> + <string name="Female - Shrug"> + Mujer - Encogimiento de hombros + </string> + <string name="Female - Stick tougue out"> + Mujer - Sacando la lengua + </string> + <string name="Female - Wow"> + Mujer - Admiración + </string> + <string name="New Daycycle"> + Nuevo Ciclo del día + </string> + <string name="New Water"> + Nueva Agua + </string> + <string name="New Sky"> + Nuevo Cielo + </string> + <string name="/bow"> + /reverencia + </string> + <string name="/clap"> + /aplaudir + </string> + <string name="/count"> + /contar + </string> + <string name="/extinguish"> + /apagar + </string> + <string name="/kmb"> + /bmc + </string> + <string name="/muscle"> + /músculo + </string> + <string name="/no"> + /no + </string> + <string name="/no!"> + /¡no! + </string> + <string name="/paper"> + /papel + </string> + <string name="/pointme"> + /señalarme + </string> + <string name="/pointyou"> + /señalarte + </string> + <string name="/rock"> + /piedra + </string> + <string name="/scissor"> + /tijera + </string> + <string name="/smoke"> + /fumar + </string> + <string name="/stretch"> + /estirar + </string> + <string name="/whistle"> + /silbar + </string> + <string name="/yes"> + /sí + </string> + <string name="/yes!"> + /¡sí! + </string> + <string name="afk"> + ausente + </string> + <string name="dance1"> + baile1 + </string> + <string name="dance2"> + baile2 + </string> + <string name="dance3"> + baile3 + </string> + <string name="dance4"> + baile4 + </string> + <string name="dance5"> + baile5 + </string> + <string name="dance6"> + baile6 + </string> + <string name="dance7"> + baile7 + </string> + <string name="dance8"> + baile8 + </string> + <string name="AvatarBirthDateFormat"> + [day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt] + </string> + <string name="DefaultMimeType"> + ninguno/ninguno + </string> + <string name="texture_load_dimensions_error"> + No se puede subir imágenes mayores de [WIDTH]*[HEIGHT] + </string> + <string name="outfit_photo_load_dimensions_error"> + La foto del vestuario puede tener como máx. un tamaño de [WIDTH]*[HEIGHT]. Cambia el tamaño o utiliza otra imagen + </string> + <string name="outfit_photo_select_dimensions_error"> + La foto del vestuario puede tener como máx. un tamaño de [WIDTH]*[HEIGHT]. Selecciona otra textura + </string> + <string name="outfit_photo_verify_dimensions_error"> + No se pueden verificar las dimensiones de la foto. Espera hasta que aparezca el tamaño de la foto en el selector + </string> <string name="words_separator" value=","/> - <string name="server_is_down">Parece que hay algún problema que ha escapado a nuestros controles. + <string name="server_is_down"> + Parece que hay algún problema que ha escapado a nuestros controles. Visita http://status.secondlifegrid.net para ver si hay alguna incidencia conocida que esté afectando al servicio. - Si sigues teniendo problemas, comprueba la configuración de la red y del servidor de seguridad.</string> - <string name="dateTimeWeekdaysNames">Domingo:Lunes:Martes:Miércoles:Jueves:Viernes:Sábado</string> - <string name="dateTimeWeekdaysShortNames">Dom:Lun:Mar:Mié:Jue:Vie:Sáb</string> - <string name="dateTimeMonthNames">Enero:Febrero:Marzo:Abril:Mayo:Junio:Julio:Agosto:Septiembre:Octubre:Noviembre:Diciembre</string> - <string name="dateTimeMonthShortNames">Ene:Feb:Mar:Abr:May:Jun:Jul:Ago:Sep:Oct:Nov:Dic</string> - <string name="dateTimeDayFormat">[MDAY]</string> - <string name="dateTimeAM">AM</string> - <string name="dateTimePM">PM</string> - <string name="LocalEstimateUSD">[AMOUNT] US$</string> - <string name="Group Ban">Expulsión de grupo</string> - <string name="Membership">Membresía</string> - <string name="Roles">Roles</string> - <string name="Group Identity">Indentidad de grupo</string> - <string name="Parcel Management">Gestión de la parcela</string> - <string name="Parcel Identity">Identidad de la parcela</string> - <string name="Parcel Settings">Configuración de la parcela</string> - <string name="Parcel Powers">Poder de la parcela</string> - <string name="Parcel Access">Acceso a la parcela</string> - <string name="Parcel Content">Contenido de la parcela</string> - <string name="Object Management">Manejo de objetos</string> - <string name="Accounting">Contabilidad</string> - <string name="Notices">Avisos</string> - <string name="Chat" value="Chat :">Chat</string> - <string name="DeleteItems">¿Deseas eliminar los elementos seleccionados?</string> - <string name="DeleteItem">¿Deseas eliminar el elemento seleccionado?</string> - <string name="EmptyOutfitText">No hay elementos en este vestuario</string> - <string name="ExternalEditorNotSet">Selecciona un editor mediante la configuración de ExternalEditor.</string> - <string name="ExternalEditorNotFound">No se encuentra el editor externo especificado. + Si sigues teniendo problemas, comprueba la configuración de la red y del servidor de seguridad. + </string> + <string name="dateTimeWeekdaysNames"> + Domingo:Lunes:Martes:Miércoles:Jueves:Viernes:Sábado + </string> + <string name="dateTimeWeekdaysShortNames"> + Dom:Lun:Mar:Mié:Jue:Vie:Sáb + </string> + <string name="dateTimeMonthNames"> + Enero:Febrero:Marzo:Abril:Mayo:Junio:Julio:Agosto:Septiembre:Octubre:Noviembre:Diciembre + </string> + <string name="dateTimeMonthShortNames"> + Ene:Feb:Mar:Abr:May:Jun:Jul:Ago:Sep:Oct:Nov:Dic + </string> + <string name="dateTimeDayFormat"> + [MDAY] + </string> + <string name="dateTimeAM"> + AM + </string> + <string name="dateTimePM"> + PM + </string> + <string name="LocalEstimateUSD"> + [AMOUNT] US$ + </string> + <string name="Group Ban"> + Expulsión de grupo + </string> + <string name="Membership"> + Membresía + </string> + <string name="Roles"> + Roles + </string> + <string name="Group Identity"> + Indentidad de grupo + </string> + <string name="Parcel Management"> + Gestión de la parcela + </string> + <string name="Parcel Identity"> + Identidad de la parcela + </string> + <string name="Parcel Settings"> + Configuración de la parcela + </string> + <string name="Parcel Powers"> + Poder de la parcela + </string> + <string name="Parcel Access"> + Acceso a la parcela + </string> + <string name="Parcel Content"> + Contenido de la parcela + </string> + <string name="Object Management"> + Manejo de objetos + </string> + <string name="Accounting"> + Contabilidad + </string> + <string name="Notices"> + Avisos + </string> + <string name="Chat" value="Chat :"> + Chat + </string> + <string name="DeleteItems"> + ¿Deseas eliminar los elementos seleccionados? + </string> + <string name="DeleteItem"> + ¿Deseas eliminar el elemento seleccionado? + </string> + <string name="EmptyOutfitText"> + No hay elementos en este vestuario + </string> + <string name="ExternalEditorNotSet"> + Selecciona un editor mediante la configuración de ExternalEditor. + </string> + <string name="ExternalEditorNotFound"> + No se encuentra el editor externo especificado. Inténtalo incluyendo la ruta de acceso al editor entre comillas -(por ejemplo, "/ruta a mi/editor" "%s").</string> - <string name="ExternalEditorCommandParseError">Error al analizar el comando de editor externo.</string> - <string name="ExternalEditorFailedToRun">Error al ejecutar el editor externo.</string> - <string name="TranslationFailed">Error al traducir: [REASON]</string> - <string name="TranslationResponseParseError">Error al analizar la respuesta de la traducción.</string> - <string name="Esc">Esc</string> - <string name="Space">Space</string> - <string name="Enter">Enter</string> - <string name="Tab">Tab</string> - <string name="Ins">Ins</string> - <string name="Del">Del</string> - <string name="Backsp">Backsp</string> - <string name="Shift">Shift</string> - <string name="Ctrl">Ctrl</string> - <string name="Alt">Alt</string> - <string name="CapsLock">CapsLock</string> - <string name="Home">Base</string> - <string name="End">End</string> - <string name="PgUp">PgUp</string> - <string name="PgDn">PgDn</string> - <string name="F1">F1</string> - <string name="F2">F2</string> - <string name="F3">F3</string> - <string name="F4">F4</string> - <string name="F5">F5</string> - <string name="F6">F6</string> - <string name="F7">F7</string> - <string name="F8">F8</string> - <string name="F9">F9</string> - <string name="F10">F10</string> - <string name="F11">F11</string> - <string name="F12">F12</string> - <string name="Add">Añadir</string> - <string name="Subtract">Restar</string> - <string name="Multiply">Multiplicar</string> - <string name="Divide">Dividir</string> - <string name="PAD_DIVIDE">PAD_DIVIDE</string> - <string name="PAD_LEFT">PAD_LEFT</string> - <string name="PAD_RIGHT">PAD_RIGHT</string> - <string name="PAD_DOWN">PAD_DOWN</string> - <string name="PAD_UP">PAD_UP</string> - <string name="PAD_HOME">PAD_HOME</string> - <string name="PAD_END">PAD_END</string> - <string name="PAD_PGUP">PAD_PGUP</string> - <string name="PAD_PGDN">PAD_PGDN</string> - <string name="PAD_CENTER">PAD_CENTER</string> - <string name="PAD_INS">PAD_INS</string> - <string name="PAD_DEL">PAD_DEL</string> - <string name="PAD_Enter">PAD_Enter</string> - <string name="PAD_BUTTON0">PAD_BUTTON0</string> - <string name="PAD_BUTTON1">PAD_BUTTON1</string> - <string name="PAD_BUTTON2">PAD_BUTTON2</string> - <string name="PAD_BUTTON3">PAD_BUTTON3</string> - <string name="PAD_BUTTON4">PAD_BUTTON4</string> - <string name="PAD_BUTTON5">PAD_BUTTON5</string> - <string name="PAD_BUTTON6">PAD_BUTTON6</string> - <string name="PAD_BUTTON7">PAD_BUTTON7</string> - <string name="PAD_BUTTON8">PAD_BUTTON8</string> - <string name="PAD_BUTTON9">PAD_BUTTON9</string> - <string name="PAD_BUTTON10">PAD_BUTTON10</string> - <string name="PAD_BUTTON11">PAD_BUTTON11</string> - <string name="PAD_BUTTON12">PAD_BUTTON12</string> - <string name="PAD_BUTTON13">PAD_BUTTON13</string> - <string name="PAD_BUTTON14">PAD_BUTTON14</string> - <string name="PAD_BUTTON15">PAD_BUTTON15</string> - <string name="-">-</string> - <string name="=">=</string> - <string name="`">`</string> - <string name=";">;</string> - <string name="[">[</string> - <string name="]">]</string> - <string name="\">\</string> - <string name="0">0</string> - <string name="1">1</string> - <string name="2">2</string> - <string name="3">3</string> - <string name="4">4</string> - <string name="5">5</string> - <string name="6">6</string> - <string name="7">7</string> - <string name="8">8</string> - <string name="9">9</string> - <string name="A">A</string> - <string name="B">B</string> - <string name="C">C</string> - <string name="D">D</string> - <string name="E">E</string> - <string name="F">F</string> - <string name="G">G</string> - <string name="H">H</string> - <string name="I">I</string> - <string name="J">J</string> - <string name="K">K</string> - <string name="L">L</string> - <string name="M">M</string> - <string name="N">N</string> - <string name="O">O</string> - <string name="P">P</string> - <string name="Q">Q</string> - <string name="R">R</string> - <string name="S">S</string> - <string name="T">T</string> - <string name="U">U</string> - <string name="V">V</string> - <string name="W">W</string> - <string name="X">X</string> - <string name="Y">Y</string> - <string name="Z">Z</string> - <string name="BeaconParticle">Viendo balizas de partículas (azules)</string> - <string name="BeaconPhysical">Viendo balizas de objetos materiales (verdes)</string> - <string name="BeaconScripted">Viendo balizas de objetos con script (rojas)</string> - <string name="BeaconScriptedTouch">Viendo el objeto con script con balizas de función táctil (rojas)</string> - <string name="BeaconSound">Viendo balizas de sonido (amarillas)</string> - <string name="BeaconMedia">Viendo balizas de medios (blancas)</string> - <string name="BeaconSun">Visualización de la baliza de dirección del sol (naranja)</string> - <string name="BeaconMoon">Visualización de la baliza de dirección de la luna (violeta)</string> - <string name="ParticleHiding">Ocultando las partículas</string> - <string name="Command_AboutLand_Label">Acerca del terreno</string> - <string name="Command_Appearance_Label">Apariencia</string> - <string name="Command_Avatar_Label">Avatar</string> - <string name="Command_Build_Label">Construir</string> - <string name="Command_Chat_Label">Chat</string> - <string name="Command_Conversations_Label">Conversaciones</string> - <string name="Command_Compass_Label">Brújula</string> - <string name="Command_Destinations_Label">Destinos</string> - <string name="Command_Environments_Label">Mis entornos</string> - <string name="Command_Facebook_Label">Facebook</string> - <string name="Command_Flickr_Label">Flickr</string> - <string name="Command_Gestures_Label">Gestos</string> - <string name="Command_Grid_Status_Label">Estado del Grid</string> - <string name="Command_HowTo_Label">Cómo</string> - <string name="Command_Inventory_Label">Inventario</string> - <string name="Command_Map_Label">Mapa</string> - <string name="Command_Marketplace_Label">Mercado</string> - <string name="Command_MarketplaceListings_Label">Mercado</string> - <string name="Command_MiniMap_Label">Minimapa</string> - <string name="Command_Move_Label">Caminar / Correr / Volar</string> - <string name="Command_Outbox_Label">Buzón de salida de comerciante</string> - <string name="Command_People_Label">Gente</string> - <string name="Command_Picks_Label">Destacados</string> - <string name="Command_Places_Label">Lugares</string> - <string name="Command_Preferences_Label">Preferencias</string> - <string name="Command_Profile_Label">Perfil</string> - <string name="Command_Report_Abuse_Label">Denunciar una infracción</string> - <string name="Command_Search_Label">Buscar</string> - <string name="Command_Snapshot_Label">Foto</string> - <string name="Command_Speak_Label">Hablar</string> - <string name="Command_Twitter_Label">Twitter</string> - <string name="Command_View_Label">Controles de la cámara</string> - <string name="Command_Voice_Label">Configuración de voz</string> - <string name="Command_AboutLand_Tooltip">Información sobre el terreno que vas a visitar</string> - <string name="Command_Appearance_Tooltip">Cambiar tu avatar</string> - <string name="Command_Avatar_Tooltip">Elegir un avatar completo</string> - <string name="Command_Build_Tooltip">Construir objetos y modificar la forma del terreno</string> - <string name="Command_Chat_Tooltip">Habla por chat de texto con las personas próximas</string> - <string name="Command_Conversations_Tooltip">Conversar con todos</string> - <string name="Command_Compass_Tooltip">Brújula</string> - <string name="Command_Destinations_Tooltip">Destinos de interés</string> - <string name="Command_Environments_Tooltip">Mis entornos</string> - <string name="Command_Facebook_Tooltip">Publicar en Facebook</string> - <string name="Command_Flickr_Tooltip">Subir a Flickr</string> - <string name="Command_Gestures_Tooltip">Gestos para tu avatar</string> - <string name="Command_Grid_Status_Tooltip">Mostrar el estado actual del Grid</string> - <string name="Command_HowTo_Tooltip">Cómo hacer las tareas habituales</string> - <string name="Command_Inventory_Tooltip">Ver y usar tus pertenencias</string> - <string name="Command_Map_Tooltip">Mapa del mundo</string> - <string name="Command_Marketplace_Tooltip">Ir de compras</string> - <string name="Command_MarketplaceListings_Tooltip">Vende tu creación</string> - <string name="Command_MiniMap_Tooltip">Mostrar la gente que está cerca</string> - <string name="Command_Move_Tooltip">Desplazando el avatar</string> - <string name="Command_Outbox_Tooltip">Transfiere objetos a tu mercado para venderlos</string> - <string name="Command_People_Tooltip">Amigos, grupos y personas próximas</string> - <string name="Command_Picks_Tooltip">Lugares que se mostrarán como favoritos en tu perfil</string> - <string name="Command_Places_Tooltip">Lugares que has guardado</string> - <string name="Command_Preferences_Tooltip">Preferencias</string> - <string name="Command_Profile_Tooltip">Consulta o edita tu perfil</string> - <string name="Command_Report_Abuse_Tooltip">Denunciar una infracción</string> - <string name="Command_Search_Tooltip">Buscar lugares, eventos y personas</string> - <string name="Command_Snapshot_Tooltip">Tomar una fotografía</string> - <string name="Command_Speak_Tooltip">Utiliza el micrófono para hablar con las personas próximas</string> - <string name="Command_Twitter_Tooltip">Twitter</string> - <string name="Command_View_Tooltip">Cambiando el ángulo de la cámara</string> - <string name="Command_Voice_Tooltip">Controles de volumen para las llamadas y la gente que se encuentre cerca de ti en el mundo virtual</string> - <string name="Toolbar_Bottom_Tooltip">actualmente en tu barra de herramientas inferior</string> - <string name="Toolbar_Left_Tooltip">actualmente en tu barra de herramientas izquierda</string> - <string name="Toolbar_Right_Tooltip">actualmente en tu barra de herramientas derecha</string> - <string name="Retain%">% retención</string> - <string name="Detail">Detalle</string> - <string name="Better Detail">Mejor detalle</string> - <string name="Surface">Superficie</string> - <string name="Solid">Sólido</string> - <string name="Wrap">Envoltura</string> - <string name="Preview">Vista previa</string> - <string name="Normal">Normal</string> - <string name="Pathfinding_Wiki_URL">http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer</string> - <string name="Pathfinding_Object_Attr_None">Ninguno</string> - <string name="Pathfinding_Object_Attr_Permanent">Afecta al navmesh</string> - <string name="Pathfinding_Object_Attr_Character">Personaje</string> - <string name="Pathfinding_Object_Attr_MultiSelect">(Múltiple)</string> - <string name="snapshot_quality_very_low">Muy bajo</string> - <string name="snapshot_quality_low">Bajo</string> - <string name="snapshot_quality_medium">Medio</string> - <string name="snapshot_quality_high">Alto</string> - <string name="snapshot_quality_very_high">Muy alto</string> - <string name="TeleportMaturityExceeded">El Residente no puede visitar esta región.</string> - <string name="UserDictionary">[Usuario]</string> - <string name="experience_tools_experience">Experiencia</string> - <string name="ExperienceNameNull">(sin experiencia)</string> - <string name="ExperienceNameUntitled">(experiencia sin título)</string> - <string name="Land-Scope">Activa en el terreno</string> - <string name="Grid-Scope">Activa en el Grid</string> - <string name="Allowed_Experiences_Tab">PERMITIDO</string> - <string name="Blocked_Experiences_Tab">BLOQUEADO</string> - <string name="Contrib_Experiences_Tab">COLABORADOR</string> - <string name="Admin_Experiences_Tab">ADMIN.</string> - <string name="Recent_Experiences_Tab">RECIENTE</string> - <string name="Owned_Experiences_Tab">PROPIEDAD</string> - <string name="ExperiencesCounter">([EXPERIENCES], máx. [MAXEXPERIENCES])</string> - <string name="ExperiencePermission1">hacerte con tus controles</string> - <string name="ExperiencePermission3">activar animaciones en tu avatar</string> - <string name="ExperiencePermission4">anexar a tu avatar</string> - <string name="ExperiencePermission9">seguimiento de la cámara</string> - <string name="ExperiencePermission10">controlar tu cámara</string> - <string name="ExperiencePermission11">teleportarte</string> - <string name="ExperiencePermission12">aceptar automáticamente permisos de experiencias</string> - <string name="ExperiencePermission16">forzar que el avatar se siente</string> - <string name="ExperiencePermission17">cambiar tu configuración del entorno</string> - <string name="ExperiencePermissionShortUnknown">realizar una operación desconocida: [Permission]</string> - <string name="ExperiencePermissionShort1">Ponerte al mando</string> - <string name="ExperiencePermissionShort3">Activar animaciones</string> - <string name="ExperiencePermissionShort4">Anexar</string> - <string name="ExperiencePermissionShort9">Seguir la cámara</string> - <string name="ExperiencePermissionShort10">Controlar la cámara</string> - <string name="ExperiencePermissionShort11">Teleporte</string> - <string name="ExperiencePermissionShort12">Otorgar permisos</string> - <string name="ExperiencePermissionShort16">Sentarte</string> - <string name="ExperiencePermissionShort17">Entorno</string> - <string name="logging_calls_disabled_log_empty">No se están registrando las conversaciones. Para empezar a grabar un registro, elige "Guardar: Solo registro" o "Guardar: Registro y transcripciones" en Preferencias > Chat.</string> - <string name="logging_calls_disabled_log_not_empty">No se registrarán más conversaciones. Para reanudar la grabación de un registro, elige "Guardar: Solo registro" o "Guardar: Registro y transcripciones" en Preferencias > Chat.</string> - <string name="logging_calls_enabled_log_empty">No hay conversaciones grabadas. Después de contactar con una persona, o de que alguien contacte contigo, aquí se mostrará una entrada de registro.</string> - <string name="loading_chat_logs">Cargando...</string> - <string name="na">n/c</string> - <string name="preset_combo_label">-Lista vacía-</string> - <string name="Default">Predeterminado</string> - <string name="none_paren_cap">(ninguno)</string> - <string name="no_limit">Sin límite</string> - <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">La forma física contiene triángulos demasiado pequeños. Intenta simplificar el modelo físico.</string> - <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH">La forma física contiene datos de confirmación erróneos. Intenta corregir el modelo físico.</string> - <string name="Mav_Details_MAV_UNKNOWN_VERSION">La versión de la forma física no es correcta. Configura la versión correcta del modelo físico.</string> - <string name="couldnt_resolve_host">Error de DNS al resolver el nombre del host([HOSTNAME]). +(por ejemplo, "/ruta a mi/editor" "%s"). + </string> + <string name="ExternalEditorCommandParseError"> + Error al analizar el comando de editor externo. + </string> + <string name="ExternalEditorFailedToRun"> + Error al ejecutar el editor externo. + </string> + <string name="TranslationFailed"> + Error al traducir: [REASON] + </string> + <string name="TranslationResponseParseError"> + Error al analizar la respuesta de la traducción. + </string> + <string name="Esc"> + Esc + </string> + <string name="Space"> + Space + </string> + <string name="Enter"> + Enter + </string> + <string name="Tab"> + Tab + </string> + <string name="Ins"> + Ins + </string> + <string name="Del"> + Del + </string> + <string name="Backsp"> + Backsp + </string> + <string name="Shift"> + Shift + </string> + <string name="Ctrl"> + Ctrl + </string> + <string name="Alt"> + Alt + </string> + <string name="CapsLock"> + CapsLock + </string> + <string name="Home"> + Base + </string> + <string name="End"> + End + </string> + <string name="PgUp"> + PgUp + </string> + <string name="PgDn"> + PgDn + </string> + <string name="F1"> + F1 + </string> + <string name="F2"> + F2 + </string> + <string name="F3"> + F3 + </string> + <string name="F4"> + F4 + </string> + <string name="F5"> + F5 + </string> + <string name="F6"> + F6 + </string> + <string name="F7"> + F7 + </string> + <string name="F8"> + F8 + </string> + <string name="F9"> + F9 + </string> + <string name="F10"> + F10 + </string> + <string name="F11"> + F11 + </string> + <string name="F12"> + F12 + </string> + <string name="Add"> + Añadir + </string> + <string name="Subtract"> + Restar + </string> + <string name="Multiply"> + Multiplicar + </string> + <string name="Divide"> + Dividir + </string> + <string name="PAD_DIVIDE"> + PAD_DIVIDE + </string> + <string name="PAD_LEFT"> + PAD_LEFT + </string> + <string name="PAD_RIGHT"> + PAD_RIGHT + </string> + <string name="PAD_DOWN"> + PAD_DOWN + </string> + <string name="PAD_UP"> + PAD_UP + </string> + <string name="PAD_HOME"> + PAD_HOME + </string> + <string name="PAD_END"> + PAD_END + </string> + <string name="PAD_PGUP"> + PAD_PGUP + </string> + <string name="PAD_PGDN"> + PAD_PGDN + </string> + <string name="PAD_CENTER"> + PAD_CENTER + </string> + <string name="PAD_INS"> + PAD_INS + </string> + <string name="PAD_DEL"> + PAD_DEL + </string> + <string name="PAD_Enter"> + PAD_Enter + </string> + <string name="PAD_BUTTON0"> + PAD_BUTTON0 + </string> + <string name="PAD_BUTTON1"> + PAD_BUTTON1 + </string> + <string name="PAD_BUTTON2"> + PAD_BUTTON2 + </string> + <string name="PAD_BUTTON3"> + PAD_BUTTON3 + </string> + <string name="PAD_BUTTON4"> + PAD_BUTTON4 + </string> + <string name="PAD_BUTTON5"> + PAD_BUTTON5 + </string> + <string name="PAD_BUTTON6"> + PAD_BUTTON6 + </string> + <string name="PAD_BUTTON7"> + PAD_BUTTON7 + </string> + <string name="PAD_BUTTON8"> + PAD_BUTTON8 + </string> + <string name="PAD_BUTTON9"> + PAD_BUTTON9 + </string> + <string name="PAD_BUTTON10"> + PAD_BUTTON10 + </string> + <string name="PAD_BUTTON11"> + PAD_BUTTON11 + </string> + <string name="PAD_BUTTON12"> + PAD_BUTTON12 + </string> + <string name="PAD_BUTTON13"> + PAD_BUTTON13 + </string> + <string name="PAD_BUTTON14"> + PAD_BUTTON14 + </string> + <string name="PAD_BUTTON15"> + PAD_BUTTON15 + </string> + <string name="-"> + - + </string> + <string name="="> + = + </string> + <string name="`"> + ` + </string> + <string name=";"> + ; + </string> + <string name="["> + [ + </string> + <string name="]"> + ] + </string> + <string name="\"> + \ + </string> + <string name="0"> + 0 + </string> + <string name="1"> + 1 + </string> + <string name="2"> + 2 + </string> + <string name="3"> + 3 + </string> + <string name="4"> + 4 + </string> + <string name="5"> + 5 + </string> + <string name="6"> + 6 + </string> + <string name="7"> + 7 + </string> + <string name="8"> + 8 + </string> + <string name="9"> + 9 + </string> + <string name="A"> + A + </string> + <string name="B"> + B + </string> + <string name="C"> + C + </string> + <string name="D"> + D + </string> + <string name="E"> + E + </string> + <string name="F"> + F + </string> + <string name="G"> + G + </string> + <string name="H"> + H + </string> + <string name="I"> + I + </string> + <string name="J"> + J + </string> + <string name="K"> + K + </string> + <string name="L"> + L + </string> + <string name="M"> + M + </string> + <string name="N"> + N + </string> + <string name="O"> + O + </string> + <string name="P"> + P + </string> + <string name="Q"> + Q + </string> + <string name="R"> + R + </string> + <string name="S"> + S + </string> + <string name="T"> + T + </string> + <string name="U"> + U + </string> + <string name="V"> + V + </string> + <string name="W"> + W + </string> + <string name="X"> + X + </string> + <string name="Y"> + Y + </string> + <string name="Z"> + Z + </string> + <string name="BeaconParticle"> + Viendo balizas de partículas (azules) + </string> + <string name="BeaconPhysical"> + Viendo balizas de objetos materiales (verdes) + </string> + <string name="BeaconScripted"> + Viendo balizas de objetos con script (rojas) + </string> + <string name="BeaconScriptedTouch"> + Viendo el objeto con script con balizas de función táctil (rojas) + </string> + <string name="BeaconSound"> + Viendo balizas de sonido (amarillas) + </string> + <string name="BeaconMedia"> + Viendo balizas de medios (blancas) + </string> + <string name="BeaconSun"> + Visualización de la baliza de dirección del sol (naranja) + </string> + <string name="BeaconMoon"> + Visualización de la baliza de dirección de la luna (violeta) + </string> + <string name="ParticleHiding"> + Ocultando las partículas + </string> + <string name="Command_AboutLand_Label"> + Acerca del terreno + </string> + <string name="Command_Appearance_Label"> + Apariencia + </string> + <string name="Command_Avatar_Label"> + Avatar + </string> + <string name="Command_Build_Label"> + Construir + </string> + <string name="Command_Chat_Label"> + Chat + </string> + <string name="Command_Conversations_Label"> + Conversaciones + </string> + <string name="Command_Compass_Label"> + Brújula + </string> + <string name="Command_Destinations_Label"> + Destinos + </string> + <string name="Command_Environments_Label"> + Mis entornos + </string> + <string name="Command_Facebook_Label"> + Facebook + </string> + <string name="Command_Flickr_Label"> + Flickr + </string> + <string name="Command_Gestures_Label"> + Gestos + </string> + <string name="Command_Grid_Status_Label"> + Estado del Grid + </string> + <string name="Command_HowTo_Label"> + Cómo + </string> + <string name="Command_Inventory_Label"> + Inventario + </string> + <string name="Command_Map_Label"> + Mapa + </string> + <string name="Command_Marketplace_Label"> + Mercado + </string> + <string name="Command_MarketplaceListings_Label"> + Mercado + </string> + <string name="Command_MiniMap_Label"> + Minimapa + </string> + <string name="Command_Move_Label"> + Caminar / Correr / Volar + </string> + <string name="Command_Outbox_Label"> + Buzón de salida de comerciante + </string> + <string name="Command_People_Label"> + Gente + </string> + <string name="Command_Picks_Label"> + Destacados + </string> + <string name="Command_Places_Label"> + Lugares + </string> + <string name="Command_Preferences_Label"> + Preferencias + </string> + <string name="Command_Profile_Label"> + Perfil + </string> + <string name="Command_Report_Abuse_Label"> + Denunciar una infracción + </string> + <string name="Command_Search_Label"> + Buscar + </string> + <string name="Command_Snapshot_Label"> + Foto + </string> + <string name="Command_Speak_Label"> + Hablar + </string> + <string name="Command_Twitter_Label"> + Twitter + </string> + <string name="Command_View_Label"> + Controles de la cámara + </string> + <string name="Command_Voice_Label"> + Configuración de voz + </string> + <string name="Command_AboutLand_Tooltip"> + Información sobre el terreno que vas a visitar + </string> + <string name="Command_Appearance_Tooltip"> + Cambiar tu avatar + </string> + <string name="Command_Avatar_Tooltip"> + Elegir un avatar completo + </string> + <string name="Command_Build_Tooltip"> + Construir objetos y modificar la forma del terreno + </string> + <string name="Command_Chat_Tooltip"> + Habla por chat de texto con las personas próximas + </string> + <string name="Command_Conversations_Tooltip"> + Conversar con todos + </string> + <string name="Command_Compass_Tooltip"> + Brújula + </string> + <string name="Command_Destinations_Tooltip"> + Destinos de interés + </string> + <string name="Command_Environments_Tooltip"> + Mis entornos + </string> + <string name="Command_Facebook_Tooltip"> + Publicar en Facebook + </string> + <string name="Command_Flickr_Tooltip"> + Subir a Flickr + </string> + <string name="Command_Gestures_Tooltip"> + Gestos para tu avatar + </string> + <string name="Command_Grid_Status_Tooltip"> + Mostrar el estado actual del Grid + </string> + <string name="Command_HowTo_Tooltip"> + Cómo hacer las tareas habituales + </string> + <string name="Command_Inventory_Tooltip"> + Ver y usar tus pertenencias + </string> + <string name="Command_Map_Tooltip"> + Mapa del mundo + </string> + <string name="Command_Marketplace_Tooltip"> + Ir de compras + </string> + <string name="Command_MarketplaceListings_Tooltip"> + Vende tu creación + </string> + <string name="Command_MiniMap_Tooltip"> + Mostrar la gente que está cerca + </string> + <string name="Command_Move_Tooltip"> + Desplazando el avatar + </string> + <string name="Command_Outbox_Tooltip"> + Transfiere objetos a tu mercado para venderlos + </string> + <string name="Command_People_Tooltip"> + Amigos, grupos y personas próximas + </string> + <string name="Command_Picks_Tooltip"> + Lugares que se mostrarán como favoritos en tu perfil + </string> + <string name="Command_Places_Tooltip"> + Lugares que has guardado + </string> + <string name="Command_Preferences_Tooltip"> + Preferencias + </string> + <string name="Command_Profile_Tooltip"> + Consulta o edita tu perfil + </string> + <string name="Command_Report_Abuse_Tooltip"> + Denunciar una infracción + </string> + <string name="Command_Search_Tooltip"> + Buscar lugares, eventos y personas + </string> + <string name="Command_Snapshot_Tooltip"> + Tomar una fotografía + </string> + <string name="Command_Speak_Tooltip"> + Utiliza el micrófono para hablar con las personas próximas + </string> + <string name="Command_Twitter_Tooltip"> + Twitter + </string> + <string name="Command_View_Tooltip"> + Cambiando el ángulo de la cámara + </string> + <string name="Command_Voice_Tooltip"> + Controles de volumen para las llamadas y la gente que se encuentre cerca de ti en el mundo virtual + </string> + <string name="Toolbar_Bottom_Tooltip"> + actualmente en tu barra de herramientas inferior + </string> + <string name="Toolbar_Left_Tooltip"> + actualmente en tu barra de herramientas izquierda + </string> + <string name="Toolbar_Right_Tooltip"> + actualmente en tu barra de herramientas derecha + </string> + <string name="Retain%"> + % retención + </string> + <string name="Detail"> + Detalle + </string> + <string name="Better Detail"> + Mejor detalle + </string> + <string name="Surface"> + Superficie + </string> + <string name="Solid"> + Sólido + </string> + <string name="Wrap"> + Envoltura + </string> + <string name="Preview"> + Vista previa + </string> + <string name="Normal"> + Normal + </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Ninguno + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Afecta al navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personaje + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Múltiple) + </string> + <string name="snapshot_quality_very_low"> + Muy bajo + </string> + <string name="snapshot_quality_low"> + Bajo + </string> + <string name="snapshot_quality_medium"> + Medio + </string> + <string name="snapshot_quality_high"> + Alto + </string> + <string name="snapshot_quality_very_high"> + Muy alto + </string> + <string name="TeleportMaturityExceeded"> + El Residente no puede visitar esta región. + </string> + <string name="UserDictionary"> + [Usuario] + </string> + <string name="experience_tools_experience"> + Experiencia + </string> + <string name="ExperienceNameNull"> + (sin experiencia) + </string> + <string name="ExperienceNameUntitled"> + (experiencia sin título) + </string> + <string name="Land-Scope"> + Activa en el terreno + </string> + <string name="Grid-Scope"> + Activa en el Grid + </string> + <string name="Allowed_Experiences_Tab"> + PERMITIDO + </string> + <string name="Blocked_Experiences_Tab"> + BLOQUEADO + </string> + <string name="Contrib_Experiences_Tab"> + COLABORADOR + </string> + <string name="Admin_Experiences_Tab"> + ADMIN. + </string> + <string name="Recent_Experiences_Tab"> + RECIENTE + </string> + <string name="Owned_Experiences_Tab"> + PROPIEDAD + </string> + <string name="ExperiencesCounter"> + ([EXPERIENCES], máx. [MAXEXPERIENCES]) + </string> + <string name="ExperiencePermission1"> + hacerte con tus controles + </string> + <string name="ExperiencePermission3"> + activar animaciones en tu avatar + </string> + <string name="ExperiencePermission4"> + anexar a tu avatar + </string> + <string name="ExperiencePermission9"> + seguimiento de la cámara + </string> + <string name="ExperiencePermission10"> + controlar tu cámara + </string> + <string name="ExperiencePermission11"> + teleportarte + </string> + <string name="ExperiencePermission12"> + aceptar automáticamente permisos de experiencias + </string> + <string name="ExperiencePermission16"> + forzar que el avatar se siente + </string> + <string name="ExperiencePermission17"> + cambiar tu configuración del entorno + </string> + <string name="ExperiencePermissionShortUnknown"> + realizar una operación desconocida: [Permission] + </string> + <string name="ExperiencePermissionShort1"> + Ponerte al mando + </string> + <string name="ExperiencePermissionShort3"> + Activar animaciones + </string> + <string name="ExperiencePermissionShort4"> + Anexar + </string> + <string name="ExperiencePermissionShort9"> + Seguir la cámara + </string> + <string name="ExperiencePermissionShort10"> + Controlar la cámara + </string> + <string name="ExperiencePermissionShort11"> + Teleporte + </string> + <string name="ExperiencePermissionShort12"> + Otorgar permisos + </string> + <string name="ExperiencePermissionShort16"> + Sentarte + </string> + <string name="ExperiencePermissionShort17"> + Entorno + </string> + <string name="logging_calls_disabled_log_empty"> + No se están registrando las conversaciones. Para empezar a grabar un registro, elige "Guardar: Solo registro" o "Guardar: Registro y transcripciones" en Preferencias > Chat. + </string> + <string name="logging_calls_disabled_log_not_empty"> + No se registrarán más conversaciones. Para reanudar la grabación de un registro, elige "Guardar: Solo registro" o "Guardar: Registro y transcripciones" en Preferencias > Chat. + </string> + <string name="logging_calls_enabled_log_empty"> + No hay conversaciones grabadas. Después de contactar con una persona, o de que alguien contacte contigo, aquí se mostrará una entrada de registro. + </string> + <string name="loading_chat_logs"> + Cargando... + </string> + <string name="na"> + n/c + </string> + <string name="preset_combo_label"> + -Lista vacía- + </string> + <string name="Default"> + Predeterminado + </string> + <string name="none_paren_cap"> + (ninguno) + </string> + <string name="no_limit"> + Sin límite + </string> + <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES"> + La forma física contiene triángulos demasiado pequeños. Intenta simplificar el modelo físico. + </string> + <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH"> + La forma física contiene datos de confirmación erróneos. Intenta corregir el modelo físico. + </string> + <string name="Mav_Details_MAV_UNKNOWN_VERSION"> + La versión de la forma física no es correcta. Configura la versión correcta del modelo físico. + </string> + <string name="couldnt_resolve_host"> + Error de DNS al resolver el nombre del host([HOSTNAME]). Por favor verifica si puedes conectarte al sitio web www.secondlife.com. Si puedes conectarte, pero aún recibes este error, por favor accede a -la sección Soporte y genera un informe del problema.</string> - <string name="ssl_peer_certificate">El servidor de inicio de sesión no pudo verificarse vía SSL. +la sección Soporte y genera un informe del problema. + </string> + <string name="ssl_peer_certificate"> + El servidor de inicio de sesión no pudo verificarse vía SSL. Si aún recibes este error, por favor accede a la sección Soporte del sitio web Secondlife.com -y genera un informe del problema.</string> - <string name="ssl_connect_error">En general esto significa que el horario de tu computadora no está bien configurado. +y genera un informe del problema. + </string> + <string name="ssl_connect_error"> + En general esto significa que el horario de tu computadora no está bien configurado. Por favor accede al Panel de control y asegúrate de que la hora y la fecha estén bien configurados. Verifica también que tu red y tu cortafuegos estén bien configurados. Si aún recibes este error, por favor accede a la sección Soporte del sitio web Secondlife.com y genera un informe del problema. -[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de conocimientos]</string> +[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de conocimientos] + </string> </strings> diff --git a/indra/newview/skins/default/xui/es/teleport_strings.xml b/indra/newview/skins/default/xui/es/teleport_strings.xml index 44be93cd80..cc6089584a 100644 --- a/indra/newview/skins/default/xui/es/teleport_strings.xml +++ b/indra/newview/skins/default/xui/es/teleport_strings.xml @@ -1,39 +1,95 @@ <?xml version="1.0" ?> <teleport_messages> <message_set name="errors"> - <message name="invalid_tport">Ha habido un problema al procesar tu petición de teleporte. Debes volver a iniciar sesión antes de poder teleportarte de nuevo. -Si sigues recibiendo este mensaje, por favor, acude al [SUPPORT_SITE].</message> - <message name="invalid_region_handoff">Ha habido un problema al procesar tu paso a otra región. Debes volver a iniciar sesión para poder pasar de región a región. -Si sigues recibiendo este mensaje, por favor, acude al [SUPPORT_SITE].</message> - <message name="blocked_tport">Lo sentimos, en estos momentos los teleportes están bloqueados. Vuelve a intentarlo en un momento. Si sigues sin poder teleportarte, desconéctate y vuelve a iniciar sesión para solucionar el problema.</message> - <message name="nolandmark_tport">Lo sentimos, pero el sistema no ha podido localizar el destino de este hito.</message> - <message name="timeout_tport">Lo sentimos, pero el sistema no ha podido completar el teleporte. -Vuelva a intentarlo en un momento.</message> - <message name="NoHelpIslandTP">No te puedes volver a teleportar a la isla de bienvenida. -Para repetir el tutorial, visita la isla de bienvenida pública.</message> - <message name="noaccess_tport">Lo sentimos, pero no tienes acceso al destino de este teleporte.</message> - <message name="missing_attach_tport">Aún no han llegado tus objetos anexados. Espera unos segundos más o desconéctate y vuelve a iniciar sesión antes de teleportarte.</message> - <message name="too_many_uploads_tport">La cola de espera en esta región está actualmente obstruida, por lo que tu petición de teleporte no se atenderá en un tiempo prudencial. Por favor, vuelve a intentarlo en unos minutos o ve a una zona menos ocupada.</message> - <message name="expired_tport">Lo sentimos, pero el sistema no ha podido atender a tu petición de teleporte en un tiempo prudencial. Por favor, vuelve a intentarlo en unos minutos.</message> - <message name="expired_region_handoff">Lo sentimos, pero el sistema no ha podido completar tu paso a otra región en un tiempo prudencial. Por favor, vuelve a intentarlo en unos minutos.</message> - <message name="no_host">Ha sido imposible encontrar el destino del teleporte: o está desactivado temporalmente o ya no existe. Por favor, vuelve a intentarlo en unos minutos.</message> - <message name="no_inventory_host">En estos momentos no está disponible el sistema del inventario.</message> - <message name="MustGetAgeRegion">Solo pueden acceder a esta región los mayores de 18 años.</message> - <message name="RegionTPSpecialUsageBlocked">No puedes entrar en la región. '[REGION_NAME]' es una región de juegos de habilidad, y debes cumplir determinados criterios para poder entrar en ella. Consulta los detalles en las [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life P+F de juegos de habilidad].</message> - <message name="preexisting_tport">Lo sentimos, pero el sistema no pudo comenzar tu teleportacion. Por favor inténtalo de nuevo en unos minutos</message> + <message name="invalid_tport"> + Ha habido un problema al procesar tu petición de teleporte. Debes volver a iniciar sesión antes de poder teleportarte de nuevo. +Si sigues recibiendo este mensaje, por favor, acude al [SUPPORT_SITE]. + </message> + <message name="invalid_region_handoff"> + Ha habido un problema al procesar tu paso a otra región. Debes volver a iniciar sesión para poder pasar de región a región. +Si sigues recibiendo este mensaje, por favor, acude al [SUPPORT_SITE]. + </message> + <message name="blocked_tport"> + Lo sentimos, en estos momentos los teleportes están bloqueados. Vuelve a intentarlo en un momento. Si sigues sin poder teleportarte, desconéctate y vuelve a iniciar sesión para solucionar el problema. + </message> + <message name="nolandmark_tport"> + Lo sentimos, pero el sistema no ha podido localizar el destino de este hito. + </message> + <message name="timeout_tport"> + Lo sentimos, pero el sistema no ha podido completar el teleporte. +Vuelva a intentarlo en un momento. + </message> + <message name="NoHelpIslandTP"> + No te puedes volver a teleportar a la isla de bienvenida. +Para repetir el tutorial, visita la isla de bienvenida pública. + </message> + <message name="noaccess_tport"> + Lo sentimos, pero no tienes acceso al destino de este teleporte. + </message> + <message name="missing_attach_tport"> + Aún no han llegado tus objetos anexados. Espera unos segundos más o desconéctate y vuelve a iniciar sesión antes de teleportarte. + </message> + <message name="too_many_uploads_tport"> + La cola de espera en esta región está actualmente obstruida, por lo que tu petición de teleporte no se atenderá en un tiempo prudencial. Por favor, vuelve a intentarlo en unos minutos o ve a una zona menos ocupada. + </message> + <message name="expired_tport"> + Lo sentimos, pero el sistema no ha podido atender a tu petición de teleporte en un tiempo prudencial. Por favor, vuelve a intentarlo en unos minutos. + </message> + <message name="expired_region_handoff"> + Lo sentimos, pero el sistema no ha podido completar tu paso a otra región en un tiempo prudencial. Por favor, vuelve a intentarlo en unos minutos. + </message> + <message name="no_host"> + Ha sido imposible encontrar el destino del teleporte: o está desactivado temporalmente o ya no existe. Por favor, vuelve a intentarlo en unos minutos. + </message> + <message name="no_inventory_host"> + En estos momentos no está disponible el sistema del inventario. + </message> + <message name="MustGetAgeRegion"> + Solo pueden acceder a esta región los mayores de 18 años. + </message> + <message name="RegionTPSpecialUsageBlocked"> + No puedes entrar en la región. '[REGION_NAME]' es una región de juegos de habilidad, y debes cumplir determinados criterios para poder entrar en ella. Consulta los detalles en las [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life P+F de juegos de habilidad]. + </message> + <message name="preexisting_tport"> + Lo sentimos, pero el sistema no pudo comenzar tu teleportacion. Por favor inténtalo de nuevo en unos minutos + </message> </message_set> <message_set name="progress"> - <message name="sending_dest">Llevando al destino.</message> - <message name="redirecting">Redireccionando a una posición diferente.</message> - <message name="relaying">Reorientando el destino.</message> - <message name="sending_home">Enviando la petición de posición de la Base.</message> - <message name="sending_landmark">Enviando la petición de posición del hito.</message> - <message name="completing">Completando el teleporte.</message> - <message name="completed_from">Teleporte realizado desde [T_SLURL]</message> - <message name="resolving">Especificando el destino.</message> - <message name="contacting">Contactando con la nueva región.</message> - <message name="arriving">Llegando...</message> - <message name="requesting">Solicitando teleporte...</message> - <message name="pending">Teleporte pendiente...</message> + <message name="sending_dest"> + Llevando al destino. + </message> + <message name="redirecting"> + Redireccionando a una posición diferente. + </message> + <message name="relaying"> + Reorientando el destino. + </message> + <message name="sending_home"> + Enviando la petición de posición de la Base. + </message> + <message name="sending_landmark"> + Enviando la petición de posición del hito. + </message> + <message name="completing"> + Completando el teleporte. + </message> + <message name="completed_from"> + Teleporte realizado desde [T_SLURL] + </message> + <message name="resolving"> + Especificando el destino. + </message> + <message name="contacting"> + Contactando con la nueva región. + </message> + <message name="arriving"> + Llegando... + </message> + <message name="requesting"> + Solicitando teleporte... + </message> + <message name="pending"> + Teleporte pendiente... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/fr/panel_login_first.xml b/indra/newview/skins/default/xui/fr/panel_login_first.xml deleted file mode 100644 index 8f40d0230c..0000000000 --- a/indra/newview/skins/default/xui/fr/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php?lang=fr - </panel.string> - <panel.string name="sign_up_url"> - https://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Nom d'utilisateur" name="username_combo" tool_tip="Nom d'utilisateur que vous avez choisi lors de votre inscription (par exemple, bobsmith12 ou Steller Sunshine)."/> - <line_editor label="Mot de passe" name="password_edit"/> - <button label="Connexion" name="connect_btn"/> - <check_box font="SansSerifSmall" label="Mémoriser mes informations" name="remember_check"/> - <text name="forgot_password_text"> - Mot de passe oublié - </text> - <text name="sign_up_text"> - S'inscrire - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Votre première étape est Learning Island. Trouvez le portail de sortie. - </text> - <text name="image_caption_right"> - Puis explorez Social Island et faites la connaissance d'autres résidents. - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml index bdedb9162f..52fa318f8e 100644 --- a/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/fr/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="Enreg. sur le disque" name="save_to_computer_btn"/> - <button label="Enreg. dans l'inventaire ([AMOUNT] L$)" name="save_to_inventory_btn"/> + <button label="Enreg. dans l'inventaire" name="save_to_inventory_btn"/> <button label="Partager sur le flux de profil" name="save_to_profile_btn"/> <button label="Partager sur Facebook" name="send_to_facebook_btn"/> <button label="Partager sur Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 5307c8d561..4fb5167d67 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -1,619 +1,1687 @@ <?xml version="1.0" ?> <strings> - <string name="SECOND_LIFE">Second Life</string> - <string name="APP_NAME">Second Life</string> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> - <string name="SECOND_LIFE_GRID">Grille de Second Life</string> - <string name="SUPPORT_SITE">Portail Assistance Second Life</string> - <string name="StartupDetectingHardware">Détection du matériel...</string> - <string name="StartupLoading">Chargement de [APP_NAME]...</string> - <string name="StartupClearingCache">Vidage du cache...</string> - <string name="StartupInitializingTextureCache">Initialisation du cache des textures...</string> - <string name="StartupRequireDriverUpdate">Échec d'initialisation des graphiques. Veuillez mettre votre pilote graphique à jour.</string> - <string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) -[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string> - <string name="BuildConfig">Configuration de la construction [BUILD_CONFIG]</string> - <string name="AboutPosition">Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> + <string name="SECOND_LIFE"> + Second Life + </string> + <string name="APP_NAME"> + Second Life + </string> + <string name="CAPITALIZED_APP_NAME"> + SECOND LIFE + </string> + <string name="SECOND_LIFE_GRID"> + Grille de Second Life + </string> + <string name="SUPPORT_SITE"> + Portail Assistance Second Life + </string> + <string name="StartupDetectingHardware"> + Détection du matériel... + </string> + <string name="StartupLoading"> + Chargement de [APP_NAME]... + </string> + <string name="StartupClearingCache"> + Vidage du cache... + </string> + <string name="StartupInitializingTextureCache"> + Initialisation du cache des textures... + </string> + <string name="StartupRequireDriverUpdate"> + Échec d'initialisation des graphiques. Veuillez mettre votre pilote graphique à jour. + </string> + <string name="AboutHeader"> + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Configuration de la construction [BUILD_CONFIG] + </string> + <string name="AboutPosition"> + Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à <nolink>[HOSTNAME]</nolink> SLURL : <nolink>[SLURL]</nolink> (coordonnées globales [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] -[SERVER_RELEASE_NOTES_URL]</string> - <string name="AboutSystem">CPU : [CPU] +[SERVER_RELEASE_NOTES_URL] + </string> + <string name="AboutSystem"> + CPU : [CPU] Mémoire : [MEMORY_MB] Mo Version OS : [OS_VERSION] Distributeur de cartes graphiques : [GRAPHICS_CARD_VENDOR] -Carte graphique : [GRAPHICS_CARD]</string> - <string name="AboutDriver">Version Windows Graphics Driver : [GRAPHICS_DRIVER_VERSION]</string> - <string name="AboutOGL">Version OpenGL : [OPENGL_VERSION]</string> - <string name="AboutSettings">Taille de la fenêtre: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Carte graphique : [GRAPHICS_CARD] + </string> + <string name="AboutDriver"> + Version Windows Graphics Driver : [GRAPHICS_DRIVER_VERSION] + </string> + <string name="AboutOGL"> + Version OpenGL : [OPENGL_VERSION] + </string> + <string name="AboutSettings"> + Taille de la fenêtre: [WINDOW_WIDTH]x[WINDOW_HEIGHT] Ajustement de la taille de la police : [FONT_SIZE_ADJUSTMENT]pt Échelle de l’interface : [UI_SCALE] Distance de dessin : [DRAW_DISTANCE]m Bande passante : [NET_BANDWITH] kbit/s Facteur LOD (niveau de détail) : [LOD_FACTOR] Qualité de rendu : [RENDER_QUALITY] -Mémoire textures : [TEXTURE_MEMORY] Mo</string> - <string name="AboutOSXHiDPI">Mode d'affichage HiDPI : [HIDPI]</string> - <string name="AboutLibs">J2C Decoder Version: [J2C_VERSION] +Mémoire textures : [TEXTURE_MEMORY] Mo + </string> + <string name="AboutOSXHiDPI"> + Mode d'affichage HiDPI : [HIDPI] + </string> + <string name="AboutLibs"> + J2C Decoder Version: [J2C_VERSION] Audio Driver Version: [AUDIO_DRIVER_VERSION] [LIBCEF_VERSION] LibVLC Version: [LIBVLC_VERSION] -Voice Server Version: [VOICE_VERSION]</string> - <string name="AboutTraffic">Paquets perdus : [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string> - <string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string> - <string name="ErrorFetchingServerReleaseNotesURL">Erreur lors de la récupération de l'URL des notes de version du serveur.</string> - <string name="BuildConfiguration">Configuration de la construction</string> - <string name="ProgressRestoring">Restauration...</string> - <string name="ProgressChangingResolution">Changement de la résolution...</string> - <string name="Fullbright">Fullbright (Legacy)</string> - <string name="LoginInProgress">La connexion à [APP_NAME] apparaît peut-être comme étant gelée. Veuillez patienter.</string> - <string name="LoginInProgressNoFrozen">Connexion...</string> - <string name="LoginAuthenticating">Authentification en cours</string> - <string name="LoginMaintenance">Maintenance du compte en cours…</string> - <string name="LoginAttempt">La tentative de connexion précédente a échoué. Connexion, esssai [NUMBER]</string> - <string name="LoginPrecaching">Monde en cours de chargement…</string> - <string name="LoginInitializingBrowser">Navigateur Web incorporé en cours d'initialisation…</string> - <string name="LoginInitializingMultimedia">Multimédia en cours d'initialisation…</string> - <string name="LoginInitializingFonts">Chargement des polices en cours...</string> - <string name="LoginVerifyingCache">Fichiers du cache en cours de vérification (peut prendre 60-90 s)...</string> - <string name="LoginProcessingResponse">Réponse en cours de traitement…</string> - <string name="LoginInitializingWorld">Monde en cours d'initialisation…</string> - <string name="LoginDecodingImages">Décodage des images en cours...</string> - <string name="LoginInitializingQuicktime">Quicktime en cours d'initialisation</string> - <string name="LoginQuicktimeNotFound">Quicktime introuvable, impossible de procéder à l'initialisation.</string> - <string name="LoginQuicktimeOK">Initialisation de Quicktime réussie.</string> - <string name="LoginRequestSeedCapGrant">Capacités de la région demandées...</string> - <string name="LoginRetrySeedCapGrant">Capacités de la région demandées... Tentative n° [NUMBER].</string> - <string name="LoginWaitingForRegionHandshake">Liaison avec la région en cours de création...</string> - <string name="LoginConnectingToRegion">Connexion avec la région en cours...</string> - <string name="LoginDownloadingClothing">Habits en cours de téléchargement...</string> - <string name="InvalidCertificate">Certificat non valide ou corrompu renvoyé par le serveur. Contactez l'administrateur de la grille.</string> - <string name="CertInvalidHostname">Nom d'hôte non valide utilisé pour accéder au serveur. Vérifiez votre nom d'hôte de grille ou SLURL.</string> - <string name="CertExpired">Il semble que le certificat renvoyé par la grille ait expiré. Vérifiez votre horloge système ou contactez l'administrateur de la grille.</string> - <string name="CertKeyUsage">Impossible d'utiliser le certificat renvoyé par le serveur pour SSL. Contactez l'administrateur de la grille.</string> - <string name="CertBasicConstraints">Certificats trop nombreux dans la chaîne des certificats du serveur. Contactez l'administrateur de la grille.</string> - <string name="CertInvalidSignature">Impossible de vérifier la signature de certificat renvoyée par le serveur de la grille. Contactez l'administrateur de la grille.</string> - <string name="LoginFailedNoNetwork">Erreur réseau : impossible d'établir la connexion. Veuillez vérifier votre connexion réseau.</string> - <string name="LoginFailedHeader">Échec de la connexion.</string> - <string name="Quit">Quitter</string> - <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - <string name="AgniGridLabel">Grille principale de Second Life (Agni)</string> - <string name="AditiGridLabel">Grille de test bêta Second Life (Aditi)</string> - <string name="ViewerDownloadURL">http://secondlife.com/download</string> - <string name="LoginFailedViewerNotPermitted">Le client que vous utilisez ne permet plus d'accéder à Second Life. Téléchargez un nouveau client à la page suivante : +Voice Server Version: [VOICE_VERSION] + </string> + <string name="AboutTraffic"> + Paquets perdus : [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) + </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> + <string name="ErrorFetchingServerReleaseNotesURL"> + Erreur lors de la récupération de l'URL des notes de version du serveur. + </string> + <string name="BuildConfiguration"> + Configuration de la construction + </string> + <string name="ProgressRestoring"> + Restauration... + </string> + <string name="ProgressChangingResolution"> + Changement de la résolution... + </string> + <string name="Fullbright"> + Fullbright (Legacy) + </string> + <string name="LoginInProgress"> + La connexion à [APP_NAME] apparaît peut-être comme étant gelée. Veuillez patienter. + </string> + <string name="LoginInProgressNoFrozen"> + Connexion... + </string> + <string name="LoginAuthenticating"> + Authentification en cours + </string> + <string name="LoginMaintenance"> + Maintenance du compte en cours… + </string> + <string name="LoginAttempt"> + La tentative de connexion précédente a échoué. Connexion, esssai [NUMBER] + </string> + <string name="LoginPrecaching"> + Monde en cours de chargement… + </string> + <string name="LoginInitializingBrowser"> + Navigateur Web incorporé en cours d'initialisation… + </string> + <string name="LoginInitializingMultimedia"> + Multimédia en cours d'initialisation… + </string> + <string name="LoginInitializingFonts"> + Chargement des polices en cours... + </string> + <string name="LoginVerifyingCache"> + Fichiers du cache en cours de vérification (peut prendre 60-90 s)... + </string> + <string name="LoginProcessingResponse"> + Réponse en cours de traitement… + </string> + <string name="LoginInitializingWorld"> + Monde en cours d'initialisation… + </string> + <string name="LoginDecodingImages"> + Décodage des images en cours... + </string> + <string name="LoginInitializingQuicktime"> + Quicktime en cours d'initialisation + </string> + <string name="LoginQuicktimeNotFound"> + Quicktime introuvable, impossible de procéder à l'initialisation. + </string> + <string name="LoginQuicktimeOK"> + Initialisation de Quicktime réussie. + </string> + <string name="LoginRequestSeedCapGrant"> + Capacités de la région demandées... + </string> + <string name="LoginRetrySeedCapGrant"> + Capacités de la région demandées... Tentative n° [NUMBER]. + </string> + <string name="LoginWaitingForRegionHandshake"> + Liaison avec la région en cours de création... + </string> + <string name="LoginConnectingToRegion"> + Connexion avec la région en cours... + </string> + <string name="LoginDownloadingClothing"> + Habits en cours de téléchargement... + </string> + <string name="InvalidCertificate"> + Certificat non valide ou corrompu renvoyé par le serveur. Contactez l'administrateur de la grille. + </string> + <string name="CertInvalidHostname"> + Nom d'hôte non valide utilisé pour accéder au serveur. Vérifiez votre nom d'hôte de grille ou SLURL. + </string> + <string name="CertExpired"> + Il semble que le certificat renvoyé par la grille ait expiré. Vérifiez votre horloge système ou contactez l'administrateur de la grille. + </string> + <string name="CertKeyUsage"> + Impossible d'utiliser le certificat renvoyé par le serveur pour SSL. Contactez l'administrateur de la grille. + </string> + <string name="CertBasicConstraints"> + Certificats trop nombreux dans la chaîne des certificats du serveur. Contactez l'administrateur de la grille. + </string> + <string name="CertInvalidSignature"> + Impossible de vérifier la signature de certificat renvoyée par le serveur de la grille. Contactez l'administrateur de la grille. + </string> + <string name="LoginFailedNoNetwork"> + Erreur réseau : impossible d'établir la connexion. Veuillez vérifier votre connexion réseau. + </string> + <string name="LoginFailedHeader"> + Échec de la connexion. + </string> + <string name="Quit"> + Quitter + </string> + <string name="create_account_url"> + http://join.secondlife.com/?sourceid=[sourceid] + </string> + <string name="AgniGridLabel"> + Grille principale de Second Life (Agni) + </string> + <string name="AditiGridLabel"> + Grille de test bêta Second Life (Aditi) + </string> + <string name="ViewerDownloadURL"> + http://secondlife.com/download + </string> + <string name="LoginFailedViewerNotPermitted"> + Le client que vous utilisez ne permet plus d'accéder à Second Life. Téléchargez un nouveau client à la page suivante : http://secondlife.com/download Pour plus d'informations, consultez la page FAQ ci-dessous : -http://secondlife.com/viewer-access-faq</string> - <string name="LoginIntermediateOptionalUpdateAvailable">Mise à jour facultative du client disponible : [VERSION]</string> - <string name="LoginFailedRequiredUpdate">Mise à jour du client requise : [VERSION]</string> - <string name="LoginFailedAlreadyLoggedIn">L'agent est déjà connecté.</string> - <string name="LoginFailedAuthenticationFailed">Désolé ! La connexion a échoué. +http://secondlife.com/viewer-access-faq + </string> + <string name="LoginIntermediateOptionalUpdateAvailable"> + Mise à jour facultative du client disponible : [VERSION] + </string> + <string name="LoginFailedRequiredUpdate"> + Mise à jour du client requise : [VERSION] + </string> + <string name="LoginFailedAlreadyLoggedIn"> + L'agent est déjà connecté. + </string> + <string name="LoginFailedAuthenticationFailed"> + Désolé ! La connexion a échoué. Veuillez vérifier que les éléments ci-dessous ont été correctement saisis : * Nom d'utilisateur (par exemple, bobsmith12 ou steller.sunshine) * Mot de passe -Assurez-vous également que la touche Verr. maj n'est pas activée.</string> - <string name="LoginFailedPasswordChanged">Votre mot de passe a été modifié pour des raisons de sécurité. +Assurez-vous également que la touche Verr. maj n'est pas activée. + </string> + <string name="LoginFailedPasswordChanged"> + Votre mot de passe a été modifié pour des raisons de sécurité. Veuillez accéder à votre compte à la page http://secondlife.com/password et répondre à la question de sécurité afin de réinitialiser votre mot de passe. -Nous vous prions de nous excuser pour la gêne occasionnée.</string> - <string name="LoginFailedPasswordReset">Vous allez devoir réinitialiser votre mot de passe suite à quelques changements effectués sur notre système. +Nous vous prions de nous excuser pour la gêne occasionnée. + </string> + <string name="LoginFailedPasswordReset"> + Vous allez devoir réinitialiser votre mot de passe suite à quelques changements effectués sur notre système. Pour cela, accédez à votre compte à la page http://secondlife.com/password et répondez à la question de sécurité. Votre mot de passe sera réinitialisé. -Nous vous prions de nous excuser pour la gêne occasionnée.</string> - <string name="LoginFailedEmployeesOnly">Second Life est temporairement fermé pour des raisons de maintenance. +Nous vous prions de nous excuser pour la gêne occasionnée. + </string> + <string name="LoginFailedEmployeesOnly"> + Second Life est temporairement fermé pour des raisons de maintenance. Seuls les employés peuvent actuellement y accéder. -Consultez la page www.secondlife.com/status pour plus d'informations.</string> - <string name="LoginFailedPremiumOnly">Les connexions à Second Life sont temporairement limitées afin de s'assurer que l'expérience des utilisateurs présents dans le monde virtuel soit optimale. +Consultez la page www.secondlife.com/status pour plus d'informations. + </string> + <string name="LoginFailedPremiumOnly"> + Les connexions à Second Life sont temporairement limitées afin de s'assurer que l'expérience des utilisateurs présents dans le monde virtuel soit optimale. -Les personnes disposant de comptes gratuits ne pourront pas accéder à Second Life pendant ce temps afin de permettre à celles qui ont payé pour pouvoir utiliser Second Life de le faire.</string> - <string name="LoginFailedComputerProhibited">Impossible d'accéder à Second Life depuis cet ordinateur. +Les personnes disposant de comptes gratuits ne pourront pas accéder à Second Life pendant ce temps afin de permettre à celles qui ont payé pour pouvoir utiliser Second Life de le faire. + </string> + <string name="LoginFailedComputerProhibited"> + Impossible d'accéder à Second Life depuis cet ordinateur. Si vous pensez qu'il s'agit d'une erreur, contactez -l'Assistance à l'adresse suivante : support@secondlife.com.</string> - <string name="LoginFailedAcountSuspended">Votre compte est inaccessible jusqu'à -[TIME], heure du Pacifique.</string> - <string name="LoginFailedAccountDisabled">Impossible de traiter votre demande à l'heure actuelle. -Pour obtenir de l'aide, veuillez contacter l'Assistance Second Life à la page suivante : http://support.secondlife.com.</string> - <string name="LoginFailedTransformError">Incohérence des données lors de la connexion. -Veuillez contacter support@secondlife.com.</string> - <string name="LoginFailedAccountMaintenance">Des opérations de maintenance mineures sont actuellement effectuées sur votre compte. +l'Assistance à l'adresse suivante : support@secondlife.com. + </string> + <string name="LoginFailedAcountSuspended"> + Votre compte est inaccessible jusqu'à +[TIME], heure du Pacifique. + </string> + <string name="LoginFailedAccountDisabled"> + Impossible de traiter votre demande à l'heure actuelle. +Pour obtenir de l'aide, veuillez contacter l'Assistance Second Life à la page suivante : http://support.secondlife.com. + </string> + <string name="LoginFailedTransformError"> + Incohérence des données lors de la connexion. +Veuillez contacter support@secondlife.com. + </string> + <string name="LoginFailedAccountMaintenance"> + Des opérations de maintenance mineures sont actuellement effectuées sur votre compte. Votre compte est inaccessible jusqu'à [TIME], heure du Pacifique. -Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com</string> - <string name="LoginFailedPendingLogoutFault">Le simulateur a renvoyé une erreur en réponse à la demande de déconnexion.</string> - <string name="LoginFailedPendingLogout">Le système est en train de vous déconnecter. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LoginFailedUnableToCreateSession">Impossible de créer de session valide.</string> - <string name="LoginFailedUnableToConnectToSimulator">Impossible de se connecter à un simulateur.</string> - <string name="LoginFailedRestrictedHours">Votre compte permet uniquement d'accéder à Second Life +Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com + </string> + <string name="LoginFailedPendingLogoutFault"> + Le simulateur a renvoyé une erreur en réponse à la demande de déconnexion. + </string> + <string name="LoginFailedPendingLogout"> + Le système est en train de vous déconnecter. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LoginFailedUnableToCreateSession"> + Impossible de créer de session valide. + </string> + <string name="LoginFailedUnableToConnectToSimulator"> + Impossible de se connecter à un simulateur. + </string> + <string name="LoginFailedRestrictedHours"> + Votre compte permet uniquement d'accéder à Second Life entre [START] et [END], heure du Pacifique. Veuillez réessayer au cours de la période indiquée. -Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com</string> - <string name="LoginFailedIncorrectParameters">Paramètres incorrects. -Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com</string> - <string name="LoginFailedFirstNameNotAlphanumeric">Le paramètre Prénom doit être alphanumérique. -Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com</string> - <string name="LoginFailedLastNameNotAlphanumeric">Le paramètre Nom doit être alphanumérique. -Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com</string> - <string name="LogoutFailedRegionGoingOffline">La région est en train d'être mise hors ligne. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LogoutFailedAgentNotInRegion">Agent absent de la région. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LogoutFailedPendingLogin">Une autre session était en cours d'ouverture au sein de la région. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LogoutFailedLoggingOut">La session précédente était en cours de fermeture au sein de la région. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LogoutFailedStillLoggingOut">Fermeture de la session précédente toujours en cours pour la région. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LogoutSucceeded">Dernière session fermée au sein de la région. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LogoutFailedLogoutBegun">Processus de déconnexion commencé pour la région. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="LoginFailedLoggingOutSession">Le système a commencé à fermer votre dernière session. -Veuillez réessayer de vous connecter dans une minute.</string> - <string name="AgentLostConnection">Il y a peut-être des problèmes techniques dans cette région. Veuillez vérifier votre connexion Internet.</string> - <string name="SavingSettings">Enregistrement des paramètres...</string> - <string name="LoggingOut">Déconnexion...</string> - <string name="ShuttingDown">Arrêt en cours...</string> - <string name="YouHaveBeenDisconnected">Vous avez été déconnecté de la région où vous étiez.</string> - <string name="SentToInvalidRegion">Vous avez été transféré vers une région non valide.</string> - <string name="TestingDisconnect">Test de déconnexion du client</string> - <string name="SocialFacebookConnecting">Connexion à Facebook…</string> - <string name="SocialFacebookPosting">Publication…</string> - <string name="SocialFacebookDisconnecting">Déconnexion de Facebook…</string> - <string name="SocialFacebookErrorConnecting">Un problème est survenu lors de la connexion à Facebook.</string> - <string name="SocialFacebookErrorPosting">Un problème est survenu lors de la publication sur Facebook.</string> - <string name="SocialFacebookErrorDisconnecting">Un problème est survenu lors de la déconnexion à Facebook.</string> - <string name="SocialFlickrConnecting">Connexion à Flickr...</string> - <string name="SocialFlickrPosting">Publication…</string> - <string name="SocialFlickrDisconnecting">Déconnexion de Flickr...</string> - <string name="SocialFlickrErrorConnecting">Un problème est survenu lors de la connexion à Flickr.</string> - <string name="SocialFlickrErrorPosting">Un problème est survenu lors de la publication sur Flickr.</string> - <string name="SocialFlickrErrorDisconnecting">Un problème est survenu lors de la déconnexion de Flickr.</string> - <string name="SocialTwitterConnecting">Connexion à Twitter...</string> - <string name="SocialTwitterPosting">Publication…</string> - <string name="SocialTwitterDisconnecting">Déconnexion de Twitter...</string> - <string name="SocialTwitterErrorConnecting">Un problème est survenu lors de la connexion à Twitter.</string> - <string name="SocialTwitterErrorPosting">Un problème est survenu lors de la publication sur Twitter.</string> - <string name="SocialTwitterErrorDisconnecting">Un problème est survenu lors de la déconnexion de Twitter.</string> - <string name="BlackAndWhite">Noir et blanc</string> - <string name="Colors1970">Couleurs des années 1970</string> - <string name="Intense">Intense</string> - <string name="Newspaper">Presse</string> - <string name="Sepia">Sépia</string> - <string name="Spotlight">Projecteur</string> - <string name="Video">Vidéo</string> - <string name="Autocontrast">Contraste automatique</string> - <string name="LensFlare">Halo</string> - <string name="Miniature">Miniature</string> - <string name="Toycamera">Toy Camera</string> - <string name="TooltipPerson">Personne</string> - <string name="TooltipNoName">(pas de nom)</string> - <string name="TooltipOwner">Propriétaire :</string> - <string name="TooltipPublic">Public</string> - <string name="TooltipIsGroup">(Groupe)</string> - <string name="TooltipForSaleL$">À vendre : [AMOUNT] L$</string> - <string name="TooltipFlagGroupBuild">Contruction de groupe</string> - <string name="TooltipFlagNoBuild">Pas de construction</string> - <string name="TooltipFlagNoEdit">Contruction de groupe</string> - <string name="TooltipFlagNotSafe">Non sécurisé</string> - <string name="TooltipFlagNoFly">Interdiction de voler</string> - <string name="TooltipFlagGroupScripts">Scripts de groupe</string> - <string name="TooltipFlagNoScripts">Pas de scripts</string> - <string name="TooltipLand">Terrain :</string> - <string name="TooltipMustSingleDrop">Impossible de faire glisser plus d'un objet ici</string> - <string name="TooltipTooManyWearables">Vous ne pouvez pas porter un dossier contenant plus de [AMOUNT] articles. Vous pouvez modifier cette limite dans Avancé > Afficher les paramètres de débogage > WearFolderLimit.</string> +Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com + </string> + <string name="LoginFailedIncorrectParameters"> + Paramètres incorrects. +Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com + </string> + <string name="LoginFailedFirstNameNotAlphanumeric"> + Le paramètre Prénom doit être alphanumérique. +Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com + </string> + <string name="LoginFailedLastNameNotAlphanumeric"> + Le paramètre Nom doit être alphanumérique. +Si vous pensez qu'il s'agit d'une erreur, contactez l'Assistance à l'adresse suivante : support@secondlife.com + </string> + <string name="LogoutFailedRegionGoingOffline"> + La région est en train d'être mise hors ligne. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LogoutFailedAgentNotInRegion"> + Agent absent de la région. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LogoutFailedPendingLogin"> + Une autre session était en cours d'ouverture au sein de la région. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LogoutFailedLoggingOut"> + La session précédente était en cours de fermeture au sein de la région. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LogoutFailedStillLoggingOut"> + Fermeture de la session précédente toujours en cours pour la région. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LogoutSucceeded"> + Dernière session fermée au sein de la région. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LogoutFailedLogoutBegun"> + Processus de déconnexion commencé pour la région. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="LoginFailedLoggingOutSession"> + Le système a commencé à fermer votre dernière session. +Veuillez réessayer de vous connecter dans une minute. + </string> + <string name="AgentLostConnection"> + Il y a peut-être des problèmes techniques dans cette région. Veuillez vérifier votre connexion Internet. + </string> + <string name="SavingSettings"> + Enregistrement des paramètres... + </string> + <string name="LoggingOut"> + Déconnexion... + </string> + <string name="ShuttingDown"> + Arrêt en cours... + </string> + <string name="YouHaveBeenDisconnected"> + Vous avez été déconnecté de la région où vous étiez. + </string> + <string name="SentToInvalidRegion"> + Vous avez été transféré vers une région non valide. + </string> + <string name="TestingDisconnect"> + Test de déconnexion du client + </string> + <string name="SocialFacebookConnecting"> + Connexion à Facebook… + </string> + <string name="SocialFacebookPosting"> + Publication… + </string> + <string name="SocialFacebookDisconnecting"> + Déconnexion de Facebook… + </string> + <string name="SocialFacebookErrorConnecting"> + Un problème est survenu lors de la connexion à Facebook. + </string> + <string name="SocialFacebookErrorPosting"> + Un problème est survenu lors de la publication sur Facebook. + </string> + <string name="SocialFacebookErrorDisconnecting"> + Un problème est survenu lors de la déconnexion à Facebook. + </string> + <string name="SocialFlickrConnecting"> + Connexion à Flickr... + </string> + <string name="SocialFlickrPosting"> + Publication… + </string> + <string name="SocialFlickrDisconnecting"> + Déconnexion de Flickr... + </string> + <string name="SocialFlickrErrorConnecting"> + Un problème est survenu lors de la connexion à Flickr. + </string> + <string name="SocialFlickrErrorPosting"> + Un problème est survenu lors de la publication sur Flickr. + </string> + <string name="SocialFlickrErrorDisconnecting"> + Un problème est survenu lors de la déconnexion de Flickr. + </string> + <string name="SocialTwitterConnecting"> + Connexion à Twitter... + </string> + <string name="SocialTwitterPosting"> + Publication… + </string> + <string name="SocialTwitterDisconnecting"> + Déconnexion de Twitter... + </string> + <string name="SocialTwitterErrorConnecting"> + Un problème est survenu lors de la connexion à Twitter. + </string> + <string name="SocialTwitterErrorPosting"> + Un problème est survenu lors de la publication sur Twitter. + </string> + <string name="SocialTwitterErrorDisconnecting"> + Un problème est survenu lors de la déconnexion de Twitter. + </string> + <string name="BlackAndWhite"> + Noir et blanc + </string> + <string name="Colors1970"> + Couleurs des années 1970 + </string> + <string name="Intense"> + Intense + </string> + <string name="Newspaper"> + Presse + </string> + <string name="Sepia"> + Sépia + </string> + <string name="Spotlight"> + Projecteur + </string> + <string name="Video"> + Vidéo + </string> + <string name="Autocontrast"> + Contraste automatique + </string> + <string name="LensFlare"> + Halo + </string> + <string name="Miniature"> + Miniature + </string> + <string name="Toycamera"> + Toy Camera + </string> + <string name="TooltipPerson"> + Personne + </string> + <string name="TooltipNoName"> + (pas de nom) + </string> + <string name="TooltipOwner"> + Propriétaire : + </string> + <string name="TooltipPublic"> + Public + </string> + <string name="TooltipIsGroup"> + (Groupe) + </string> + <string name="TooltipForSaleL$"> + À vendre : [AMOUNT] L$ + </string> + <string name="TooltipFlagGroupBuild"> + Contruction de groupe + </string> + <string name="TooltipFlagNoBuild"> + Pas de construction + </string> + <string name="TooltipFlagNoEdit"> + Contruction de groupe + </string> + <string name="TooltipFlagNotSafe"> + Non sécurisé + </string> + <string name="TooltipFlagNoFly"> + Interdiction de voler + </string> + <string name="TooltipFlagGroupScripts"> + Scripts de groupe + </string> + <string name="TooltipFlagNoScripts"> + Pas de scripts + </string> + <string name="TooltipLand"> + Terrain : + </string> + <string name="TooltipMustSingleDrop"> + Impossible de faire glisser plus d'un objet ici + </string> + <string name="TooltipTooManyWearables"> + Vous ne pouvez pas porter un dossier contenant plus de [AMOUNT] articles. Vous pouvez modifier cette limite dans Avancé > Afficher les paramètres de débogage > WearFolderLimit. + </string> <string name="TooltipPrice" value="[AMOUNT] L$ :"/> - <string name="TooltipSLIcon">Il s’agit d’un lien vers une page dans le domaine officiel SecondLife.com ou LindenLab.com.</string> - <string name="TooltipOutboxDragToWorld">Vous ne pouvez pas rezzer (charger) des articles du dossier Annonces de la Place de marché</string> - <string name="TooltipOutboxWorn">Vous ne pouvez pas mettre d'articles que vous portez dans le dossier Annonces de la Place du marché</string> - <string name="TooltipOutboxFolderLevels">Le niveau de dossiers imbriqués dépasse [AMOUNT]. Diminuez le nombre de niveaux de dossiers imbriqués dans d'autres dossiers. Si nécessaire, placez certains articles dans une boîte.</string> - <string name="TooltipOutboxTooManyFolders">Le nombre de sous-dossiers dépasse [AMOUNT]. Diminuez le nombre de sous-dossiers dans votre annonce. Si nécessaire, placez certains articles dans une boîte.</string> - <string name="TooltipOutboxTooManyObjects">Le nombre d'articles dépasse [AMOUNT]. Pour pouvoir vendre plus de [AMOUNT] articles au sein d'une même annonce, vous devez placer certains de ces articles dans une boîte.</string> - <string name="TooltipOutboxTooManyStockItems">Le nombre d'articles de stock dépasse [AMOUNT].</string> - <string name="TooltipOutboxCannotDropOnRoot">Vous pouvez uniquement déposer des articles ou des dossiers dans les onglets TOUS ou NON ASSOCIÉS. Sélectionnez l’un de ces onglets et déplacez à nouveau votre ou vos article ou dossiers.</string> - <string name="TooltipOutboxNoTransfer">Impossible de vendre ou de transférer un ou plusieurs de ces objets</string> - <string name="TooltipOutboxNotInInventory">Vous ne pouvez mettre sur la Place du marché que des articles de votre inventaire</string> - <string name="TooltipOutboxLinked">Vous ne pouvez pas mettre des articles ou dossiers liés sur la Place du marché</string> - <string name="TooltipOutboxCallingCard">Vous ne pouvez pas mettre des cartes de visite sur la Place du marché</string> - <string name="TooltipOutboxDragActive">vous ne pouvez pas déplacer une annonce publiée</string> - <string name="TooltipOutboxCannotMoveRoot">Vous ne pouvez pas déplacer le dossier racine des annonces de la Place du marché</string> - <string name="TooltipOutboxMixedStock">tous les articles d'un dossier de stock doivent avoir le même type et droit</string> - <string name="TooltipDragOntoOwnChild">Impossible de déplacer un dossier vers son enfant</string> - <string name="TooltipDragOntoSelf">Impossible de déplacer un dossier vers lui-même</string> - <string name="TooltipHttpUrl">Cliquez pour afficher cette page web</string> - <string name="TooltipSLURL">Cliquez pour en savoir plus sur cet endroit</string> - <string name="TooltipAgentUrl">Cliquez pour afficher le profil de ce résident</string> - <string name="TooltipAgentInspect">En savoir plus sur ce résident</string> - <string name="TooltipAgentMute">Cliquer pour ignorer ce résident</string> - <string name="TooltipAgentUnmute">Cliquer pour ne plus ignorer ce résident</string> - <string name="TooltipAgentIM">Cliquer pour envoyer un IM à ce résident</string> - <string name="TooltipAgentPay">Cliquer pour payer ce résident</string> - <string name="TooltipAgentOfferTeleport">Cliquer pour proposer une téléportation à ce résident</string> - <string name="TooltipAgentRequestFriend">Cliquer pour demander à ce résident d'être votre ami</string> - <string name="TooltipGroupUrl">Cliquez pour afficher la description de ce groupe</string> - <string name="TooltipEventUrl">Cliquez pour afficher la description de cet événement</string> - <string name="TooltipClassifiedUrl">Cliquez pour afficher cette petite annonce</string> - <string name="TooltipParcelUrl">Cliquez pour afficher la description de cette parcelle</string> - <string name="TooltipTeleportUrl">Cliquez pour vous téléporter à cet endroit</string> - <string name="TooltipObjectIMUrl">Cliquez pour afficher la description de cet objet</string> - <string name="TooltipMapUrl">Cliquez pour voir cet emplacement sur la carte</string> - <string name="TooltipSLAPP">Cliquez pour exécuter la commande secondlife://</string> + <string name="TooltipSLIcon"> + Il s’agit d’un lien vers une page dans le domaine officiel SecondLife.com ou LindenLab.com. + </string> + <string name="TooltipOutboxDragToWorld"> + Vous ne pouvez pas rezzer (charger) des articles du dossier Annonces de la Place de marché + </string> + <string name="TooltipOutboxWorn"> + Vous ne pouvez pas mettre d'articles que vous portez dans le dossier Annonces de la Place du marché + </string> + <string name="TooltipOutboxFolderLevels"> + Le niveau de dossiers imbriqués dépasse [AMOUNT]. Diminuez le nombre de niveaux de dossiers imbriqués dans d'autres dossiers. Si nécessaire, placez certains articles dans une boîte. + </string> + <string name="TooltipOutboxTooManyFolders"> + Le nombre de sous-dossiers dépasse [AMOUNT]. Diminuez le nombre de sous-dossiers dans votre annonce. Si nécessaire, placez certains articles dans une boîte. + </string> + <string name="TooltipOutboxTooManyObjects"> + Le nombre d'articles dépasse [AMOUNT]. Pour pouvoir vendre plus de [AMOUNT] articles au sein d'une même annonce, vous devez placer certains de ces articles dans une boîte. + </string> + <string name="TooltipOutboxTooManyStockItems"> + Le nombre d'articles de stock dépasse [AMOUNT]. + </string> + <string name="TooltipOutboxCannotDropOnRoot"> + Vous pouvez uniquement déposer des articles ou des dossiers dans les onglets TOUS ou NON ASSOCIÉS. Sélectionnez l’un de ces onglets et déplacez à nouveau votre ou vos article ou dossiers. + </string> + <string name="TooltipOutboxNoTransfer"> + Impossible de vendre ou de transférer un ou plusieurs de ces objets + </string> + <string name="TooltipOutboxNotInInventory"> + Vous ne pouvez mettre sur la Place du marché que des articles de votre inventaire + </string> + <string name="TooltipOutboxLinked"> + Vous ne pouvez pas mettre des articles ou dossiers liés sur la Place du marché + </string> + <string name="TooltipOutboxCallingCard"> + Vous ne pouvez pas mettre des cartes de visite sur la Place du marché + </string> + <string name="TooltipOutboxDragActive"> + vous ne pouvez pas déplacer une annonce publiée + </string> + <string name="TooltipOutboxCannotMoveRoot"> + Vous ne pouvez pas déplacer le dossier racine des annonces de la Place du marché + </string> + <string name="TooltipOutboxMixedStock"> + tous les articles d'un dossier de stock doivent avoir le même type et droit + </string> + <string name="TooltipDragOntoOwnChild"> + Impossible de déplacer un dossier vers son enfant + </string> + <string name="TooltipDragOntoSelf"> + Impossible de déplacer un dossier vers lui-même + </string> + <string name="TooltipHttpUrl"> + Cliquez pour afficher cette page web + </string> + <string name="TooltipSLURL"> + Cliquez pour en savoir plus sur cet endroit + </string> + <string name="TooltipAgentUrl"> + Cliquez pour afficher le profil de ce résident + </string> + <string name="TooltipAgentInspect"> + En savoir plus sur ce résident + </string> + <string name="TooltipAgentMute"> + Cliquer pour ignorer ce résident + </string> + <string name="TooltipAgentUnmute"> + Cliquer pour ne plus ignorer ce résident + </string> + <string name="TooltipAgentIM"> + Cliquer pour envoyer un IM à ce résident + </string> + <string name="TooltipAgentPay"> + Cliquer pour payer ce résident + </string> + <string name="TooltipAgentOfferTeleport"> + Cliquer pour proposer une téléportation à ce résident + </string> + <string name="TooltipAgentRequestFriend"> + Cliquer pour demander à ce résident d'être votre ami + </string> + <string name="TooltipGroupUrl"> + Cliquez pour afficher la description de ce groupe + </string> + <string name="TooltipEventUrl"> + Cliquez pour afficher la description de cet événement + </string> + <string name="TooltipClassifiedUrl"> + Cliquez pour afficher cette petite annonce + </string> + <string name="TooltipParcelUrl"> + Cliquez pour afficher la description de cette parcelle + </string> + <string name="TooltipTeleportUrl"> + Cliquez pour vous téléporter à cet endroit + </string> + <string name="TooltipObjectIMUrl"> + Cliquez pour afficher la description de cet objet + </string> + <string name="TooltipMapUrl"> + Cliquez pour voir cet emplacement sur la carte + </string> + <string name="TooltipSLAPP"> + Cliquez pour exécuter la commande secondlife:// + </string> <string name="CurrentURL" value=" URL actuelle : [CurrentURL]"/> - <string name="TooltipEmail">Cliquez pour composer un message</string> - <string name="SLurlLabelTeleport">Me téléporter vers</string> - <string name="SLurlLabelShowOnMap">Afficher la carte pour</string> - <string name="SLappAgentMute">Ignorer</string> - <string name="SLappAgentUnmute">Ne plus ignorer</string> - <string name="SLappAgentIM">IM</string> - <string name="SLappAgentPay">Payer</string> - <string name="SLappAgentOfferTeleport">Proposer une téléportation à</string> - <string name="SLappAgentRequestFriend">Demande d'amitié</string> - <string name="SLappAgentRemoveFriend">Suppression d'un ami</string> - <string name="BUTTON_CLOSE_DARWIN">Fermer (⌘W)</string> - <string name="BUTTON_CLOSE_WIN">Fermer (Ctrl+W)</string> - <string name="BUTTON_CLOSE_CHROME">Fermer</string> - <string name="BUTTON_RESTORE">Restaurer</string> - <string name="BUTTON_MINIMIZE">Minimiser</string> - <string name="BUTTON_TEAR_OFF">Réduire</string> - <string name="BUTTON_DOCK">Attacher</string> - <string name="BUTTON_HELP">Afficher l'aide</string> - <string name="TooltipNotecardNotAllowedTypeDrop">Les éléments de ce type ne peuvent pas être attachés -aux notes de cette région.</string> - <string name="TooltipNotecardOwnerRestrictedDrop">Seuls des éléments avec des autorisation + <string name="TooltipEmail"> + Cliquez pour composer un message + </string> + <string name="SLurlLabelTeleport"> + Me téléporter vers + </string> + <string name="SLurlLabelShowOnMap"> + Afficher la carte pour + </string> + <string name="SLappAgentMute"> + Ignorer + </string> + <string name="SLappAgentUnmute"> + Ne plus ignorer + </string> + <string name="SLappAgentIM"> + IM + </string> + <string name="SLappAgentPay"> + Payer + </string> + <string name="SLappAgentOfferTeleport"> + Proposer une téléportation à + </string> + <string name="SLappAgentRequestFriend"> + Demande d'amitié + </string> + <string name="SLappAgentRemoveFriend"> + Suppression d'un ami + </string> + <string name="BUTTON_CLOSE_DARWIN"> + Fermer (⌘W) + </string> + <string name="BUTTON_CLOSE_WIN"> + Fermer (Ctrl+W) + </string> + <string name="BUTTON_CLOSE_CHROME"> + Fermer + </string> + <string name="BUTTON_RESTORE"> + Restaurer + </string> + <string name="BUTTON_MINIMIZE"> + Minimiser + </string> + <string name="BUTTON_TEAR_OFF"> + Réduire + </string> + <string name="BUTTON_DOCK"> + Attacher + </string> + <string name="BUTTON_HELP"> + Afficher l'aide + </string> + <string name="TooltipNotecardNotAllowedTypeDrop"> + Les éléments de ce type ne peuvent pas être attachés +aux notes de cette région. + </string> + <string name="TooltipNotecardOwnerRestrictedDrop"> + Seuls des éléments avec des autorisation illimitées pour le 'prochain propriétaire' -peuvent être joints aux notes.</string> - <string name="Searching">Recherche...</string> - <string name="NoneFound">Aucun résultat.</string> - <string name="RetrievingData">En cours d'extraction...</string> - <string name="ReleaseNotes">Notes de version</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> - <string name="LoadingData">Chargement...</string> - <string name="AvatarNameNobody">(personne)</string> - <string name="AvatarNameWaiting">(en attente)</string> - <string name="AvatarNameMultiple">(multiple)</string> - <string name="GroupNameNone">(aucun)</string> - <string name="AssetErrorNone">Aucune erreur</string> - <string name="AssetErrorRequestFailed">Requête de l'actif : échec</string> - <string name="AssetErrorNonexistentFile">Requête de l'actif : fichier inexistant</string> - <string name="AssetErrorNotInDatabase">Requête de l'actif : actif introuvable dans la base de données</string> - <string name="AssetErrorEOF">Fin du ficher</string> - <string name="AssetErrorCannotOpenFile">Impossible d'ouvrir le fichier</string> - <string name="AssetErrorFileNotFound">Fichier introuvable</string> - <string name="AssetErrorTCPTimeout">Délai d'attente du transfert du fichier dépassé</string> - <string name="AssetErrorCircuitGone">Disparition du circuit</string> - <string name="AssetErrorPriceMismatch">Il y a une différence de prix entre le client et le serveur</string> - <string name="AssetErrorUnknownStatus">Statut inconnu</string> - <string name="AssetUploadServerUnreacheble">Service inaccessible.</string> - <string name="AssetUploadServerDifficulties">Le serveur rencontres des difficultés imprévues.</string> - <string name="AssetUploadServerUnavaliable">Services non disponible ou la durée du chargement est dépassée.</string> - <string name="AssetUploadRequestInvalid">Erreur dans la demande de chargement. Veuillez consulter le site : -http://secondlife.com/support pour vous aider à résoudre ce problème.</string> - <string name="SettingValidationError">Échec de la validation pour l'importation des paramètres [NAME]</string> - <string name="SettingImportFileError">Impossible d'ouvre le fichier [FILE]</string> - <string name="SettingParseFileError">Impossible d'ouvre le fichier [FILE]</string> - <string name="SettingTranslateError">Impossible de traduit les paramètres windlight hérités [NAME]</string> - <string name="texture">texture</string> - <string name="sound">son</string> - <string name="calling card">carte de visite</string> - <string name="landmark">repère</string> - <string name="legacy script">script (ancienne version)</string> - <string name="clothing">habits</string> - <string name="object">objet</string> - <string name="note card">note</string> - <string name="folder">dossier</string> - <string name="root">racine</string> - <string name="lsl2 script">script LSL2</string> - <string name="lsl bytecode">bytecode LSL</string> - <string name="tga texture">texture tga</string> - <string name="body part">partie du corps</string> - <string name="snapshot">photo</string> - <string name="lost and found">Objets trouvés</string> - <string name="targa image">image targa</string> - <string name="trash">Corbeille</string> - <string name="jpeg image">image jpeg</string> - <string name="animation">animation</string> - <string name="gesture">geste</string> - <string name="simstate">simstate</string> - <string name="favorite">favori</string> - <string name="symbolic link">lien</string> - <string name="symbolic folder link">lien du dossier</string> - <string name="settings blob">paramètres</string> - <string name="mesh">maillage</string> - <string name="AvatarEditingAppearance">(Apparence en cours de modification)</string> - <string name="AvatarAway">Absent</string> - <string name="AvatarDoNotDisturb">Ne pas déranger</string> - <string name="AvatarMuted">Bloqué(e)</string> - <string name="anim_express_afraid">Effrayé</string> - <string name="anim_express_anger">En colère</string> - <string name="anim_away">Absent</string> - <string name="anim_backflip">Salto arrière</string> - <string name="anim_express_laugh">Rire en se tenant le ventre</string> - <string name="anim_express_toothsmile">Grand sourire</string> - <string name="anim_blowkiss">Envoyer un baiser</string> - <string name="anim_express_bored">Bailler d'ennui</string> - <string name="anim_bow">S'incliner</string> - <string name="anim_clap">Applaudir</string> - <string name="anim_courtbow">Révérence de cour</string> - <string name="anim_express_cry">Pleurer</string> - <string name="anim_dance1">Danse 1</string> - <string name="anim_dance2">Danse 2</string> - <string name="anim_dance3">Danse 3</string> - <string name="anim_dance4">Danse 4</string> - <string name="anim_dance5">Danse 5</string> - <string name="anim_dance6">Danse 6</string> - <string name="anim_dance7">Danse 7</string> - <string name="anim_dance8">Danse 8</string> - <string name="anim_express_disdain">Mépris</string> - <string name="anim_drink">Boire</string> - <string name="anim_express_embarrased">Gêne</string> - <string name="anim_angry_fingerwag">Désapprobation</string> - <string name="anim_fist_pump">Victoire</string> - <string name="anim_yoga_float">Yoga</string> - <string name="anim_express_frown">Froncer les sourcils</string> - <string name="anim_impatient">Impatient</string> - <string name="anim_jumpforjoy">Sauter de joie</string> - <string name="anim_kissmybutt">Va te faire voir !</string> - <string name="anim_express_kiss">Envoyer un baiser</string> - <string name="anim_laugh_short">Rire</string> - <string name="anim_musclebeach">Montrer ses muscles</string> - <string name="anim_no_unhappy">Non (mécontent)</string> - <string name="anim_no_head">Non</string> - <string name="anim_nyanya">Na na na na nère</string> - <string name="anim_punch_onetwo">Gauche-droite</string> - <string name="anim_express_open_mouth">Bouche ouverte</string> - <string name="anim_peace">Paix</string> - <string name="anim_point_you">Montrer quelqu'un du doigt</string> - <string name="anim_point_me">Se montrer du doigt</string> - <string name="anim_punch_l">Gauche</string> - <string name="anim_punch_r">Droite</string> - <string name="anim_rps_countdown">Compter (pierre-papier-ciseaux)</string> - <string name="anim_rps_paper">Papier (pierre-papier-ciseaux)</string> - <string name="anim_rps_rock">Pierre (pierre-papier-ciseaux)</string> - <string name="anim_rps_scissors">Ciseaux (pierre-papier-ciseaux)</string> - <string name="anim_express_repulsed">Dégoût</string> - <string name="anim_kick_roundhouse_r">Coup de pied circulaire</string> - <string name="anim_express_sad">Triste</string> - <string name="anim_salute">Salut</string> - <string name="anim_shout">Crier</string> - <string name="anim_express_shrug">Hausser les épaules</string> - <string name="anim_express_smile">Sourire</string> - <string name="anim_smoke_idle">Fumer, immobile</string> - <string name="anim_smoke_inhale">Fumer, prendre une bouffée</string> - <string name="anim_smoke_throw_down">Fumer, jeter son mégot</string> - <string name="anim_express_surprise">Surprise</string> - <string name="anim_sword_strike_r">Coup d'épée</string> - <string name="anim_angry_tantrum">Caprice</string> - <string name="anim_express_tongue_out">Tirer la langue</string> - <string name="anim_hello">Faire signe</string> - <string name="anim_whisper">Chuchoter</string> - <string name="anim_whistle">Siffler</string> - <string name="anim_express_wink">Clin d'œil</string> - <string name="anim_wink_hollywood">Clin d'œil (Hollywood)</string> - <string name="anim_express_worry">Soucis</string> - <string name="anim_yes_happy">Oui (Joie)</string> - <string name="anim_yes_head">Oui</string> - <string name="multiple_textures">Multiples</string> - <string name="use_texture">Utiliser la texture</string> - <string name="manip_hint1">Faites glisser le curseur sur l'axe</string> - <string name="manip_hint2">pour le fixer sur la grille</string> - <string name="texture_loading">Chargement...</string> - <string name="worldmap_offline">Hors ligne</string> - <string name="worldmap_item_tooltip_format">[AREA] m² [PRICE] L$</string> - <string name="worldmap_results_none_found">Aucun résultat.</string> - <string name="Ok">OK</string> - <string name="Premature end of file">Fichier incomplet</string> - <string name="ST_NO_JOINT">Impossible de trouver ROOT ou JOINT.</string> - <string name="NearbyChatTitle">Chat près de moi</string> - <string name="NearbyChatLabel">(Chat près de moi)</string> - <string name="whisper">chuchote :</string> - <string name="shout">crie :</string> - <string name="ringing">Connexion au chat vocal du Monde en cours…</string> - <string name="connected">Connecté(e)</string> - <string name="unavailable">Voix non disponible à l'endroit où vous êtes</string> - <string name="hang_up">Déconnecté du chat vocal</string> - <string name="reconnect_nearby">Vous allez maintenant être reconnecté(e) au chat vocal près de vous.</string> - <string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', un objet appartenant à [OWNERNAME], situé dans [REGIONNAME] à [REGIONPOS], a reçu le droit de : [PERMISSIONS].</string> - <string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', un objet appartenant à [OWNERNAME], situé dans [REGIONNAME] à [REGIONPOS], n'a pas reçu le droit de : [PERMISSIONS].</string> - <string name="AdditionalPermissionsRequestHeader">Si vous autorisez un accès à votre compte, vous autorisez également l'objet à :</string> - <string name="ScriptTakeMoney">Débiter vos Linden dollars (L$)</string> - <string name="ActOnControlInputs">Utiliser vos touches de commandes</string> - <string name="RemapControlInputs">Reconfigurer vos touches de commandes</string> - <string name="AnimateYourAvatar">Animer votre avatar</string> - <string name="AttachToYourAvatar">Attacher à votre avatar</string> - <string name="ReleaseOwnership">Passer l'objet dans le domaine public (sans propriétaire)</string> - <string name="LinkAndDelink">Lier et délier d'autres objets</string> - <string name="AddAndRemoveJoints">Créer et supprimer des liens avec d'autres objets</string> - <string name="ChangePermissions">Modifier ses droits</string> - <string name="TrackYourCamera">Suivre votre caméra</string> - <string name="ControlYourCamera">Contrôler votre caméra</string> - <string name="TeleportYourAgent">Vous téléporter</string> - <string name="ForceSitAvatar">Forcez votre avatar à s’asseoir</string> - <string name="ChangeEnvSettings">Changer vos paramètres d'environnement</string> - <string name="NotConnected">Pas connecté(e)</string> - <string name="AgentNameSubst">(Vous)</string> +peuvent être joints aux notes. + </string> + <string name="Searching"> + Recherche... + </string> + <string name="NoneFound"> + Aucun résultat. + </string> + <string name="RetrievingData"> + En cours d'extraction... + </string> + <string name="ReleaseNotes"> + Notes de version + </string> + <string name="RELEASE_NOTES_BASE_URL"> + https://releasenotes.secondlife.com/viewer/ + </string> + <string name="LoadingData"> + Chargement... + </string> + <string name="AvatarNameNobody"> + (personne) + </string> + <string name="AvatarNameWaiting"> + (en attente) + </string> + <string name="AvatarNameMultiple"> + (multiple) + </string> + <string name="GroupNameNone"> + (aucun) + </string> + <string name="AssetErrorNone"> + Aucune erreur + </string> + <string name="AssetErrorRequestFailed"> + Requête de l'actif : échec + </string> + <string name="AssetErrorNonexistentFile"> + Requête de l'actif : fichier inexistant + </string> + <string name="AssetErrorNotInDatabase"> + Requête de l'actif : actif introuvable dans la base de données + </string> + <string name="AssetErrorEOF"> + Fin du ficher + </string> + <string name="AssetErrorCannotOpenFile"> + Impossible d'ouvrir le fichier + </string> + <string name="AssetErrorFileNotFound"> + Fichier introuvable + </string> + <string name="AssetErrorTCPTimeout"> + Délai d'attente du transfert du fichier dépassé + </string> + <string name="AssetErrorCircuitGone"> + Disparition du circuit + </string> + <string name="AssetErrorPriceMismatch"> + Il y a une différence de prix entre le client et le serveur + </string> + <string name="AssetErrorUnknownStatus"> + Statut inconnu + </string> + <string name="AssetUploadServerUnreacheble"> + Service inaccessible. + </string> + <string name="AssetUploadServerDifficulties"> + Le serveur rencontres des difficultés imprévues. + </string> + <string name="AssetUploadServerUnavaliable"> + Services non disponible ou la durée du chargement est dépassée. + </string> + <string name="AssetUploadRequestInvalid"> + Erreur dans la demande de chargement. Veuillez consulter le site : +http://secondlife.com/support pour vous aider à résoudre ce problème. + </string> + <string name="SettingValidationError"> + Échec de la validation pour l'importation des paramètres [NAME] + </string> + <string name="SettingImportFileError"> + Impossible d'ouvre le fichier [FILE] + </string> + <string name="SettingParseFileError"> + Impossible d'ouvre le fichier [FILE] + </string> + <string name="SettingTranslateError"> + Impossible de traduit les paramètres windlight hérités [NAME] + </string> + <string name="texture"> + texture + </string> + <string name="sound"> + son + </string> + <string name="calling card"> + carte de visite + </string> + <string name="landmark"> + repère + </string> + <string name="legacy script"> + script (ancienne version) + </string> + <string name="clothing"> + habits + </string> + <string name="object"> + objet + </string> + <string name="note card"> + note + </string> + <string name="folder"> + dossier + </string> + <string name="root"> + racine + </string> + <string name="lsl2 script"> + script LSL2 + </string> + <string name="lsl bytecode"> + bytecode LSL + </string> + <string name="tga texture"> + texture tga + </string> + <string name="body part"> + partie du corps + </string> + <string name="snapshot"> + photo + </string> + <string name="lost and found"> + Objets trouvés + </string> + <string name="targa image"> + image targa + </string> + <string name="trash"> + Corbeille + </string> + <string name="jpeg image"> + image jpeg + </string> + <string name="animation"> + animation + </string> + <string name="gesture"> + geste + </string> + <string name="simstate"> + simstate + </string> + <string name="favorite"> + favori + </string> + <string name="symbolic link"> + lien + </string> + <string name="symbolic folder link"> + lien du dossier + </string> + <string name="settings blob"> + paramètres + </string> + <string name="mesh"> + maillage + </string> + <string name="AvatarEditingAppearance"> + (Apparence en cours de modification) + </string> + <string name="AvatarAway"> + Absent + </string> + <string name="AvatarDoNotDisturb"> + Ne pas déranger + </string> + <string name="AvatarMuted"> + Bloqué(e) + </string> + <string name="anim_express_afraid"> + Effrayé + </string> + <string name="anim_express_anger"> + En colère + </string> + <string name="anim_away"> + Absent + </string> + <string name="anim_backflip"> + Salto arrière + </string> + <string name="anim_express_laugh"> + Rire en se tenant le ventre + </string> + <string name="anim_express_toothsmile"> + Grand sourire + </string> + <string name="anim_blowkiss"> + Envoyer un baiser + </string> + <string name="anim_express_bored"> + Bailler d'ennui + </string> + <string name="anim_bow"> + S'incliner + </string> + <string name="anim_clap"> + Applaudir + </string> + <string name="anim_courtbow"> + Révérence de cour + </string> + <string name="anim_express_cry"> + Pleurer + </string> + <string name="anim_dance1"> + Danse 1 + </string> + <string name="anim_dance2"> + Danse 2 + </string> + <string name="anim_dance3"> + Danse 3 + </string> + <string name="anim_dance4"> + Danse 4 + </string> + <string name="anim_dance5"> + Danse 5 + </string> + <string name="anim_dance6"> + Danse 6 + </string> + <string name="anim_dance7"> + Danse 7 + </string> + <string name="anim_dance8"> + Danse 8 + </string> + <string name="anim_express_disdain"> + Mépris + </string> + <string name="anim_drink"> + Boire + </string> + <string name="anim_express_embarrased"> + Gêne + </string> + <string name="anim_angry_fingerwag"> + Désapprobation + </string> + <string name="anim_fist_pump"> + Victoire + </string> + <string name="anim_yoga_float"> + Yoga + </string> + <string name="anim_express_frown"> + Froncer les sourcils + </string> + <string name="anim_impatient"> + Impatient + </string> + <string name="anim_jumpforjoy"> + Sauter de joie + </string> + <string name="anim_kissmybutt"> + Va te faire voir ! + </string> + <string name="anim_express_kiss"> + Envoyer un baiser + </string> + <string name="anim_laugh_short"> + Rire + </string> + <string name="anim_musclebeach"> + Montrer ses muscles + </string> + <string name="anim_no_unhappy"> + Non (mécontent) + </string> + <string name="anim_no_head"> + Non + </string> + <string name="anim_nyanya"> + Na na na na nère + </string> + <string name="anim_punch_onetwo"> + Gauche-droite + </string> + <string name="anim_express_open_mouth"> + Bouche ouverte + </string> + <string name="anim_peace"> + Paix + </string> + <string name="anim_point_you"> + Montrer quelqu'un du doigt + </string> + <string name="anim_point_me"> + Se montrer du doigt + </string> + <string name="anim_punch_l"> + Gauche + </string> + <string name="anim_punch_r"> + Droite + </string> + <string name="anim_rps_countdown"> + Compter (pierre-papier-ciseaux) + </string> + <string name="anim_rps_paper"> + Papier (pierre-papier-ciseaux) + </string> + <string name="anim_rps_rock"> + Pierre (pierre-papier-ciseaux) + </string> + <string name="anim_rps_scissors"> + Ciseaux (pierre-papier-ciseaux) + </string> + <string name="anim_express_repulsed"> + Dégoût + </string> + <string name="anim_kick_roundhouse_r"> + Coup de pied circulaire + </string> + <string name="anim_express_sad"> + Triste + </string> + <string name="anim_salute"> + Salut + </string> + <string name="anim_shout"> + Crier + </string> + <string name="anim_express_shrug"> + Hausser les épaules + </string> + <string name="anim_express_smile"> + Sourire + </string> + <string name="anim_smoke_idle"> + Fumer, immobile + </string> + <string name="anim_smoke_inhale"> + Fumer, prendre une bouffée + </string> + <string name="anim_smoke_throw_down"> + Fumer, jeter son mégot + </string> + <string name="anim_express_surprise"> + Surprise + </string> + <string name="anim_sword_strike_r"> + Coup d'épée + </string> + <string name="anim_angry_tantrum"> + Caprice + </string> + <string name="anim_express_tongue_out"> + Tirer la langue + </string> + <string name="anim_hello"> + Faire signe + </string> + <string name="anim_whisper"> + Chuchoter + </string> + <string name="anim_whistle"> + Siffler + </string> + <string name="anim_express_wink"> + Clin d'œil + </string> + <string name="anim_wink_hollywood"> + Clin d'œil (Hollywood) + </string> + <string name="anim_express_worry"> + Soucis + </string> + <string name="anim_yes_happy"> + Oui (Joie) + </string> + <string name="anim_yes_head"> + Oui + </string> + <string name="multiple_textures"> + Multiples + </string> + <string name="use_texture"> + Utiliser la texture + </string> + <string name="manip_hint1"> + Faites glisser le curseur sur l'axe + </string> + <string name="manip_hint2"> + pour le fixer sur la grille + </string> + <string name="texture_loading"> + Chargement... + </string> + <string name="worldmap_offline"> + Hors ligne + </string> + <string name="worldmap_item_tooltip_format"> + [AREA] m² [PRICE] L$ + </string> + <string name="worldmap_results_none_found"> + Aucun résultat. + </string> + <string name="Ok"> + OK + </string> + <string name="Premature end of file"> + Fichier incomplet + </string> + <string name="ST_NO_JOINT"> + Impossible de trouver ROOT ou JOINT. + </string> + <string name="NearbyChatTitle"> + Chat près de moi + </string> + <string name="NearbyChatLabel"> + (Chat près de moi) + </string> + <string name="whisper"> + chuchote : + </string> + <string name="shout"> + crie : + </string> + <string name="ringing"> + Connexion au chat vocal du Monde en cours… + </string> + <string name="connected"> + Connecté(e) + </string> + <string name="unavailable"> + Voix non disponible à l'endroit où vous êtes + </string> + <string name="hang_up"> + Déconnecté du chat vocal + </string> + <string name="reconnect_nearby"> + Vous allez maintenant être reconnecté(e) au chat vocal près de vous. + </string> + <string name="ScriptQuestionCautionChatGranted"> + '[OBJECTNAME]', un objet appartenant à [OWNERNAME], situé dans [REGIONNAME] à [REGIONPOS], a reçu le droit de : [PERMISSIONS]. + </string> + <string name="ScriptQuestionCautionChatDenied"> + '[OBJECTNAME]', un objet appartenant à [OWNERNAME], situé dans [REGIONNAME] à [REGIONPOS], n'a pas reçu le droit de : [PERMISSIONS]. + </string> + <string name="AdditionalPermissionsRequestHeader"> + Si vous autorisez un accès à votre compte, vous autorisez également l'objet à : + </string> + <string name="ScriptTakeMoney"> + Débiter vos Linden dollars (L$) + </string> + <string name="ActOnControlInputs"> + Utiliser vos touches de commandes + </string> + <string name="RemapControlInputs"> + Reconfigurer vos touches de commandes + </string> + <string name="AnimateYourAvatar"> + Animer votre avatar + </string> + <string name="AttachToYourAvatar"> + Attacher à votre avatar + </string> + <string name="ReleaseOwnership"> + Passer l'objet dans le domaine public (sans propriétaire) + </string> + <string name="LinkAndDelink"> + Lier et délier d'autres objets + </string> + <string name="AddAndRemoveJoints"> + Créer et supprimer des liens avec d'autres objets + </string> + <string name="ChangePermissions"> + Modifier ses droits + </string> + <string name="TrackYourCamera"> + Suivre votre caméra + </string> + <string name="ControlYourCamera"> + Contrôler votre caméra + </string> + <string name="TeleportYourAgent"> + Vous téléporter + </string> + <string name="ForceSitAvatar"> + Forcez votre avatar à s’asseoir + </string> + <string name="ChangeEnvSettings"> + Changer vos paramètres d'environnement + </string> + <string name="NotConnected"> + Pas connecté(e) + </string> + <string name="AgentNameSubst"> + (Vous) + </string> <string name="JoinAnExperience"/> - <string name="SilentlyManageEstateAccess">Supprimer les alertes lors de la gestion des listes d'accès aux domaines</string> - <string name="OverrideYourAnimations">Remplacer vos animations par défaut</string> - <string name="ScriptReturnObjects">Renvoyer les objets de votre part</string> - <string name="UnknownScriptPermission">(inconnu)</string> - <string name="SIM_ACCESS_PG">Général</string> - <string name="SIM_ACCESS_MATURE">Modéré</string> - <string name="SIM_ACCESS_ADULT">Adulte</string> - <string name="SIM_ACCESS_DOWN">Hors ligne</string> - <string name="SIM_ACCESS_MIN">Inconnu</string> - <string name="land_type_unknown">(inconnu)</string> - <string name="Estate / Full Region">Domaine / Région entière</string> - <string name="Estate / Homestead">Domaine / Homestead</string> - <string name="Mainland / Homestead">Continent / Homestead</string> - <string name="Mainland / Full Region">Continent / Région entière</string> - <string name="all_files">Tous fichiers</string> - <string name="sound_files">Sons</string> - <string name="animation_files">Animations</string> - <string name="image_files">Images</string> - <string name="save_file_verb">Enregistrer</string> - <string name="load_file_verb">Charger</string> - <string name="targa_image_files">Images Targa</string> - <string name="bitmap_image_files">Images Bitmap</string> - <string name="png_image_files">Images PNG</string> - <string name="save_texture_image_files">Images Targa ou PNG</string> - <string name="avi_movie_file">Fichier de film AVI</string> - <string name="xaf_animation_file">Fichier d'animation XAF</string> - <string name="xml_file">Fichier XML</string> - <string name="raw_file">Fichier RAW</string> - <string name="compressed_image_files">Images compressées</string> - <string name="load_files">Charger des fichiers</string> - <string name="choose_the_directory">Choisir le répertoire</string> - <string name="script_files">Scripts</string> - <string name="dictionary_files">Dictionnaires</string> - <string name="shape">Silhouette</string> - <string name="skin">Peau</string> - <string name="hair">Cheveux</string> - <string name="eyes">Yeux</string> - <string name="shirt">Chemise</string> - <string name="pants">Pantalon</string> - <string name="shoes">Chaussures</string> - <string name="socks">Chaussettes</string> - <string name="jacket">Veste</string> - <string name="gloves">Gants</string> - <string name="undershirt">Débardeur</string> - <string name="underpants">Caleçon</string> - <string name="skirt">Jupe</string> - <string name="alpha">Alpha</string> - <string name="tattoo">Tatouage</string> - <string name="universal">Universel</string> - <string name="physics">Propriétés physiques</string> - <string name="invalid">non valide</string> - <string name="none">aucun</string> - <string name="shirt_not_worn">Chemise non portée</string> - <string name="pants_not_worn">Pantalon non porté</string> - <string name="shoes_not_worn">Chaussures non portées</string> - <string name="socks_not_worn">Chaussettes non portées</string> - <string name="jacket_not_worn">Veste non portée</string> - <string name="gloves_not_worn">Gants non portés</string> - <string name="undershirt_not_worn">Débardeur non porté</string> - <string name="underpants_not_worn">Caleçon non porté</string> - <string name="skirt_not_worn">Jupe non portée</string> - <string name="alpha_not_worn">Alpha non porté</string> - <string name="tattoo_not_worn">Tatouage non porté</string> - <string name="universal_not_worn">Universel non porté</string> - <string name="physics_not_worn">Propriétés physiques non portées</string> - <string name="invalid_not_worn">non valide</string> - <string name="create_new_shape">Créer une nouvelle silhouette</string> - <string name="create_new_skin">Créer une nouvelle peau</string> - <string name="create_new_hair">Créer de nouveaux cheveux</string> - <string name="create_new_eyes">Créer de nouveaux yeux</string> - <string name="create_new_shirt">Créer une nouvelle chemise</string> - <string name="create_new_pants">Créer un nouveau pantalon</string> - <string name="create_new_shoes">Créer de nouvelles chaussures</string> - <string name="create_new_socks">Créer de nouvelles chaussettes</string> - <string name="create_new_jacket">Créer une nouvelle veste</string> - <string name="create_new_gloves">Créer de nouveaux gants</string> - <string name="create_new_undershirt">Créer un nouveau débardeur</string> - <string name="create_new_underpants">Créer un nouveau caleçon</string> - <string name="create_new_skirt">Créer une nouvelle jupe</string> - <string name="create_new_alpha">Créer un nouvel alpha</string> - <string name="create_new_tattoo">Créer un nouveau tatouage</string> - <string name="create_new_universal">Créer un nouvel environnement universel</string> - <string name="create_new_physics">Créer de nouvelles propriétés physiques</string> - <string name="create_new_invalid">non valide</string> - <string name="NewWearable">Nouv. [WEARABLE_ITEM]</string> - <string name="next">Suivant</string> - <string name="ok">OK</string> - <string name="GroupNotifyGroupNotice">Note au groupe</string> - <string name="GroupNotifyGroupNotices">Notices au groupe</string> - <string name="GroupNotifySentBy">Envoyée par</string> - <string name="GroupNotifyAttached">Pièce(s) jointe(s) :</string> - <string name="GroupNotifyViewPastNotices">Consultez les notices précédentes ou choisissez de ne plus recevoir ces messages ici.</string> - <string name="GroupNotifyOpenAttachment">Ouvrir pièce jointe</string> - <string name="GroupNotifySaveAttachment">Enregistrer la pièce jointe</string> - <string name="TeleportOffer">Offre de téléportation</string> - <string name="StartUpNotifications">De nouvelles notifications sont arrivées en votre absence.</string> - <string name="OverflowInfoChannelString">Vous avez %d notification(s) supplémentaire(s)</string> - <string name="BodyPartsRightArm">Bras droit</string> - <string name="BodyPartsHead">Tête</string> - <string name="BodyPartsLeftArm">Bras gauche</string> - <string name="BodyPartsLeftLeg">Jambe gauche</string> - <string name="BodyPartsTorso">Torse</string> - <string name="BodyPartsRightLeg">Jambe droite</string> - <string name="BodyPartsEnhancedSkeleton">Squelette amélioré</string> - <string name="GraphicsQualityLow">Faible</string> - <string name="GraphicsQualityMid">Moyen</string> - <string name="GraphicsQualityHigh">Élevé</string> - <string name="LeaveMouselook">Appuyez sur ESC pour quitter la vue subjective</string> - <string name="InventoryNoMatchingItems">Vous n'avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/all/[SEARCH_TERM] Rechercher].</string> - <string name="InventoryNoMatchingRecentItems">Avez-vous trouvé ce que vous cherchiez ? Essayez [secondlife:///app/inventory/filters Show filters].</string> - <string name="PlacesNoMatchingItems">Vous n'avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/places/[SEARCH_TERM] Rechercher].</string> - <string name="FavoritesNoMatchingItems">Faites glisser un repère ici pour l'ajouter à vos Favoris.</string> - <string name="MarketplaceNoMatchingItems">Aucun article trouvé. Vérifiez l'orthographe de votre chaîne de recherche et réessayez.</string> - <string name="InventoryNoTexture">Vous n'avez pas de copie de cette texture dans votre inventaire</string> - <string name="InventoryInboxNoItems">Les achats que vous avez effectués sur la Place du marché s'affichent ici. Vous pouvez alors les faire glisser vers votre inventaire afin de les utiliser.</string> - <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> - <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3</string> - <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string> - <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string> - <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string> - <string name="InventoryPlayAnimationTooltip">Ouvrir la fenêtre avec les options Jeu</string> - <string name="InventoryPlayGestureTooltip">Exécuter le geste sélectionné dans le monde virtuel.</string> - <string name="InventoryPlaySoundTooltip">Ouvrir la fenêtre avec les options Jeu</string> - <string name="InventoryOutboxNotMerchantTitle">Tout le monde peut vendre des articles sur la Place du marché.</string> + <string name="SilentlyManageEstateAccess"> + Supprimer les alertes lors de la gestion des listes d'accès aux domaines + </string> + <string name="OverrideYourAnimations"> + Remplacer vos animations par défaut + </string> + <string name="ScriptReturnObjects"> + Renvoyer les objets de votre part + </string> + <string name="UnknownScriptPermission"> + (inconnu) + </string> + <string name="SIM_ACCESS_PG"> + Général + </string> + <string name="SIM_ACCESS_MATURE"> + Modéré + </string> + <string name="SIM_ACCESS_ADULT"> + Adulte + </string> + <string name="SIM_ACCESS_DOWN"> + Hors ligne + </string> + <string name="SIM_ACCESS_MIN"> + Inconnu + </string> + <string name="land_type_unknown"> + (inconnu) + </string> + <string name="Estate / Full Region"> + Domaine / Région entière + </string> + <string name="Estate / Homestead"> + Domaine / Homestead + </string> + <string name="Mainland / Homestead"> + Continent / Homestead + </string> + <string name="Mainland / Full Region"> + Continent / Région entière + </string> + <string name="all_files"> + Tous fichiers + </string> + <string name="sound_files"> + Sons + </string> + <string name="animation_files"> + Animations + </string> + <string name="image_files"> + Images + </string> + <string name="save_file_verb"> + Enregistrer + </string> + <string name="load_file_verb"> + Charger + </string> + <string name="targa_image_files"> + Images Targa + </string> + <string name="bitmap_image_files"> + Images Bitmap + </string> + <string name="png_image_files"> + Images PNG + </string> + <string name="save_texture_image_files"> + Images Targa ou PNG + </string> + <string name="avi_movie_file"> + Fichier de film AVI + </string> + <string name="xaf_animation_file"> + Fichier d'animation XAF + </string> + <string name="xml_file"> + Fichier XML + </string> + <string name="raw_file"> + Fichier RAW + </string> + <string name="compressed_image_files"> + Images compressées + </string> + <string name="load_files"> + Charger des fichiers + </string> + <string name="choose_the_directory"> + Choisir le répertoire + </string> + <string name="script_files"> + Scripts + </string> + <string name="dictionary_files"> + Dictionnaires + </string> + <string name="shape"> + Silhouette + </string> + <string name="skin"> + Peau + </string> + <string name="hair"> + Cheveux + </string> + <string name="eyes"> + Yeux + </string> + <string name="shirt"> + Chemise + </string> + <string name="pants"> + Pantalon + </string> + <string name="shoes"> + Chaussures + </string> + <string name="socks"> + Chaussettes + </string> + <string name="jacket"> + Veste + </string> + <string name="gloves"> + Gants + </string> + <string name="undershirt"> + Débardeur + </string> + <string name="underpants"> + Caleçon + </string> + <string name="skirt"> + Jupe + </string> + <string name="alpha"> + Alpha + </string> + <string name="tattoo"> + Tatouage + </string> + <string name="universal"> + Universel + </string> + <string name="physics"> + Propriétés physiques + </string> + <string name="invalid"> + non valide + </string> + <string name="none"> + aucun + </string> + <string name="shirt_not_worn"> + Chemise non portée + </string> + <string name="pants_not_worn"> + Pantalon non porté + </string> + <string name="shoes_not_worn"> + Chaussures non portées + </string> + <string name="socks_not_worn"> + Chaussettes non portées + </string> + <string name="jacket_not_worn"> + Veste non portée + </string> + <string name="gloves_not_worn"> + Gants non portés + </string> + <string name="undershirt_not_worn"> + Débardeur non porté + </string> + <string name="underpants_not_worn"> + Caleçon non porté + </string> + <string name="skirt_not_worn"> + Jupe non portée + </string> + <string name="alpha_not_worn"> + Alpha non porté + </string> + <string name="tattoo_not_worn"> + Tatouage non porté + </string> + <string name="universal_not_worn"> + Universel non porté + </string> + <string name="physics_not_worn"> + Propriétés physiques non portées + </string> + <string name="invalid_not_worn"> + non valide + </string> + <string name="create_new_shape"> + Créer une nouvelle silhouette + </string> + <string name="create_new_skin"> + Créer une nouvelle peau + </string> + <string name="create_new_hair"> + Créer de nouveaux cheveux + </string> + <string name="create_new_eyes"> + Créer de nouveaux yeux + </string> + <string name="create_new_shirt"> + Créer une nouvelle chemise + </string> + <string name="create_new_pants"> + Créer un nouveau pantalon + </string> + <string name="create_new_shoes"> + Créer de nouvelles chaussures + </string> + <string name="create_new_socks"> + Créer de nouvelles chaussettes + </string> + <string name="create_new_jacket"> + Créer une nouvelle veste + </string> + <string name="create_new_gloves"> + Créer de nouveaux gants + </string> + <string name="create_new_undershirt"> + Créer un nouveau débardeur + </string> + <string name="create_new_underpants"> + Créer un nouveau caleçon + </string> + <string name="create_new_skirt"> + Créer une nouvelle jupe + </string> + <string name="create_new_alpha"> + Créer un nouvel alpha + </string> + <string name="create_new_tattoo"> + Créer un nouveau tatouage + </string> + <string name="create_new_universal"> + Créer un nouvel environnement universel + </string> + <string name="create_new_physics"> + Créer de nouvelles propriétés physiques + </string> + <string name="create_new_invalid"> + non valide + </string> + <string name="NewWearable"> + Nouv. [WEARABLE_ITEM] + </string> + <string name="next"> + Suivant + </string> + <string name="ok"> + OK + </string> + <string name="GroupNotifyGroupNotice"> + Note au groupe + </string> + <string name="GroupNotifyGroupNotices"> + Notices au groupe + </string> + <string name="GroupNotifySentBy"> + Envoyée par + </string> + <string name="GroupNotifyAttached"> + Pièce(s) jointe(s) : + </string> + <string name="GroupNotifyViewPastNotices"> + Consultez les notices précédentes ou choisissez de ne plus recevoir ces messages ici. + </string> + <string name="GroupNotifyOpenAttachment"> + Ouvrir pièce jointe + </string> + <string name="GroupNotifySaveAttachment"> + Enregistrer la pièce jointe + </string> + <string name="TeleportOffer"> + Offre de téléportation + </string> + <string name="StartUpNotifications"> + De nouvelles notifications sont arrivées en votre absence. + </string> + <string name="OverflowInfoChannelString"> + Vous avez %d notification(s) supplémentaire(s) + </string> + <string name="BodyPartsRightArm"> + Bras droit + </string> + <string name="BodyPartsHead"> + Tête + </string> + <string name="BodyPartsLeftArm"> + Bras gauche + </string> + <string name="BodyPartsLeftLeg"> + Jambe gauche + </string> + <string name="BodyPartsTorso"> + Torse + </string> + <string name="BodyPartsRightLeg"> + Jambe droite + </string> + <string name="BodyPartsEnhancedSkeleton"> + Squelette amélioré + </string> + <string name="GraphicsQualityLow"> + Faible + </string> + <string name="GraphicsQualityMid"> + Moyen + </string> + <string name="GraphicsQualityHigh"> + Élevé + </string> + <string name="LeaveMouselook"> + Appuyez sur ESC pour quitter la vue subjective + </string> + <string name="InventoryNoMatchingItems"> + Vous n'avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/all/[SEARCH_TERM] Rechercher]. + </string> + <string name="InventoryNoMatchingRecentItems"> + Avez-vous trouvé ce que vous cherchiez ? Essayez [secondlife:///app/inventory/filters Show filters]. + </string> + <string name="PlacesNoMatchingItems"> + Vous n'avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/places/[SEARCH_TERM] Rechercher]. + </string> + <string name="FavoritesNoMatchingItems"> + Faites glisser un repère ici pour l'ajouter à vos Favoris. + </string> + <string name="MarketplaceNoMatchingItems"> + Aucun article trouvé. Vérifiez l'orthographe de votre chaîne de recherche et réessayez. + </string> + <string name="InventoryNoTexture"> + Vous n'avez pas de copie de cette texture dans votre inventaire + </string> + <string name="InventoryInboxNoItems"> + Les achats que vous avez effectués sur la Place du marché s'affichent ici. Vous pouvez alors les faire glisser vers votre inventaire afin de les utiliser. + </string> + <string name="MarketplaceURL"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ + </string> + <string name="MarketplaceURL_CreateStore"> + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3 + </string> + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard + </string> + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports + </string> + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more + </string> + <string name="InventoryPlayAnimationTooltip"> + Ouvrir la fenêtre avec les options Jeu + </string> + <string name="InventoryPlayGestureTooltip"> + Exécuter le geste sélectionné dans le monde virtuel. + </string> + <string name="InventoryPlaySoundTooltip"> + Ouvrir la fenêtre avec les options Jeu + </string> + <string name="InventoryOutboxNotMerchantTitle"> + Tout le monde peut vendre des articles sur la Place du marché. + </string> <string name="InventoryOutboxNotMerchantTooltip"/> - <string name="InventoryOutboxNotMerchant">Pour devenir vendeur, vous devez [[MARKETPLACE_CREATE_STORE_URL] créer une boutique sur la Place du marché].</string> - <string name="InventoryOutboxNoItemsTitle">Votre boîte d'envoi est vide.</string> + <string name="InventoryOutboxNotMerchant"> + Pour devenir vendeur, vous devez [[MARKETPLACE_CREATE_STORE_URL] créer une boutique sur la Place du marché]. + </string> + <string name="InventoryOutboxNoItemsTitle"> + Votre boîte d'envoi est vide. + </string> <string name="InventoryOutboxNoItemsTooltip"/> - <string name="InventoryOutboxNoItems">Pour mettre des dossiers en vente sur la [[MARKETPLACE_DASHBOARD_URL] Place du marché], faites-les glisser vers cette zone et cliquez sur "Envoyer vers la Place du marché".</string> - <string name="InventoryOutboxInitializingTitle">Initialisation de la Place du marché...</string> - <string name="InventoryOutboxInitializing">Nous sommes en train d'accéder à votre compte dans la [[MARKETPLACE_CREATE_STORE_URL] boutique de la Place du marché].</string> - <string name="InventoryOutboxErrorTitle">Erreurs de la Place du marché.</string> - <string name="InventoryOutboxError">La [[MARKETPLACE_CREATE_STORE_URL] boutique de la Place du marché] renvoie des erreurs.</string> - <string name="InventoryMarketplaceError">Une erreur est survenue lors de l’ouverture des annonces de la Place du marché. -Si vous continuez de recevoir ce message, contactez l’assistance Second Life à http://support.secondlife.com pour obtenir de l’aide.</string> - <string name="InventoryMarketplaceListingsNoItemsTitle">Votre dossier Annonces de la Place du marché est vide.</string> - <string name="InventoryMarketplaceListingsNoItems">Pour mettre des dossiers en vente sur la [[MARKETPLACE_DASHBOARD_URL] Place du marché], faites-les glisser vers cette zone.</string> - <string name="InventoryItemsCount">( [ITEMS_COUNT] Articles )</string> - <string name="Marketplace Validation Warning Stock">le dossier de stock doit être contenu dans un dossier de version</string> - <string name="Marketplace Validation Error Mixed Stock">: Erreur : tous les articles d'un dossier de stock doivent être non reproductibles et de même type</string> - <string name="Marketplace Validation Error Subfolder In Stock">: Erreur : un dossier de stock ne peut pas contenir de sous-dossiers</string> - <string name="Marketplace Validation Warning Empty">: Avertissement : le dossier ne contient aucun article</string> - <string name="Marketplace Validation Warning Create Stock">: Avertissement : création du dossier de stock</string> - <string name="Marketplace Validation Warning Create Version">: Avertissement : création du dossier de version</string> - <string name="Marketplace Validation Warning Move">: Avertissement : déplacement d'articles</string> - <string name="Marketplace Validation Warning Delete">: Avertissement : contenu du dossier transféré vers le dossier de stock, suppression du dossier vide</string> - <string name="Marketplace Validation Error Stock Item">: Erreur : les articles non reproductibles doivent être contenus dans un dossier de stock</string> - <string name="Marketplace Validation Warning Unwrapped Item">: Avertissement : les articles doivent être contenus dans un dossier de version</string> - <string name="Marketplace Validation Error">: Erreur :</string> - <string name="Marketplace Validation Warning">: Avertissement :</string> - <string name="Marketplace Validation Error Empty Version">: Avertissement : le dossier de version doit contenir au moins 1 article</string> - <string name="Marketplace Validation Error Empty Stock">: Avertissement : le dossier de stock doit contenir au moins 1 article</string> - <string name="Marketplace Validation No Error">Pas d'erreur ni d'avertissement à signaler</string> - <string name="Marketplace Error None">Aucune erreur</string> - <string name="Marketplace Error Prefix">Erreur :</string> - <string name="Marketplace Error Not Merchant">Avant d'envoyer des articles vers la Place du marché, vous devez vous configurer comme vendeur (gratuit).</string> - <string name="Marketplace Error Not Accepted">Impossible de déplacer l'article dans ce dossier.</string> - <string name="Marketplace Error Unsellable Item">Cet article ne peut pas être vendu sur la Place du marché.</string> - <string name="MarketplaceNoID">no Mkt ID</string> - <string name="MarketplaceLive">publié</string> - <string name="MarketplaceActive">actif</string> - <string name="MarketplaceMax">max.</string> - <string name="MarketplaceStock">stock</string> - <string name="MarketplaceNoStock">rupture de stock</string> - <string name="MarketplaceUpdating">mise à jour...</string> - <string name="UploadFeeInfo">Les frais dépendent de votre niveau d'abonnement. Les niveaux supérieurs sont soumis à des frais moins élevés. [https://secondlife.com/my/account/membership.php? En savoir plus]</string> - <string name="Open landmarks">Points de repère ouverts</string> - <string name="Unconstrained">Sans contrainte</string> + <string name="InventoryOutboxNoItems"> + Pour mettre des dossiers en vente sur la [[MARKETPLACE_DASHBOARD_URL] Place du marché], faites-les glisser vers cette zone et cliquez sur "Envoyer vers la Place du marché". + </string> + <string name="InventoryOutboxInitializingTitle"> + Initialisation de la Place du marché... + </string> + <string name="InventoryOutboxInitializing"> + Nous sommes en train d'accéder à votre compte dans la [[MARKETPLACE_CREATE_STORE_URL] boutique de la Place du marché]. + </string> + <string name="InventoryOutboxErrorTitle"> + Erreurs de la Place du marché. + </string> + <string name="InventoryOutboxError"> + La [[MARKETPLACE_CREATE_STORE_URL] boutique de la Place du marché] renvoie des erreurs. + </string> + <string name="InventoryMarketplaceError"> + Une erreur est survenue lors de l’ouverture des annonces de la Place du marché. +Si vous continuez de recevoir ce message, contactez l’assistance Second Life à http://support.secondlife.com pour obtenir de l’aide. + </string> + <string name="InventoryMarketplaceListingsNoItemsTitle"> + Votre dossier Annonces de la Place du marché est vide. + </string> + <string name="InventoryMarketplaceListingsNoItems"> + Pour mettre des dossiers en vente sur la [[MARKETPLACE_DASHBOARD_URL] Place du marché], faites-les glisser vers cette zone. + </string> + <string name="InventoryItemsCount"> + ( [ITEMS_COUNT] Articles ) + </string> + <string name="Marketplace Validation Warning Stock"> + le dossier de stock doit être contenu dans un dossier de version + </string> + <string name="Marketplace Validation Error Mixed Stock"> + : Erreur : tous les articles d'un dossier de stock doivent être non reproductibles et de même type + </string> + <string name="Marketplace Validation Error Subfolder In Stock"> + : Erreur : un dossier de stock ne peut pas contenir de sous-dossiers + </string> + <string name="Marketplace Validation Warning Empty"> + : Avertissement : le dossier ne contient aucun article + </string> + <string name="Marketplace Validation Warning Create Stock"> + : Avertissement : création du dossier de stock + </string> + <string name="Marketplace Validation Warning Create Version"> + : Avertissement : création du dossier de version + </string> + <string name="Marketplace Validation Warning Move"> + : Avertissement : déplacement d'articles + </string> + <string name="Marketplace Validation Warning Delete"> + : Avertissement : contenu du dossier transféré vers le dossier de stock, suppression du dossier vide + </string> + <string name="Marketplace Validation Error Stock Item"> + : Erreur : les articles non reproductibles doivent être contenus dans un dossier de stock + </string> + <string name="Marketplace Validation Warning Unwrapped Item"> + : Avertissement : les articles doivent être contenus dans un dossier de version + </string> + <string name="Marketplace Validation Error"> + : Erreur : + </string> + <string name="Marketplace Validation Warning"> + : Avertissement : + </string> + <string name="Marketplace Validation Error Empty Version"> + : Avertissement : le dossier de version doit contenir au moins 1 article + </string> + <string name="Marketplace Validation Error Empty Stock"> + : Avertissement : le dossier de stock doit contenir au moins 1 article + </string> + <string name="Marketplace Validation No Error"> + Pas d'erreur ni d'avertissement à signaler + </string> + <string name="Marketplace Error None"> + Aucune erreur + </string> + <string name="Marketplace Error Prefix"> + Erreur : + </string> + <string name="Marketplace Error Not Merchant"> + Avant d'envoyer des articles vers la Place du marché, vous devez vous configurer comme vendeur (gratuit). + </string> + <string name="Marketplace Error Not Accepted"> + Impossible de déplacer l'article dans ce dossier. + </string> + <string name="Marketplace Error Unsellable Item"> + Cet article ne peut pas être vendu sur la Place du marché. + </string> + <string name="MarketplaceNoID"> + no Mkt ID + </string> + <string name="MarketplaceLive"> + publié + </string> + <string name="MarketplaceActive"> + actif + </string> + <string name="MarketplaceMax"> + max. + </string> + <string name="MarketplaceStock"> + stock + </string> + <string name="MarketplaceNoStock"> + rupture de stock + </string> + <string name="MarketplaceUpdating"> + mise à jour... + </string> + <string name="UploadFeeInfo"> + Les frais dépendent de votre niveau d'abonnement. Les niveaux supérieurs sont soumis à des frais moins élevés. [https://secondlife.com/my/account/membership.php? En savoir plus] + </string> + <string name="Open landmarks"> + Points de repère ouverts + </string> + <string name="Unconstrained"> + Sans contrainte + </string> <string name="no_transfer" value=" (pas de transfert)"/> <string name="no_modify" value=" (pas de modification)"/> <string name="no_copy" value=" (pas de copie)"/> <string name="worn" value=" (porté)"/> <string name="link" value=" (lien)"/> <string name="broken_link" value=" (broken_link)"/> - <string name="LoadingContents">chargement des contenus en cours...</string> - <string name="NoContents">Aucun contenu</string> + <string name="LoadingContents"> + chargement des contenus en cours... + </string> + <string name="NoContents"> + Aucun contenu + </string> <string name="WornOnAttachmentPoint" value=" (porté sur [ATTACHMENT_POINT])"/> <string name="AttachmentErrorMessage" value="([ATTACHMENT_ERROR])"/> <string name="ActiveGesture" value="[GESLABEL] (actif)"/> - <string name="PermYes">Oui</string> - <string name="PermNo">Non</string> + <string name="PermYes"> + Oui + </string> + <string name="PermNo"> + Non + </string> <string name="Chat Message" value="Chat :"/> <string name="Sound" value=" Son :"/> <string name="Wait" value=" --- Attendre :"/> @@ -637,1439 +1705,4215 @@ Si vous continuez de recevoir ce message, contactez l’assistance Second Life <string name="Snapshots" value=" Photos,"/> <string name="No Filters" value="Non "/> <string name="Since Logoff" value="depuis la déconnexion"/> - <string name="InvFolder My Inventory">Mon inventaire</string> - <string name="InvFolder Library">Bibliothèque</string> - <string name="InvFolder Textures">Textures</string> - <string name="InvFolder Sounds">Sons</string> - <string name="InvFolder Calling Cards">Cartes de visite</string> - <string name="InvFolder Landmarks">Repères</string> - <string name="InvFolder Scripts">Scripts</string> - <string name="InvFolder Clothing">Habits</string> - <string name="InvFolder Objects">Objets</string> - <string name="InvFolder Notecards">Notes</string> - <string name="InvFolder New Folder">Nouveau dossier</string> - <string name="InvFolder Inventory">Inventaire</string> - <string name="InvFolder Uncompressed Images">Images non compressées</string> - <string name="InvFolder Body Parts">Parties du corps</string> - <string name="InvFolder Trash">Corbeille</string> - <string name="InvFolder Photo Album">Albums photo</string> - <string name="InvFolder Lost And Found">Objets trouvés</string> - <string name="InvFolder Uncompressed Sounds">Sons non compressés</string> - <string name="InvFolder Animations">Animations</string> - <string name="InvFolder Gestures">Gestes</string> - <string name="InvFolder Favorite">Mes Favoris</string> - <string name="InvFolder favorite">Mes Favoris</string> - <string name="InvFolder Favorites">Mes favoris</string> - <string name="InvFolder favorites">Mes favoris</string> - <string name="InvFolder Current Outfit">Tenue actuelle</string> - <string name="InvFolder Initial Outfits">Tenues initiales</string> - <string name="InvFolder My Outfits">Mes tenues</string> - <string name="InvFolder Accessories">Accessoires</string> - <string name="InvFolder Meshes">Maillages</string> - <string name="InvFolder Received Items">Articles reçus</string> - <string name="InvFolder Merchant Outbox">Boîte d'envoi vendeur</string> - <string name="InvFolder Friends">Amis</string> - <string name="InvFolder All">Tout</string> - <string name="no_attachments">Aucun élément attaché porté</string> - <string name="Attachments remain">Éléments attachés ([COUNT] emplacements restants)</string> - <string name="Buy">Acheter</string> - <string name="BuyforL$">Acheter des L$</string> - <string name="Stone">Pierre</string> - <string name="Metal">Métal</string> - <string name="Glass">Verre</string> - <string name="Wood">Bois</string> - <string name="Flesh">Chair</string> - <string name="Plastic">Plastique</string> - <string name="Rubber">Caoutchouc</string> - <string name="Light">Léger</string> - <string name="KBShift">Maj-</string> - <string name="KBCtrl">Ctrl</string> - <string name="Chest">Poitrine</string> - <string name="Skull">Crâne</string> - <string name="Left Shoulder">Épaule gauche</string> - <string name="Right Shoulder">Épaule droite</string> - <string name="Left Hand">Main gauche</string> - <string name="Right Hand">Main droite</string> - <string name="Left Foot">Pied gauche</string> - <string name="Right Foot">Pied droit</string> - <string name="Spine">Colonne</string> - <string name="Pelvis">Bassin</string> - <string name="Mouth">Bouche</string> - <string name="Chin">Menton</string> - <string name="Left Ear">Oreille gauche</string> - <string name="Right Ear">Oreille droite</string> - <string name="Left Eyeball">Globe oculaire gauche</string> - <string name="Right Eyeball">Globe oculaire droit</string> - <string name="Nose">Nez</string> - <string name="R Upper Arm">Bras D</string> - <string name="R Forearm">Avant-bras D</string> - <string name="L Upper Arm">Bras G</string> - <string name="L Forearm">Avant-bras G</string> - <string name="Right Hip">Hanche droite</string> - <string name="R Upper Leg">Cuisse D</string> - <string name="R Lower Leg">Jambe D</string> - <string name="Left Hip">Hanche gauche</string> - <string name="L Upper Leg">Cuisse G</string> - <string name="L Lower Leg">Jambe G</string> - <string name="Stomach">Estomac</string> - <string name="Left Pec">Pectoral gauche</string> - <string name="Right Pec">Pectoral droit</string> - <string name="Neck">Cou</string> - <string name="Avatar Center">Centre de l'avatar</string> - <string name="Left Ring Finger">Annulaire gauche</string> - <string name="Right Ring Finger">Annulaire droit</string> - <string name="Tail Base">Base de la queue</string> - <string name="Tail Tip">Bout de la queue</string> - <string name="Left Wing">Aile gauche</string> - <string name="Right Wing">Aile droite</string> - <string name="Jaw">Mâchoire</string> - <string name="Alt Left Ear">Oreille gauche différente</string> - <string name="Alt Right Ear">Oreille droite différente</string> - <string name="Alt Left Eye">Œil gauche différent</string> - <string name="Alt Right Eye">Œil droit différent</string> - <string name="Tongue">Langue</string> - <string name="Groin">Aine</string> - <string name="Left Hind Foot">Pied arrière gauche</string> - <string name="Right Hind Foot">Pied arrière droit</string> - <string name="Invalid Attachment">Point d'attache non valide</string> - <string name="ATTACHMENT_MISSING_ITEM">Erreur : article manquant</string> - <string name="ATTACHMENT_MISSING_BASE_ITEM">Erreur : article de base manquant</string> - <string name="ATTACHMENT_NOT_ATTACHED">Erreur : l'objet est dans une tenue actuelle, mais il n'est pas attaché</string> - <string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS]</string> - <string name="YearsOld">[AGEYEARS]</string> - <string name="MonthsOld">[AGEMONTHS]</string> - <string name="WeeksOld">[AGEWEEKS]</string> - <string name="DaysOld">[AGEDAYS]</string> - <string name="TodayOld">Inscrit aujourd'hui</string> - <string name="av_render_everyone_now">Désormais, tout le monde peut vous voir.</string> - <string name="av_render_not_everyone">Vous risquez de ne pas être rendu par tous les gens qui vous entourent.</string> - <string name="av_render_over_half">Vous risquez de ne pas être rendu par plus de la moitié des gens qui vous entourent.</string> - <string name="av_render_most_of">Vous risquez de ne pas être rendu par la plupart des gens qui vous entourent.</string> - <string name="av_render_anyone">Vous risquez de n’être rendu par aucune des personnes qui vous entourent.</string> - <string name="hud_description_total">Votre HUD</string> - <string name="hud_name_with_joint">[OBJ_NAME] (porté sur [JNT_NAME])</string> - <string name="hud_render_memory_warning">[HUD_DETAILS] utilise beaucoup de mémoire textures</string> - <string name="hud_render_cost_warning">[HUD_DETAILS] contient beaucoup de textures et d’objets volumineux</string> - <string name="hud_render_heavy_textures_warning">[HUD_DETAILS] contient beaucoup de textures volumineuses</string> - <string name="hud_render_cramped_warning">[HUD_DETAILS] contient trop d’objets</string> - <string name="hud_render_textures_warning">[HUD_DETAILS] contient trop de textures</string> - <string name="AgeYearsA">[COUNT] an</string> - <string name="AgeYearsB">[COUNT] ans</string> - <string name="AgeYearsC">[COUNT] ans</string> - <string name="AgeMonthsA">[COUNT] mois</string> - <string name="AgeMonthsB">[COUNT] mois</string> - <string name="AgeMonthsC">[COUNT] mois</string> - <string name="AgeWeeksA">[COUNT] semaine</string> - <string name="AgeWeeksB">[COUNT] semaines</string> - <string name="AgeWeeksC">[COUNT] semaines</string> - <string name="AgeDaysA">[COUNT] jour</string> - <string name="AgeDaysB">[COUNT] jours</string> - <string name="AgeDaysC">[COUNT] jours</string> - <string name="GroupMembersA">[COUNT] membre</string> - <string name="GroupMembersB">[COUNT] membres</string> - <string name="GroupMembersC">[COUNT] membres</string> - <string name="AcctTypeResident">Résident</string> - <string name="AcctTypeTrial">Essai</string> - <string name="AcctTypeCharterMember">Membre originaire</string> - <string name="AcctTypeEmployee">Employé(e) de Linden Lab</string> - <string name="PaymentInfoUsed">Infos de paiement utilisées</string> - <string name="PaymentInfoOnFile">Infos de paiement enregistrées</string> - <string name="NoPaymentInfoOnFile">Aucune info de paiement enregistrée</string> - <string name="AgeVerified">Personne dont l'âge a été vérifié</string> - <string name="NotAgeVerified">Personne dont l'âge n'a pas été vérifié</string> - <string name="Center 2">Centre 2</string> - <string name="Top Right">En haut à droite</string> - <string name="Top">En haut</string> - <string name="Top Left">En haut à gauche</string> - <string name="Center">Centre</string> - <string name="Bottom Left">En bas à gauche</string> - <string name="Bottom">Bas</string> - <string name="Bottom Right">En bas à droite</string> - <string name="CompileQueueDownloadedCompiling">Téléchargé, compilation en cours</string> - <string name="CompileQueueServiceUnavailable">Service de compilation de script indisponible.</string> - <string name="CompileQueueScriptNotFound">Script introuvable sur le serveur.</string> - <string name="CompileQueueProblemDownloading">Problème lors du téléchargement</string> - <string name="CompileQueueInsufficientPermDownload">Droits insuffisants pour télécharger un script.</string> - <string name="CompileQueueInsufficientPermFor">Droits insuffisants pour</string> - <string name="CompileQueueUnknownFailure">Échec du téléchargement, erreur inconnue</string> - <string name="CompileNoExperiencePerm">En train d’ignorer le script [SCRIPT] avec l’expérience [EXPERIENCE].</string> - <string name="CompileQueueTitle">Recompilation - progrès</string> - <string name="CompileQueueStart">recompiler</string> - <string name="ResetQueueTitle">Réinitialiser les progrès</string> - <string name="ResetQueueStart">réinitialiser</string> - <string name="RunQueueTitle">Lancer</string> - <string name="RunQueueStart">lancer</string> - <string name="NotRunQueueTitle">Arrêter</string> - <string name="NotRunQueueStart">arrêter</string> - <string name="CompileSuccessful">Compilation réussie !</string> - <string name="CompileSuccessfulSaving">Compilation réussie, enregistrement en cours...</string> - <string name="SaveComplete">Enregistrement terminé.</string> - <string name="UploadFailed">Échec du chargement de fichier :</string> - <string name="ObjectOutOfRange">Script (objet hors de portée)</string> - <string name="ScriptWasDeleted">Script (supprimé de l’inventaire)</string> - <string name="GodToolsObjectOwnedBy">Objet [OBJECT] appartenant à [OWNER]</string> - <string name="GroupsNone">aucun</string> + <string name="InvFolder My Inventory"> + Mon inventaire + </string> + <string name="InvFolder Library"> + Bibliothèque + </string> + <string name="InvFolder Textures"> + Textures + </string> + <string name="InvFolder Sounds"> + Sons + </string> + <string name="InvFolder Calling Cards"> + Cartes de visite + </string> + <string name="InvFolder Landmarks"> + Repères + </string> + <string name="InvFolder Scripts"> + Scripts + </string> + <string name="InvFolder Clothing"> + Habits + </string> + <string name="InvFolder Objects"> + Objets + </string> + <string name="InvFolder Notecards"> + Notes + </string> + <string name="InvFolder New Folder"> + Nouveau dossier + </string> + <string name="InvFolder Inventory"> + Inventaire + </string> + <string name="InvFolder Uncompressed Images"> + Images non compressées + </string> + <string name="InvFolder Body Parts"> + Parties du corps + </string> + <string name="InvFolder Trash"> + Corbeille + </string> + <string name="InvFolder Photo Album"> + Albums photo + </string> + <string name="InvFolder Lost And Found"> + Objets trouvés + </string> + <string name="InvFolder Uncompressed Sounds"> + Sons non compressés + </string> + <string name="InvFolder Animations"> + Animations + </string> + <string name="InvFolder Gestures"> + Gestes + </string> + <string name="InvFolder Favorite"> + Mes Favoris + </string> + <string name="InvFolder favorite"> + Mes Favoris + </string> + <string name="InvFolder Favorites"> + Mes favoris + </string> + <string name="InvFolder favorites"> + Mes favoris + </string> + <string name="InvFolder Current Outfit"> + Tenue actuelle + </string> + <string name="InvFolder Initial Outfits"> + Tenues initiales + </string> + <string name="InvFolder My Outfits"> + Mes tenues + </string> + <string name="InvFolder Accessories"> + Accessoires + </string> + <string name="InvFolder Meshes"> + Maillages + </string> + <string name="InvFolder Received Items"> + Articles reçus + </string> + <string name="InvFolder Merchant Outbox"> + Boîte d'envoi vendeur + </string> + <string name="InvFolder Friends"> + Amis + </string> + <string name="InvFolder All"> + Tout + </string> + <string name="no_attachments"> + Aucun élément attaché porté + </string> + <string name="Attachments remain"> + Éléments attachés ([COUNT] emplacements restants) + </string> + <string name="Buy"> + Acheter + </string> + <string name="BuyforL$"> + Acheter des L$ + </string> + <string name="Stone"> + Pierre + </string> + <string name="Metal"> + Métal + </string> + <string name="Glass"> + Verre + </string> + <string name="Wood"> + Bois + </string> + <string name="Flesh"> + Chair + </string> + <string name="Plastic"> + Plastique + </string> + <string name="Rubber"> + Caoutchouc + </string> + <string name="Light"> + Léger + </string> + <string name="KBShift"> + Maj- + </string> + <string name="KBCtrl"> + Ctrl + </string> + <string name="Chest"> + Poitrine + </string> + <string name="Skull"> + Crâne + </string> + <string name="Left Shoulder"> + Épaule gauche + </string> + <string name="Right Shoulder"> + Épaule droite + </string> + <string name="Left Hand"> + Main gauche + </string> + <string name="Right Hand"> + Main droite + </string> + <string name="Left Foot"> + Pied gauche + </string> + <string name="Right Foot"> + Pied droit + </string> + <string name="Spine"> + Colonne + </string> + <string name="Pelvis"> + Bassin + </string> + <string name="Mouth"> + Bouche + </string> + <string name="Chin"> + Menton + </string> + <string name="Left Ear"> + Oreille gauche + </string> + <string name="Right Ear"> + Oreille droite + </string> + <string name="Left Eyeball"> + Globe oculaire gauche + </string> + <string name="Right Eyeball"> + Globe oculaire droit + </string> + <string name="Nose"> + Nez + </string> + <string name="R Upper Arm"> + Bras D + </string> + <string name="R Forearm"> + Avant-bras D + </string> + <string name="L Upper Arm"> + Bras G + </string> + <string name="L Forearm"> + Avant-bras G + </string> + <string name="Right Hip"> + Hanche droite + </string> + <string name="R Upper Leg"> + Cuisse D + </string> + <string name="R Lower Leg"> + Jambe D + </string> + <string name="Left Hip"> + Hanche gauche + </string> + <string name="L Upper Leg"> + Cuisse G + </string> + <string name="L Lower Leg"> + Jambe G + </string> + <string name="Stomach"> + Estomac + </string> + <string name="Left Pec"> + Pectoral gauche + </string> + <string name="Right Pec"> + Pectoral droit + </string> + <string name="Neck"> + Cou + </string> + <string name="Avatar Center"> + Centre de l'avatar + </string> + <string name="Left Ring Finger"> + Annulaire gauche + </string> + <string name="Right Ring Finger"> + Annulaire droit + </string> + <string name="Tail Base"> + Base de la queue + </string> + <string name="Tail Tip"> + Bout de la queue + </string> + <string name="Left Wing"> + Aile gauche + </string> + <string name="Right Wing"> + Aile droite + </string> + <string name="Jaw"> + Mâchoire + </string> + <string name="Alt Left Ear"> + Oreille gauche différente + </string> + <string name="Alt Right Ear"> + Oreille droite différente + </string> + <string name="Alt Left Eye"> + Œil gauche différent + </string> + <string name="Alt Right Eye"> + Œil droit différent + </string> + <string name="Tongue"> + Langue + </string> + <string name="Groin"> + Aine + </string> + <string name="Left Hind Foot"> + Pied arrière gauche + </string> + <string name="Right Hind Foot"> + Pied arrière droit + </string> + <string name="Invalid Attachment"> + Point d'attache non valide + </string> + <string name="ATTACHMENT_MISSING_ITEM"> + Erreur : article manquant + </string> + <string name="ATTACHMENT_MISSING_BASE_ITEM"> + Erreur : article de base manquant + </string> + <string name="ATTACHMENT_NOT_ATTACHED"> + Erreur : l'objet est dans une tenue actuelle, mais il n'est pas attaché + </string> + <string name="YearsMonthsOld"> + [AGEYEARS] [AGEMONTHS] + </string> + <string name="YearsOld"> + [AGEYEARS] + </string> + <string name="MonthsOld"> + [AGEMONTHS] + </string> + <string name="WeeksOld"> + [AGEWEEKS] + </string> + <string name="DaysOld"> + [AGEDAYS] + </string> + <string name="TodayOld"> + Inscrit aujourd'hui + </string> + <string name="av_render_everyone_now"> + Désormais, tout le monde peut vous voir. + </string> + <string name="av_render_not_everyone"> + Vous risquez de ne pas être rendu par tous les gens qui vous entourent. + </string> + <string name="av_render_over_half"> + Vous risquez de ne pas être rendu par plus de la moitié des gens qui vous entourent. + </string> + <string name="av_render_most_of"> + Vous risquez de ne pas être rendu par la plupart des gens qui vous entourent. + </string> + <string name="av_render_anyone"> + Vous risquez de n’être rendu par aucune des personnes qui vous entourent. + </string> + <string name="hud_description_total"> + Votre HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (porté sur [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] utilise beaucoup de mémoire textures + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contient beaucoup de textures et d’objets volumineux + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contient beaucoup de textures volumineuses + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contient trop d’objets + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contient trop de textures + </string> + <string name="AgeYearsA"> + [COUNT] an + </string> + <string name="AgeYearsB"> + [COUNT] ans + </string> + <string name="AgeYearsC"> + [COUNT] ans + </string> + <string name="AgeMonthsA"> + [COUNT] mois + </string> + <string name="AgeMonthsB"> + [COUNT] mois + </string> + <string name="AgeMonthsC"> + [COUNT] mois + </string> + <string name="AgeWeeksA"> + [COUNT] semaine + </string> + <string name="AgeWeeksB"> + [COUNT] semaines + </string> + <string name="AgeWeeksC"> + [COUNT] semaines + </string> + <string name="AgeDaysA"> + [COUNT] jour + </string> + <string name="AgeDaysB"> + [COUNT] jours + </string> + <string name="AgeDaysC"> + [COUNT] jours + </string> + <string name="GroupMembersA"> + [COUNT] membre + </string> + <string name="GroupMembersB"> + [COUNT] membres + </string> + <string name="GroupMembersC"> + [COUNT] membres + </string> + <string name="AcctTypeResident"> + Résident + </string> + <string name="AcctTypeTrial"> + Essai + </string> + <string name="AcctTypeCharterMember"> + Membre originaire + </string> + <string name="AcctTypeEmployee"> + Employé(e) de Linden Lab + </string> + <string name="PaymentInfoUsed"> + Infos de paiement utilisées + </string> + <string name="PaymentInfoOnFile"> + Infos de paiement enregistrées + </string> + <string name="NoPaymentInfoOnFile"> + Aucune info de paiement enregistrée + </string> + <string name="AgeVerified"> + Personne dont l'âge a été vérifié + </string> + <string name="NotAgeVerified"> + Personne dont l'âge n'a pas été vérifié + </string> + <string name="Center 2"> + Centre 2 + </string> + <string name="Top Right"> + En haut à droite + </string> + <string name="Top"> + En haut + </string> + <string name="Top Left"> + En haut à gauche + </string> + <string name="Center"> + Centre + </string> + <string name="Bottom Left"> + En bas à gauche + </string> + <string name="Bottom"> + Bas + </string> + <string name="Bottom Right"> + En bas à droite + </string> + <string name="CompileQueueDownloadedCompiling"> + Téléchargé, compilation en cours + </string> + <string name="CompileQueueServiceUnavailable"> + Service de compilation de script indisponible. + </string> + <string name="CompileQueueScriptNotFound"> + Script introuvable sur le serveur. + </string> + <string name="CompileQueueProblemDownloading"> + Problème lors du téléchargement + </string> + <string name="CompileQueueInsufficientPermDownload"> + Droits insuffisants pour télécharger un script. + </string> + <string name="CompileQueueInsufficientPermFor"> + Droits insuffisants pour + </string> + <string name="CompileQueueUnknownFailure"> + Échec du téléchargement, erreur inconnue + </string> + <string name="CompileNoExperiencePerm"> + En train d’ignorer le script [SCRIPT] avec l’expérience [EXPERIENCE]. + </string> + <string name="CompileQueueTitle"> + Recompilation - progrès + </string> + <string name="CompileQueueStart"> + recompiler + </string> + <string name="ResetQueueTitle"> + Réinitialiser les progrès + </string> + <string name="ResetQueueStart"> + réinitialiser + </string> + <string name="RunQueueTitle"> + Lancer + </string> + <string name="RunQueueStart"> + lancer + </string> + <string name="NotRunQueueTitle"> + Arrêter + </string> + <string name="NotRunQueueStart"> + arrêter + </string> + <string name="CompileSuccessful"> + Compilation réussie ! + </string> + <string name="CompileSuccessfulSaving"> + Compilation réussie, enregistrement en cours... + </string> + <string name="SaveComplete"> + Enregistrement terminé. + </string> + <string name="UploadFailed"> + Échec du chargement de fichier : + </string> + <string name="ObjectOutOfRange"> + Script (objet hors de portée) + </string> + <string name="ScriptWasDeleted"> + Script (supprimé de l’inventaire) + </string> + <string name="GodToolsObjectOwnedBy"> + Objet [OBJECT] appartenant à [OWNER] + </string> + <string name="GroupsNone"> + aucun + </string> <string name="Group" value=" (groupe)"/> - <string name="Unknown">(Inconnu)</string> + <string name="Unknown"> + (Inconnu) + </string> <string name="SummaryForTheWeek" value="Récapitulatif de la semaine, début le "/> <string name="NextStipendDay" value=". Prochaine prime le "/> - <string name="GroupPlanningDate">[day,datetime,utc]/[mthnum,datetime,utc]/[year,datetime,utc]</string> + <string name="GroupPlanningDate"> + [day,datetime,utc]/[mthnum,datetime,utc]/[year,datetime,utc] + </string> <string name="GroupIndividualShare" value=" Groupe Part individuelle"/> <string name="GroupColumn" value="Groupe"/> - <string name="Balance">Solde</string> - <string name="Credits">Crédits</string> - <string name="Debits">Débits</string> - <string name="Total">Total</string> - <string name="NoGroupDataFound">Aucune donnée trouvée pour le groupe</string> - <string name="IMParentEstate">domaine parent</string> - <string name="IMMainland">continent</string> - <string name="IMTeen">teen</string> - <string name="Anyone">n'importe qui</string> - <string name="RegionInfoError">erreur</string> - <string name="RegionInfoAllEstatesOwnedBy">tous les domaines appartenant à [OWNER]</string> - <string name="RegionInfoAllEstatesYouOwn">tous les domaines vous appartenant</string> - <string name="RegionInfoAllEstatesYouManage">tous les domaines que vous gérez pour [OWNER]</string> - <string name="RegionInfoAllowedResidents">Toujours autorisé : ([ALLOWEDAGENTS], max [MAXACCESS])</string> - <string name="RegionInfoAllowedGroups">Groupes toujours autorisés : [ALLOWEDGROUPS], max [MAXACCESS])</string> - <string name="RegionInfoBannedResidents">Toujours interdits : ([BANNEDAGENTS], max. [MAXBANNED])</string> - <string name="RegionInfoListTypeAllowedAgents">Toujours autorisé</string> - <string name="RegionInfoListTypeBannedAgents">Toujours interdit</string> - <string name="RegionInfoAllEstates">tous les domaines</string> - <string name="RegionInfoManagedEstates">domaines gérés</string> - <string name="RegionInfoThisEstate">ce domaine</string> - <string name="AndNMore">et [EXTRA_COUNT] plus</string> - <string name="ScriptLimitsParcelScriptMemory">Mémoire des scripts de parcelles</string> - <string name="ScriptLimitsParcelsOwned">Parcelles répertoriées : [PARCELS]</string> - <string name="ScriptLimitsMemoryUsed">Mémoire utilisée : [COUNT] Ko sur [MAX] ; [AVAILABLE] Ko disponibles</string> - <string name="ScriptLimitsMemoryUsedSimple">Mémoire utilisée : [COUNT] Ko</string> - <string name="ScriptLimitsParcelScriptURLs">URL des scripts de parcelles</string> - <string name="ScriptLimitsURLsUsed">URL utilisées : [COUNT] sur [MAX] ; [AVAILABLE] disponible(s)</string> - <string name="ScriptLimitsURLsUsedSimple">URL utilisées : [COUNT]</string> - <string name="ScriptLimitsRequestError">Une erreur est survenue pendant la requête d'informations.</string> - <string name="ScriptLimitsRequestNoParcelSelected">Aucune parcelle sélectionnée</string> - <string name="ScriptLimitsRequestWrongRegion">Erreur : les informations de script ne sont disponibles que dans votre région actuelle.</string> - <string name="ScriptLimitsRequestWaiting">Extraction des informations en cours...</string> - <string name="ScriptLimitsRequestDontOwnParcel">Vous n'avez pas le droit d'examiner cette parcelle.</string> - <string name="SITTING_ON">Assis(e) dessus</string> - <string name="ATTACH_CHEST">Poitrine</string> - <string name="ATTACH_HEAD">Crâne</string> - <string name="ATTACH_LSHOULDER">Épaule gauche</string> - <string name="ATTACH_RSHOULDER">Épaule droite</string> - <string name="ATTACH_LHAND">Main gauche</string> - <string name="ATTACH_RHAND">Main droite</string> - <string name="ATTACH_LFOOT">Pied gauche</string> - <string name="ATTACH_RFOOT">Pied droit</string> - <string name="ATTACH_BACK">Colonne vertébrale</string> - <string name="ATTACH_PELVIS">Bassin</string> - <string name="ATTACH_MOUTH">Bouche</string> - <string name="ATTACH_CHIN">Menton</string> - <string name="ATTACH_LEAR">Oreille gauche</string> - <string name="ATTACH_REAR">Oreille droite</string> - <string name="ATTACH_LEYE">Œil gauche</string> - <string name="ATTACH_REYE">Œil droit</string> - <string name="ATTACH_NOSE">Nez</string> - <string name="ATTACH_RUARM">Bras droit</string> - <string name="ATTACH_RLARM">Avant-bras droit</string> - <string name="ATTACH_LUARM">Bras gauche</string> - <string name="ATTACH_LLARM">Avant-bras gauche</string> - <string name="ATTACH_RHIP">Hanche droite</string> - <string name="ATTACH_RULEG">Cuisse droite</string> - <string name="ATTACH_RLLEG">Jambe droite</string> - <string name="ATTACH_LHIP">Hanche gauche</string> - <string name="ATTACH_LULEG">Cuisse gauche</string> - <string name="ATTACH_LLLEG">Jambe gauche</string> - <string name="ATTACH_BELLY">Estomac</string> - <string name="ATTACH_LEFT_PEC">Pectoral gauche</string> - <string name="ATTACH_RIGHT_PEC">Pectoral droit</string> - <string name="ATTACH_HUD_CENTER_2">HUD centre 2</string> - <string name="ATTACH_HUD_TOP_RIGHT">HUD en haut à droite</string> - <string name="ATTACH_HUD_TOP_CENTER">HUD en haut au centre</string> - <string name="ATTACH_HUD_TOP_LEFT">HUD en haut à gauche</string> - <string name="ATTACH_HUD_CENTER_1">HUD centre 1</string> - <string name="ATTACH_HUD_BOTTOM_LEFT">HUD en bas à gauche</string> - <string name="ATTACH_HUD_BOTTOM">HUD en bas</string> - <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD en bas à droite</string> - <string name="ATTACH_NECK">Cou</string> - <string name="ATTACH_AVATAR_CENTER">Centre de l'avatar</string> - <string name="ATTACH_LHAND_RING1">Annulaire gauche</string> - <string name="ATTACH_RHAND_RING1">Annulaire droit</string> - <string name="ATTACH_TAIL_BASE">Base de la queue</string> - <string name="ATTACH_TAIL_TIP">Bout de la queue</string> - <string name="ATTACH_LWING">Aile gauche</string> - <string name="ATTACH_RWING">Aile droite</string> - <string name="ATTACH_FACE_JAW">Mâchoire</string> - <string name="ATTACH_FACE_LEAR">Oreille gauche différente</string> - <string name="ATTACH_FACE_REAR">Oreille droite différente</string> - <string name="ATTACH_FACE_LEYE">Œil gauche différent</string> - <string name="ATTACH_FACE_REYE">Œil droit différent</string> - <string name="ATTACH_FACE_TONGUE">Langue</string> - <string name="ATTACH_GROIN">Aine</string> - <string name="ATTACH_HIND_LFOOT">Pied arrière gauche</string> - <string name="ATTACH_HIND_RFOOT">Pied arrière droit</string> - <string name="CursorPos">Ligne [LINE], colonne [COLUMN]</string> - <string name="PanelDirCountFound">[COUNT] trouvé(s)</string> - <string name="PanelDirTimeStr">[hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt]</string> - <string name="PanelDirEventsDateText">[mthnum,datetime,slt]/[day,datetime,slt]</string> - <string name="PanelContentsTooltip">Contenu de l'objet</string> - <string name="PanelContentsNewScript">Nouveau script</string> - <string name="DoNotDisturbModeResponseDefault">Ce résident a activé Ne pas déranger et verra votre message plus tard.</string> - <string name="MuteByName">(par nom)</string> - <string name="MuteAgent">(résident)</string> - <string name="MuteObject">(objet)</string> - <string name="MuteGroup">(groupe)</string> - <string name="MuteExternal">(externe)</string> - <string name="RegionNoCovenant">Il n'y a aucun règlement pour ce domaine.</string> - <string name="RegionNoCovenantOtherOwner">Il n'y a aucun règlement pour ce domaine. Le terrain sur ce domaine est vendu par le propriétaire, non par Linden Lab. Pour en savoir plus, veuillez contacter le propriétaire.</string> + <string name="Balance"> + Solde + </string> + <string name="Credits"> + Crédits + </string> + <string name="Debits"> + Débits + </string> + <string name="Total"> + Total + </string> + <string name="NoGroupDataFound"> + Aucune donnée trouvée pour le groupe + </string> + <string name="IMParentEstate"> + domaine parent + </string> + <string name="IMMainland"> + continent + </string> + <string name="IMTeen"> + teen + </string> + <string name="Anyone"> + n'importe qui + </string> + <string name="RegionInfoError"> + erreur + </string> + <string name="RegionInfoAllEstatesOwnedBy"> + tous les domaines appartenant à [OWNER] + </string> + <string name="RegionInfoAllEstatesYouOwn"> + tous les domaines vous appartenant + </string> + <string name="RegionInfoAllEstatesYouManage"> + tous les domaines que vous gérez pour [OWNER] + </string> + <string name="RegionInfoAllowedResidents"> + Toujours autorisé : ([ALLOWEDAGENTS], max [MAXACCESS]) + </string> + <string name="RegionInfoAllowedGroups"> + Groupes toujours autorisés : [ALLOWEDGROUPS], max [MAXACCESS]) + </string> + <string name="RegionInfoBannedResidents"> + Toujours interdits : ([BANNEDAGENTS], max. [MAXBANNED]) + </string> + <string name="RegionInfoListTypeAllowedAgents"> + Toujours autorisé + </string> + <string name="RegionInfoListTypeBannedAgents"> + Toujours interdit + </string> + <string name="RegionInfoAllEstates"> + tous les domaines + </string> + <string name="RegionInfoManagedEstates"> + domaines gérés + </string> + <string name="RegionInfoThisEstate"> + ce domaine + </string> + <string name="AndNMore"> + et [EXTRA_COUNT] plus + </string> + <string name="ScriptLimitsParcelScriptMemory"> + Mémoire des scripts de parcelles + </string> + <string name="ScriptLimitsParcelsOwned"> + Parcelles répertoriées : [PARCELS] + </string> + <string name="ScriptLimitsMemoryUsed"> + Mémoire utilisée : [COUNT] Ko sur [MAX] ; [AVAILABLE] Ko disponibles + </string> + <string name="ScriptLimitsMemoryUsedSimple"> + Mémoire utilisée : [COUNT] Ko + </string> + <string name="ScriptLimitsParcelScriptURLs"> + URL des scripts de parcelles + </string> + <string name="ScriptLimitsURLsUsed"> + URL utilisées : [COUNT] sur [MAX] ; [AVAILABLE] disponible(s) + </string> + <string name="ScriptLimitsURLsUsedSimple"> + URL utilisées : [COUNT] + </string> + <string name="ScriptLimitsRequestError"> + Une erreur est survenue pendant la requête d'informations. + </string> + <string name="ScriptLimitsRequestNoParcelSelected"> + Aucune parcelle sélectionnée + </string> + <string name="ScriptLimitsRequestWrongRegion"> + Erreur : les informations de script ne sont disponibles que dans votre région actuelle. + </string> + <string name="ScriptLimitsRequestWaiting"> + Extraction des informations en cours... + </string> + <string name="ScriptLimitsRequestDontOwnParcel"> + Vous n'avez pas le droit d'examiner cette parcelle. + </string> + <string name="SITTING_ON"> + Assis(e) dessus + </string> + <string name="ATTACH_CHEST"> + Poitrine + </string> + <string name="ATTACH_HEAD"> + Crâne + </string> + <string name="ATTACH_LSHOULDER"> + Épaule gauche + </string> + <string name="ATTACH_RSHOULDER"> + Épaule droite + </string> + <string name="ATTACH_LHAND"> + Main gauche + </string> + <string name="ATTACH_RHAND"> + Main droite + </string> + <string name="ATTACH_LFOOT"> + Pied gauche + </string> + <string name="ATTACH_RFOOT"> + Pied droit + </string> + <string name="ATTACH_BACK"> + Colonne vertébrale + </string> + <string name="ATTACH_PELVIS"> + Bassin + </string> + <string name="ATTACH_MOUTH"> + Bouche + </string> + <string name="ATTACH_CHIN"> + Menton + </string> + <string name="ATTACH_LEAR"> + Oreille gauche + </string> + <string name="ATTACH_REAR"> + Oreille droite + </string> + <string name="ATTACH_LEYE"> + Œil gauche + </string> + <string name="ATTACH_REYE"> + Œil droit + </string> + <string name="ATTACH_NOSE"> + Nez + </string> + <string name="ATTACH_RUARM"> + Bras droit + </string> + <string name="ATTACH_RLARM"> + Avant-bras droit + </string> + <string name="ATTACH_LUARM"> + Bras gauche + </string> + <string name="ATTACH_LLARM"> + Avant-bras gauche + </string> + <string name="ATTACH_RHIP"> + Hanche droite + </string> + <string name="ATTACH_RULEG"> + Cuisse droite + </string> + <string name="ATTACH_RLLEG"> + Jambe droite + </string> + <string name="ATTACH_LHIP"> + Hanche gauche + </string> + <string name="ATTACH_LULEG"> + Cuisse gauche + </string> + <string name="ATTACH_LLLEG"> + Jambe gauche + </string> + <string name="ATTACH_BELLY"> + Estomac + </string> + <string name="ATTACH_LEFT_PEC"> + Pectoral gauche + </string> + <string name="ATTACH_RIGHT_PEC"> + Pectoral droit + </string> + <string name="ATTACH_HUD_CENTER_2"> + HUD centre 2 + </string> + <string name="ATTACH_HUD_TOP_RIGHT"> + HUD en haut à droite + </string> + <string name="ATTACH_HUD_TOP_CENTER"> + HUD en haut au centre + </string> + <string name="ATTACH_HUD_TOP_LEFT"> + HUD en haut à gauche + </string> + <string name="ATTACH_HUD_CENTER_1"> + HUD centre 1 + </string> + <string name="ATTACH_HUD_BOTTOM_LEFT"> + HUD en bas à gauche + </string> + <string name="ATTACH_HUD_BOTTOM"> + HUD en bas + </string> + <string name="ATTACH_HUD_BOTTOM_RIGHT"> + HUD en bas à droite + </string> + <string name="ATTACH_NECK"> + Cou + </string> + <string name="ATTACH_AVATAR_CENTER"> + Centre de l'avatar + </string> + <string name="ATTACH_LHAND_RING1"> + Annulaire gauche + </string> + <string name="ATTACH_RHAND_RING1"> + Annulaire droit + </string> + <string name="ATTACH_TAIL_BASE"> + Base de la queue + </string> + <string name="ATTACH_TAIL_TIP"> + Bout de la queue + </string> + <string name="ATTACH_LWING"> + Aile gauche + </string> + <string name="ATTACH_RWING"> + Aile droite + </string> + <string name="ATTACH_FACE_JAW"> + Mâchoire + </string> + <string name="ATTACH_FACE_LEAR"> + Oreille gauche différente + </string> + <string name="ATTACH_FACE_REAR"> + Oreille droite différente + </string> + <string name="ATTACH_FACE_LEYE"> + Œil gauche différent + </string> + <string name="ATTACH_FACE_REYE"> + Œil droit différent + </string> + <string name="ATTACH_FACE_TONGUE"> + Langue + </string> + <string name="ATTACH_GROIN"> + Aine + </string> + <string name="ATTACH_HIND_LFOOT"> + Pied arrière gauche + </string> + <string name="ATTACH_HIND_RFOOT"> + Pied arrière droit + </string> + <string name="CursorPos"> + Ligne [LINE], colonne [COLUMN] + </string> + <string name="PanelDirCountFound"> + [COUNT] trouvé(s) + </string> + <string name="PanelDirTimeStr"> + [hour12,datetime,slt]:[min,datetime,slt] [ampm,datetime,slt] + </string> + <string name="PanelDirEventsDateText"> + [mthnum,datetime,slt]/[day,datetime,slt] + </string> + <string name="PanelContentsTooltip"> + Contenu de l'objet + </string> + <string name="PanelContentsNewScript"> + Nouveau script + </string> + <string name="DoNotDisturbModeResponseDefault"> + Ce résident a activé Ne pas déranger et verra votre message plus tard. + </string> + <string name="MuteByName"> + (par nom) + </string> + <string name="MuteAgent"> + (résident) + </string> + <string name="MuteObject"> + (objet) + </string> + <string name="MuteGroup"> + (groupe) + </string> + <string name="MuteExternal"> + (externe) + </string> + <string name="RegionNoCovenant"> + Il n'y a aucun règlement pour ce domaine. + </string> + <string name="RegionNoCovenantOtherOwner"> + Il n'y a aucun règlement pour ce domaine. Le terrain sur ce domaine est vendu par le propriétaire, non par Linden Lab. Pour en savoir plus, veuillez contacter le propriétaire. + </string> <string name="covenant_last_modified" value="Dernière modification :"/> <string name="none_text" value=" (aucun)"/> <string name="never_text" value=" (jamais)"/> - <string name="GroupOwned">Propriété du groupe</string> - <string name="Public">Public</string> - <string name="LocalSettings">Réglages locaux</string> - <string name="RegionSettings">Réglages de la région</string> - <string name="NoEnvironmentSettings">Cette région ne prend pas en charge les paramètres environnementaux.</string> - <string name="EnvironmentSun">Soleil</string> - <string name="EnvironmentMoon">Lune</string> - <string name="EnvironmentBloom">Éclat</string> - <string name="EnvironmentCloudNoise">Bruit du nuage</string> - <string name="EnvironmentNormalMap">Carte normale</string> - <string name="EnvironmentTransparent">Transparent</string> - <string name="ClassifiedClicksTxt">Clics : [TELEPORT] téléportation, [MAP] carte, [PROFILE] profil</string> - <string name="ClassifiedUpdateAfterPublish">(mise à jour après la publication)</string> - <string name="NoPicksClassifiedsText">Vous n'avez pas créé de favoris ni de petites annonces Cliquez sur le bouton Plus pour créer un favori ou une petite annonce.</string> - <string name="NoPicksText">Vous n'avez pas créé de favoris Cliquer sur le bouton Nouveau pour créer un favori</string> - <string name="NoClassifiedsText">Vous n'avez pas créé de petites annonces Cliquer sur le bouton Nouveau pour créer une petite annonce.</string> - <string name="NoAvatarPicksClassifiedsText">L'utilisateur n'a ni favoris ni petites annonces.</string> - <string name="NoAvatarPicksText">L'utilisateur n'a pas de favoris</string> - <string name="NoAvatarClassifiedsText">L'utilisateur n'a pas de petites annonces</string> - <string name="PicksClassifiedsLoadingText">Chargement...</string> - <string name="MultiPreviewTitle">Prévisualiser</string> - <string name="MultiPropertiesTitle">Propriétés</string> - <string name="InvOfferAnObjectNamed">Un objet appelé</string> - <string name="InvOfferOwnedByGroup">possédé par le groupe</string> - <string name="InvOfferOwnedByUnknownGroup">possédé par un groupe inconnu</string> - <string name="InvOfferOwnedBy">possédé par</string> - <string name="InvOfferOwnedByUnknownUser">possédé par un résident inconnu</string> - <string name="InvOfferGaveYou">vous a donné</string> - <string name="InvOfferDecline">Vous refusez l'offre [DESC] de <nolink>[NAME]</nolink>.</string> - <string name="GroupMoneyTotal">Total</string> - <string name="GroupMoneyBought">acheté</string> - <string name="GroupMoneyPaidYou">vous a payé</string> - <string name="GroupMoneyPaidInto">payé</string> - <string name="GroupMoneyBoughtPassTo">a acheté un pass à</string> - <string name="GroupMoneyPaidFeeForEvent">a payé des frais pour un événement</string> - <string name="GroupMoneyPaidPrizeForEvent">a payé un prix pour un événement</string> - <string name="GroupMoneyBalance">Solde</string> - <string name="GroupMoneyCredits">Crédits</string> - <string name="GroupMoneyDebits">Débits</string> - <string name="GroupMoneyDate">[weekday,datetime,utc] [day,datetime,utc] [mth,datetime,utc] [year,datetime,utc]</string> - <string name="AcquiredItems">Objets acquis</string> - <string name="Cancel">Annuler</string> - <string name="UploadingCosts">Le chargement de [NAME] coûte [AMOUNT] L$</string> - <string name="BuyingCosts">Cet achat coûte [AMOUNT] L$</string> - <string name="UnknownFileExtension">Extension de fichier inconnue .%s -.wav, .tga, .bmp, .jpg, .jpeg, ou .bvh acceptés</string> - <string name="MuteObject2">Ignorer</string> - <string name="MuteAvatar">Ignorer</string> - <string name="UnmuteObject">Ne plus ignorer</string> - <string name="UnmuteAvatar">Ne plus ignorer</string> - <string name="AddLandmarkNavBarMenu">Ajouter à mes repères...</string> - <string name="EditLandmarkNavBarMenu">Modifier mon repère...</string> - <string name="accel-mac-control">⌃</string> - <string name="accel-mac-command">⌘</string> - <string name="accel-mac-option">⌥</string> - <string name="accel-mac-shift">⇧</string> - <string name="accel-win-control">Ctrl+</string> - <string name="accel-win-alt">Alt+</string> - <string name="accel-win-shift">Maj+</string> - <string name="FileSaved">Fichier enregistré</string> - <string name="Receiving">Réception</string> - <string name="AM">Matin</string> - <string name="PM">Après-midi</string> - <string name="PST">PST</string> - <string name="PDT">PDT</string> - <string name="Direction_Forward">Avant</string> - <string name="Direction_Left">Gauche</string> - <string name="Direction_Right">Droite</string> - <string name="Direction_Back">Arrière</string> - <string name="Direction_North">Nord</string> - <string name="Direction_South">Sud</string> - <string name="Direction_West">Ouest</string> - <string name="Direction_East">Est</string> - <string name="Direction_Up">Haut</string> - <string name="Direction_Down">Bas</string> - <string name="Any Category">Toutes catégories</string> - <string name="Shopping">Shopping</string> - <string name="Land Rental">Terrains à louer</string> - <string name="Property Rental">Propriétés à louer</string> - <string name="Special Attraction">Divertissements</string> - <string name="New Products">Nouveaux produits</string> - <string name="Employment">Emplois</string> - <string name="Wanted">Offres</string> - <string name="Service">Services</string> - <string name="Personal">Divers</string> - <string name="None">Aucun</string> - <string name="Linden Location">Appartenant aux Lindens</string> - <string name="Adult">Adulte</string> - <string name="Arts&Culture">Arts et culture</string> - <string name="Business">Business</string> - <string name="Educational">Éducation</string> - <string name="Gaming">Jeux</string> - <string name="Hangout">Favoris</string> - <string name="Newcomer Friendly">Accueil pour les nouveaux</string> - <string name="Parks&Nature">Parcs et nature</string> - <string name="Residential">Résidentiel</string> - <string name="Stage">Phase</string> - <string name="Other">Autre</string> - <string name="Rental">Location</string> - <string name="Any">Aucun</string> - <string name="You">Vous</string> - <string name=":">:</string> - <string name=",">,</string> - <string name="...">...</string> - <string name="***">***</string> - <string name="(">(</string> - <string name=")">)</string> - <string name=".">.</string> - <string name="'">'</string> - <string name="---">---</string> - <string name="Multiple Media">Médias multiples</string> - <string name="Play Media">Lire/pauser le média</string> - <string name="IntelDriverPage">http://www.intel.com/p/fr_FR/support/detect/graphics</string> - <string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=fr</string> - <string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string> - <string name="MBCmdLineError">Une erreur est survenue lors de la lecture de la ligne de commande. + <string name="GroupOwned"> + Propriété du groupe + </string> + <string name="Public"> + Public + </string> + <string name="LocalSettings"> + Réglages locaux + </string> + <string name="RegionSettings"> + Réglages de la région + </string> + <string name="NoEnvironmentSettings"> + Cette région ne prend pas en charge les paramètres environnementaux. + </string> + <string name="EnvironmentSun"> + Soleil + </string> + <string name="EnvironmentMoon"> + Lune + </string> + <string name="EnvironmentBloom"> + Éclat + </string> + <string name="EnvironmentCloudNoise"> + Bruit du nuage + </string> + <string name="EnvironmentNormalMap"> + Carte normale + </string> + <string name="EnvironmentTransparent"> + Transparent + </string> + <string name="ClassifiedClicksTxt"> + Clics : [TELEPORT] téléportation, [MAP] carte, [PROFILE] profil + </string> + <string name="ClassifiedUpdateAfterPublish"> + (mise à jour après la publication) + </string> + <string name="NoPicksClassifiedsText"> + Vous n'avez pas créé de favoris ni de petites annonces Cliquez sur le bouton Plus pour créer un favori ou une petite annonce. + </string> + <string name="NoPicksText"> + Vous n'avez pas créé de favoris Cliquer sur le bouton Nouveau pour créer un favori + </string> + <string name="NoClassifiedsText"> + Vous n'avez pas créé de petites annonces Cliquer sur le bouton Nouveau pour créer une petite annonce. + </string> + <string name="NoAvatarPicksClassifiedsText"> + L'utilisateur n'a ni favoris ni petites annonces. + </string> + <string name="NoAvatarPicksText"> + L'utilisateur n'a pas de favoris + </string> + <string name="NoAvatarClassifiedsText"> + L'utilisateur n'a pas de petites annonces + </string> + <string name="PicksClassifiedsLoadingText"> + Chargement... + </string> + <string name="MultiPreviewTitle"> + Prévisualiser + </string> + <string name="MultiPropertiesTitle"> + Propriétés + </string> + <string name="InvOfferAnObjectNamed"> + Un objet appelé + </string> + <string name="InvOfferOwnedByGroup"> + possédé par le groupe + </string> + <string name="InvOfferOwnedByUnknownGroup"> + possédé par un groupe inconnu + </string> + <string name="InvOfferOwnedBy"> + possédé par + </string> + <string name="InvOfferOwnedByUnknownUser"> + possédé par un résident inconnu + </string> + <string name="InvOfferGaveYou"> + vous a donné + </string> + <string name="InvOfferDecline"> + Vous refusez l'offre [DESC] de <nolink>[NAME]</nolink>. + </string> + <string name="GroupMoneyTotal"> + Total + </string> + <string name="GroupMoneyBought"> + acheté + </string> + <string name="GroupMoneyPaidYou"> + vous a payé + </string> + <string name="GroupMoneyPaidInto"> + payé + </string> + <string name="GroupMoneyBoughtPassTo"> + a acheté un pass à + </string> + <string name="GroupMoneyPaidFeeForEvent"> + a payé des frais pour un événement + </string> + <string name="GroupMoneyPaidPrizeForEvent"> + a payé un prix pour un événement + </string> + <string name="GroupMoneyBalance"> + Solde + </string> + <string name="GroupMoneyCredits"> + Crédits + </string> + <string name="GroupMoneyDebits"> + Débits + </string> + <string name="GroupMoneyDate"> + [weekday,datetime,utc] [day,datetime,utc] [mth,datetime,utc] [year,datetime,utc] + </string> + <string name="AcquiredItems"> + Objets acquis + </string> + <string name="Cancel"> + Annuler + </string> + <string name="UploadingCosts"> + Le chargement de [NAME] coûte [AMOUNT] L$ + </string> + <string name="BuyingCosts"> + Cet achat coûte [AMOUNT] L$ + </string> + <string name="UnknownFileExtension"> + Extension de fichier inconnue .%s +.wav, .tga, .bmp, .jpg, .jpeg, ou .bvh acceptés + </string> + <string name="MuteObject2"> + Ignorer + </string> + <string name="MuteAvatar"> + Ignorer + </string> + <string name="UnmuteObject"> + Ne plus ignorer + </string> + <string name="UnmuteAvatar"> + Ne plus ignorer + </string> + <string name="AddLandmarkNavBarMenu"> + Ajouter à mes repères... + </string> + <string name="EditLandmarkNavBarMenu"> + Modifier mon repère... + </string> + <string name="accel-mac-control"> + ⌃ + </string> + <string name="accel-mac-command"> + ⌘ + </string> + <string name="accel-mac-option"> + ⌥ + </string> + <string name="accel-mac-shift"> + ⇧ + </string> + <string name="accel-win-control"> + Ctrl+ + </string> + <string name="accel-win-alt"> + Alt+ + </string> + <string name="accel-win-shift"> + Maj+ + </string> + <string name="FileSaved"> + Fichier enregistré + </string> + <string name="Receiving"> + Réception + </string> + <string name="AM"> + Matin + </string> + <string name="PM"> + Après-midi + </string> + <string name="PST"> + PST + </string> + <string name="PDT"> + PDT + </string> + <string name="Direction_Forward"> + Avant + </string> + <string name="Direction_Left"> + Gauche + </string> + <string name="Direction_Right"> + Droite + </string> + <string name="Direction_Back"> + Arrière + </string> + <string name="Direction_North"> + Nord + </string> + <string name="Direction_South"> + Sud + </string> + <string name="Direction_West"> + Ouest + </string> + <string name="Direction_East"> + Est + </string> + <string name="Direction_Up"> + Haut + </string> + <string name="Direction_Down"> + Bas + </string> + <string name="Any Category"> + Toutes catégories + </string> + <string name="Shopping"> + Shopping + </string> + <string name="Land Rental"> + Terrains à louer + </string> + <string name="Property Rental"> + Propriétés à louer + </string> + <string name="Special Attraction"> + Divertissements + </string> + <string name="New Products"> + Nouveaux produits + </string> + <string name="Employment"> + Emplois + </string> + <string name="Wanted"> + Offres + </string> + <string name="Service"> + Services + </string> + <string name="Personal"> + Divers + </string> + <string name="None"> + Aucun + </string> + <string name="Linden Location"> + Appartenant aux Lindens + </string> + <string name="Adult"> + Adulte + </string> + <string name="Arts&Culture"> + Arts et culture + </string> + <string name="Business"> + Business + </string> + <string name="Educational"> + Éducation + </string> + <string name="Gaming"> + Jeux + </string> + <string name="Hangout"> + Favoris + </string> + <string name="Newcomer Friendly"> + Accueil pour les nouveaux + </string> + <string name="Parks&Nature"> + Parcs et nature + </string> + <string name="Residential"> + Résidentiel + </string> + <string name="Stage"> + Phase + </string> + <string name="Other"> + Autre + </string> + <string name="Rental"> + Location + </string> + <string name="Any"> + Aucun + </string> + <string name="You"> + Vous + </string> + <string name=":"> + : + </string> + <string name=","> + , + </string> + <string name="..."> + ... + </string> + <string name="***"> + *** + </string> + <string name="("> + ( + </string> + <string name=")"> + ) + </string> + <string name="."> + . + </string> + <string name="'"> + ' + </string> + <string name="---"> + --- + </string> + <string name="Multiple Media"> + Médias multiples + </string> + <string name="Play Media"> + Lire/pauser le média + </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/fr_FR/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=fr + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> + <string name="MBCmdLineError"> + Une erreur est survenue lors de la lecture de la ligne de commande. Merci de consulter : http://wiki.secondlife.com/wiki/Client_parameters -Erreur :</string> - <string name="MBCmdLineUsg">[APP_NAME] - Utilisation de la ligne de commande :</string> - <string name="MBUnableToAccessFile">[APP_NAME] ne peut accéder à un fichier requis. +Erreur : + </string> + <string name="MBCmdLineUsg"> + [APP_NAME] - Utilisation de la ligne de commande : + </string> + <string name="MBUnableToAccessFile"> + [APP_NAME] ne peut accéder à un fichier requis. Cela vient du fait que quelqu'un a ouvert plusieurs copies ou que votre système pense qu'un fichier est ouvert. Si ce message persiste, veuillez redémarrer votre ordinateur. -Si le problème persiste, vous devrez peut-être complètement désinstaller puis réinstaller [APP_NAME].</string> - <string name="MBFatalError">Erreur fatale</string> - <string name="MBRequiresAltiVec">[APP_NAME] nécessite un microprocesseur AltiVec (version G4 ou antérieure).</string> - <string name="MBAlreadyRunning">[APP_NAME] est déjà en cours d'exécution. +Si le problème persiste, vous devrez peut-être complètement désinstaller puis réinstaller [APP_NAME]. + </string> + <string name="MBFatalError"> + Erreur fatale + </string> + <string name="MBRequiresAltiVec"> + [APP_NAME] nécessite un microprocesseur AltiVec (version G4 ou antérieure). + </string> + <string name="MBAlreadyRunning"> + [APP_NAME] est déjà en cours d'exécution. Vérifiez si une version minimisée du programme apparaît dans votre barre de tâches. -Si ce message persiste, redémarrez votre ordinateur.</string> - <string name="MBFrozenCrashed">[APP_NAME] semble avoir crashé lors de l'utilisation précédente. -Voulez-vous envoyer un rapport de crash ?</string> - <string name="MBAlert">Notification</string> - <string name="MBNoDirectX">[APP_NAME] ne peut détecter DirectX 9.0b ou une version supérieure. +Si ce message persiste, redémarrez votre ordinateur. + </string> + <string name="MBFrozenCrashed"> + [APP_NAME] semble avoir crashé lors de l'utilisation précédente. +Voulez-vous envoyer un rapport de crash ? + </string> + <string name="MBAlert"> + Notification + </string> + <string name="MBNoDirectX"> + [APP_NAME] ne peut détecter DirectX 9.0b ou une version supérieure. [APP_NAME] utilise DirectX pour détecter les matériels et/ou les pilotes qui ne sont pas à jour et peuvent causer des problèmes de stabilité, de performance ou des plantages. Bien que vous puissiez utiliser [APP_NAME] sans DirectX, nous vous recommandons de l'utiliser avec DirectX 9.0b. -Voulez-vous continuer ?</string> - <string name="MBWarning">Avertissement</string> - <string name="MBNoAutoUpdate">Les mises à jour automatiques n'existent pas encore pour Linux. -Veuillez télécharger la dernière version sur www.secondlife.com.</string> - <string name="MBRegClassFailed">RegisterClass a échoué</string> - <string name="MBError">Erreur</string> - <string name="MBFullScreenErr">Impossible d'ouvrir le mode plein écran à [WIDTH] x [HEIGHT]. -Utilisation du mode fenêtré.</string> - <string name="MBDestroyWinFailed">Erreur de fermeture lors de la destruction de la fenêtre (DestroyWindow() a échoué)</string> - <string name="MBShutdownErr">Erreur de fermeture</string> - <string name="MBDevContextErr">Impossible de créer le contexte GL</string> - <string name="MBPixelFmtErr">Impossible de trouver le format pixel approprié</string> - <string name="MBPixelFmtDescErr">Impossible de trouver la description du format pixel</string> - <string name="MBTrueColorWindow">[APP_NAME] nécessite True Color (32 bits) pour s'exécuter. -Accédez aux paramètres d'affichage de votre ordinateur et réglez le mode couleur sur 32 bits.</string> - <string name="MBAlpha">[APP_NAME] ne peut pas s'exécuter, car il n'y pas de canal alpha 8 bits accessible. En général, ceci vient de problèmes avec le pilote de la carte vidéo. +Voulez-vous continuer ? + </string> + <string name="MBWarning"> + Avertissement + </string> + <string name="MBNoAutoUpdate"> + Les mises à jour automatiques n'existent pas encore pour Linux. +Veuillez télécharger la dernière version sur www.secondlife.com. + </string> + <string name="MBRegClassFailed"> + RegisterClass a échoué + </string> + <string name="MBError"> + Erreur + </string> + <string name="MBFullScreenErr"> + Impossible d'ouvrir le mode plein écran à [WIDTH] x [HEIGHT]. +Utilisation du mode fenêtré. + </string> + <string name="MBDestroyWinFailed"> + Erreur de fermeture lors de la destruction de la fenêtre (DestroyWindow() a échoué) + </string> + <string name="MBShutdownErr"> + Erreur de fermeture + </string> + <string name="MBDevContextErr"> + Impossible de créer le contexte GL + </string> + <string name="MBPixelFmtErr"> + Impossible de trouver le format pixel approprié + </string> + <string name="MBPixelFmtDescErr"> + Impossible de trouver la description du format pixel + </string> + <string name="MBTrueColorWindow"> + [APP_NAME] nécessite True Color (32 bits) pour s'exécuter. +Accédez aux paramètres d'affichage de votre ordinateur et réglez le mode couleur sur 32 bits. + </string> + <string name="MBAlpha"> + [APP_NAME] ne peut pas s'exécuter, car il n'y pas de canal alpha 8 bits accessible. En général, ceci vient de problèmes avec le pilote de la carte vidéo. Assurez-vous d'avoir installé le pilote de carte vidéo le plus récent possible. Assurez-vous aussi que votre écran est réglé sur True Color (32 bits) sous Panneau de configuration > Affichage > Paramètres. -Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].</string> - <string name="MBPixelFmtSetErr">Impossible de trouver le format pixel approprié</string> - <string name="MBGLContextErr">Impossible de créer le contexte de rendu GL</string> - <string name="MBGLContextActErr">Impossible d'activer le contexte de rendu GL</string> - <string name="MBVideoDrvErr">[APP_NAME] ne peut pas s'exécuter car les pilotes de votre carte vidéo n'ont pas été installés correctement, ne sont pas à jour, ou sont pour du matériel non pris en charge. Assurez-vous d'avoir des pilotes de cartes vidéos récents, et même si vous avez les plus récents, réinstallez-les. +Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. + </string> + <string name="MBPixelFmtSetErr"> + Impossible de trouver le format pixel approprié + </string> + <string name="MBGLContextErr"> + Impossible de créer le contexte de rendu GL + </string> + <string name="MBGLContextActErr"> + Impossible d'activer le contexte de rendu GL + </string> + <string name="MBVideoDrvErr"> + [APP_NAME] ne peut pas s'exécuter car les pilotes de votre carte vidéo n'ont pas été installés correctement, ne sont pas à jour, ou sont pour du matériel non pris en charge. Assurez-vous d'avoir des pilotes de cartes vidéos récents, et même si vous avez les plus récents, réinstallez-les. -Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].</string> - <string name="5 O'Clock Shadow">Peu</string> - <string name="All White">Tout blancs</string> - <string name="Anime Eyes">Grand yeux</string> - <string name="Arced">Arqués</string> - <string name="Arm Length">Longueur des bras</string> - <string name="Attached">Attachés</string> - <string name="Attached Earlobes">Lobes</string> - <string name="Back Fringe">Mèches de derrière</string> - <string name="Baggy">Plus</string> - <string name="Bangs">Frange</string> - <string name="Beady Eyes">Yeux perçants</string> - <string name="Belly Size">Taille du ventre</string> - <string name="Big">Plus</string> - <string name="Big Butt">Grosses fesses</string> - <string name="Big Hair Back">Volume : Derrière</string> - <string name="Big Hair Front">Volume : Devant</string> - <string name="Big Hair Top">Volume : Haut</string> - <string name="Big Head">Plus</string> - <string name="Big Pectorals">Gros pectoraux</string> - <string name="Big Spikes">Spikes</string> - <string name="Black">Noir</string> - <string name="Blonde">Blond</string> - <string name="Blonde Hair">Cheveux blonds</string> - <string name="Blush">Blush</string> - <string name="Blush Color">Couleur du blush</string> - <string name="Blush Opacity">Opacité du blush</string> - <string name="Body Definition">Contour du corps</string> - <string name="Body Fat">Graisse</string> - <string name="Body Freckles">Grains de beauté</string> - <string name="Body Thick">Plus</string> - <string name="Body Thickness">Épaisseur du corps</string> - <string name="Body Thin">Moins</string> - <string name="Bow Legged">Jambes arquées</string> - <string name="Breast Buoyancy">Hauteur des seins</string> - <string name="Breast Cleavage">Clivage</string> - <string name="Breast Size">Taille des seins</string> - <string name="Bridge Width">Arête du nez</string> - <string name="Broad">Large</string> - <string name="Brow Size">Taille du front</string> - <string name="Bug Eyes">Yeux globuleux</string> - <string name="Bugged Eyes">Yeux globuleux</string> - <string name="Bulbous">En bulbe</string> - <string name="Bulbous Nose">Nez en bulbe</string> - <string name="Breast Physics Mass">Masse des seins</string> - <string name="Breast Physics Smoothing">Lissage des seins</string> - <string name="Breast Physics Gravity">Gravité des seins</string> - <string name="Breast Physics Drag">Résistance de l'air sur les seins</string> - <string name="Breast Physics InOut Max Effect">Effet max.</string> - <string name="Breast Physics InOut Spring">Élasticité</string> - <string name="Breast Physics InOut Gain">Amplification</string> - <string name="Breast Physics InOut Damping">Amortissement</string> - <string name="Breast Physics UpDown Max Effect">Effet max.</string> - <string name="Breast Physics UpDown Spring">Élasticité</string> - <string name="Breast Physics UpDown Gain">Amplification</string> - <string name="Breast Physics UpDown Damping">Amortissement</string> - <string name="Breast Physics LeftRight Max Effect">Effet max.</string> - <string name="Breast Physics LeftRight Spring">Élasticité</string> - <string name="Breast Physics LeftRight Gain">Amplification</string> - <string name="Breast Physics LeftRight Damping">Amortissement</string> - <string name="Belly Physics Mass">Masse du ventre</string> - <string name="Belly Physics Smoothing">Lissage du ventre</string> - <string name="Belly Physics Gravity">Gravité du ventre</string> - <string name="Belly Physics Drag">Résistance de l'air sur le ventre</string> - <string name="Belly Physics UpDown Max Effect">Effet max.</string> - <string name="Belly Physics UpDown Spring">Élasticité</string> - <string name="Belly Physics UpDown Gain">Amplification</string> - <string name="Belly Physics UpDown Damping">Amortissement</string> - <string name="Butt Physics Mass">Masse des fesses</string> - <string name="Butt Physics Smoothing">Lissage des fesses</string> - <string name="Butt Physics Gravity">Gravité des fesses</string> - <string name="Butt Physics Drag">Résistance de l'air sur les fesses</string> - <string name="Butt Physics UpDown Max Effect">Effet max.</string> - <string name="Butt Physics UpDown Spring">Élasticité</string> - <string name="Butt Physics UpDown Gain">Amplification</string> - <string name="Butt Physics UpDown Damping">Amortissement</string> - <string name="Butt Physics LeftRight Max Effect">Effet max.</string> - <string name="Butt Physics LeftRight Spring">Élasticité</string> - <string name="Butt Physics LeftRight Gain">Amplification</string> - <string name="Butt Physics LeftRight Damping">Amortissement</string> - <string name="Bushy Eyebrows">Sourcils touffus</string> - <string name="Bushy Hair">Beaucoup</string> - <string name="Butt Size">Taille des fesses</string> - <string name="Butt Gravity">Gravité des fesses</string> - <string name="bustle skirt">Jupe gonflante</string> - <string name="no bustle">Pas gonflante</string> - <string name="more bustle">Plus gonflante</string> - <string name="Chaplin">Moins</string> - <string name="Cheek Bones">Pommettes</string> - <string name="Chest Size">Taille de la poitrine</string> - <string name="Chin Angle">Angle du menton</string> - <string name="Chin Cleft">Fente du menton</string> - <string name="Chin Curtains">Favoris</string> - <string name="Chin Depth">Profondeur</string> - <string name="Chin Heavy">Menton lourd</string> - <string name="Chin In">Menton rentré</string> - <string name="Chin Out">Menton sorti</string> - <string name="Chin-Neck">Menton-cou</string> - <string name="Clear">Clair</string> - <string name="Cleft">Fendu</string> - <string name="Close Set Eyes">Yeux rapprochés</string> - <string name="Closed">Fermé(s)</string> - <string name="Closed Back">Fermé à l'arrière</string> - <string name="Closed Front">Fermé devant</string> - <string name="Closed Left">Fermé à gauche</string> - <string name="Closed Right">Fermé à droite</string> - <string name="Coin Purse">Mini</string> - <string name="Collar Back">Col arrière</string> - <string name="Collar Front">Col devant</string> - <string name="Corner Down">Coin vers le bas</string> - <string name="Corner Up">Coin vers le haut</string> - <string name="Creased">Fripée</string> - <string name="Crooked Nose">Déviation du nez</string> - <string name="Cuff Flare">Jambes</string> - <string name="Dark">Sombre</string> - <string name="Dark Green">Vert foncé</string> - <string name="Darker">Plus foncé</string> - <string name="Deep">Profonde</string> - <string name="Default Heels">Talons par défaut</string> - <string name="Dense">Dense</string> - <string name="Double Chin">Double menton</string> - <string name="Downturned">Pointant vers le bas</string> - <string name="Duffle Bag">Maxi</string> - <string name="Ear Angle">Angle de l'oreille</string> - <string name="Ear Size">Taille</string> - <string name="Ear Tips">Extrémités</string> - <string name="Egg Head">Proéminence</string> - <string name="Eye Bags">Cernes</string> - <string name="Eye Color">Couleur des yeux</string> - <string name="Eye Depth">Profondeur</string> - <string name="Eye Lightness">Clarté</string> - <string name="Eye Opening">Ouverture</string> - <string name="Eye Pop">Œil proéminent</string> - <string name="Eye Size">Taille de l'œil</string> - <string name="Eye Spacing">Espacement</string> - <string name="Eyebrow Arc">Arc</string> - <string name="Eyebrow Density">Épaisseur sourcils</string> - <string name="Eyebrow Height">Hauteur</string> - <string name="Eyebrow Points">Direction</string> - <string name="Eyebrow Size">Taille</string> - <string name="Eyelash Length">Longueur des cils</string> - <string name="Eyeliner">Eyeliner</string> - <string name="Eyeliner Color">Couleur de l'eyeliner</string> - <string name="Eyes Bugged">Yeux globuleux</string> - <string name="Face Shear">Visage</string> - <string name="Facial Definition">Définition</string> - <string name="Far Set Eyes">Yeux écartés</string> - <string name="Fat Lips">Lèvres épaisses</string> - <string name="Female">Femme</string> - <string name="Fingerless">Sans doigts</string> - <string name="Fingers">Doigts</string> - <string name="Flared Cuffs">Jambes larges</string> - <string name="Flat">Moins</string> - <string name="Flat Butt">Fesses plates</string> - <string name="Flat Head">Tête plate</string> - <string name="Flat Toe">Orteil plat</string> - <string name="Foot Size">Pointure</string> - <string name="Forehead Angle">Angle du front</string> - <string name="Forehead Heavy">Front lourd</string> - <string name="Freckles">Tâches de rousseur</string> - <string name="Front Fringe">Mèches de devant</string> - <string name="Full Back">Arrière touffu</string> - <string name="Full Eyeliner">Eyeliner marqué</string> - <string name="Full Front">Devant touffu</string> - <string name="Full Hair Sides">Côtés touffus</string> - <string name="Full Sides">Côtés touffus</string> - <string name="Glossy">Brillant</string> - <string name="Glove Fingers">Gants avec doigts</string> - <string name="Glove Length">Longueur</string> - <string name="Hair">Cheveux</string> - <string name="Hair Back">Cheveux : Derrière</string> - <string name="Hair Front">Cheveux : Devant</string> - <string name="Hair Sides">Cheveux : Côtés</string> - <string name="Hair Sweep">Sens de la coiffure</string> - <string name="Hair Thickess">Épaisseur cheveux</string> - <string name="Hair Thickness">Épaisseur cheveux</string> - <string name="Hair Tilt">Inclinaison</string> - <string name="Hair Tilted Left">Vers la gauche</string> - <string name="Hair Tilted Right">Vers la droite</string> - <string name="Hair Volume">Cheveux : Volume</string> - <string name="Hand Size">Taille de la main</string> - <string name="Handlebars">Plus</string> - <string name="Head Length">Longueur</string> - <string name="Head Shape">Forme</string> - <string name="Head Size">Taille</string> - <string name="Head Stretch">Allongement</string> - <string name="Heel Height">Talons</string> - <string name="Heel Shape">Forme des talons</string> - <string name="Height">Taille</string> - <string name="High">Haut</string> - <string name="High Heels">Talons hauts</string> - <string name="High Jaw">Haut</string> - <string name="High Platforms">Haute</string> - <string name="High and Tight">Haut et serré</string> - <string name="Higher">Plus élevé</string> - <string name="Hip Length">Longueur hanche</string> - <string name="Hip Width">Largeur hanche</string> - <string name="Hover">Survol</string> - <string name="In">Rentré</string> - <string name="In Shdw Color">Couleur ombre interne</string> - <string name="In Shdw Opacity">Opacité ombre interne</string> - <string name="Inner Eye Corner">Coin interne</string> - <string name="Inner Eye Shadow">Ombre de l'œil interne</string> - <string name="Inner Shadow">Ombre interne</string> - <string name="Jacket Length">Longueur de la veste</string> - <string name="Jacket Wrinkles">Plis de la veste</string> - <string name="Jaw Angle">Angle mâchoire</string> - <string name="Jaw Jut">Saillie mâchoire</string> - <string name="Jaw Shape">Mâchoire</string> - <string name="Join">Rapprochés</string> - <string name="Jowls">Bajoues</string> - <string name="Knee Angle">Angle du genou</string> - <string name="Knock Kneed">Genoux rapprochés</string> - <string name="Large">Plus</string> - <string name="Large Hands">Grandes mains</string> - <string name="Left Part">Raie à gauche</string> - <string name="Leg Length">Longueur</string> - <string name="Leg Muscles">Muscles</string> - <string name="Less">Moins</string> - <string name="Less Body Fat">Moins</string> - <string name="Less Curtains">Moins</string> - <string name="Less Freckles">Moins</string> - <string name="Less Full">Moins</string> - <string name="Less Gravity">Moins</string> - <string name="Less Love">Moins</string> - <string name="Less Muscles">Moins</string> - <string name="Less Muscular">Moins</string> - <string name="Less Rosy">Moins</string> - <string name="Less Round">Moins ronde</string> - <string name="Less Saddle">Moins</string> - <string name="Less Square">Moins carrée</string> - <string name="Less Volume">Moins</string> - <string name="Less soul">Moins</string> - <string name="Lighter">Plus léger</string> - <string name="Lip Cleft">Fente labiale</string> - <string name="Lip Cleft Depth">Prof. fente labiale</string> - <string name="Lip Fullness">Volume des lèvres</string> - <string name="Lip Pinkness">Rougeur des lèvres</string> - <string name="Lip Ratio">Proportion des lèvres</string> - <string name="Lip Thickness">Épaisseur</string> - <string name="Lip Width">Largeur</string> - <string name="Lipgloss">Brillant à lèvres</string> - <string name="Lipstick">Rouge à lèvres</string> - <string name="Lipstick Color">Couleur du rouge à lèvres</string> - <string name="Long">Plus</string> - <string name="Long Head">Tête longue</string> - <string name="Long Hips">Hanches longues</string> - <string name="Long Legs">Jambes longues</string> - <string name="Long Neck">Long cou</string> - <string name="Long Pigtails">Longues couettes</string> - <string name="Long Ponytail">Longue queue de cheval</string> - <string name="Long Torso">Torse long</string> - <string name="Long arms">Bras longs</string> - <string name="Loose Pants">Pantalons amples</string> - <string name="Loose Shirt">Chemise ample</string> - <string name="Loose Sleeves">Manches amples</string> - <string name="Love Handles">Poignées d'amour</string> - <string name="Low">Bas</string> - <string name="Low Heels">Talons bas</string> - <string name="Low Jaw">Bas</string> - <string name="Low Platforms">Basse</string> - <string name="Low and Loose">Bas et ample</string> - <string name="Lower">Abaisser</string> - <string name="Lower Bridge">Arête inférieure</string> - <string name="Lower Cheeks">Joue inférieure</string> - <string name="Male">Homme</string> - <string name="Middle Part">Raie au milieu</string> - <string name="More">Plus</string> - <string name="More Blush">Plus</string> - <string name="More Body Fat">Plus</string> - <string name="More Curtains">Plus</string> - <string name="More Eyeshadow">Plus</string> - <string name="More Freckles">Plus</string> - <string name="More Full">Plus</string> - <string name="More Gravity">Plus</string> - <string name="More Lipstick">Plus</string> - <string name="More Love">Plus</string> - <string name="More Lower Lip">Inférieure plus grosse</string> - <string name="More Muscles">Plus</string> - <string name="More Muscular">Plus</string> - <string name="More Rosy">Plus</string> - <string name="More Round">Plus</string> - <string name="More Saddle">Plus</string> - <string name="More Sloped">Plus</string> - <string name="More Square">Plus</string> - <string name="More Upper Lip">Supérieure plus grosse</string> - <string name="More Vertical">Plus</string> - <string name="More Volume">Plus</string> - <string name="More soul">Plus</string> - <string name="Moustache">Moustache</string> - <string name="Mouth Corner">Coin de la bouche</string> - <string name="Mouth Position">Position</string> - <string name="Mowhawk">Mowhawk</string> - <string name="Muscular">Musclé</string> - <string name="Mutton Chops">Longs</string> - <string name="Nail Polish">Vernis à ongles</string> - <string name="Nail Polish Color">Couleur du vernis</string> - <string name="Narrow">Moins</string> - <string name="Narrow Back">Arrière étroit</string> - <string name="Narrow Front">Devant étroit</string> - <string name="Narrow Lips">Lèvres étroites</string> - <string name="Natural">Naturel</string> - <string name="Neck Length">Longueur du cou</string> - <string name="Neck Thickness">Épaisseur du cou</string> - <string name="No Blush">Pas de blush</string> - <string name="No Eyeliner">Pas d'eyeliner</string> - <string name="No Eyeshadow">Pas d'ombre à paupières</string> - <string name="No Lipgloss">Pas de brillant à lèvres</string> - <string name="No Lipstick">Pas de rouge à lèvres</string> - <string name="No Part">Pas de raie</string> - <string name="No Polish">Pas de vernis</string> - <string name="No Red">Pas de rouge</string> - <string name="No Spikes">Pas de spikes</string> - <string name="No White">Pas de blanc</string> - <string name="No Wrinkles">Pas de rides</string> - <string name="Normal Lower">Normal plus bas</string> - <string name="Normal Upper">Normal plus haut</string> - <string name="Nose Left">Nez à gauche</string> - <string name="Nose Right">Nez à droite</string> - <string name="Nose Size">Taille du nez</string> - <string name="Nose Thickness">Épaisseur du nez</string> - <string name="Nose Tip Angle">Angle bout du nez</string> - <string name="Nose Tip Shape">Forme bout du nez</string> - <string name="Nose Width">Largeur du nez</string> - <string name="Nostril Division">Division narines</string> - <string name="Nostril Width">Largeur narines</string> - <string name="Opaque">Opaque</string> - <string name="Open">Ouvert</string> - <string name="Open Back">Derrière ouvert</string> - <string name="Open Front">Devant ouvert</string> - <string name="Open Left">Ouvert à gauche</string> - <string name="Open Right">Ouvert à droite</string> - <string name="Orange">Orange</string> - <string name="Out">Sorti</string> - <string name="Out Shdw Color">Couleur de l'ombre externe</string> - <string name="Out Shdw Opacity">Opacité de l'ombre externe</string> - <string name="Outer Eye Corner">Coin externe</string> - <string name="Outer Eye Shadow">Ombre de l'œil externe</string> - <string name="Outer Shadow">Ombre externe</string> - <string name="Overbite">Rentrée</string> - <string name="Package">Parties</string> - <string name="Painted Nails">Ongles vernis</string> - <string name="Pale">Pâle</string> - <string name="Pants Crotch">Entrejambe</string> - <string name="Pants Fit">Taille</string> - <string name="Pants Length">Longueur</string> - <string name="Pants Waist">Taille</string> - <string name="Pants Wrinkles">Plis</string> - <string name="Part">Raie</string> - <string name="Part Bangs">Séparation frange</string> - <string name="Pectorals">Pectoraux</string> - <string name="Pigment">Pigmentation</string> - <string name="Pigtails">Couettes</string> - <string name="Pink">Rose</string> - <string name="Pinker">Plus rose</string> - <string name="Platform Height">Platef. (hauteur)</string> - <string name="Platform Width">Platef. (largeur)</string> - <string name="Pointy">Pointue</string> - <string name="Pointy Heels">Talons pointus</string> - <string name="Ponytail">Queue de cheval</string> - <string name="Poofy Skirt">Jupe bouffante</string> - <string name="Pop Left Eye">Œil gauche saillant</string> - <string name="Pop Right Eye">Œil droit saillant</string> - <string name="Puffy">Plus</string> - <string name="Puffy Eyelids">Paup. gonflées</string> - <string name="Rainbow Color">Couleur arc en ciel</string> - <string name="Red Hair">Cheveux roux</string> - <string name="Regular">Standard</string> - <string name="Right Part">Raie à droite</string> - <string name="Rosy Complexion">Teint rosé</string> - <string name="Round">Rond</string> - <string name="Ruddiness">Rougeur</string> - <string name="Ruddy">Rouge</string> - <string name="Rumpled Hair">Texture</string> - <string name="Saddle Bags">Culotte de cheval</string> - <string name="Scrawny Leg">Jambes maigres</string> - <string name="Separate">Séparés</string> - <string name="Shallow">Creux</string> - <string name="Shear Back">Coupe derrière</string> - <string name="Shear Face">Visage</string> - <string name="Shear Front">Front</string> - <string name="Shear Left Up">Haut gauche décalé</string> - <string name="Shear Right Up">Haut droit décalé</string> - <string name="Sheared Back">Dégagé derrière</string> - <string name="Sheared Front">Dégagé devant</string> - <string name="Shift Left">Vers la gauche</string> - <string name="Shift Mouth">Déplacement</string> - <string name="Shift Right">Vers la droite</string> - <string name="Shirt Bottom">Chemise</string> - <string name="Shirt Fit">Taille</string> - <string name="Shirt Wrinkles">Plis</string> - <string name="Shoe Height">Hauteur</string> - <string name="Short">Moins</string> - <string name="Short Arms">Bras courts</string> - <string name="Short Legs">Jambes courtes</string> - <string name="Short Neck">Petit cou</string> - <string name="Short Pigtails">Couettes courtes</string> - <string name="Short Ponytail">Queue de cheval courte</string> - <string name="Short Sideburns">Court</string> - <string name="Short Torso">Torse court</string> - <string name="Short hips">Hanches courtes</string> - <string name="Shoulders">Épaules</string> - <string name="Side Fringe">Mèches sur le côté</string> - <string name="Sideburns">Favoris</string> - <string name="Sides Hair">Cheveux sur le côté</string> - <string name="Sides Hair Down">Cheveux sur le côté en bas</string> - <string name="Sides Hair Up">Cheveux sur le côté en haut</string> - <string name="Skinny Neck">Cou maigre</string> - <string name="Skirt Fit">Taille jupe</string> - <string name="Skirt Length">Longueur jupe</string> - <string name="Slanted Forehead">Front incliné</string> - <string name="Sleeve Length">Longueur manche</string> - <string name="Sleeve Looseness">Ampleur manche</string> - <string name="Slit Back">Fente : Derrière</string> - <string name="Slit Front">Fente : Devant</string> - <string name="Slit Left">Fente : Gauche</string> - <string name="Slit Right">Fente : Droite</string> - <string name="Small">Moins</string> - <string name="Small Hands">Petites mains</string> - <string name="Small Head">Moins</string> - <string name="Smooth">Moins</string> - <string name="Smooth Hair">Cheveux lisses</string> - <string name="Socks Length">Longueur</string> - <string name="Soulpatch">Barbichette</string> - <string name="Sparse">Rares</string> - <string name="Spiked Hair">Mèches en pointe</string> - <string name="Square">Carrée</string> - <string name="Square Toe">Orteil carré</string> - <string name="Squash Head">Écraser la tête</string> - <string name="Stretch Head">Allonger la tête</string> - <string name="Sunken">Saillante</string> - <string name="Sunken Chest">Poitrine enfoncée</string> - <string name="Sunken Eyes">Yeux enfoncés</string> - <string name="Sweep Back">En arrière</string> - <string name="Sweep Forward">Vers l'avant</string> - <string name="Tall">Plus</string> - <string name="Taper Back">Arrière</string> - <string name="Taper Front">Avant</string> - <string name="Thick Heels">Talons épais</string> - <string name="Thick Neck">Cou épais</string> - <string name="Thick Toe">Orteil épais</string> - <string name="Thin">Mince</string> - <string name="Thin Eyebrows">Sourcils fins</string> - <string name="Thin Lips">Lèvres fines</string> - <string name="Thin Nose">Nez fin</string> - <string name="Tight Chin">Menton fin</string> - <string name="Tight Cuffs">Jambes serrées</string> - <string name="Tight Pants">Pantalons serrés</string> - <string name="Tight Shirt">Chemise serrée</string> - <string name="Tight Skirt">Jupe serrée</string> - <string name="Tight Sleeves">Manches serrées</string> - <string name="Toe Shape">Forme de l'orteil</string> - <string name="Toe Thickness">Épaisseur orteil</string> - <string name="Torso Length">Longueur du torse</string> - <string name="Torso Muscles">Muscles du torse</string> - <string name="Torso Scrawny">Torse maigre</string> - <string name="Unattached">Séparés</string> - <string name="Uncreased">Lisse</string> - <string name="Underbite">Sortie</string> - <string name="Unnatural">Artificiel</string> - <string name="Upper Bridge">Arête supérieure</string> - <string name="Upper Cheeks">Joue supérieure</string> - <string name="Upper Chin Cleft">Menton supérieur</string> - <string name="Upper Eyelid Fold">Paupière sup.</string> - <string name="Upturned">En trompette</string> - <string name="Very Red">Très rouge</string> - <string name="Waist Height">Hauteur taille</string> - <string name="Well-Fed">Ronde</string> - <string name="White Hair">Cheveux blancs</string> - <string name="Wide">Plus</string> - <string name="Wide Back">Derrière large</string> - <string name="Wide Front">Devant large</string> - <string name="Wide Lips">Lèvres larges</string> - <string name="Wild">Artificiel</string> - <string name="Wrinkles">Rides</string> - <string name="LocationCtrlAddLandmarkTooltip">Ajouter à mes repères</string> - <string name="LocationCtrlEditLandmarkTooltip">Modifier mon repère</string> - <string name="LocationCtrlInfoBtnTooltip">En savoir plus sur l'emplacement actuel</string> - <string name="LocationCtrlComboBtnTooltip">Historique de mes emplacements</string> - <string name="LocationCtrlForSaleTooltip">Acheter ce terrain</string> - <string name="LocationCtrlVoiceTooltip">Chat vocal indisponible ici</string> - <string name="LocationCtrlFlyTooltip">Vol interdit</string> - <string name="LocationCtrlPushTooltip">Pas de bousculades</string> - <string name="LocationCtrlBuildTooltip">Construction/placement d'objets interdit</string> - <string name="LocationCtrlScriptsTooltip">Scripts interdits</string> - <string name="LocationCtrlDamageTooltip">Santé</string> - <string name="LocationCtrlAdultIconTooltip">Région de type Adulte</string> - <string name="LocationCtrlModerateIconTooltip">Région de type Modéré</string> - <string name="LocationCtrlGeneralIconTooltip">Région de type Général</string> - <string name="LocationCtrlSeeAVsTooltip">Les avatars à l'extérieur de cette parcelle ne peuvent pas voir ni entendre les avatars qui se trouvent à l'intérieur.</string> - <string name="LocationCtrlPathfindingDirtyTooltip">Les objets mobiles risquent de ne pas se comporter correctement dans cette région tant qu'elle n'est pas refigée.</string> - <string name="LocationCtrlPathfindingDisabledTooltip">La recherche de chemin dynamique n'est pas activée dans cette région.</string> - <string name="UpdaterWindowTitle">[APP_NAME] - Mise à jour</string> - <string name="UpdaterNowUpdating">Mise à jour de [APP_NAME]...</string> - <string name="UpdaterNowInstalling">Installation de [APP_NAME]...</string> - <string name="UpdaterUpdatingDescriptive">Le client [APP_NAME] est en train d'être mis à jour. Cela peut prendre un certain temps, merci de votre patience.</string> - <string name="UpdaterProgressBarTextWithEllipses">Mise à jour en cours...</string> - <string name="UpdaterProgressBarText">Mise à jour en cours</string> - <string name="UpdaterFailDownloadTitle">Le téléchargement de la mise à jour a échoué</string> - <string name="UpdaterFailUpdateDescriptive">Une erreur est survenue lors de la mise à jour de [APP_NAME]. Veuillez télécharger la dernière version sur www.secondlife.com.</string> - <string name="UpdaterFailInstallTitle">L'installation de la mise à jour a échoué</string> - <string name="UpdaterFailStartTitle">Impossible de lancer le client</string> - <string name="ItemsComingInTooFastFrom">[APP_NAME] : transfert trop rapide des articles de [FROM_NAME] ; aperçu automatique désactivé pendant [TIME] secondes</string> - <string name="ItemsComingInTooFast">[APP_NAME] : transfert trop rapide des articles ; aperçu automatique désactivé pendant [TIME] secondes</string> - <string name="IM_logging_string">-- Archivage des IM activé --</string> - <string name="IM_typing_start_string">[NAME] est en train d'écrire...</string> - <string name="Unnamed">(sans nom)</string> - <string name="IM_moderated_chat_label">(Modéré : Voix désactivées par défaut)</string> - <string name="IM_unavailable_text_label">Le chat écrit n'est pas disponible pour cet appel.</string> - <string name="IM_muted_text_label">Votre chat écrit a été désactivé par un modérateur de groupe.</string> - <string name="IM_default_text_label">Cliquez ici pour envoyer un message instantané.</string> - <string name="IM_to_label">À</string> - <string name="IM_moderator_label">(Modérateur)</string> - <string name="Saved_message">(Enregistrement : [LONG_TIMESTAMP])</string> - <string name="IM_unblock_only_groups_friends">Pour afficher ce message, vous devez désactiver la case Seuls mes amis et groupes peuvent m'appeler ou m'envoyer un IM, sous Préférences/Confidentialité.</string> - <string name="OnlineStatus">En ligne</string> - <string name="OfflineStatus">Hors ligne</string> - <string name="not_online_msg">Utilisateur non connecté - le message sera enregistré et livré plus tard.</string> - <string name="not_online_inventory">Utilisateur non connecté - l'inventaire a été enregistré</string> - <string name="answered_call">Votre appel a fait l'objet d'une réponse</string> - <string name="you_started_call">Vous appelez.</string> - <string name="you_joined_call">Vous avez rejoint l'appel</string> - <string name="you_auto_rejected_call-im">Vous avez automatiquement refusé l'appel vocal quand le mode Ne pas déranger était activé.</string> - <string name="name_started_call">[NAME] appelle.</string> - <string name="ringing-im">En train de rejoindre l'appel...</string> - <string name="connected-im">Connecté(e), cliquez sur Quitter l'appel pour raccrocher</string> - <string name="hang_up-im">A quitté l'appel</string> - <string name="answering-im">Connexion en cours...</string> - <string name="conference-title">Chat à plusieurs</string> - <string name="conference-title-incoming">Conférence avec [AGENT_NAME]</string> - <string name="inventory_item_offered-im">Objet de l’inventaire [ITEM_NAME] offert</string> - <string name="inventory_folder_offered-im">Dossier de l’inventaire [ITEM_NAME] offert</string> - <string name="share_alert">Faire glisser les objets de l'inventaire ici</string> - <string name="facebook_post_success">Vous avez publié sur Facebook.</string> - <string name="flickr_post_success">Vous avez publié sur Flickr.</string> - <string name="twitter_post_success">Vous avez publié sur Twitter.</string> - <string name="no_session_message">(Session IM inexistante)</string> - <string name="only_user_message">Vous êtes le seul participant à cette session.</string> - <string name="offline_message">[NAME] est hors ligne.</string> - <string name="invite_message">Pour accepter ce chat vocal/vous connecter, cliquez sur le bouton [BUTTON NAME].</string> - <string name="muted_message">Vous ignorez ce résident. Si vous lui envoyez un message, il ne sera plus ignoré.</string> - <string name="generic">Erreur lors de la requête, veuillez réessayer ultérieurement.</string> - <string name="generic_request_error">Erreur lors de la requête, veuillez réessayer ultérieurement.</string> - <string name="insufficient_perms_error">Vous n'avez pas les droits requis.</string> - <string name="session_does_not_exist_error">La session a expiré</string> - <string name="no_ability_error">Vous n'avez pas ce pouvoir.</string> - <string name="no_ability">Vous n'avez pas ce pouvoir.</string> - <string name="not_a_mod_error">Vous n'êtes pas modérateur de session.</string> - <string name="muted">Un modérateur de groupe a désactivé votre chat écrit.</string> - <string name="muted_error">Un modérateur de groupe a désactivé votre chat écrit.</string> - <string name="add_session_event">Impossible d'ajouter des participants à la session de chat avec [RECIPIENT].</string> - <string name="message">Impossible d'envoyer votre message à la session de chat avec [RECIPIENT].</string> - <string name="message_session_event">Impossible d'envoyer votre message à la session de chat avec [RECIPIENT].</string> - <string name="mute">Erreur lors de la modération.</string> - <string name="removed">Vous avez été supprimé du groupe.</string> - <string name="removed_from_group">Vous avez été supprimé du groupe.</string> - <string name="close_on_no_ability">Vous ne pouvez plus participer à la session de chat.</string> - <string name="unread_chat_single">[SOURCES] a dit quelque chose de nouveau</string> - <string name="unread_chat_multiple">[SOURCES] ont dit quelque chose de nouveau</string> - <string name="session_initialization_timed_out_error">Expiration du délai d'initialisation de la session</string> - <string name="Home position set.">Emplacement du domicile défini.</string> - <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string> - <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string> - <string name="paid_you_ldollars">[NAME] vous a payé [AMOUNT] L$ [REASON].</string> - <string name="paid_you_ldollars_gift">[NAME] vous a payé [AMOUNT] L$ : [REASON]</string> - <string name="paid_you_ldollars_no_reason">[NAME] vous a payé [AMOUNT] L$.</string> - <string name="you_paid_ldollars">Vous avez payé à [AMOUNT] L$ [REASON].</string> - <string name="you_paid_ldollars_gift">Vous avez payé à [NAME] [AMOUNT] L$ : [REASON]</string> - <string name="you_paid_ldollars_no_info">Vous avez payé [AMOUNT] L$.</string> - <string name="you_paid_ldollars_no_reason">Vous avez payé à [NAME] [AMOUNT] L$.</string> - <string name="you_paid_ldollars_no_name">Vous avez payé à [AMOUNT] L$ [REASON].</string> - <string name="you_paid_failure_ldollars">Votre paiement de [AMOUNT] L$ à [NAME] [REASON] a échoué.</string> - <string name="you_paid_failure_ldollars_gift">Votre paiement de [AMOUNT] L$ à [NAME] a échoué : [REASON]</string> - <string name="you_paid_failure_ldollars_no_info">Votre paiement de [AMOUNT] L$ a échoué.</string> - <string name="you_paid_failure_ldollars_no_reason">Votre paiement de [AMOUNT] L$ à [NAME] a échoué.</string> - <string name="you_paid_failure_ldollars_no_name">Votre paiement de [AMOUNT] L$ [REASON] a échoué.</string> - <string name="for item">pour l'article suivant : [ITEM]</string> - <string name="for a parcel of land">pour une parcelle de terrain</string> - <string name="for a land access pass">pour un pass d'accès au terrain</string> - <string name="for deeding land">pour une cession de terrain</string> - <string name="to create a group">pour créer un groupe</string> - <string name="to join a group">pour rejoindre un groupe</string> - <string name="to upload">pour charger</string> - <string name="to publish a classified ad">pour publier une petite annonce</string> - <string name="giving">Donner [AMOUNT] L$</string> - <string name="uploading_costs">Le chargement coûte [AMOUNT] L$</string> - <string name="this_costs">Cela coûte [AMOUNT] L$</string> - <string name="buying_selected_land">Achat du terrain sélectionné pour [AMOUNT] L$</string> - <string name="this_object_costs">Cet objet coûte [AMOUNT] L$</string> - <string name="group_role_everyone">Tous</string> - <string name="group_role_officers">Officiers</string> - <string name="group_role_owners">Propriétaires</string> - <string name="group_member_status_online">En ligne</string> - <string name="uploading_abuse_report">Chargement... +Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE]. + </string> + <string name="5 O'Clock Shadow"> + Peu + </string> + <string name="All White"> + Tout blancs + </string> + <string name="Anime Eyes"> + Grand yeux + </string> + <string name="Arced"> + Arqués + </string> + <string name="Arm Length"> + Longueur des bras + </string> + <string name="Attached"> + Attachés + </string> + <string name="Attached Earlobes"> + Lobes + </string> + <string name="Back Fringe"> + Mèches de derrière + </string> + <string name="Baggy"> + Plus + </string> + <string name="Bangs"> + Frange + </string> + <string name="Beady Eyes"> + Yeux perçants + </string> + <string name="Belly Size"> + Taille du ventre + </string> + <string name="Big"> + Plus + </string> + <string name="Big Butt"> + Grosses fesses + </string> + <string name="Big Hair Back"> + Volume : Derrière + </string> + <string name="Big Hair Front"> + Volume : Devant + </string> + <string name="Big Hair Top"> + Volume : Haut + </string> + <string name="Big Head"> + Plus + </string> + <string name="Big Pectorals"> + Gros pectoraux + </string> + <string name="Big Spikes"> + Spikes + </string> + <string name="Black"> + Noir + </string> + <string name="Blonde"> + Blond + </string> + <string name="Blonde Hair"> + Cheveux blonds + </string> + <string name="Blush"> + Blush + </string> + <string name="Blush Color"> + Couleur du blush + </string> + <string name="Blush Opacity"> + Opacité du blush + </string> + <string name="Body Definition"> + Contour du corps + </string> + <string name="Body Fat"> + Graisse + </string> + <string name="Body Freckles"> + Grains de beauté + </string> + <string name="Body Thick"> + Plus + </string> + <string name="Body Thickness"> + Épaisseur du corps + </string> + <string name="Body Thin"> + Moins + </string> + <string name="Bow Legged"> + Jambes arquées + </string> + <string name="Breast Buoyancy"> + Hauteur des seins + </string> + <string name="Breast Cleavage"> + Clivage + </string> + <string name="Breast Size"> + Taille des seins + </string> + <string name="Bridge Width"> + Arête du nez + </string> + <string name="Broad"> + Large + </string> + <string name="Brow Size"> + Taille du front + </string> + <string name="Bug Eyes"> + Yeux globuleux + </string> + <string name="Bugged Eyes"> + Yeux globuleux + </string> + <string name="Bulbous"> + En bulbe + </string> + <string name="Bulbous Nose"> + Nez en bulbe + </string> + <string name="Breast Physics Mass"> + Masse des seins + </string> + <string name="Breast Physics Smoothing"> + Lissage des seins + </string> + <string name="Breast Physics Gravity"> + Gravité des seins + </string> + <string name="Breast Physics Drag"> + Résistance de l'air sur les seins + </string> + <string name="Breast Physics InOut Max Effect"> + Effet max. + </string> + <string name="Breast Physics InOut Spring"> + Élasticité + </string> + <string name="Breast Physics InOut Gain"> + Amplification + </string> + <string name="Breast Physics InOut Damping"> + Amortissement + </string> + <string name="Breast Physics UpDown Max Effect"> + Effet max. + </string> + <string name="Breast Physics UpDown Spring"> + Élasticité + </string> + <string name="Breast Physics UpDown Gain"> + Amplification + </string> + <string name="Breast Physics UpDown Damping"> + Amortissement + </string> + <string name="Breast Physics LeftRight Max Effect"> + Effet max. + </string> + <string name="Breast Physics LeftRight Spring"> + Élasticité + </string> + <string name="Breast Physics LeftRight Gain"> + Amplification + </string> + <string name="Breast Physics LeftRight Damping"> + Amortissement + </string> + <string name="Belly Physics Mass"> + Masse du ventre + </string> + <string name="Belly Physics Smoothing"> + Lissage du ventre + </string> + <string name="Belly Physics Gravity"> + Gravité du ventre + </string> + <string name="Belly Physics Drag"> + Résistance de l'air sur le ventre + </string> + <string name="Belly Physics UpDown Max Effect"> + Effet max. + </string> + <string name="Belly Physics UpDown Spring"> + Élasticité + </string> + <string name="Belly Physics UpDown Gain"> + Amplification + </string> + <string name="Belly Physics UpDown Damping"> + Amortissement + </string> + <string name="Butt Physics Mass"> + Masse des fesses + </string> + <string name="Butt Physics Smoothing"> + Lissage des fesses + </string> + <string name="Butt Physics Gravity"> + Gravité des fesses + </string> + <string name="Butt Physics Drag"> + Résistance de l'air sur les fesses + </string> + <string name="Butt Physics UpDown Max Effect"> + Effet max. + </string> + <string name="Butt Physics UpDown Spring"> + Élasticité + </string> + <string name="Butt Physics UpDown Gain"> + Amplification + </string> + <string name="Butt Physics UpDown Damping"> + Amortissement + </string> + <string name="Butt Physics LeftRight Max Effect"> + Effet max. + </string> + <string name="Butt Physics LeftRight Spring"> + Élasticité + </string> + <string name="Butt Physics LeftRight Gain"> + Amplification + </string> + <string name="Butt Physics LeftRight Damping"> + Amortissement + </string> + <string name="Bushy Eyebrows"> + Sourcils touffus + </string> + <string name="Bushy Hair"> + Beaucoup + </string> + <string name="Butt Size"> + Taille des fesses + </string> + <string name="Butt Gravity"> + Gravité des fesses + </string> + <string name="bustle skirt"> + Jupe gonflante + </string> + <string name="no bustle"> + Pas gonflante + </string> + <string name="more bustle"> + Plus gonflante + </string> + <string name="Chaplin"> + Moins + </string> + <string name="Cheek Bones"> + Pommettes + </string> + <string name="Chest Size"> + Taille de la poitrine + </string> + <string name="Chin Angle"> + Angle du menton + </string> + <string name="Chin Cleft"> + Fente du menton + </string> + <string name="Chin Curtains"> + Favoris + </string> + <string name="Chin Depth"> + Profondeur + </string> + <string name="Chin Heavy"> + Menton lourd + </string> + <string name="Chin In"> + Menton rentré + </string> + <string name="Chin Out"> + Menton sorti + </string> + <string name="Chin-Neck"> + Menton-cou + </string> + <string name="Clear"> + Clair + </string> + <string name="Cleft"> + Fendu + </string> + <string name="Close Set Eyes"> + Yeux rapprochés + </string> + <string name="Closed"> + Fermé(s) + </string> + <string name="Closed Back"> + Fermé à l'arrière + </string> + <string name="Closed Front"> + Fermé devant + </string> + <string name="Closed Left"> + Fermé à gauche + </string> + <string name="Closed Right"> + Fermé à droite + </string> + <string name="Coin Purse"> + Mini + </string> + <string name="Collar Back"> + Col arrière + </string> + <string name="Collar Front"> + Col devant + </string> + <string name="Corner Down"> + Coin vers le bas + </string> + <string name="Corner Up"> + Coin vers le haut + </string> + <string name="Creased"> + Fripée + </string> + <string name="Crooked Nose"> + Déviation du nez + </string> + <string name="Cuff Flare"> + Jambes + </string> + <string name="Dark"> + Sombre + </string> + <string name="Dark Green"> + Vert foncé + </string> + <string name="Darker"> + Plus foncé + </string> + <string name="Deep"> + Profonde + </string> + <string name="Default Heels"> + Talons par défaut + </string> + <string name="Dense"> + Dense + </string> + <string name="Double Chin"> + Double menton + </string> + <string name="Downturned"> + Pointant vers le bas + </string> + <string name="Duffle Bag"> + Maxi + </string> + <string name="Ear Angle"> + Angle de l'oreille + </string> + <string name="Ear Size"> + Taille + </string> + <string name="Ear Tips"> + Extrémités + </string> + <string name="Egg Head"> + Proéminence + </string> + <string name="Eye Bags"> + Cernes + </string> + <string name="Eye Color"> + Couleur des yeux + </string> + <string name="Eye Depth"> + Profondeur + </string> + <string name="Eye Lightness"> + Clarté + </string> + <string name="Eye Opening"> + Ouverture + </string> + <string name="Eye Pop"> + Œil proéminent + </string> + <string name="Eye Size"> + Taille de l'œil + </string> + <string name="Eye Spacing"> + Espacement + </string> + <string name="Eyebrow Arc"> + Arc + </string> + <string name="Eyebrow Density"> + Épaisseur sourcils + </string> + <string name="Eyebrow Height"> + Hauteur + </string> + <string name="Eyebrow Points"> + Direction + </string> + <string name="Eyebrow Size"> + Taille + </string> + <string name="Eyelash Length"> + Longueur des cils + </string> + <string name="Eyeliner"> + Eyeliner + </string> + <string name="Eyeliner Color"> + Couleur de l'eyeliner + </string> + <string name="Eyes Bugged"> + Yeux globuleux + </string> + <string name="Face Shear"> + Visage + </string> + <string name="Facial Definition"> + Définition + </string> + <string name="Far Set Eyes"> + Yeux écartés + </string> + <string name="Fat Lips"> + Lèvres épaisses + </string> + <string name="Female"> + Femme + </string> + <string name="Fingerless"> + Sans doigts + </string> + <string name="Fingers"> + Doigts + </string> + <string name="Flared Cuffs"> + Jambes larges + </string> + <string name="Flat"> + Moins + </string> + <string name="Flat Butt"> + Fesses plates + </string> + <string name="Flat Head"> + Tête plate + </string> + <string name="Flat Toe"> + Orteil plat + </string> + <string name="Foot Size"> + Pointure + </string> + <string name="Forehead Angle"> + Angle du front + </string> + <string name="Forehead Heavy"> + Front lourd + </string> + <string name="Freckles"> + Tâches de rousseur + </string> + <string name="Front Fringe"> + Mèches de devant + </string> + <string name="Full Back"> + Arrière touffu + </string> + <string name="Full Eyeliner"> + Eyeliner marqué + </string> + <string name="Full Front"> + Devant touffu + </string> + <string name="Full Hair Sides"> + Côtés touffus + </string> + <string name="Full Sides"> + Côtés touffus + </string> + <string name="Glossy"> + Brillant + </string> + <string name="Glove Fingers"> + Gants avec doigts + </string> + <string name="Glove Length"> + Longueur + </string> + <string name="Hair"> + Cheveux + </string> + <string name="Hair Back"> + Cheveux : Derrière + </string> + <string name="Hair Front"> + Cheveux : Devant + </string> + <string name="Hair Sides"> + Cheveux : Côtés + </string> + <string name="Hair Sweep"> + Sens de la coiffure + </string> + <string name="Hair Thickess"> + Épaisseur cheveux + </string> + <string name="Hair Thickness"> + Épaisseur cheveux + </string> + <string name="Hair Tilt"> + Inclinaison + </string> + <string name="Hair Tilted Left"> + Vers la gauche + </string> + <string name="Hair Tilted Right"> + Vers la droite + </string> + <string name="Hair Volume"> + Cheveux : Volume + </string> + <string name="Hand Size"> + Taille de la main + </string> + <string name="Handlebars"> + Plus + </string> + <string name="Head Length"> + Longueur + </string> + <string name="Head Shape"> + Forme + </string> + <string name="Head Size"> + Taille + </string> + <string name="Head Stretch"> + Allongement + </string> + <string name="Heel Height"> + Talons + </string> + <string name="Heel Shape"> + Forme des talons + </string> + <string name="Height"> + Taille + </string> + <string name="High"> + Haut + </string> + <string name="High Heels"> + Talons hauts + </string> + <string name="High Jaw"> + Haut + </string> + <string name="High Platforms"> + Haute + </string> + <string name="High and Tight"> + Haut et serré + </string> + <string name="Higher"> + Plus élevé + </string> + <string name="Hip Length"> + Longueur hanche + </string> + <string name="Hip Width"> + Largeur hanche + </string> + <string name="Hover"> + Survol + </string> + <string name="In"> + Rentré + </string> + <string name="In Shdw Color"> + Couleur ombre interne + </string> + <string name="In Shdw Opacity"> + Opacité ombre interne + </string> + <string name="Inner Eye Corner"> + Coin interne + </string> + <string name="Inner Eye Shadow"> + Ombre de l'œil interne + </string> + <string name="Inner Shadow"> + Ombre interne + </string> + <string name="Jacket Length"> + Longueur de la veste + </string> + <string name="Jacket Wrinkles"> + Plis de la veste + </string> + <string name="Jaw Angle"> + Angle mâchoire + </string> + <string name="Jaw Jut"> + Saillie mâchoire + </string> + <string name="Jaw Shape"> + Mâchoire + </string> + <string name="Join"> + Rapprochés + </string> + <string name="Jowls"> + Bajoues + </string> + <string name="Knee Angle"> + Angle du genou + </string> + <string name="Knock Kneed"> + Genoux rapprochés + </string> + <string name="Large"> + Plus + </string> + <string name="Large Hands"> + Grandes mains + </string> + <string name="Left Part"> + Raie à gauche + </string> + <string name="Leg Length"> + Longueur + </string> + <string name="Leg Muscles"> + Muscles + </string> + <string name="Less"> + Moins + </string> + <string name="Less Body Fat"> + Moins + </string> + <string name="Less Curtains"> + Moins + </string> + <string name="Less Freckles"> + Moins + </string> + <string name="Less Full"> + Moins + </string> + <string name="Less Gravity"> + Moins + </string> + <string name="Less Love"> + Moins + </string> + <string name="Less Muscles"> + Moins + </string> + <string name="Less Muscular"> + Moins + </string> + <string name="Less Rosy"> + Moins + </string> + <string name="Less Round"> + Moins ronde + </string> + <string name="Less Saddle"> + Moins + </string> + <string name="Less Square"> + Moins carrée + </string> + <string name="Less Volume"> + Moins + </string> + <string name="Less soul"> + Moins + </string> + <string name="Lighter"> + Plus léger + </string> + <string name="Lip Cleft"> + Fente labiale + </string> + <string name="Lip Cleft Depth"> + Prof. fente labiale + </string> + <string name="Lip Fullness"> + Volume des lèvres + </string> + <string name="Lip Pinkness"> + Rougeur des lèvres + </string> + <string name="Lip Ratio"> + Proportion des lèvres + </string> + <string name="Lip Thickness"> + Épaisseur + </string> + <string name="Lip Width"> + Largeur + </string> + <string name="Lipgloss"> + Brillant à lèvres + </string> + <string name="Lipstick"> + Rouge à lèvres + </string> + <string name="Lipstick Color"> + Couleur du rouge à lèvres + </string> + <string name="Long"> + Plus + </string> + <string name="Long Head"> + Tête longue + </string> + <string name="Long Hips"> + Hanches longues + </string> + <string name="Long Legs"> + Jambes longues + </string> + <string name="Long Neck"> + Long cou + </string> + <string name="Long Pigtails"> + Longues couettes + </string> + <string name="Long Ponytail"> + Longue queue de cheval + </string> + <string name="Long Torso"> + Torse long + </string> + <string name="Long arms"> + Bras longs + </string> + <string name="Loose Pants"> + Pantalons amples + </string> + <string name="Loose Shirt"> + Chemise ample + </string> + <string name="Loose Sleeves"> + Manches amples + </string> + <string name="Love Handles"> + Poignées d'amour + </string> + <string name="Low"> + Bas + </string> + <string name="Low Heels"> + Talons bas + </string> + <string name="Low Jaw"> + Bas + </string> + <string name="Low Platforms"> + Basse + </string> + <string name="Low and Loose"> + Bas et ample + </string> + <string name="Lower"> + Abaisser + </string> + <string name="Lower Bridge"> + Arête inférieure + </string> + <string name="Lower Cheeks"> + Joue inférieure + </string> + <string name="Male"> + Homme + </string> + <string name="Middle Part"> + Raie au milieu + </string> + <string name="More"> + Plus + </string> + <string name="More Blush"> + Plus + </string> + <string name="More Body Fat"> + Plus + </string> + <string name="More Curtains"> + Plus + </string> + <string name="More Eyeshadow"> + Plus + </string> + <string name="More Freckles"> + Plus + </string> + <string name="More Full"> + Plus + </string> + <string name="More Gravity"> + Plus + </string> + <string name="More Lipstick"> + Plus + </string> + <string name="More Love"> + Plus + </string> + <string name="More Lower Lip"> + Inférieure plus grosse + </string> + <string name="More Muscles"> + Plus + </string> + <string name="More Muscular"> + Plus + </string> + <string name="More Rosy"> + Plus + </string> + <string name="More Round"> + Plus + </string> + <string name="More Saddle"> + Plus + </string> + <string name="More Sloped"> + Plus + </string> + <string name="More Square"> + Plus + </string> + <string name="More Upper Lip"> + Supérieure plus grosse + </string> + <string name="More Vertical"> + Plus + </string> + <string name="More Volume"> + Plus + </string> + <string name="More soul"> + Plus + </string> + <string name="Moustache"> + Moustache + </string> + <string name="Mouth Corner"> + Coin de la bouche + </string> + <string name="Mouth Position"> + Position + </string> + <string name="Mowhawk"> + Mowhawk + </string> + <string name="Muscular"> + Musclé + </string> + <string name="Mutton Chops"> + Longs + </string> + <string name="Nail Polish"> + Vernis à ongles + </string> + <string name="Nail Polish Color"> + Couleur du vernis + </string> + <string name="Narrow"> + Moins + </string> + <string name="Narrow Back"> + Arrière étroit + </string> + <string name="Narrow Front"> + Devant étroit + </string> + <string name="Narrow Lips"> + Lèvres étroites + </string> + <string name="Natural"> + Naturel + </string> + <string name="Neck Length"> + Longueur du cou + </string> + <string name="Neck Thickness"> + Épaisseur du cou + </string> + <string name="No Blush"> + Pas de blush + </string> + <string name="No Eyeliner"> + Pas d'eyeliner + </string> + <string name="No Eyeshadow"> + Pas d'ombre à paupières + </string> + <string name="No Lipgloss"> + Pas de brillant à lèvres + </string> + <string name="No Lipstick"> + Pas de rouge à lèvres + </string> + <string name="No Part"> + Pas de raie + </string> + <string name="No Polish"> + Pas de vernis + </string> + <string name="No Red"> + Pas de rouge + </string> + <string name="No Spikes"> + Pas de spikes + </string> + <string name="No White"> + Pas de blanc + </string> + <string name="No Wrinkles"> + Pas de rides + </string> + <string name="Normal Lower"> + Normal plus bas + </string> + <string name="Normal Upper"> + Normal plus haut + </string> + <string name="Nose Left"> + Nez à gauche + </string> + <string name="Nose Right"> + Nez à droite + </string> + <string name="Nose Size"> + Taille du nez + </string> + <string name="Nose Thickness"> + Épaisseur du nez + </string> + <string name="Nose Tip Angle"> + Angle bout du nez + </string> + <string name="Nose Tip Shape"> + Forme bout du nez + </string> + <string name="Nose Width"> + Largeur du nez + </string> + <string name="Nostril Division"> + Division narines + </string> + <string name="Nostril Width"> + Largeur narines + </string> + <string name="Opaque"> + Opaque + </string> + <string name="Open"> + Ouvert + </string> + <string name="Open Back"> + Derrière ouvert + </string> + <string name="Open Front"> + Devant ouvert + </string> + <string name="Open Left"> + Ouvert à gauche + </string> + <string name="Open Right"> + Ouvert à droite + </string> + <string name="Orange"> + Orange + </string> + <string name="Out"> + Sorti + </string> + <string name="Out Shdw Color"> + Couleur de l'ombre externe + </string> + <string name="Out Shdw Opacity"> + Opacité de l'ombre externe + </string> + <string name="Outer Eye Corner"> + Coin externe + </string> + <string name="Outer Eye Shadow"> + Ombre de l'œil externe + </string> + <string name="Outer Shadow"> + Ombre externe + </string> + <string name="Overbite"> + Rentrée + </string> + <string name="Package"> + Parties + </string> + <string name="Painted Nails"> + Ongles vernis + </string> + <string name="Pale"> + Pâle + </string> + <string name="Pants Crotch"> + Entrejambe + </string> + <string name="Pants Fit"> + Taille + </string> + <string name="Pants Length"> + Longueur + </string> + <string name="Pants Waist"> + Taille + </string> + <string name="Pants Wrinkles"> + Plis + </string> + <string name="Part"> + Raie + </string> + <string name="Part Bangs"> + Séparation frange + </string> + <string name="Pectorals"> + Pectoraux + </string> + <string name="Pigment"> + Pigmentation + </string> + <string name="Pigtails"> + Couettes + </string> + <string name="Pink"> + Rose + </string> + <string name="Pinker"> + Plus rose + </string> + <string name="Platform Height"> + Platef. (hauteur) + </string> + <string name="Platform Width"> + Platef. (largeur) + </string> + <string name="Pointy"> + Pointue + </string> + <string name="Pointy Heels"> + Talons pointus + </string> + <string name="Ponytail"> + Queue de cheval + </string> + <string name="Poofy Skirt"> + Jupe bouffante + </string> + <string name="Pop Left Eye"> + Œil gauche saillant + </string> + <string name="Pop Right Eye"> + Œil droit saillant + </string> + <string name="Puffy"> + Plus + </string> + <string name="Puffy Eyelids"> + Paup. gonflées + </string> + <string name="Rainbow Color"> + Couleur arc en ciel + </string> + <string name="Red Hair"> + Cheveux roux + </string> + <string name="Regular"> + Standard + </string> + <string name="Right Part"> + Raie à droite + </string> + <string name="Rosy Complexion"> + Teint rosé + </string> + <string name="Round"> + Rond + </string> + <string name="Ruddiness"> + Rougeur + </string> + <string name="Ruddy"> + Rouge + </string> + <string name="Rumpled Hair"> + Texture + </string> + <string name="Saddle Bags"> + Culotte de cheval + </string> + <string name="Scrawny Leg"> + Jambes maigres + </string> + <string name="Separate"> + Séparés + </string> + <string name="Shallow"> + Creux + </string> + <string name="Shear Back"> + Coupe derrière + </string> + <string name="Shear Face"> + Visage + </string> + <string name="Shear Front"> + Front + </string> + <string name="Shear Left Up"> + Haut gauche décalé + </string> + <string name="Shear Right Up"> + Haut droit décalé + </string> + <string name="Sheared Back"> + Dégagé derrière + </string> + <string name="Sheared Front"> + Dégagé devant + </string> + <string name="Shift Left"> + Vers la gauche + </string> + <string name="Shift Mouth"> + Déplacement + </string> + <string name="Shift Right"> + Vers la droite + </string> + <string name="Shirt Bottom"> + Chemise + </string> + <string name="Shirt Fit"> + Taille + </string> + <string name="Shirt Wrinkles"> + Plis + </string> + <string name="Shoe Height"> + Hauteur + </string> + <string name="Short"> + Moins + </string> + <string name="Short Arms"> + Bras courts + </string> + <string name="Short Legs"> + Jambes courtes + </string> + <string name="Short Neck"> + Petit cou + </string> + <string name="Short Pigtails"> + Couettes courtes + </string> + <string name="Short Ponytail"> + Queue de cheval courte + </string> + <string name="Short Sideburns"> + Court + </string> + <string name="Short Torso"> + Torse court + </string> + <string name="Short hips"> + Hanches courtes + </string> + <string name="Shoulders"> + Épaules + </string> + <string name="Side Fringe"> + Mèches sur le côté + </string> + <string name="Sideburns"> + Favoris + </string> + <string name="Sides Hair"> + Cheveux sur le côté + </string> + <string name="Sides Hair Down"> + Cheveux sur le côté en bas + </string> + <string name="Sides Hair Up"> + Cheveux sur le côté en haut + </string> + <string name="Skinny Neck"> + Cou maigre + </string> + <string name="Skirt Fit"> + Taille jupe + </string> + <string name="Skirt Length"> + Longueur jupe + </string> + <string name="Slanted Forehead"> + Front incliné + </string> + <string name="Sleeve Length"> + Longueur manche + </string> + <string name="Sleeve Looseness"> + Ampleur manche + </string> + <string name="Slit Back"> + Fente : Derrière + </string> + <string name="Slit Front"> + Fente : Devant + </string> + <string name="Slit Left"> + Fente : Gauche + </string> + <string name="Slit Right"> + Fente : Droite + </string> + <string name="Small"> + Moins + </string> + <string name="Small Hands"> + Petites mains + </string> + <string name="Small Head"> + Moins + </string> + <string name="Smooth"> + Moins + </string> + <string name="Smooth Hair"> + Cheveux lisses + </string> + <string name="Socks Length"> + Longueur + </string> + <string name="Soulpatch"> + Barbichette + </string> + <string name="Sparse"> + Rares + </string> + <string name="Spiked Hair"> + Mèches en pointe + </string> + <string name="Square"> + Carrée + </string> + <string name="Square Toe"> + Orteil carré + </string> + <string name="Squash Head"> + Écraser la tête + </string> + <string name="Stretch Head"> + Allonger la tête + </string> + <string name="Sunken"> + Saillante + </string> + <string name="Sunken Chest"> + Poitrine enfoncée + </string> + <string name="Sunken Eyes"> + Yeux enfoncés + </string> + <string name="Sweep Back"> + En arrière + </string> + <string name="Sweep Forward"> + Vers l'avant + </string> + <string name="Tall"> + Plus + </string> + <string name="Taper Back"> + Arrière + </string> + <string name="Taper Front"> + Avant + </string> + <string name="Thick Heels"> + Talons épais + </string> + <string name="Thick Neck"> + Cou épais + </string> + <string name="Thick Toe"> + Orteil épais + </string> + <string name="Thin"> + Mince + </string> + <string name="Thin Eyebrows"> + Sourcils fins + </string> + <string name="Thin Lips"> + Lèvres fines + </string> + <string name="Thin Nose"> + Nez fin + </string> + <string name="Tight Chin"> + Menton fin + </string> + <string name="Tight Cuffs"> + Jambes serrées + </string> + <string name="Tight Pants"> + Pantalons serrés + </string> + <string name="Tight Shirt"> + Chemise serrée + </string> + <string name="Tight Skirt"> + Jupe serrée + </string> + <string name="Tight Sleeves"> + Manches serrées + </string> + <string name="Toe Shape"> + Forme de l'orteil + </string> + <string name="Toe Thickness"> + Épaisseur orteil + </string> + <string name="Torso Length"> + Longueur du torse + </string> + <string name="Torso Muscles"> + Muscles du torse + </string> + <string name="Torso Scrawny"> + Torse maigre + </string> + <string name="Unattached"> + Séparés + </string> + <string name="Uncreased"> + Lisse + </string> + <string name="Underbite"> + Sortie + </string> + <string name="Unnatural"> + Artificiel + </string> + <string name="Upper Bridge"> + Arête supérieure + </string> + <string name="Upper Cheeks"> + Joue supérieure + </string> + <string name="Upper Chin Cleft"> + Menton supérieur + </string> + <string name="Upper Eyelid Fold"> + Paupière sup. + </string> + <string name="Upturned"> + En trompette + </string> + <string name="Very Red"> + Très rouge + </string> + <string name="Waist Height"> + Hauteur taille + </string> + <string name="Well-Fed"> + Ronde + </string> + <string name="White Hair"> + Cheveux blancs + </string> + <string name="Wide"> + Plus + </string> + <string name="Wide Back"> + Derrière large + </string> + <string name="Wide Front"> + Devant large + </string> + <string name="Wide Lips"> + Lèvres larges + </string> + <string name="Wild"> + Artificiel + </string> + <string name="Wrinkles"> + Rides + </string> + <string name="LocationCtrlAddLandmarkTooltip"> + Ajouter à mes repères + </string> + <string name="LocationCtrlEditLandmarkTooltip"> + Modifier mon repère + </string> + <string name="LocationCtrlInfoBtnTooltip"> + En savoir plus sur l'emplacement actuel + </string> + <string name="LocationCtrlComboBtnTooltip"> + Historique de mes emplacements + </string> + <string name="LocationCtrlForSaleTooltip"> + Acheter ce terrain + </string> + <string name="LocationCtrlVoiceTooltip"> + Chat vocal indisponible ici + </string> + <string name="LocationCtrlFlyTooltip"> + Vol interdit + </string> + <string name="LocationCtrlPushTooltip"> + Pas de bousculades + </string> + <string name="LocationCtrlBuildTooltip"> + Construction/placement d'objets interdit + </string> + <string name="LocationCtrlScriptsTooltip"> + Scripts interdits + </string> + <string name="LocationCtrlDamageTooltip"> + Santé + </string> + <string name="LocationCtrlAdultIconTooltip"> + Région de type Adulte + </string> + <string name="LocationCtrlModerateIconTooltip"> + Région de type Modéré + </string> + <string name="LocationCtrlGeneralIconTooltip"> + Région de type Général + </string> + <string name="LocationCtrlSeeAVsTooltip"> + Les avatars à l'extérieur de cette parcelle ne peuvent pas voir ni entendre les avatars qui se trouvent à l'intérieur. + </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Les objets mobiles risquent de ne pas se comporter correctement dans cette région tant qu'elle n'est pas refigée. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + La recherche de chemin dynamique n'est pas activée dans cette région. + </string> + <string name="UpdaterWindowTitle"> + [APP_NAME] - Mise à jour + </string> + <string name="UpdaterNowUpdating"> + Mise à jour de [APP_NAME]... + </string> + <string name="UpdaterNowInstalling"> + Installation de [APP_NAME]... + </string> + <string name="UpdaterUpdatingDescriptive"> + Le client [APP_NAME] est en train d'être mis à jour. Cela peut prendre un certain temps, merci de votre patience. + </string> + <string name="UpdaterProgressBarTextWithEllipses"> + Mise à jour en cours... + </string> + <string name="UpdaterProgressBarText"> + Mise à jour en cours + </string> + <string name="UpdaterFailDownloadTitle"> + Le téléchargement de la mise à jour a échoué + </string> + <string name="UpdaterFailUpdateDescriptive"> + Une erreur est survenue lors de la mise à jour de [APP_NAME]. Veuillez télécharger la dernière version sur www.secondlife.com. + </string> + <string name="UpdaterFailInstallTitle"> + L'installation de la mise à jour a échoué + </string> + <string name="UpdaterFailStartTitle"> + Impossible de lancer le client + </string> + <string name="ItemsComingInTooFastFrom"> + [APP_NAME] : transfert trop rapide des articles de [FROM_NAME] ; aperçu automatique désactivé pendant [TIME] secondes + </string> + <string name="ItemsComingInTooFast"> + [APP_NAME] : transfert trop rapide des articles ; aperçu automatique désactivé pendant [TIME] secondes + </string> + <string name="IM_logging_string"> + -- Archivage des IM activé -- + </string> + <string name="IM_typing_start_string"> + [NAME] est en train d'écrire... + </string> + <string name="Unnamed"> + (sans nom) + </string> + <string name="IM_moderated_chat_label"> + (Modéré : Voix désactivées par défaut) + </string> + <string name="IM_unavailable_text_label"> + Le chat écrit n'est pas disponible pour cet appel. + </string> + <string name="IM_muted_text_label"> + Votre chat écrit a été désactivé par un modérateur de groupe. + </string> + <string name="IM_default_text_label"> + Cliquez ici pour envoyer un message instantané. + </string> + <string name="IM_to_label"> + À + </string> + <string name="IM_moderator_label"> + (Modérateur) + </string> + <string name="Saved_message"> + (Enregistrement : [LONG_TIMESTAMP]) + </string> + <string name="IM_unblock_only_groups_friends"> + Pour afficher ce message, vous devez désactiver la case Seuls mes amis et groupes peuvent m'appeler ou m'envoyer un IM, sous Préférences/Confidentialité. + </string> + <string name="OnlineStatus"> + En ligne + </string> + <string name="OfflineStatus"> + Hors ligne + </string> + <string name="not_online_msg"> + Utilisateur non connecté - le message sera enregistré et livré plus tard. + </string> + <string name="not_online_inventory"> + Utilisateur non connecté - l'inventaire a été enregistré + </string> + <string name="answered_call"> + Votre appel a fait l'objet d'une réponse + </string> + <string name="you_started_call"> + Vous appelez. + </string> + <string name="you_joined_call"> + Vous avez rejoint l'appel + </string> + <string name="you_auto_rejected_call-im"> + Vous avez automatiquement refusé l'appel vocal quand le mode Ne pas déranger était activé. + </string> + <string name="name_started_call"> + [NAME] appelle. + </string> + <string name="ringing-im"> + En train de rejoindre l'appel... + </string> + <string name="connected-im"> + Connecté(e), cliquez sur Quitter l'appel pour raccrocher + </string> + <string name="hang_up-im"> + A quitté l'appel + </string> + <string name="answering-im"> + Connexion en cours... + </string> + <string name="conference-title"> + Chat à plusieurs + </string> + <string name="conference-title-incoming"> + Conférence avec [AGENT_NAME] + </string> + <string name="inventory_item_offered-im"> + Objet de l’inventaire [ITEM_NAME] offert + </string> + <string name="inventory_folder_offered-im"> + Dossier de l’inventaire [ITEM_NAME] offert + </string> + <string name="bot_warning"> + Vous discutez avec un bot, [NAME]. Ne partagez pas d’informations personnelles. +En savoir plus sur https://second.life/scripted-agents. + </string> + <string name="share_alert"> + Faire glisser les objets de l'inventaire ici + </string> + <string name="facebook_post_success"> + Vous avez publié sur Facebook. + </string> + <string name="flickr_post_success"> + Vous avez publié sur Flickr. + </string> + <string name="twitter_post_success"> + Vous avez publié sur Twitter. + </string> + <string name="no_session_message"> + (Session IM inexistante) + </string> + <string name="only_user_message"> + Vous êtes le seul participant à cette session. + </string> + <string name="offline_message"> + [NAME] est hors ligne. + </string> + <string name="invite_message"> + Pour accepter ce chat vocal/vous connecter, cliquez sur le bouton [BUTTON NAME]. + </string> + <string name="muted_message"> + Vous ignorez ce résident. Si vous lui envoyez un message, il ne sera plus ignoré. + </string> + <string name="generic"> + Erreur lors de la requête, veuillez réessayer ultérieurement. + </string> + <string name="generic_request_error"> + Erreur lors de la requête, veuillez réessayer ultérieurement. + </string> + <string name="insufficient_perms_error"> + Vous n'avez pas les droits requis. + </string> + <string name="session_does_not_exist_error"> + La session a expiré + </string> + <string name="no_ability_error"> + Vous n'avez pas ce pouvoir. + </string> + <string name="no_ability"> + Vous n'avez pas ce pouvoir. + </string> + <string name="not_a_mod_error"> + Vous n'êtes pas modérateur de session. + </string> + <string name="muted"> + Un modérateur de groupe a désactivé votre chat écrit. + </string> + <string name="muted_error"> + Un modérateur de groupe a désactivé votre chat écrit. + </string> + <string name="add_session_event"> + Impossible d'ajouter des participants à la session de chat avec [RECIPIENT]. + </string> + <string name="message"> + Impossible d'envoyer votre message à la session de chat avec [RECIPIENT]. + </string> + <string name="message_session_event"> + Impossible d'envoyer votre message à la session de chat avec [RECIPIENT]. + </string> + <string name="mute"> + Erreur lors de la modération. + </string> + <string name="removed"> + Vous avez été supprimé du groupe. + </string> + <string name="removed_from_group"> + Vous avez été supprimé du groupe. + </string> + <string name="close_on_no_ability"> + Vous ne pouvez plus participer à la session de chat. + </string> + <string name="unread_chat_single"> + [SOURCES] a dit quelque chose de nouveau + </string> + <string name="unread_chat_multiple"> + [SOURCES] ont dit quelque chose de nouveau + </string> + <string name="session_initialization_timed_out_error"> + Expiration du délai d'initialisation de la session + </string> + <string name="Home position set."> + Emplacement du domicile défini. + </string> + <string name="voice_morphing_url"> + https://secondlife.com/destination/voice-island + </string> + <string name="premium_voice_morphing_url"> + https://secondlife.com/destination/voice-morphing-premium + </string> + <string name="paid_you_ldollars"> + [NAME] vous a payé [AMOUNT] L$ [REASON]. + </string> + <string name="paid_you_ldollars_gift"> + [NAME] vous a payé [AMOUNT] L$ : [REASON] + </string> + <string name="paid_you_ldollars_no_reason"> + [NAME] vous a payé [AMOUNT] L$. + </string> + <string name="you_paid_ldollars"> + Vous avez payé à [AMOUNT] L$ [REASON]. + </string> + <string name="you_paid_ldollars_gift"> + Vous avez payé à [NAME] [AMOUNT] L$ : [REASON] + </string> + <string name="you_paid_ldollars_no_info"> + Vous avez payé [AMOUNT] L$. + </string> + <string name="you_paid_ldollars_no_reason"> + Vous avez payé à [NAME] [AMOUNT] L$. + </string> + <string name="you_paid_ldollars_no_name"> + Vous avez payé à [AMOUNT] L$ [REASON]. + </string> + <string name="you_paid_failure_ldollars"> + Votre paiement de [AMOUNT] L$ à [NAME] [REASON] a échoué. + </string> + <string name="you_paid_failure_ldollars_gift"> + Votre paiement de [AMOUNT] L$ à [NAME] a échoué : [REASON] + </string> + <string name="you_paid_failure_ldollars_no_info"> + Votre paiement de [AMOUNT] L$ a échoué. + </string> + <string name="you_paid_failure_ldollars_no_reason"> + Votre paiement de [AMOUNT] L$ à [NAME] a échoué. + </string> + <string name="you_paid_failure_ldollars_no_name"> + Votre paiement de [AMOUNT] L$ [REASON] a échoué. + </string> + <string name="for item"> + pour l'article suivant : [ITEM] + </string> + <string name="for a parcel of land"> + pour une parcelle de terrain + </string> + <string name="for a land access pass"> + pour un pass d'accès au terrain + </string> + <string name="for deeding land"> + pour une cession de terrain + </string> + <string name="to create a group"> + pour créer un groupe + </string> + <string name="to join a group"> + pour rejoindre un groupe + </string> + <string name="to upload"> + pour charger + </string> + <string name="to publish a classified ad"> + pour publier une petite annonce + </string> + <string name="giving"> + Donner [AMOUNT] L$ + </string> + <string name="uploading_costs"> + Le chargement coûte [AMOUNT] L$ + </string> + <string name="this_costs"> + Cela coûte [AMOUNT] L$ + </string> + <string name="buying_selected_land"> + Achat du terrain sélectionné pour [AMOUNT] L$ + </string> + <string name="this_object_costs"> + Cet objet coûte [AMOUNT] L$ + </string> + <string name="group_role_everyone"> + Tous + </string> + <string name="group_role_officers"> + Officiers + </string> + <string name="group_role_owners"> + Propriétaires + </string> + <string name="group_member_status_online"> + En ligne + </string> + <string name="uploading_abuse_report"> + Chargement... -du rapport d'infraction</string> - <string name="New Shape">Nouvelle silhouette</string> - <string name="New Skin">Nouvelle peau</string> - <string name="New Hair">Nouveaux cheveux</string> - <string name="New Eyes">Nouveaux yeux</string> - <string name="New Shirt">Nouvelle chemise</string> - <string name="New Pants">Nouveau pantalon</string> - <string name="New Shoes">Nouvelles chaussures</string> - <string name="New Socks">Nouvelles chaussettes</string> - <string name="New Jacket">Nouvelle veste</string> - <string name="New Gloves">Nouveaux gants</string> - <string name="New Undershirt">Nouveau débardeur</string> - <string name="New Underpants">Nouveau caleçon</string> - <string name="New Skirt">Nouvelle jupe</string> - <string name="New Alpha">Nouvel alpha</string> - <string name="New Tattoo">Nouveau tatouage</string> - <string name="New Universal">Nouvel environnement universel</string> - <string name="New Physics">Nouvelles propriétés physiques</string> - <string name="Invalid Wearable">Objet à porter non valide</string> - <string name="New Gesture">Nouveau geste</string> - <string name="New Script">Nouveau script</string> - <string name="New Note">Nouvelle note</string> - <string name="New Folder">Nouveau dossier</string> - <string name="Contents">Contenus</string> - <string name="Gesture">Geste</string> - <string name="Male Gestures">Gestes masculins</string> - <string name="Female Gestures">Gestes féminins</string> - <string name="Other Gestures">Autres gestes</string> - <string name="Speech Gestures">Gestes liés à la parole</string> - <string name="Common Gestures">Gestes communs</string> - <string name="Male - Excuse me">Homme - Demander pardon</string> - <string name="Male - Get lost">Homme - Get lost</string> - <string name="Male - Blow kiss">Homme - Envoyer un baiser</string> - <string name="Male - Boo">Homme - Hou !</string> - <string name="Male - Bored">Homme - Ennui</string> - <string name="Male - Hey">Homme - Hé !</string> - <string name="Male - Laugh">Homme - Rire</string> - <string name="Male - Repulsed">Homme - Dégoût</string> - <string name="Male - Shrug">Homme - Hausser les épaules</string> - <string name="Male - Stick tougue out">Homme - Tirer la langue</string> - <string name="Male - Wow">Homme - Ouah !</string> - <string name="Female - Chuckle">Femme - Glousser</string> - <string name="Female - Cry">Femme - Pleurer</string> - <string name="Female - Embarrassed">Femme - Gêne</string> - <string name="Female - Excuse me">Femme - Demander pardon</string> - <string name="Female - Get lost">Femme - Get lost</string> - <string name="Female - Blow kiss">Femme - Envoyer un baiser</string> - <string name="Female - Boo">Femme - Hou !</string> - <string name="Female - Bored">Femme - Ennui</string> - <string name="Female - Hey">Femme - Hé !</string> - <string name="Female - Hey baby">Femme - Hey baby</string> - <string name="Female - Laugh">Femme - Rire</string> - <string name="Female - Looking good">Femme - Looking good</string> - <string name="Female - Over here">Femme - Over here</string> - <string name="Female - Please">Femme - Please</string> - <string name="Female - Repulsed">Femme - Dégoût</string> - <string name="Female - Shrug">Femme - Hausser les épaules</string> - <string name="Female - Stick tougue out">Femme - Tirer la langue</string> - <string name="Female - Wow">Femme - Ouah !</string> - <string name="New Daycycle">Nouveau cycle du jour</string> - <string name="New Water">Nouvelle eau</string> - <string name="New Sky">Nouveau ciel</string> - <string name="/bow">/s'incliner</string> - <string name="/clap">/applaudir</string> - <string name="/count">/compter</string> - <string name="/extinguish">/éteindre</string> - <string name="/kmb">/vatefairevoir</string> - <string name="/muscle">/montrersesmuscles</string> - <string name="/no">/non</string> - <string name="/no!">/non !</string> - <string name="/paper">/papier</string> - <string name="/pointme">/memontrerdudoigt</string> - <string name="/pointyou">/montrerl'autredudoigt</string> - <string name="/rock">/pierre</string> - <string name="/scissor">/ciseaux</string> - <string name="/smoke">/fumer</string> - <string name="/stretch">/bailler</string> - <string name="/whistle">/siffler</string> - <string name="/yes">/oui</string> - <string name="/yes!">/oui !</string> - <string name="afk">absent</string> - <string name="dance1">danse1</string> - <string name="dance2">danse2</string> - <string name="dance3">danse3</string> - <string name="dance4">danse4</string> - <string name="dance5">danse5</string> - <string name="dance6">danse6</string> - <string name="dance7">danse7</string> - <string name="dance8">danse8</string> - <string name="AvatarBirthDateFormat">[day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt]</string> - <string name="DefaultMimeType">aucun/aucun</string> - <string name="texture_load_dimensions_error">Impossible de charger des images de taille supérieure à [WIDTH]*[HEIGHT]</string> - <string name="outfit_photo_load_dimensions_error">Taille max. de la photo de la tenue : [WIDTH]*[HEIGHT]. Redimensionnez l’image ou utilisez-en une autre.</string> - <string name="outfit_photo_select_dimensions_error">Taille max. de la photo de la tenue : [WIDTH]*[HEIGHT]. Sélectionnez une autre texture.</string> - <string name="outfit_photo_verify_dimensions_error">Impossible de vérifier les dimensions de la photo. Attendez que la taille de la photo s’affiche dans le sélecteur.</string> +du rapport d'infraction + </string> + <string name="New Shape"> + Nouvelle silhouette + </string> + <string name="New Skin"> + Nouvelle peau + </string> + <string name="New Hair"> + Nouveaux cheveux + </string> + <string name="New Eyes"> + Nouveaux yeux + </string> + <string name="New Shirt"> + Nouvelle chemise + </string> + <string name="New Pants"> + Nouveau pantalon + </string> + <string name="New Shoes"> + Nouvelles chaussures + </string> + <string name="New Socks"> + Nouvelles chaussettes + </string> + <string name="New Jacket"> + Nouvelle veste + </string> + <string name="New Gloves"> + Nouveaux gants + </string> + <string name="New Undershirt"> + Nouveau débardeur + </string> + <string name="New Underpants"> + Nouveau caleçon + </string> + <string name="New Skirt"> + Nouvelle jupe + </string> + <string name="New Alpha"> + Nouvel alpha + </string> + <string name="New Tattoo"> + Nouveau tatouage + </string> + <string name="New Universal"> + Nouvel environnement universel + </string> + <string name="New Physics"> + Nouvelles propriétés physiques + </string> + <string name="Invalid Wearable"> + Objet à porter non valide + </string> + <string name="New Gesture"> + Nouveau geste + </string> + <string name="New Script"> + Nouveau script + </string> + <string name="New Note"> + Nouvelle note + </string> + <string name="New Folder"> + Nouveau dossier + </string> + <string name="Contents"> + Contenus + </string> + <string name="Gesture"> + Geste + </string> + <string name="Male Gestures"> + Gestes masculins + </string> + <string name="Female Gestures"> + Gestes féminins + </string> + <string name="Other Gestures"> + Autres gestes + </string> + <string name="Speech Gestures"> + Gestes liés à la parole + </string> + <string name="Common Gestures"> + Gestes communs + </string> + <string name="Male - Excuse me"> + Homme - Demander pardon + </string> + <string name="Male - Get lost"> + Homme - Get lost + </string> + <string name="Male - Blow kiss"> + Homme - Envoyer un baiser + </string> + <string name="Male - Boo"> + Homme - Hou ! + </string> + <string name="Male - Bored"> + Homme - Ennui + </string> + <string name="Male - Hey"> + Homme - Hé ! + </string> + <string name="Male - Laugh"> + Homme - Rire + </string> + <string name="Male - Repulsed"> + Homme - Dégoût + </string> + <string name="Male - Shrug"> + Homme - Hausser les épaules + </string> + <string name="Male - Stick tougue out"> + Homme - Tirer la langue + </string> + <string name="Male - Wow"> + Homme - Ouah ! + </string> + <string name="Female - Chuckle"> + Femme - Glousser + </string> + <string name="Female - Cry"> + Femme - Pleurer + </string> + <string name="Female - Embarrassed"> + Femme - Gêne + </string> + <string name="Female - Excuse me"> + Femme - Demander pardon + </string> + <string name="Female - Get lost"> + Femme - Get lost + </string> + <string name="Female - Blow kiss"> + Femme - Envoyer un baiser + </string> + <string name="Female - Boo"> + Femme - Hou ! + </string> + <string name="Female - Bored"> + Femme - Ennui + </string> + <string name="Female - Hey"> + Femme - Hé ! + </string> + <string name="Female - Hey baby"> + Femme - Hey baby + </string> + <string name="Female - Laugh"> + Femme - Rire + </string> + <string name="Female - Looking good"> + Femme - Looking good + </string> + <string name="Female - Over here"> + Femme - Over here + </string> + <string name="Female - Please"> + Femme - Please + </string> + <string name="Female - Repulsed"> + Femme - Dégoût + </string> + <string name="Female - Shrug"> + Femme - Hausser les épaules + </string> + <string name="Female - Stick tougue out"> + Femme - Tirer la langue + </string> + <string name="Female - Wow"> + Femme - Ouah ! + </string> + <string name="New Daycycle"> + Nouveau cycle du jour + </string> + <string name="New Water"> + Nouvelle eau + </string> + <string name="New Sky"> + Nouveau ciel + </string> + <string name="/bow"> + /s'incliner + </string> + <string name="/clap"> + /applaudir + </string> + <string name="/count"> + /compter + </string> + <string name="/extinguish"> + /éteindre + </string> + <string name="/kmb"> + /vatefairevoir + </string> + <string name="/muscle"> + /montrersesmuscles + </string> + <string name="/no"> + /non + </string> + <string name="/no!"> + /non ! + </string> + <string name="/paper"> + /papier + </string> + <string name="/pointme"> + /memontrerdudoigt + </string> + <string name="/pointyou"> + /montrerl'autredudoigt + </string> + <string name="/rock"> + /pierre + </string> + <string name="/scissor"> + /ciseaux + </string> + <string name="/smoke"> + /fumer + </string> + <string name="/stretch"> + /bailler + </string> + <string name="/whistle"> + /siffler + </string> + <string name="/yes"> + /oui + </string> + <string name="/yes!"> + /oui ! + </string> + <string name="afk"> + absent + </string> + <string name="dance1"> + danse1 + </string> + <string name="dance2"> + danse2 + </string> + <string name="dance3"> + danse3 + </string> + <string name="dance4"> + danse4 + </string> + <string name="dance5"> + danse5 + </string> + <string name="dance6"> + danse6 + </string> + <string name="dance7"> + danse7 + </string> + <string name="dance8"> + danse8 + </string> + <string name="AvatarBirthDateFormat"> + [day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt] + </string> + <string name="DefaultMimeType"> + aucun/aucun + </string> + <string name="texture_load_dimensions_error"> + Impossible de charger des images de taille supérieure à [WIDTH]*[HEIGHT] + </string> + <string name="outfit_photo_load_dimensions_error"> + Taille max. de la photo de la tenue : [WIDTH]*[HEIGHT]. Redimensionnez l’image ou utilisez-en une autre. + </string> + <string name="outfit_photo_select_dimensions_error"> + Taille max. de la photo de la tenue : [WIDTH]*[HEIGHT]. Sélectionnez une autre texture. + </string> + <string name="outfit_photo_verify_dimensions_error"> + Impossible de vérifier les dimensions de la photo. Attendez que la taille de la photo s’affiche dans le sélecteur. + </string> <string name="words_separator" value=","/> - <string name="server_is_down">Malgré nos efforts, une erreur inattendue s’est produite. + <string name="server_is_down"> + Malgré nos efforts, une erreur inattendue s’est produite. Veuillez vous reporter à http://status.secondlifegrid.net afin de déterminer si un problème connu existe avec ce service. - Si le problème persiste, vérifiez la configuration de votre réseau et de votre pare-feu.</string> - <string name="dateTimeWeekdaysNames">Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday</string> - <string name="dateTimeWeekdaysShortNames">Sun:Mon:Tue:Wed:Thu:Fri:Sat</string> - <string name="dateTimeMonthNames">January:February:March:April:May:June:July:August:September:October:November:December</string> - <string name="dateTimeMonthShortNames">Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec</string> - <string name="dateTimeDayFormat">[MDAY]</string> - <string name="dateTimeAM">AM</string> - <string name="dateTimePM">PM</string> - <string name="LocalEstimateUSD">[AMOUNT] US$</string> - <string name="Group Ban">Bannissement de groupe</string> - <string name="Membership">Inscription</string> - <string name="Roles">Rôles</string> - <string name="Group Identity">Identité du groupe</string> - <string name="Parcel Management">Gestion des parcelles</string> - <string name="Parcel Identity">Identité des parcelles</string> - <string name="Parcel Settings">Paramètres des parcelles</string> - <string name="Parcel Powers">Pouvoirs sur les parcelles</string> - <string name="Parcel Access">Accès aux parcelles</string> - <string name="Parcel Content">Contenu des parcelles</string> - <string name="Object Management">Gestion des objets</string> - <string name="Accounting">Comptabilité</string> - <string name="Notices">Notices</string> - <string name="Chat" value=" Chat :">Chat</string> - <string name="BaseMembership">Base</string> - <string name="PremiumMembership">Premium</string> - <string name="Premium_PlusMembership">Premium Plus</string> - <string name="DeleteItems">Supprimer les articles sélectionnés ?</string> - <string name="DeleteItem">Supprimer l'article sélectionné ?</string> - <string name="EmptyOutfitText">Cette tenue ne contient aucun article.</string> - <string name="ExternalEditorNotSet">Sélectionnez un éditeur à l'aide du paramètre ExternalEditor.</string> - <string name="ExternalEditorNotFound">Éditeur externe spécifié introuvable. + Si le problème persiste, vérifiez la configuration de votre réseau et de votre pare-feu. + </string> + <string name="dateTimeWeekdaysNames"> + Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday + </string> + <string name="dateTimeWeekdaysShortNames"> + Sun:Mon:Tue:Wed:Thu:Fri:Sat + </string> + <string name="dateTimeMonthNames"> + January:February:March:April:May:June:July:August:September:October:November:December + </string> + <string name="dateTimeMonthShortNames"> + Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Oct:Nov:Dec + </string> + <string name="dateTimeDayFormat"> + [MDAY] + </string> + <string name="dateTimeAM"> + AM + </string> + <string name="dateTimePM"> + PM + </string> + <string name="LocalEstimateUSD"> + [AMOUNT] US$ + </string> + <string name="Group Ban"> + Bannissement de groupe + </string> + <string name="Membership"> + Inscription + </string> + <string name="Roles"> + Rôles + </string> + <string name="Group Identity"> + Identité du groupe + </string> + <string name="Parcel Management"> + Gestion des parcelles + </string> + <string name="Parcel Identity"> + Identité des parcelles + </string> + <string name="Parcel Settings"> + Paramètres des parcelles + </string> + <string name="Parcel Powers"> + Pouvoirs sur les parcelles + </string> + <string name="Parcel Access"> + Accès aux parcelles + </string> + <string name="Parcel Content"> + Contenu des parcelles + </string> + <string name="Object Management"> + Gestion des objets + </string> + <string name="Accounting"> + Comptabilité + </string> + <string name="Notices"> + Notices + </string> + <string name="Chat" value=" Chat :"> + Chat + </string> + <string name="BaseMembership"> + Base + </string> + <string name="PremiumMembership"> + Premium + </string> + <string name="Premium_PlusMembership"> + Premium Plus + </string> + <string name="DeleteItems"> + Supprimer les articles sélectionnés ? + </string> + <string name="DeleteItem"> + Supprimer l'article sélectionné ? + </string> + <string name="EmptyOutfitText"> + Cette tenue ne contient aucun article. + </string> + <string name="ExternalEditorNotSet"> + Sélectionnez un éditeur à l'aide du paramètre ExternalEditor. + </string> + <string name="ExternalEditorNotFound"> + Éditeur externe spécifié introuvable. Essayez avec le chemin d'accès à l'éditeur entre guillemets doubles -(par ex. : "/chemin_accès/editor" "%s").</string> - <string name="ExternalEditorCommandParseError">Erreur lors de l'analyse de la commande d'éditeur externe.</string> - <string name="ExternalEditorFailedToRun">Échec d'exécution de l'éditeur externe.</string> - <string name="TranslationFailed">Échec de traduction : [REASON]</string> - <string name="TranslationResponseParseError">Erreur lors de l'analyse de la réponse relative à la traduction.</string> - <string name="Esc">Échap</string> - <string name="Space">Space</string> - <string name="Enter">Enter</string> - <string name="Tab">Tab</string> - <string name="Ins">Ins</string> - <string name="Del">Del</string> - <string name="Backsp">Backsp</string> - <string name="Shift">Maj</string> - <string name="Ctrl">Ctrl</string> - <string name="Alt">Alt</string> - <string name="CapsLock">CapsLock</string> - <string name="Home">Début</string> - <string name="End">End</string> - <string name="PgUp">PgUp</string> - <string name="PgDn">PgDn</string> - <string name="F1">F1</string> - <string name="F2">F2</string> - <string name="F3">F3</string> - <string name="F4">F4</string> - <string name="F5">F5</string> - <string name="F6">F6</string> - <string name="F7">F7</string> - <string name="F8">F8</string> - <string name="F9">F9</string> - <string name="F10">F10</string> - <string name="F11">F11</string> - <string name="F12">F12</string> - <string name="Add">Ajouter</string> - <string name="Subtract">Soustraire</string> - <string name="Multiply">Multiplier</string> - <string name="Divide">Diviser</string> - <string name="PAD_DIVIDE">PAD_DIVIDE</string> - <string name="PAD_LEFT">PAD_LEFT</string> - <string name="PAD_RIGHT">PAD_RIGHT</string> - <string name="PAD_DOWN">PAD_DOWN</string> - <string name="PAD_UP">PAD_UP</string> - <string name="PAD_HOME">PAD_HOME</string> - <string name="PAD_END">PAD_END</string> - <string name="PAD_PGUP">PAD_PGUP</string> - <string name="PAD_PGDN">PAD_PGDN</string> - <string name="PAD_CENTER">PAD_CENTER</string> - <string name="PAD_INS">PAD_INS</string> - <string name="PAD_DEL">PAD_DEL</string> - <string name="PAD_Enter">PAD_Enter</string> - <string name="PAD_BUTTON0">PAD_BUTTON0</string> - <string name="PAD_BUTTON1">PAD_BUTTON1</string> - <string name="PAD_BUTTON2">PAD_BUTTON2</string> - <string name="PAD_BUTTON3">PAD_BUTTON3</string> - <string name="PAD_BUTTON4">PAD_BUTTON4</string> - <string name="PAD_BUTTON5">PAD_BUTTON5</string> - <string name="PAD_BUTTON6">PAD_BUTTON6</string> - <string name="PAD_BUTTON7">PAD_BUTTON7</string> - <string name="PAD_BUTTON8">PAD_BUTTON8</string> - <string name="PAD_BUTTON9">PAD_BUTTON9</string> - <string name="PAD_BUTTON10">PAD_BUTTON10</string> - <string name="PAD_BUTTON11">PAD_BUTTON11</string> - <string name="PAD_BUTTON12">PAD_BUTTON12</string> - <string name="PAD_BUTTON13">PAD_BUTTON13</string> - <string name="PAD_BUTTON14">PAD_BUTTON14</string> - <string name="PAD_BUTTON15">PAD_BUTTON15</string> - <string name="-">-</string> - <string name="=">=</string> - <string name="`">`</string> - <string name=";">;</string> - <string name="[">[</string> - <string name="]">]</string> - <string name="\">\</string> - <string name="0">0</string> - <string name="1">1</string> - <string name="2">2</string> - <string name="3">3</string> - <string name="4">4</string> - <string name="5">5</string> - <string name="6">6</string> - <string name="7">7</string> - <string name="8">8</string> - <string name="9">9</string> - <string name="A">A</string> - <string name="B">B</string> - <string name="C">C</string> - <string name="D">D</string> - <string name="E">E</string> - <string name="F">F</string> - <string name="G">G</string> - <string name="H">H</string> - <string name="I">I</string> - <string name="J">J</string> - <string name="K">K</string> - <string name="L">L</string> - <string name="M">M</string> - <string name="N">N</string> - <string name="O">O</string> - <string name="P">P</string> - <string name="Q">Q</string> - <string name="R">R</string> - <string name="S">S</string> - <string name="T">T</string> - <string name="U">U</string> - <string name="V">V</string> - <string name="W">W</string> - <string name="X">X</string> - <string name="Y">Y</string> - <string name="Z">Z</string> - <string name="BeaconParticle">Affichage des balises de particule (bleu)</string> - <string name="BeaconPhysical">Affichage des balises d'objet physique (vert)</string> - <string name="BeaconScripted">Affichage des balises d'objet scripté (rouge)</string> - <string name="BeaconScriptedTouch">Affichage des balises d'objet scripté avec fonction de toucher (rouge)</string> - <string name="BeaconSound">Affichage des balises de son (jaune)</string> - <string name="BeaconMedia">Affichage des balises de média (blanc)</string> - <string name="BeaconSun">Balise de visibilité du soleil (orange)</string> - <string name="BeaconMoon">Observation de la balise de direction de la lune (violet)</string> - <string name="ParticleHiding">Masquage des particules</string> - <string name="Command_AboutLand_Label">À propos du terrain</string> - <string name="Command_Appearance_Label">Apparence</string> - <string name="Command_Avatar_Label">Avatar</string> - <string name="Command_Build_Label">Construire</string> - <string name="Command_Chat_Label">Chat</string> - <string name="Command_Conversations_Label">Conversations</string> - <string name="Command_Compass_Label">Boussole</string> - <string name="Command_Destinations_Label">Destinations</string> - <string name="Command_Environments_Label">Mes environnements</string> - <string name="Command_Facebook_Label">Facebook</string> - <string name="Command_Flickr_Label">Flickr</string> - <string name="Command_Gestures_Label">Gestes</string> - <string name="Command_Grid_Status_Label">État de la grille</string> - <string name="Command_HowTo_Label">Aide rapide</string> - <string name="Command_Inventory_Label">Inventaire</string> - <string name="Command_Map_Label">Carte</string> - <string name="Command_Marketplace_Label">Place du marché</string> - <string name="Command_MarketplaceListings_Label">Place du marché</string> - <string name="Command_MiniMap_Label">Mini-carte</string> - <string name="Command_Move_Label">Marcher / Courir / Voler</string> - <string name="Command_Outbox_Label">Boîte d'envoi vendeur</string> - <string name="Command_People_Label">Personnes</string> - <string name="Command_Picks_Label">Favoris</string> - <string name="Command_Places_Label">Lieux</string> - <string name="Command_Preferences_Label">Préférences</string> - <string name="Command_Profile_Label">Profil</string> - <string name="Command_Report_Abuse_Label">Signaler une infraction</string> - <string name="Command_Search_Label">Recherche</string> - <string name="Command_Snapshot_Label">Photo</string> - <string name="Command_Speak_Label">Parler</string> - <string name="Command_Twitter_Label">Twitter</string> - <string name="Command_View_Label">Caméra</string> - <string name="Command_Voice_Label">Paramètres vocaux</string> - <string name="Command_AboutLand_Tooltip">Information sur le terrain que vous visitez</string> - <string name="Command_Appearance_Tooltip">Modifier votre avatar</string> - <string name="Command_Avatar_Tooltip">Choisir un avatar complet</string> - <string name="Command_Build_Tooltip">Construction d'objets et remodelage du terrain</string> - <string name="Command_Chat_Tooltip">Parler aux personnes près de vous par chat écrit</string> - <string name="Command_Conversations_Tooltip">Parler à quelqu'un</string> - <string name="Command_Compass_Tooltip">Boussole</string> - <string name="Command_Destinations_Tooltip">Destinations intéressantes</string> - <string name="Command_Environments_Tooltip">Mes environnements</string> - <string name="Command_Facebook_Tooltip">Publier sur Facebook</string> - <string name="Command_Flickr_Tooltip">Charger sur Flickr</string> - <string name="Command_Gestures_Tooltip">Gestes de votre avatar</string> - <string name="Command_Grid_Status_Tooltip">Afficher l’état actuel de la grille</string> - <string name="Command_HowTo_Tooltip">Comment effectuer les opérations courantes</string> - <string name="Command_Inventory_Tooltip">Afficher et utiliser vos possessions</string> - <string name="Command_Map_Tooltip">Carte du monde</string> - <string name="Command_Marketplace_Tooltip">Faire du shopping</string> - <string name="Command_MarketplaceListings_Tooltip">Vendez votre création</string> - <string name="Command_MiniMap_Tooltip">Afficher les personnes près de vous</string> - <string name="Command_Move_Tooltip">Faire bouger votre avatar</string> - <string name="Command_Outbox_Tooltip">Transférer des articles vers votre place de marché afin de les vendre.</string> - <string name="Command_People_Tooltip">Amis, groupes et personnes près de vous</string> - <string name="Command_Picks_Tooltip">Lieux à afficher comme favoris dans votre profil</string> - <string name="Command_Places_Tooltip">Lieux enregistrés</string> - <string name="Command_Preferences_Tooltip">Préférences</string> - <string name="Command_Profile_Tooltip">Modifier ou afficher votre profil</string> - <string name="Command_Report_Abuse_Tooltip">Signaler une infraction</string> - <string name="Command_Search_Tooltip">Trouver des lieux, personnes, événements</string> - <string name="Command_Snapshot_Tooltip">Prendre une photo</string> - <string name="Command_Speak_Tooltip">Parler aux personnes près de vous en utilisant votre micro</string> - <string name="Command_Twitter_Tooltip">Twitter</string> - <string name="Command_View_Tooltip">Changer l'angle de la caméra</string> - <string name="Command_Voice_Tooltip">Commandes de réglage du volume des appels et des personnes près de vous dans Second Life.</string> - <string name="Toolbar_Bottom_Tooltip">actuellement dans la barre d'outils du bas</string> - <string name="Toolbar_Left_Tooltip">actuellement dans la barre d'outils de gauche</string> - <string name="Toolbar_Right_Tooltip">actuellement dans la barre d'outils de droite</string> - <string name="Retain%">Garder%</string> - <string name="Detail">Détail</string> - <string name="Better Detail">Meilleur détail</string> - <string name="Surface">Surface</string> - <string name="Solid">Solide</string> - <string name="Wrap">Wrap</string> - <string name="Preview">Aperçu</string> - <string name="Normal">Normal</string> - <string name="Pathfinding_Wiki_URL">http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer</string> - <string name="Pathfinding_Object_Attr_None">Aucun</string> - <string name="Pathfinding_Object_Attr_Permanent">Maillage de navigation affecté</string> - <string name="Pathfinding_Object_Attr_Character">Personnage</string> - <string name="Pathfinding_Object_Attr_MultiSelect">(Multiple)</string> - <string name="snapshot_quality_very_low">Très faible</string> - <string name="snapshot_quality_low">Faible</string> - <string name="snapshot_quality_medium">Moyenne</string> - <string name="snapshot_quality_high">Élevée</string> - <string name="snapshot_quality_very_high">Très élevée</string> - <string name="TeleportMaturityExceeded">Le résident ne peut pas visiter cette région.</string> - <string name="UserDictionary">[User]</string> - <string name="experience_tools_experience">Expérience</string> - <string name="ExperienceNameNull">(aucune expérience)</string> - <string name="ExperienceNameUntitled">(expérience sans titre)</string> - <string name="Land-Scope">À l’échelle des terrains</string> - <string name="Grid-Scope">À l’échelle de la grille</string> - <string name="Allowed_Experiences_Tab">AUTORISÉE</string> - <string name="Blocked_Experiences_Tab">BLOQUÉE</string> - <string name="Contrib_Experiences_Tab">CONTRIBUTEUR</string> - <string name="Admin_Experiences_Tab">ADMIN</string> - <string name="Recent_Experiences_Tab">RÉCENTE</string> - <string name="Owned_Experiences_Tab">AVEC PROPRIÉTAIRE</string> - <string name="ExperiencesCounter">([EXPERIENCES], [MAXEXPERIENCES] max.)</string> - <string name="ExperiencePermission1">assumer vos contrôles</string> - <string name="ExperiencePermission3">déclencher des animations pour votre avatar</string> - <string name="ExperiencePermission4">attacher à votre avatar</string> - <string name="ExperiencePermission9">suivre votre caméra</string> - <string name="ExperiencePermission10">contrôler votre caméra</string> - <string name="ExperiencePermission11">vous téléporter</string> - <string name="ExperiencePermission12">accepter automatiquement les permissions d’expérience</string> - <string name="ExperiencePermission16">forcez votre avatar à s’asseoir</string> - <string name="ExperiencePermission17">changer vos paramètres d'environnement</string> - <string name="ExperiencePermissionShortUnknown">a effectué une opération inconnue : [Permission]</string> - <string name="ExperiencePermissionShort1">Prendre le contrôle</string> - <string name="ExperiencePermissionShort3">Déclencher des animations</string> - <string name="ExperiencePermissionShort4">Attacher</string> - <string name="ExperiencePermissionShort9">Suivre la caméra</string> - <string name="ExperiencePermissionShort10">Contrôler la caméra</string> - <string name="ExperiencePermissionShort11">Téléportation</string> - <string name="ExperiencePermissionShort12">Permission</string> - <string name="ExperiencePermissionShort16">M'asseoir</string> - <string name="ExperiencePermissionShort17">Environnement</string> - <string name="logging_calls_disabled_log_empty">Les conversations ne sont pas archivées. Pour commencer à tenir un journal, choisissez Enregistrer : Journal seul ou Enregistrer : Journal et transcriptions sous Préférences > Chat.</string> - <string name="logging_calls_disabled_log_not_empty">Aucune conversation ne sera plus enregistrée. Pour recommencer à tenir un journal, choisissez Enregistrer : Journal seul ou Enregistrer : Journal et transcriptions sous Préférences > Chat.</string> - <string name="logging_calls_enabled_log_empty">Il n'y a aucune conversation enregistrée. Quand quelqu'un vous contacte ou quand vous contactez quelqu'un, une entrée de journal s'affiche ici.</string> - <string name="loading_chat_logs">Chargement...</string> - <string name="na">s.o.</string> - <string name="preset_combo_label">-Liste vide-</string> - <string name="Default">Valeur par défaut</string> - <string name="none_paren_cap">(Aucun/Aucune)</string> - <string name="no_limit">Aucune limite</string> - <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">La forme physique contient des triangles trop petits. Essayez de simplifier le modèle physique.</string> - <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH">La forme physique contient de mauvaises données de confirmation. Essayez de corriger le modèle physique.</string> - <string name="Mav_Details_MAV_UNKNOWN_VERSION">La forme physique n’a pas la version correcte. Configurez la version correcte pour le modèle physique.</string> - <string name="couldnt_resolve_host">DNS n'a pas pu résoudre le nom d'hôte([HOSTNAME]). +(par ex. : "/chemin_accès/editor" "%s"). + </string> + <string name="ExternalEditorCommandParseError"> + Erreur lors de l'analyse de la commande d'éditeur externe. + </string> + <string name="ExternalEditorFailedToRun"> + Échec d'exécution de l'éditeur externe. + </string> + <string name="TranslationFailed"> + Échec de traduction : [REASON] + </string> + <string name="TranslationResponseParseError"> + Erreur lors de l'analyse de la réponse relative à la traduction. + </string> + <string name="Esc"> + Échap + </string> + <string name="Space"> + Space + </string> + <string name="Enter"> + Enter + </string> + <string name="Tab"> + Tab + </string> + <string name="Ins"> + Ins + </string> + <string name="Del"> + Del + </string> + <string name="Backsp"> + Backsp + </string> + <string name="Shift"> + Maj + </string> + <string name="Ctrl"> + Ctrl + </string> + <string name="Alt"> + Alt + </string> + <string name="CapsLock"> + CapsLock + </string> + <string name="Home"> + Début + </string> + <string name="End"> + End + </string> + <string name="PgUp"> + PgUp + </string> + <string name="PgDn"> + PgDn + </string> + <string name="F1"> + F1 + </string> + <string name="F2"> + F2 + </string> + <string name="F3"> + F3 + </string> + <string name="F4"> + F4 + </string> + <string name="F5"> + F5 + </string> + <string name="F6"> + F6 + </string> + <string name="F7"> + F7 + </string> + <string name="F8"> + F8 + </string> + <string name="F9"> + F9 + </string> + <string name="F10"> + F10 + </string> + <string name="F11"> + F11 + </string> + <string name="F12"> + F12 + </string> + <string name="Add"> + Ajouter + </string> + <string name="Subtract"> + Soustraire + </string> + <string name="Multiply"> + Multiplier + </string> + <string name="Divide"> + Diviser + </string> + <string name="PAD_DIVIDE"> + PAD_DIVIDE + </string> + <string name="PAD_LEFT"> + PAD_LEFT + </string> + <string name="PAD_RIGHT"> + PAD_RIGHT + </string> + <string name="PAD_DOWN"> + PAD_DOWN + </string> + <string name="PAD_UP"> + PAD_UP + </string> + <string name="PAD_HOME"> + PAD_HOME + </string> + <string name="PAD_END"> + PAD_END + </string> + <string name="PAD_PGUP"> + PAD_PGUP + </string> + <string name="PAD_PGDN"> + PAD_PGDN + </string> + <string name="PAD_CENTER"> + PAD_CENTER + </string> + <string name="PAD_INS"> + PAD_INS + </string> + <string name="PAD_DEL"> + PAD_DEL + </string> + <string name="PAD_Enter"> + PAD_Enter + </string> + <string name="PAD_BUTTON0"> + PAD_BUTTON0 + </string> + <string name="PAD_BUTTON1"> + PAD_BUTTON1 + </string> + <string name="PAD_BUTTON2"> + PAD_BUTTON2 + </string> + <string name="PAD_BUTTON3"> + PAD_BUTTON3 + </string> + <string name="PAD_BUTTON4"> + PAD_BUTTON4 + </string> + <string name="PAD_BUTTON5"> + PAD_BUTTON5 + </string> + <string name="PAD_BUTTON6"> + PAD_BUTTON6 + </string> + <string name="PAD_BUTTON7"> + PAD_BUTTON7 + </string> + <string name="PAD_BUTTON8"> + PAD_BUTTON8 + </string> + <string name="PAD_BUTTON9"> + PAD_BUTTON9 + </string> + <string name="PAD_BUTTON10"> + PAD_BUTTON10 + </string> + <string name="PAD_BUTTON11"> + PAD_BUTTON11 + </string> + <string name="PAD_BUTTON12"> + PAD_BUTTON12 + </string> + <string name="PAD_BUTTON13"> + PAD_BUTTON13 + </string> + <string name="PAD_BUTTON14"> + PAD_BUTTON14 + </string> + <string name="PAD_BUTTON15"> + PAD_BUTTON15 + </string> + <string name="-"> + - + </string> + <string name="="> + = + </string> + <string name="`"> + ` + </string> + <string name=";"> + ; + </string> + <string name="["> + [ + </string> + <string name="]"> + ] + </string> + <string name="\"> + \ + </string> + <string name="0"> + 0 + </string> + <string name="1"> + 1 + </string> + <string name="2"> + 2 + </string> + <string name="3"> + 3 + </string> + <string name="4"> + 4 + </string> + <string name="5"> + 5 + </string> + <string name="6"> + 6 + </string> + <string name="7"> + 7 + </string> + <string name="8"> + 8 + </string> + <string name="9"> + 9 + </string> + <string name="A"> + A + </string> + <string name="B"> + B + </string> + <string name="C"> + C + </string> + <string name="D"> + D + </string> + <string name="E"> + E + </string> + <string name="F"> + F + </string> + <string name="G"> + G + </string> + <string name="H"> + H + </string> + <string name="I"> + I + </string> + <string name="J"> + J + </string> + <string name="K"> + K + </string> + <string name="L"> + L + </string> + <string name="M"> + M + </string> + <string name="N"> + N + </string> + <string name="O"> + O + </string> + <string name="P"> + P + </string> + <string name="Q"> + Q + </string> + <string name="R"> + R + </string> + <string name="S"> + S + </string> + <string name="T"> + T + </string> + <string name="U"> + U + </string> + <string name="V"> + V + </string> + <string name="W"> + W + </string> + <string name="X"> + X + </string> + <string name="Y"> + Y + </string> + <string name="Z"> + Z + </string> + <string name="BeaconParticle"> + Affichage des balises de particule (bleu) + </string> + <string name="BeaconPhysical"> + Affichage des balises d'objet physique (vert) + </string> + <string name="BeaconScripted"> + Affichage des balises d'objet scripté (rouge) + </string> + <string name="BeaconScriptedTouch"> + Affichage des balises d'objet scripté avec fonction de toucher (rouge) + </string> + <string name="BeaconSound"> + Affichage des balises de son (jaune) + </string> + <string name="BeaconMedia"> + Affichage des balises de média (blanc) + </string> + <string name="BeaconSun"> + Balise de visibilité du soleil (orange) + </string> + <string name="BeaconMoon"> + Observation de la balise de direction de la lune (violet) + </string> + <string name="ParticleHiding"> + Masquage des particules + </string> + <string name="Command_AboutLand_Label"> + À propos du terrain + </string> + <string name="Command_Appearance_Label"> + Apparence + </string> + <string name="Command_Avatar_Label"> + Avatar + </string> + <string name="Command_Build_Label"> + Construire + </string> + <string name="Command_Chat_Label"> + Chat + </string> + <string name="Command_Conversations_Label"> + Conversations + </string> + <string name="Command_Compass_Label"> + Boussole + </string> + <string name="Command_Destinations_Label"> + Destinations + </string> + <string name="Command_Environments_Label"> + Mes environnements + </string> + <string name="Command_Facebook_Label"> + Facebook + </string> + <string name="Command_Flickr_Label"> + Flickr + </string> + <string name="Command_Gestures_Label"> + Gestes + </string> + <string name="Command_Grid_Status_Label"> + État de la grille + </string> + <string name="Command_HowTo_Label"> + Aide rapide + </string> + <string name="Command_Inventory_Label"> + Inventaire + </string> + <string name="Command_Map_Label"> + Carte + </string> + <string name="Command_Marketplace_Label"> + Place du marché + </string> + <string name="Command_MarketplaceListings_Label"> + Place du marché + </string> + <string name="Command_MiniMap_Label"> + Mini-carte + </string> + <string name="Command_Move_Label"> + Marcher / Courir / Voler + </string> + <string name="Command_Outbox_Label"> + Boîte d'envoi vendeur + </string> + <string name="Command_People_Label"> + Personnes + </string> + <string name="Command_Picks_Label"> + Favoris + </string> + <string name="Command_Places_Label"> + Lieux + </string> + <string name="Command_Preferences_Label"> + Préférences + </string> + <string name="Command_Profile_Label"> + Profil + </string> + <string name="Command_Report_Abuse_Label"> + Signaler une infraction + </string> + <string name="Command_Search_Label"> + Recherche + </string> + <string name="Command_Snapshot_Label"> + Photo + </string> + <string name="Command_Speak_Label"> + Parler + </string> + <string name="Command_Twitter_Label"> + Twitter + </string> + <string name="Command_View_Label"> + Caméra + </string> + <string name="Command_Voice_Label"> + Paramètres vocaux + </string> + <string name="Command_AboutLand_Tooltip"> + Information sur le terrain que vous visitez + </string> + <string name="Command_Appearance_Tooltip"> + Modifier votre avatar + </string> + <string name="Command_Avatar_Tooltip"> + Choisir un avatar complet + </string> + <string name="Command_Build_Tooltip"> + Construction d'objets et remodelage du terrain + </string> + <string name="Command_Chat_Tooltip"> + Parler aux personnes près de vous par chat écrit + </string> + <string name="Command_Conversations_Tooltip"> + Parler à quelqu'un + </string> + <string name="Command_Compass_Tooltip"> + Boussole + </string> + <string name="Command_Destinations_Tooltip"> + Destinations intéressantes + </string> + <string name="Command_Environments_Tooltip"> + Mes environnements + </string> + <string name="Command_Facebook_Tooltip"> + Publier sur Facebook + </string> + <string name="Command_Flickr_Tooltip"> + Charger sur Flickr + </string> + <string name="Command_Gestures_Tooltip"> + Gestes de votre avatar + </string> + <string name="Command_Grid_Status_Tooltip"> + Afficher l’état actuel de la grille + </string> + <string name="Command_HowTo_Tooltip"> + Comment effectuer les opérations courantes + </string> + <string name="Command_Inventory_Tooltip"> + Afficher et utiliser vos possessions + </string> + <string name="Command_Map_Tooltip"> + Carte du monde + </string> + <string name="Command_Marketplace_Tooltip"> + Faire du shopping + </string> + <string name="Command_MarketplaceListings_Tooltip"> + Vendez votre création + </string> + <string name="Command_MiniMap_Tooltip"> + Afficher les personnes près de vous + </string> + <string name="Command_Move_Tooltip"> + Faire bouger votre avatar + </string> + <string name="Command_Outbox_Tooltip"> + Transférer des articles vers votre place de marché afin de les vendre. + </string> + <string name="Command_People_Tooltip"> + Amis, groupes et personnes près de vous + </string> + <string name="Command_Picks_Tooltip"> + Lieux à afficher comme favoris dans votre profil + </string> + <string name="Command_Places_Tooltip"> + Lieux enregistrés + </string> + <string name="Command_Preferences_Tooltip"> + Préférences + </string> + <string name="Command_Profile_Tooltip"> + Modifier ou afficher votre profil + </string> + <string name="Command_Report_Abuse_Tooltip"> + Signaler une infraction + </string> + <string name="Command_Search_Tooltip"> + Trouver des lieux, personnes, événements + </string> + <string name="Command_Snapshot_Tooltip"> + Prendre une photo + </string> + <string name="Command_Speak_Tooltip"> + Parler aux personnes près de vous en utilisant votre micro + </string> + <string name="Command_Twitter_Tooltip"> + Twitter + </string> + <string name="Command_View_Tooltip"> + Changer l'angle de la caméra + </string> + <string name="Command_Voice_Tooltip"> + Commandes de réglage du volume des appels et des personnes près de vous dans Second Life. + </string> + <string name="Toolbar_Bottom_Tooltip"> + actuellement dans la barre d'outils du bas + </string> + <string name="Toolbar_Left_Tooltip"> + actuellement dans la barre d'outils de gauche + </string> + <string name="Toolbar_Right_Tooltip"> + actuellement dans la barre d'outils de droite + </string> + <string name="Retain%"> + Garder% + </string> + <string name="Detail"> + Détail + </string> + <string name="Better Detail"> + Meilleur détail + </string> + <string name="Surface"> + Surface + </string> + <string name="Solid"> + Solide + </string> + <string name="Wrap"> + Wrap + </string> + <string name="Preview"> + Aperçu + </string> + <string name="Normal"> + Normal + </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Aucun + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Maillage de navigation affecté + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personnage + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Multiple) + </string> + <string name="snapshot_quality_very_low"> + Très faible + </string> + <string name="snapshot_quality_low"> + Faible + </string> + <string name="snapshot_quality_medium"> + Moyenne + </string> + <string name="snapshot_quality_high"> + Élevée + </string> + <string name="snapshot_quality_very_high"> + Très élevée + </string> + <string name="TeleportMaturityExceeded"> + Le résident ne peut pas visiter cette région. + </string> + <string name="UserDictionary"> + [User] + </string> + <string name="experience_tools_experience"> + Expérience + </string> + <string name="ExperienceNameNull"> + (aucune expérience) + </string> + <string name="ExperienceNameUntitled"> + (expérience sans titre) + </string> + <string name="Land-Scope"> + À l’échelle des terrains + </string> + <string name="Grid-Scope"> + À l’échelle de la grille + </string> + <string name="Allowed_Experiences_Tab"> + AUTORISÉE + </string> + <string name="Blocked_Experiences_Tab"> + BLOQUÉE + </string> + <string name="Contrib_Experiences_Tab"> + CONTRIBUTEUR + </string> + <string name="Admin_Experiences_Tab"> + ADMIN + </string> + <string name="Recent_Experiences_Tab"> + RÉCENTE + </string> + <string name="Owned_Experiences_Tab"> + AVEC PROPRIÉTAIRE + </string> + <string name="ExperiencesCounter"> + ([EXPERIENCES], [MAXEXPERIENCES] max.) + </string> + <string name="ExperiencePermission1"> + assumer vos contrôles + </string> + <string name="ExperiencePermission3"> + déclencher des animations pour votre avatar + </string> + <string name="ExperiencePermission4"> + attacher à votre avatar + </string> + <string name="ExperiencePermission9"> + suivre votre caméra + </string> + <string name="ExperiencePermission10"> + contrôler votre caméra + </string> + <string name="ExperiencePermission11"> + vous téléporter + </string> + <string name="ExperiencePermission12"> + accepter automatiquement les permissions d’expérience + </string> + <string name="ExperiencePermission16"> + forcez votre avatar à s’asseoir + </string> + <string name="ExperiencePermission17"> + changer vos paramètres d'environnement + </string> + <string name="ExperiencePermissionShortUnknown"> + a effectué une opération inconnue : [Permission] + </string> + <string name="ExperiencePermissionShort1"> + Prendre le contrôle + </string> + <string name="ExperiencePermissionShort3"> + Déclencher des animations + </string> + <string name="ExperiencePermissionShort4"> + Attacher + </string> + <string name="ExperiencePermissionShort9"> + Suivre la caméra + </string> + <string name="ExperiencePermissionShort10"> + Contrôler la caméra + </string> + <string name="ExperiencePermissionShort11"> + Téléportation + </string> + <string name="ExperiencePermissionShort12"> + Permission + </string> + <string name="ExperiencePermissionShort16"> + M'asseoir + </string> + <string name="ExperiencePermissionShort17"> + Environnement + </string> + <string name="logging_calls_disabled_log_empty"> + Les conversations ne sont pas archivées. Pour commencer à tenir un journal, choisissez Enregistrer : Journal seul ou Enregistrer : Journal et transcriptions sous Préférences > Chat. + </string> + <string name="logging_calls_disabled_log_not_empty"> + Aucune conversation ne sera plus enregistrée. Pour recommencer à tenir un journal, choisissez Enregistrer : Journal seul ou Enregistrer : Journal et transcriptions sous Préférences > Chat. + </string> + <string name="logging_calls_enabled_log_empty"> + Il n'y a aucune conversation enregistrée. Quand quelqu'un vous contacte ou quand vous contactez quelqu'un, une entrée de journal s'affiche ici. + </string> + <string name="loading_chat_logs"> + Chargement... + </string> + <string name="na"> + s.o. + </string> + <string name="preset_combo_label"> + -Liste vide- + </string> + <string name="Default"> + Valeur par défaut + </string> + <string name="none_paren_cap"> + (Aucun/Aucune) + </string> + <string name="no_limit"> + Aucune limite + </string> + <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES"> + La forme physique contient des triangles trop petits. Essayez de simplifier le modèle physique. + </string> + <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH"> + La forme physique contient de mauvaises données de confirmation. Essayez de corriger le modèle physique. + </string> + <string name="Mav_Details_MAV_UNKNOWN_VERSION"> + La forme physique n’a pas la version correcte. Configurez la version correcte pour le modèle physique. + </string> + <string name="couldnt_resolve_host"> + DNS n'a pas pu résoudre le nom d'hôte([HOSTNAME]). Veuillez vérifier que vous parvenez à vous connecter au site www.secondlife.com. Si c'est le cas, et que vous continuez à recevoir ce message d'erreur, veuillez vous -rendre à la section Support et signaler ce problème</string> - <string name="ssl_peer_certificate">Le serveur d'identification a rencontré une erreur de connexion SSL. +rendre à la section Support et signaler ce problème + </string> + <string name="ssl_peer_certificate"> + Le serveur d'identification a rencontré une erreur de connexion SSL. Si vous continuez à recevoir ce message d'erreur, veuillez vous rendre à la section Support du site web -SecondLife.com et signaler ce problème</string> - <string name="ssl_connect_error">Ceci est souvent dû à un mauvais réglage de l'horloge de votre ordinateur. +SecondLife.com et signaler ce problème + </string> + <string name="ssl_connect_error"> + Ceci est souvent dû à un mauvais réglage de l'horloge de votre ordinateur. Veuillez aller à Tableaux de bord et assurez-vous que l'heure et la date sont réglés correctement. Vérifiez également que votre réseau et votre pare-feu sont configurés correctement. Si vous continuez à recevoir ce message d'erreur, veuillez vous rendre à la section Support du site web SecondLife.com et signaler ce problème. -[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de connaissances]</string> +[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de connaissances] + </string> </strings> diff --git a/indra/newview/skins/default/xui/fr/teleport_strings.xml b/indra/newview/skins/default/xui/fr/teleport_strings.xml index 1272723c6b..cad8911fde 100644 --- a/indra/newview/skins/default/xui/fr/teleport_strings.xml +++ b/indra/newview/skins/default/xui/fr/teleport_strings.xml @@ -1,40 +1,96 @@ <?xml version="1.0" ?> <teleport_messages> <message_set name="errors"> - <message name="invalid_tport">Nous avons rencontré des problèmes en essayant de vous téléporter. Vous devrez peut-être vous reconnecter avant de pouvoir vous téléporter. -Si ce message persiste, veuillez consulter la page [SUPPORT_SITE].</message> - <message name="invalid_region_handoff">Nous avons rencontré des problèmes en essayant de vous téléporter. Vous devrez peut-être vous reconnecter avant de pouvoir traverser des régions. -Si ce message persiste, veuillez consulter la page [SUPPORT_SITE].</message> - <message name="blocked_tport">Désolé, la téléportation est bloquée actuellement. Veuillez réessayer dans un moment. -Si vous ne parvenez toujours pas à être téléporté, déconnectez-vous puis reconnectez-vous pour résoudre le problème.</message> - <message name="nolandmark_tport">Désolé, le système n'a pas réussi à localiser la destination de votre repère.</message> - <message name="timeout_tport">Désolé, la connexion vers votre lieu de téléportation n'a pas abouti. -Veuillez réessayer dans un moment.</message> - <message name="NoHelpIslandTP">Vous ne pouvez pas vous téléporter à nouveau vers Welcome Island. -Pour recommencer le didacticiel, accédez à Welcome Island Public.</message> - <message name="noaccess_tport">Désolé, vous n'avez pas accès à cette destination.</message> - <message name="missing_attach_tport">Vos pieces-jointes ne sont pas encore arrivées. Attendez quelques secondes de plus ou déconnectez-vous puis reconnectez-vous avant d'essayer de vous téléporter.</message> - <message name="too_many_uploads_tport">Le trafic vers cette région est bouché en ce moment. Votre téléportation ne pourra pas avoir lieu immédiatement. Veuillez réessayer dans quelques minutes ou bien aller dans une zone moins fréquentée.</message> - <message name="expired_tport">Désolé, votre demande de téléportation n'a pas abouti assez rapidement. Veuillez réessayer dans quelques minutes.</message> - <message name="expired_region_handoff">Désolé, votre demande pour passer dans une autre région n'a pas abouti assez rapidement. Veuillez réessayer dans quelques minutes.</message> - <message name="no_host">Impossible de trouver la destination de la téléportation. Il est possible que cette destination soit temporairement indisponible ou qu'elle n'existe plus. Veuillez réessayer dans quelques minutes.</message> - <message name="no_inventory_host">L'inventaire est temporairement indisponible.</message> - <message name="MustGetAgeRegion">Pour accéder à cette région, vous devez avoir au moins 18 ans.</message> - <message name="RegionTPSpecialUsageBlocked">Impossible de pénétrer dans la région. « [REGION_NAME] » est une région de jeux d'adresse et vous devez satisfaire à certains critères pour y pénétrer. Pour en savoir plus, consultez la page [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life FAQ sur les jeux d'adresse].</message> - <message name="preexisting_tport">Désolé, mais le système n'a pas pu démarrer votre téléport. Veuillez réessayer dans quelques minutes.</message> + <message name="invalid_tport"> + Nous avons rencontré des problèmes en essayant de vous téléporter. Vous devrez peut-être vous reconnecter avant de pouvoir vous téléporter. +Si ce message persiste, veuillez consulter la page [SUPPORT_SITE]. + </message> + <message name="invalid_region_handoff"> + Nous avons rencontré des problèmes en essayant de vous téléporter. Vous devrez peut-être vous reconnecter avant de pouvoir traverser des régions. +Si ce message persiste, veuillez consulter la page [SUPPORT_SITE]. + </message> + <message name="blocked_tport"> + Désolé, la téléportation est bloquée actuellement. Veuillez réessayer dans un moment. +Si vous ne parvenez toujours pas à être téléporté, déconnectez-vous puis reconnectez-vous pour résoudre le problème. + </message> + <message name="nolandmark_tport"> + Désolé, le système n'a pas réussi à localiser la destination de votre repère. + </message> + <message name="timeout_tport"> + Désolé, la connexion vers votre lieu de téléportation n'a pas abouti. +Veuillez réessayer dans un moment. + </message> + <message name="NoHelpIslandTP"> + Vous ne pouvez pas vous téléporter à nouveau vers Welcome Island. +Pour recommencer le didacticiel, accédez à Welcome Island Public. + </message> + <message name="noaccess_tport"> + Désolé, vous n'avez pas accès à cette destination. + </message> + <message name="missing_attach_tport"> + Vos pieces-jointes ne sont pas encore arrivées. Attendez quelques secondes de plus ou déconnectez-vous puis reconnectez-vous avant d'essayer de vous téléporter. + </message> + <message name="too_many_uploads_tport"> + Le trafic vers cette région est bouché en ce moment. Votre téléportation ne pourra pas avoir lieu immédiatement. Veuillez réessayer dans quelques minutes ou bien aller dans une zone moins fréquentée. + </message> + <message name="expired_tport"> + Désolé, votre demande de téléportation n'a pas abouti assez rapidement. Veuillez réessayer dans quelques minutes. + </message> + <message name="expired_region_handoff"> + Désolé, votre demande pour passer dans une autre région n'a pas abouti assez rapidement. Veuillez réessayer dans quelques minutes. + </message> + <message name="no_host"> + Impossible de trouver la destination de la téléportation. Il est possible que cette destination soit temporairement indisponible ou qu'elle n'existe plus. Veuillez réessayer dans quelques minutes. + </message> + <message name="no_inventory_host"> + L'inventaire est temporairement indisponible. + </message> + <message name="MustGetAgeRegion"> + Pour accéder à cette région, vous devez avoir au moins 18 ans. + </message> + <message name="RegionTPSpecialUsageBlocked"> + Impossible de pénétrer dans la région. « [REGION_NAME] » est une région de jeux d'adresse et vous devez satisfaire à certains critères pour y pénétrer. Pour en savoir plus, consultez la page [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life FAQ sur les jeux d'adresse]. + </message> + <message name="preexisting_tport"> + Désolé, mais le système n'a pas pu démarrer votre téléport. Veuillez réessayer dans quelques minutes. + </message> </message_set> <message_set name="progress"> - <message name="sending_dest">Envoi vers la destination en cours.</message> - <message name="redirecting">Redirection vers un emplacement différent en cours.</message> - <message name="relaying">Relai vers la destination en cours.</message> - <message name="sending_home">Requête de la demande d'envoi vers votre domicile en cours.</message> - <message name="sending_landmark">Requête de la demande d'envoi vers le repère en cours.</message> - <message name="completing">Téléportation sur le point d'aboutir.</message> - <message name="completed_from">Téléportation depuis [T_SLURL] terminée</message> - <message name="resolving">Destination en cours de résolution.</message> - <message name="contacting">Contact avec la nouvelle région en cours.</message> - <message name="arriving">Vous arrivez...</message> - <message name="requesting">Demande de téléportation en cours...</message> - <message name="pending">En attente de téléportation...</message> + <message name="sending_dest"> + Envoi vers la destination en cours. + </message> + <message name="redirecting"> + Redirection vers un emplacement différent en cours. + </message> + <message name="relaying"> + Relai vers la destination en cours. + </message> + <message name="sending_home"> + Requête de la demande d'envoi vers votre domicile en cours. + </message> + <message name="sending_landmark"> + Requête de la demande d'envoi vers le repère en cours. + </message> + <message name="completing"> + Téléportation sur le point d'aboutir. + </message> + <message name="completed_from"> + Téléportation depuis [T_SLURL] terminée + </message> + <message name="resolving"> + Destination en cours de résolution. + </message> + <message name="contacting"> + Contact avec la nouvelle région en cours. + </message> + <message name="arriving"> + Vous arrivez... + </message> + <message name="requesting"> + Demande de téléportation en cours... + </message> + <message name="pending"> + En attente de téléportation... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/it/panel_login_first.xml b/indra/newview/skins/default/xui/it/panel_login_first.xml deleted file mode 100644 index 5b04fd411a..0000000000 --- a/indra/newview/skins/default/xui/it/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php?lang=it - </panel.string> - <panel.string name="sign_up_url"> - http://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Nome utente" name="username_combo" tool_tip="Il nome utente che hai scelto durante la registrazione, come roby12 o Stella Solare"/> - <line_editor label="Password" name="password_edit"/> - <button label="Accedi" name="connect_btn"/> - <check_box label="Ricordami" name="remember_check"/> - <text name="forgot_password_text"> - Password dimenticata - </text> - <text name="sign_up_text"> - Registrati - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Il primo passo è a Learning Island. Trova il portale di uscita! - </text> - <text name="image_caption_right"> - Quindi esplora Social Island e incontra altri nuovi residenti. - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/it/panel_snapshot_options.xml b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml index 50fb3d39fa..7fce171326 100644 --- a/indra/newview/skins/default/xui/it/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/it/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="Salva sul disco" name="save_to_computer_btn"/> - <button label="Salva nell'inventario (L$[AMOUNT])" name="save_to_inventory_btn"/> + <button label="Salva nell'inventario" name="save_to_inventory_btn"/> <button label="Condividi sul feed del profilo" name="save_to_profile_btn"/> <button label="Condividi su Facebook" name="send_to_facebook_btn"/> <button label="Condividi su Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index bb22ff788e..2ddb7d77d1 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -1,610 +1,1668 @@ <?xml version="1.0" ?> <strings> - <string name="SECOND_LIFE">Second Life</string> - <string name="APP_NAME">Second Life</string> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> - <string name="SUPPORT_SITE">Portale di supporto di Second Life</string> - <string name="StartupDetectingHardware">Ricerca hardware...</string> - <string name="StartupLoading">Caricamento di [APP_NAME]...</string> - <string name="StartupClearingCache">Pulizia della cache...</string> - <string name="StartupInitializingTextureCache">Inizializzazione della cache texture...</string> - <string name="StartupRequireDriverUpdate">Inizializzazione grafica non riuscita. Aggiorna il driver della scheda grafica!</string> - <string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) -[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string> - <string name="BuildConfig">Configurazione struttura [BUILD_CONFIG]</string> - <string name="AboutPosition">Tu sei a [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> + <string name="SECOND_LIFE"> + Second Life + </string> + <string name="APP_NAME"> + Second Life + </string> + <string name="CAPITALIZED_APP_NAME"> + SECOND LIFE + </string> + <string name="SUPPORT_SITE"> + Portale di supporto di Second Life + </string> + <string name="StartupDetectingHardware"> + Ricerca hardware... + </string> + <string name="StartupLoading"> + Caricamento di [APP_NAME]... + </string> + <string name="StartupClearingCache"> + Pulizia della cache... + </string> + <string name="StartupInitializingTextureCache"> + Inizializzazione della cache texture... + </string> + <string name="StartupRequireDriverUpdate"> + Inizializzazione grafica non riuscita. Aggiorna il driver della scheda grafica! + </string> + <string name="AboutHeader"> + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Configurazione struttura [BUILD_CONFIG] + </string> + <string name="AboutPosition"> + Tu sei a [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a <nolink>[HOSTNAME]</nolink> SLURL: <nolink>[SLURL]</nolink> (coordinate globali [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] -[SERVER_RELEASE_NOTES_URL]</string> - <string name="AboutSystem">CPU: [CPU] +[SERVER_RELEASE_NOTES_URL] + </string> + <string name="AboutSystem"> + CPU: [CPU] Memoria: [MEMORY_MB] MB Versione sistema operativo: [OS_VERSION] Venditore scheda grafica: [GRAPHICS_CARD_VENDOR] -Scheda grafica: [GRAPHICS_CARD]</string> - <string name="AboutDriver">Versione driver Windows per grafica: [GRAPHICS_DRIVER_VERSION]</string> - <string name="AboutOGL">Versione OpenGL: [OPENGL_VERSION]</string> - <string name="AboutSettings">Dimensione finestra: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Scheda grafica: [GRAPHICS_CARD] + </string> + <string name="AboutDriver"> + Versione driver Windows per grafica: [GRAPHICS_DRIVER_VERSION] + </string> + <string name="AboutOGL"> + Versione OpenGL: [OPENGL_VERSION] + </string> + <string name="AboutSettings"> + Dimensione finestra: [WINDOW_WIDTH]x[WINDOW_HEIGHT] Regolazione dimensioni carattere: [FONT_SIZE_ADJUSTMENT]pt Scala UI: [UI_SCALE] Distanza visualizzazione: [DRAW_DISTANCE]m Larghezza banda: [NET_BANDWITH]kbit/s Fattore livello di dettaglio: [LOD_FACTOR] Qualità di rendering: [RENDER_QUALITY] -Memoria texture: [TEXTURE_MEMORY]MB</string> - <string name="AboutOSXHiDPI">Modalità display HiDPI: [HIDPI]</string> - <string name="AboutLibs">J2C Versione decoder: [J2C_VERSION] +Memoria texture: [TEXTURE_MEMORY]MB + </string> + <string name="AboutOSXHiDPI"> + Modalità display HiDPI: [HIDPI] + </string> + <string name="AboutLibs"> + J2C Versione decoder: [J2C_VERSION] Versione del driver audio: [AUDIO_DRIVER_VERSION][LIBCEF_VERSION] Versione LibVLC: [LIBVLC_VERSION] -Versione server voce: [VOICE_VERSION]</string> - <string name="AboutTraffic">Pacchetti perduti: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string> - <string name="AboutTime">[day, datetime, slt] [month, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string> - <string name="ErrorFetchingServerReleaseNotesURL">Errore nel recupero URL note rilascio versione</string> - <string name="BuildConfiguration">Costruisci configurazione</string> - <string name="ProgressRestoring">Ripristino in corso...</string> - <string name="ProgressChangingResolution">Modifica della risoluzione...</string> - <string name="Fullbright">Luminosità massima (vers. precedente)</string> - <string name="LoginInProgress">In connessione. [APP_NAME] può sembrare rallentata. Attendi.</string> - <string name="LoginInProgressNoFrozen">Accesso in corso...</string> - <string name="LoginAuthenticating">In autenticazione</string> - <string name="LoginMaintenance">Aggiornamento account in corso...</string> - <string name="LoginAttempt">Un precedente tentativo di login è fallito. Tentativo di connessione [NUMBER]</string> - <string name="LoginPrecaching">Sto caricando [SECOND_LIFE]...</string> - <string name="LoginInitializingBrowser">Inizializzazione del browser web incorporato...</string> - <string name="LoginInitializingMultimedia">Inizializzazione dati multimediali...</string> - <string name="LoginInitializingFonts">Caricamento caratteri...</string> - <string name="LoginVerifyingCache">Verifica file della cache (tempo previsto 60-90 secondi)...</string> - <string name="LoginProcessingResponse">Elaborazione risposta...</string> - <string name="LoginInitializingWorld">Inizializzazione mondo...</string> - <string name="LoginDecodingImages">Decodifica immagini...</string> - <string name="LoginInitializingQuicktime">Inizializzazione QuickTime...</string> - <string name="LoginQuicktimeNotFound">QuickTime non trovato - impossibile inizializzare.</string> - <string name="LoginQuicktimeOK">QuickTime configurato con successo.</string> - <string name="LoginRequestSeedCapGrant">Richiesta capacità regione...</string> - <string name="LoginRetrySeedCapGrant">Richiesta capacità regione, tentativo [NUMBER]...</string> - <string name="LoginWaitingForRegionHandshake">In attesa della risposta della regione...</string> - <string name="LoginConnectingToRegion">Connessione alla regione...</string> - <string name="LoginDownloadingClothing">Sto caricando i vestiti...</string> - <string name="InvalidCertificate">Il server ha inviato un certificato non valido o errato. Rivolgiti all'amministratore della griglia.</string> - <string name="CertInvalidHostname">Per accedere al server è stato utilizzato un nome host non valido; controlla lo SLURL o il nome host della griglia.</string> - <string name="CertExpired">Il certificato inviato dalla griglia sembra essere scaduto. Controlla l'orologio del sistema o rivolgiti all'amministratore della griglia.</string> - <string name="CertKeyUsage">Impossibile utilizzare per SSl il certificato inviato dal server. Rivolgiti all'amministratore della griglia.</string> - <string name="CertBasicConstraints">Nella catena dei certificati del server erano presenti troppi certificati. Rivolgiti all'amministratore della griglia.</string> - <string name="CertInvalidSignature">Impossibile verificare la firma del certificato inviato dal server della griglia. Rivolgiti all'amministratore della griglia.</string> - <string name="LoginFailedNoNetwork">Errore di rete: Non è stato possibile stabilire un collegamento, controlla la tua connessione.</string> - <string name="LoginFailedHeader">Accesso non riuscito.</string> - <string name="Quit">Esci</string> - <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - <string name="AgniGridLabel">Griglia principale di Second Life (Agni)</string> - <string name="AditiGridLabel">Griglia per beta test di Second Life (Aditi)</string> - <string name="ViewerDownloadURL">http://secondlife.com/download.</string> - <string name="LoginFailedViewerNotPermitted">Il viewer utilizzato non è più in grado di accedere a Second Life. Visita la parina seguente per scaricare un nuovo viewer: +Versione server voce: [VOICE_VERSION] + </string> + <string name="AboutTraffic"> + Pacchetti perduti: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) + </string> + <string name="AboutTime"> + [day, datetime, slt] [month, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> + <string name="ErrorFetchingServerReleaseNotesURL"> + Errore nel recupero URL note rilascio versione + </string> + <string name="BuildConfiguration"> + Costruisci configurazione + </string> + <string name="ProgressRestoring"> + Ripristino in corso... + </string> + <string name="ProgressChangingResolution"> + Modifica della risoluzione... + </string> + <string name="Fullbright"> + Luminosità massima (vers. precedente) + </string> + <string name="LoginInProgress"> + In connessione. [APP_NAME] può sembrare rallentata. Attendi. + </string> + <string name="LoginInProgressNoFrozen"> + Accesso in corso... + </string> + <string name="LoginAuthenticating"> + In autenticazione + </string> + <string name="LoginMaintenance"> + Aggiornamento account in corso... + </string> + <string name="LoginAttempt"> + Un precedente tentativo di login è fallito. Tentativo di connessione [NUMBER] + </string> + <string name="LoginPrecaching"> + Sto caricando [SECOND_LIFE]... + </string> + <string name="LoginInitializingBrowser"> + Inizializzazione del browser web incorporato... + </string> + <string name="LoginInitializingMultimedia"> + Inizializzazione dati multimediali... + </string> + <string name="LoginInitializingFonts"> + Caricamento caratteri... + </string> + <string name="LoginVerifyingCache"> + Verifica file della cache (tempo previsto 60-90 secondi)... + </string> + <string name="LoginProcessingResponse"> + Elaborazione risposta... + </string> + <string name="LoginInitializingWorld"> + Inizializzazione mondo... + </string> + <string name="LoginDecodingImages"> + Decodifica immagini... + </string> + <string name="LoginInitializingQuicktime"> + Inizializzazione QuickTime... + </string> + <string name="LoginQuicktimeNotFound"> + QuickTime non trovato - impossibile inizializzare. + </string> + <string name="LoginQuicktimeOK"> + QuickTime configurato con successo. + </string> + <string name="LoginRequestSeedCapGrant"> + Richiesta capacità regione... + </string> + <string name="LoginRetrySeedCapGrant"> + Richiesta capacità regione, tentativo [NUMBER]... + </string> + <string name="LoginWaitingForRegionHandshake"> + In attesa della risposta della regione... + </string> + <string name="LoginConnectingToRegion"> + Connessione alla regione... + </string> + <string name="LoginDownloadingClothing"> + Sto caricando i vestiti... + </string> + <string name="InvalidCertificate"> + Il server ha inviato un certificato non valido o errato. Rivolgiti all'amministratore della griglia. + </string> + <string name="CertInvalidHostname"> + Per accedere al server è stato utilizzato un nome host non valido; controlla lo SLURL o il nome host della griglia. + </string> + <string name="CertExpired"> + Il certificato inviato dalla griglia sembra essere scaduto. Controlla l'orologio del sistema o rivolgiti all'amministratore della griglia. + </string> + <string name="CertKeyUsage"> + Impossibile utilizzare per SSl il certificato inviato dal server. Rivolgiti all'amministratore della griglia. + </string> + <string name="CertBasicConstraints"> + Nella catena dei certificati del server erano presenti troppi certificati. Rivolgiti all'amministratore della griglia. + </string> + <string name="CertInvalidSignature"> + Impossibile verificare la firma del certificato inviato dal server della griglia. Rivolgiti all'amministratore della griglia. + </string> + <string name="LoginFailedNoNetwork"> + Errore di rete: Non è stato possibile stabilire un collegamento, controlla la tua connessione. + </string> + <string name="LoginFailedHeader"> + Accesso non riuscito. + </string> + <string name="Quit"> + Esci + </string> + <string name="create_account_url"> + http://join.secondlife.com/?sourceid=[sourceid] + </string> + <string name="AgniGridLabel"> + Griglia principale di Second Life (Agni) + </string> + <string name="AditiGridLabel"> + Griglia per beta test di Second Life (Aditi) + </string> + <string name="ViewerDownloadURL"> + http://secondlife.com/download. + </string> + <string name="LoginFailedViewerNotPermitted"> + Il viewer utilizzato non è più in grado di accedere a Second Life. Visita la parina seguente per scaricare un nuovo viewer: http://secondlife.com/download. Per maggiori informazioni, consulta le domande frequenti alla pagina seguente: -http://secondlife.com/viewer-access-faq</string> - <string name="LoginIntermediateOptionalUpdateAvailable">Disponibile aggiornamento facoltativo viewer: [VERSION]</string> - <string name="LoginFailedRequiredUpdate">Aggernamento viewer richiesto: [VERSION]</string> - <string name="LoginFailedAlreadyLoggedIn">Questo agente ha già eseguito il login.</string> - <string name="LoginFailedAuthenticationFailed">Siamo spiacenti. Il tentativo di accesso non è riuscito. +http://secondlife.com/viewer-access-faq + </string> + <string name="LoginIntermediateOptionalUpdateAvailable"> + Disponibile aggiornamento facoltativo viewer: [VERSION] + </string> + <string name="LoginFailedRequiredUpdate"> + Aggernamento viewer richiesto: [VERSION] + </string> + <string name="LoginFailedAlreadyLoggedIn"> + Questo agente ha già eseguito il login. + </string> + <string name="LoginFailedAuthenticationFailed"> + Siamo spiacenti. Il tentativo di accesso non è riuscito. Verifica di avere inserito correttamente * Nome utente (come robby12 o Stella Soleggiato) * Password -Verifica anche che il blocco delle maiuscole non sia attivato.</string> - <string name="LoginFailedPasswordChanged">Come misura precauzionale, la tua password è stata cambiata. +Verifica anche che il blocco delle maiuscole non sia attivato. + </string> + <string name="LoginFailedPasswordChanged"> + Come misura precauzionale, la tua password è stata cambiata. Visita la pagina del tuo account a http://secondlife.com/password e rispondi alla domanda di sicurezza per reimpostare la password. -Ci scusiamo per l'inconveniente.</string> - <string name="LoginFailedPasswordReset">Abbiamo effettuato delle modifiche al sistema che richiedono di reimpostare la password. +Ci scusiamo per l'inconveniente. + </string> + <string name="LoginFailedPasswordReset"> + Abbiamo effettuato delle modifiche al sistema che richiedono di reimpostare la password. Visita la pagina del tuo account a http://secondlife.com/password e rispondi alla domanda di sicurezza per reimpostare la password. -Ci scusiamo per l'inconveniente.</string> - <string name="LoginFailedEmployeesOnly">Second Life è chiuso temporaneamente per manutenzione. +Ci scusiamo per l'inconveniente. + </string> + <string name="LoginFailedEmployeesOnly"> + Second Life è chiuso temporaneamente per manutenzione. Al momento, solo i dipendenti possono eseguire l'accesso. -Visita www.secondlife.com/status per aggiornamenti.</string> - <string name="LoginFailedPremiumOnly">L'accesso a Second Life è temporaneamente limitato per garantire che chi è nel mondo virtuale abbia la migliore esperienza possibile. +Visita www.secondlife.com/status per aggiornamenti. + </string> + <string name="LoginFailedPremiumOnly"> + L'accesso a Second Life è temporaneamente limitato per garantire che chi è nel mondo virtuale abbia la migliore esperienza possibile. -Le persone con account gratuiti non potranno accedere a Second Life durante questo periodo, per lasciare spazio alle persone che hanno pagato per Second Life.</string> - <string name="LoginFailedComputerProhibited">Non si può accedere a Second Life da questo computer. +Le persone con account gratuiti non potranno accedere a Second Life durante questo periodo, per lasciare spazio alle persone che hanno pagato per Second Life. + </string> + <string name="LoginFailedComputerProhibited"> + Non si può accedere a Second Life da questo computer. Se ritieni che si tratta di un errore, contatta -support@secondlife.com.</string> - <string name="LoginFailedAcountSuspended">Il tuo account non è accessibile fino alle -[TIME] fuso orario del Pacifico.</string> - <string name="LoginFailedAccountDisabled">Non siamo attualmente in grado di completare la tua richiesta. -Contatta l'assistenza Second Life alla pagina http://support.secondlife.com.</string> - <string name="LoginFailedTransformError">Dati incompatibili rilevati durante l'accesso. -Contattare support@secondlife.com.</string> - <string name="LoginFailedAccountMaintenance">Il tuo account è in fase di leggera manutenzione. +support@secondlife.com. + </string> + <string name="LoginFailedAcountSuspended"> + Il tuo account non è accessibile fino alle +[TIME] fuso orario del Pacifico. + </string> + <string name="LoginFailedAccountDisabled"> + Non siamo attualmente in grado di completare la tua richiesta. +Contatta l'assistenza Second Life alla pagina http://support.secondlife.com. + </string> + <string name="LoginFailedTransformError"> + Dati incompatibili rilevati durante l'accesso. +Contattare support@secondlife.com. + </string> + <string name="LoginFailedAccountMaintenance"> + Il tuo account è in fase di leggera manutenzione. Il tuo account non è accessibile fino alle [TIME] fuso orario del Pacifico. -Se ritieni che si tratta di un errore, contatta support@secondlife.com.</string> - <string name="LoginFailedPendingLogoutFault">Errore del simulatore in seguito alla richiesta di logout.</string> - <string name="LoginFailedPendingLogout">Il sistema sta eseguendo il logout in questo momento. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LoginFailedUnableToCreateSession">Non è possibile creare una sessione valida.</string> - <string name="LoginFailedUnableToConnectToSimulator">Non è possibile collegarsi a un simulatore.</string> - <string name="LoginFailedRestrictedHours">Il tuo account può accedere a Second Life solo +Se ritieni che si tratta di un errore, contatta support@secondlife.com. + </string> + <string name="LoginFailedPendingLogoutFault"> + Errore del simulatore in seguito alla richiesta di logout. + </string> + <string name="LoginFailedPendingLogout"> + Il sistema sta eseguendo il logout in questo momento. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LoginFailedUnableToCreateSession"> + Non è possibile creare una sessione valida. + </string> + <string name="LoginFailedUnableToConnectToSimulator"> + Non è possibile collegarsi a un simulatore. + </string> + <string name="LoginFailedRestrictedHours"> + Il tuo account può accedere a Second Life solo tra le [START] e le [END] fuso orario del Pacifico. Torna durante quell'orario. -Se ritieni che si tratta di un errore, contatta support@secondlife.com.</string> - <string name="LoginFailedIncorrectParameters">Parametri errati. -Se ritieni che si tratta di un errore, contatta support@secondlife.com.</string> - <string name="LoginFailedFirstNameNotAlphanumeric">Il parametro Nome deve includere solo caratteri alfanumerici. -Se ritieni che si tratta di un errore, contatta support@secondlife.com.</string> - <string name="LoginFailedLastNameNotAlphanumeric">Il parametro Cognome deve includere solo caratteri alfanumerici. -Se ritieni che si tratta di un errore, contatta support@secondlife.com.</string> - <string name="LogoutFailedRegionGoingOffline">La regione sta passando allo stato non in linea. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LogoutFailedAgentNotInRegion">L'agente non è nella regione. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LogoutFailedPendingLogin">La regione ha eseguito l'accesso in un'altre sessione. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LogoutFailedLoggingOut">La regione stava eseguendo il logout della sessione precedente. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LogoutFailedStillLoggingOut">La regione sta ancora eseguendo il logout della sessione precedente. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LogoutSucceeded">La regione ha eseguito il logout dell'ultima sessione. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LogoutFailedLogoutBegun">La regione ha iniziato la procedura di logout. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="LoginFailedLoggingOutSession">Il sistema ha iniziato il logout dell'ultima sessione. -Prova ad accedere nuovamente tra un minuto.</string> - <string name="AgentLostConnection">Questa regione sta avendo problemi. Verifica la tua connessione a Internet.</string> - <string name="SavingSettings">Salvataggio delle impostazioni...</string> - <string name="LoggingOut">Uscita...</string> - <string name="ShuttingDown">Chiusura...</string> - <string name="YouHaveBeenDisconnected">Sei scollegato dalla regione in cui ti trovavi.</string> - <string name="SentToInvalidRegion">Sei stato indirizzato in una regione non valida.</string> - <string name="TestingDisconnect">Verifica scollegamento viewer</string> - <string name="SocialFacebookConnecting">Connessione a Facebook in corso...</string> - <string name="SocialFacebookPosting">Caricamento post...</string> - <string name="SocialFacebookDisconnecting">Disconnessione da Facebook in corso...</string> - <string name="SocialFacebookErrorConnecting">Problemi con la connessione a Facebook</string> - <string name="SocialFacebookErrorPosting">Problemi con la connessione a Facebook</string> - <string name="SocialFacebookErrorDisconnecting">Problemi con la disconnessione da Facebook</string> - <string name="SocialFlickrConnecting">Collegamento a Flickr...</string> - <string name="SocialFlickrPosting">Caricamento post...</string> - <string name="SocialFlickrDisconnecting">Interruzione del collegamento con Flickr...</string> - <string name="SocialFlickrErrorConnecting">Problema nel collegamento a Flickr</string> - <string name="SocialFlickrErrorPosting">Problema nel caricamento post su Flickr</string> - <string name="SocialFlickrErrorDisconnecting">Problema nell'interruzione del collegamento da Flickr</string> - <string name="SocialTwitterConnecting">Collegamento a Twitter...</string> - <string name="SocialTwitterPosting">Caricamento post...</string> - <string name="SocialTwitterDisconnecting">Interruzione del collegamento con Twitter...</string> - <string name="SocialTwitterErrorConnecting">Problema nel collegamento a Twitter</string> - <string name="SocialTwitterErrorPosting">Problema nel caricamento post su Twitter</string> - <string name="SocialTwitterErrorDisconnecting">Problema nell'interruzione del collegamento da Twitter</string> - <string name="BlackAndWhite">Bianco e nero</string> - <string name="Colors1970">Colori anni '70</string> - <string name="Intense">Intenso</string> - <string name="Newspaper">Giornale</string> - <string name="Sepia">Seppia</string> - <string name="Spotlight">Faretto</string> - <string name="Video">Video</string> - <string name="Autocontrast">Auto contrasto</string> - <string name="LensFlare">Bagliore</string> - <string name="Miniature">Miniatura</string> - <string name="Toycamera">Toy camera</string> - <string name="TooltipPerson">Persona</string> - <string name="TooltipNoName">(nessun nome)</string> - <string name="TooltipOwner">Proprietario:</string> - <string name="TooltipPublic">Pubblico</string> - <string name="TooltipIsGroup">(Gruppo)</string> - <string name="TooltipForSaleL$">In Vendita: [AMOUNT]L$</string> - <string name="TooltipFlagGroupBuild">Costruzione solo con gruppo</string> - <string name="TooltipFlagNoBuild">Divieto di Costruire</string> - <string name="TooltipFlagNoEdit">Costruzione solo con gruppo</string> - <string name="TooltipFlagNotSafe">Non Sicuro</string> - <string name="TooltipFlagNoFly">Divieto di Volare</string> - <string name="TooltipFlagGroupScripts">Script solo con gruppo</string> - <string name="TooltipFlagNoScripts">Script vietati</string> - <string name="TooltipLand">Terreno:</string> - <string name="TooltipMustSingleDrop">Solo un singolo oggetto può essere creato qui</string> - <string name="TooltipTooManyWearables">Non puoi indossare una cartella che contiene più di [AMOUNT] elementi. Per modificare questo limite, accedi ad Avanzate > Mostra impostazioni di debug > WearFolderLimit.</string> +Se ritieni che si tratta di un errore, contatta support@secondlife.com. + </string> + <string name="LoginFailedIncorrectParameters"> + Parametri errati. +Se ritieni che si tratta di un errore, contatta support@secondlife.com. + </string> + <string name="LoginFailedFirstNameNotAlphanumeric"> + Il parametro Nome deve includere solo caratteri alfanumerici. +Se ritieni che si tratta di un errore, contatta support@secondlife.com. + </string> + <string name="LoginFailedLastNameNotAlphanumeric"> + Il parametro Cognome deve includere solo caratteri alfanumerici. +Se ritieni che si tratta di un errore, contatta support@secondlife.com. + </string> + <string name="LogoutFailedRegionGoingOffline"> + La regione sta passando allo stato non in linea. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LogoutFailedAgentNotInRegion"> + L'agente non è nella regione. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LogoutFailedPendingLogin"> + La regione ha eseguito l'accesso in un'altre sessione. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LogoutFailedLoggingOut"> + La regione stava eseguendo il logout della sessione precedente. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LogoutFailedStillLoggingOut"> + La regione sta ancora eseguendo il logout della sessione precedente. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LogoutSucceeded"> + La regione ha eseguito il logout dell'ultima sessione. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LogoutFailedLogoutBegun"> + La regione ha iniziato la procedura di logout. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="LoginFailedLoggingOutSession"> + Il sistema ha iniziato il logout dell'ultima sessione. +Prova ad accedere nuovamente tra un minuto. + </string> + <string name="AgentLostConnection"> + Questa regione sta avendo problemi. Verifica la tua connessione a Internet. + </string> + <string name="SavingSettings"> + Salvataggio delle impostazioni... + </string> + <string name="LoggingOut"> + Uscita... + </string> + <string name="ShuttingDown"> + Chiusura... + </string> + <string name="YouHaveBeenDisconnected"> + Sei scollegato dalla regione in cui ti trovavi. + </string> + <string name="SentToInvalidRegion"> + Sei stato indirizzato in una regione non valida. + </string> + <string name="TestingDisconnect"> + Verifica scollegamento viewer + </string> + <string name="SocialFacebookConnecting"> + Connessione a Facebook in corso... + </string> + <string name="SocialFacebookPosting"> + Caricamento post... + </string> + <string name="SocialFacebookDisconnecting"> + Disconnessione da Facebook in corso... + </string> + <string name="SocialFacebookErrorConnecting"> + Problemi con la connessione a Facebook + </string> + <string name="SocialFacebookErrorPosting"> + Problemi con la connessione a Facebook + </string> + <string name="SocialFacebookErrorDisconnecting"> + Problemi con la disconnessione da Facebook + </string> + <string name="SocialFlickrConnecting"> + Collegamento a Flickr... + </string> + <string name="SocialFlickrPosting"> + Caricamento post... + </string> + <string name="SocialFlickrDisconnecting"> + Interruzione del collegamento con Flickr... + </string> + <string name="SocialFlickrErrorConnecting"> + Problema nel collegamento a Flickr + </string> + <string name="SocialFlickrErrorPosting"> + Problema nel caricamento post su Flickr + </string> + <string name="SocialFlickrErrorDisconnecting"> + Problema nell'interruzione del collegamento da Flickr + </string> + <string name="SocialTwitterConnecting"> + Collegamento a Twitter... + </string> + <string name="SocialTwitterPosting"> + Caricamento post... + </string> + <string name="SocialTwitterDisconnecting"> + Interruzione del collegamento con Twitter... + </string> + <string name="SocialTwitterErrorConnecting"> + Problema nel collegamento a Twitter + </string> + <string name="SocialTwitterErrorPosting"> + Problema nel caricamento post su Twitter + </string> + <string name="SocialTwitterErrorDisconnecting"> + Problema nell'interruzione del collegamento da Twitter + </string> + <string name="BlackAndWhite"> + Bianco e nero + </string> + <string name="Colors1970"> + Colori anni '70 + </string> + <string name="Intense"> + Intenso + </string> + <string name="Newspaper"> + Giornale + </string> + <string name="Sepia"> + Seppia + </string> + <string name="Spotlight"> + Faretto + </string> + <string name="Video"> + Video + </string> + <string name="Autocontrast"> + Auto contrasto + </string> + <string name="LensFlare"> + Bagliore + </string> + <string name="Miniature"> + Miniatura + </string> + <string name="Toycamera"> + Toy camera + </string> + <string name="TooltipPerson"> + Persona + </string> + <string name="TooltipNoName"> + (nessun nome) + </string> + <string name="TooltipOwner"> + Proprietario: + </string> + <string name="TooltipPublic"> + Pubblico + </string> + <string name="TooltipIsGroup"> + (Gruppo) + </string> + <string name="TooltipForSaleL$"> + In Vendita: [AMOUNT]L$ + </string> + <string name="TooltipFlagGroupBuild"> + Costruzione solo con gruppo + </string> + <string name="TooltipFlagNoBuild"> + Divieto di Costruire + </string> + <string name="TooltipFlagNoEdit"> + Costruzione solo con gruppo + </string> + <string name="TooltipFlagNotSafe"> + Non Sicuro + </string> + <string name="TooltipFlagNoFly"> + Divieto di Volare + </string> + <string name="TooltipFlagGroupScripts"> + Script solo con gruppo + </string> + <string name="TooltipFlagNoScripts"> + Script vietati + </string> + <string name="TooltipLand"> + Terreno: + </string> + <string name="TooltipMustSingleDrop"> + Solo un singolo oggetto può essere creato qui + </string> + <string name="TooltipTooManyWearables"> + Non puoi indossare una cartella che contiene più di [AMOUNT] elementi. Per modificare questo limite, accedi ad Avanzate > Mostra impostazioni di debug > WearFolderLimit. + </string> <string name="TooltipPrice" value="L$ [AMOUNT]:"/> - <string name="TooltipSLIcon">Questo link porta a una pagina nel dominio ufficiale SecondLife.com o LindenLab.com.</string> - <string name="TooltipOutboxDragToWorld">Non puoi rezzare articoli dalla cartella degli annunci di Marketplace</string> - <string name="TooltipOutboxWorn">Non puoi inserire nella cartella degli annunci in Marketplace gli articoli che indossi</string> - <string name="TooltipOutboxFolderLevels">La profondità delle caselle nidificate è maggiore di [AMOUNT]. Diminuisci la profondità delle cartelle nidificate; se necessario, raggruppa gli articoli.</string> - <string name="TooltipOutboxTooManyFolders">Il numero di sottocartelle è maggiore di [AMOUNT]. Diminuisci il numero delle cartelle nel tuo annuncio; se necessario, raggruppa gli articoli.</string> - <string name="TooltipOutboxTooManyObjects">Il numero di articoli è maggiore di [AMOUNT]. Per vendere più di [AMOUNT] articoli in un annuncio, devi raggruppare alcuni di essi.</string> - <string name="TooltipOutboxTooManyStockItems">Il numero di articoli in magazzino è maggiore di [AMOUNT].</string> - <string name="TooltipOutboxCannotDropOnRoot">Puoi trascinare elementi o cartelle solo nelle schede TUTTI o NON ASSOCIATO. Seleziona una di quelle schede e sposta nuovamente gli elementi o le cartelle.</string> - <string name="TooltipOutboxNoTransfer">Almeno uno di questi oggetti non può essere venduto o trasferito</string> - <string name="TooltipOutboxNotInInventory">Puoi aggiungere a Marketplace solo gli articoli nel tuo inventario</string> - <string name="TooltipOutboxLinked">Non puoi inserire cartelle o articoli collegati tramite link nel Marketplace</string> - <string name="TooltipOutboxCallingCard">Non puoi inserire biglietti da visita in Marketplace</string> - <string name="TooltipOutboxDragActive">non puoi muovere un annuncio attivo</string> - <string name="TooltipOutboxCannotMoveRoot">Non puoi spostare la cartella principale degli annunci di Marketplace</string> - <string name="TooltipOutboxMixedStock">Tutti gli articoli in una cartella di magazzino devono essere dello stesso tipo e con le stesse autorizzazioni</string> - <string name="TooltipDragOntoOwnChild">Non puoi spostare una cartella nella relativa cartella secondaria</string> - <string name="TooltipDragOntoSelf">Non puoi spostare una cartella in se stessa</string> - <string name="TooltipHttpUrl">Clicca per visitare questa pagina web</string> - <string name="TooltipSLURL">Clicca per avere maggiori informazioni sul luogo</string> - <string name="TooltipAgentUrl">Clicca per vedere il profilo di questo residente</string> - <string name="TooltipAgentInspect">Ulteriori informazioni su questo Residente</string> - <string name="TooltipAgentMute">Clicca per disattivare l'audio di questo residente</string> - <string name="TooltipAgentUnmute">Clicca per attivare l'audio del residente</string> - <string name="TooltipAgentIM">Clicca per inviare un IM a questo residente</string> - <string name="TooltipAgentPay">Clicca per pagare il residente</string> - <string name="TooltipAgentOfferTeleport">Fai clic per inviare un'offerta di teleport al residente</string> - <string name="TooltipAgentRequestFriend">Fai clic per inviare una richiesta di amicizia al residente</string> - <string name="TooltipGroupUrl">Clicca per vedere la descrizione del gruppo</string> - <string name="TooltipEventUrl">Clicca per vedere la descrizione dell'evento</string> - <string name="TooltipClassifiedUrl">Clicca per vedere questa inserzione</string> - <string name="TooltipParcelUrl">Clicca per vedere la descrizione del lotto</string> - <string name="TooltipTeleportUrl">Clicca per effettuare il teleport a questa destinazione</string> - <string name="TooltipObjectIMUrl">Clicca per vedere la descrizione dell'oggetto</string> - <string name="TooltipMapUrl">Clicca per vedere questo posto sulla mappa</string> - <string name="TooltipSLAPP">Clicca per avviare il comando secondlife://</string> + <string name="TooltipSLIcon"> + Questo link porta a una pagina nel dominio ufficiale SecondLife.com o LindenLab.com. + </string> + <string name="TooltipOutboxDragToWorld"> + Non puoi rezzare articoli dalla cartella degli annunci di Marketplace + </string> + <string name="TooltipOutboxWorn"> + Non puoi inserire nella cartella degli annunci in Marketplace gli articoli che indossi + </string> + <string name="TooltipOutboxFolderLevels"> + La profondità delle caselle nidificate è maggiore di [AMOUNT]. Diminuisci la profondità delle cartelle nidificate; se necessario, raggruppa gli articoli. + </string> + <string name="TooltipOutboxTooManyFolders"> + Il numero di sottocartelle è maggiore di [AMOUNT]. Diminuisci il numero delle cartelle nel tuo annuncio; se necessario, raggruppa gli articoli. + </string> + <string name="TooltipOutboxTooManyObjects"> + Il numero di articoli è maggiore di [AMOUNT]. Per vendere più di [AMOUNT] articoli in un annuncio, devi raggruppare alcuni di essi. + </string> + <string name="TooltipOutboxTooManyStockItems"> + Il numero di articoli in magazzino è maggiore di [AMOUNT]. + </string> + <string name="TooltipOutboxCannotDropOnRoot"> + Puoi trascinare elementi o cartelle solo nelle schede TUTTI o NON ASSOCIATO. Seleziona una di quelle schede e sposta nuovamente gli elementi o le cartelle. + </string> + <string name="TooltipOutboxNoTransfer"> + Almeno uno di questi oggetti non può essere venduto o trasferito + </string> + <string name="TooltipOutboxNotInInventory"> + Puoi aggiungere a Marketplace solo gli articoli nel tuo inventario + </string> + <string name="TooltipOutboxLinked"> + Non puoi inserire cartelle o articoli collegati tramite link nel Marketplace + </string> + <string name="TooltipOutboxCallingCard"> + Non puoi inserire biglietti da visita in Marketplace + </string> + <string name="TooltipOutboxDragActive"> + non puoi muovere un annuncio attivo + </string> + <string name="TooltipOutboxCannotMoveRoot"> + Non puoi spostare la cartella principale degli annunci di Marketplace + </string> + <string name="TooltipOutboxMixedStock"> + Tutti gli articoli in una cartella di magazzino devono essere dello stesso tipo e con le stesse autorizzazioni + </string> + <string name="TooltipDragOntoOwnChild"> + Non puoi spostare una cartella nella relativa cartella secondaria + </string> + <string name="TooltipDragOntoSelf"> + Non puoi spostare una cartella in se stessa + </string> + <string name="TooltipHttpUrl"> + Clicca per visitare questa pagina web + </string> + <string name="TooltipSLURL"> + Clicca per avere maggiori informazioni sul luogo + </string> + <string name="TooltipAgentUrl"> + Clicca per vedere il profilo di questo residente + </string> + <string name="TooltipAgentInspect"> + Ulteriori informazioni su questo Residente + </string> + <string name="TooltipAgentMute"> + Clicca per disattivare l'audio di questo residente + </string> + <string name="TooltipAgentUnmute"> + Clicca per attivare l'audio del residente + </string> + <string name="TooltipAgentIM"> + Clicca per inviare un IM a questo residente + </string> + <string name="TooltipAgentPay"> + Clicca per pagare il residente + </string> + <string name="TooltipAgentOfferTeleport"> + Fai clic per inviare un'offerta di teleport al residente + </string> + <string name="TooltipAgentRequestFriend"> + Fai clic per inviare una richiesta di amicizia al residente + </string> + <string name="TooltipGroupUrl"> + Clicca per vedere la descrizione del gruppo + </string> + <string name="TooltipEventUrl"> + Clicca per vedere la descrizione dell'evento + </string> + <string name="TooltipClassifiedUrl"> + Clicca per vedere questa inserzione + </string> + <string name="TooltipParcelUrl"> + Clicca per vedere la descrizione del lotto + </string> + <string name="TooltipTeleportUrl"> + Clicca per effettuare il teleport a questa destinazione + </string> + <string name="TooltipObjectIMUrl"> + Clicca per vedere la descrizione dell'oggetto + </string> + <string name="TooltipMapUrl"> + Clicca per vedere questo posto sulla mappa + </string> + <string name="TooltipSLAPP"> + Clicca per avviare il comando secondlife:// + </string> <string name="CurrentURL" value="URL attuale: [CurrentURL]"/> - <string name="TooltipEmail">Fai clic per comporre un'email</string> - <string name="SLurlLabelTeleport">Teleportati a</string> - <string name="SLurlLabelShowOnMap">Mostra la mappa per</string> - <string name="SLappAgentMute">Disattiva audio</string> - <string name="SLappAgentUnmute">Riattiva audio</string> - <string name="SLappAgentIM">IM</string> - <string name="SLappAgentPay">Paga</string> - <string name="SLappAgentOfferTeleport">Offri teleport a</string> - <string name="SLappAgentRequestFriend">Richiesta di amicizia</string> - <string name="SLappAgentRemoveFriend">Rimozione amico</string> - <string name="BUTTON_CLOSE_DARWIN">Chiudi (⌘W)</string> - <string name="BUTTON_CLOSE_WIN">Chiudi (Ctrl+W)</string> - <string name="BUTTON_CLOSE_CHROME">Chiudi</string> - <string name="BUTTON_RESTORE">Ripristina</string> - <string name="BUTTON_MINIMIZE">Minimizza</string> - <string name="BUTTON_TEAR_OFF">Distacca</string> - <string name="BUTTON_DOCK">Àncora</string> - <string name="BUTTON_HELP">Mostra Aiuto</string> - <string name="TooltipNotecardNotAllowedTypeDrop">Oggetti di questo tipo non possono essere allegati ai -biglietti in questa regione.</string> - <string name="TooltipNotecardOwnerRestrictedDrop">Solamente gli oggetti con autorizzazioni + <string name="TooltipEmail"> + Fai clic per comporre un'email + </string> + <string name="SLurlLabelTeleport"> + Teleportati a + </string> + <string name="SLurlLabelShowOnMap"> + Mostra la mappa per + </string> + <string name="SLappAgentMute"> + Disattiva audio + </string> + <string name="SLappAgentUnmute"> + Riattiva audio + </string> + <string name="SLappAgentIM"> + IM + </string> + <string name="SLappAgentPay"> + Paga + </string> + <string name="SLappAgentOfferTeleport"> + Offri teleport a + </string> + <string name="SLappAgentRequestFriend"> + Richiesta di amicizia + </string> + <string name="SLappAgentRemoveFriend"> + Rimozione amico + </string> + <string name="BUTTON_CLOSE_DARWIN"> + Chiudi (⌘W) + </string> + <string name="BUTTON_CLOSE_WIN"> + Chiudi (Ctrl+W) + </string> + <string name="BUTTON_CLOSE_CHROME"> + Chiudi + </string> + <string name="BUTTON_RESTORE"> + Ripristina + </string> + <string name="BUTTON_MINIMIZE"> + Minimizza + </string> + <string name="BUTTON_TEAR_OFF"> + Distacca + </string> + <string name="BUTTON_DOCK"> + Àncora + </string> + <string name="BUTTON_HELP"> + Mostra Aiuto + </string> + <string name="TooltipNotecardNotAllowedTypeDrop"> + Oggetti di questo tipo non possono essere allegati ai +biglietti in questa regione. + </string> + <string name="TooltipNotecardOwnerRestrictedDrop"> + Solamente gli oggetti con autorizzazioni illimitate al “proprietario successivo” -possono essere allegati ai biglietti.</string> - <string name="Searching">Ricerca in corso...</string> - <string name="NoneFound">Nessun risultato.</string> - <string name="RetrievingData">Recupero dati in corso...</string> - <string name="ReleaseNotes">Note sulla versione</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> - <string name="LoadingData">In caricamento...</string> - <string name="AvatarNameNobody">(nessuno)</string> - <string name="AvatarNameWaiting">(in attesa)</string> - <string name="GroupNameNone">(nessuno)</string> - <string name="AssetErrorNone">Nessun errore</string> - <string name="AssetErrorRequestFailed">Richiesta risorsa: fallita</string> - <string name="AssetErrorNonexistentFile">Richiesta risorsa: file non esistente</string> - <string name="AssetErrorNotInDatabase">Richiesta risorsa: risorsa non trovata nel database</string> - <string name="AssetErrorEOF">Fine del file</string> - <string name="AssetErrorCannotOpenFile">Apertura del file non possibile</string> - <string name="AssetErrorFileNotFound">File non trovato</string> - <string name="AssetErrorTCPTimeout">Tempo esaurito per il trasferimento file</string> - <string name="AssetErrorCircuitGone">Circuito perso</string> - <string name="AssetErrorPriceMismatch">Il programma e il server non combaciano nel prezzo</string> - <string name="AssetErrorUnknownStatus">Stato sconosciuto</string> - <string name="AssetUploadServerUnreacheble">Servizio non raggiungibile.</string> - <string name="AssetUploadServerDifficulties">Il servizio sta riscontrando difficoltà inaspettate.</string> - <string name="AssetUploadServerUnavaliable">Servizio non disponibile o limite di tempo per il caricamento raggiunto.</string> - <string name="AssetUploadRequestInvalid">Errore nella richiesta di caricamento. Vai alla pagina -http://secondlife.com/support per risolvere il problema.</string> - <string name="SettingValidationError">Impossibile convalidare le impostazioni importate [NAME]</string> - <string name="SettingImportFileError">Impossibile aprire il file [FILE]</string> - <string name="SettingParseFileError">Impossibile aprire il file [FILE]</string> - <string name="SettingTranslateError">Impossibile tradurre la legacy vento e luce [NAME]</string> - <string name="texture">texture</string> - <string name="sound">suono</string> - <string name="calling card">biglietto da visita</string> - <string name="landmark">punto di riferimento</string> - <string name="legacy script">script (vecchia versione)</string> - <string name="clothing">vestiario</string> - <string name="object">oggetto</string> - <string name="note card">biglietto</string> - <string name="folder">cartella</string> - <string name="root">cartella principale</string> - <string name="lsl2 script">script LSL2</string> - <string name="lsl bytecode">bytecode LSL</string> - <string name="tga texture">tga texture</string> - <string name="body part">parte del corpo</string> - <string name="snapshot">fotografia</string> - <string name="lost and found">oggetti smarriti</string> - <string name="targa image">immagine targa</string> - <string name="trash">Cestino</string> - <string name="jpeg image">immagine jpeg</string> - <string name="animation">animazione</string> - <string name="gesture">gesture</string> - <string name="simstate">simstate</string> - <string name="favorite">preferiti</string> - <string name="symbolic link">link</string> - <string name="symbolic folder link">link alla cartella</string> - <string name="settings blob">impostazioni</string> - <string name="mesh">reticolo</string> - <string name="AvatarEditingAppearance">(Modifica Aspetto)</string> - <string name="AvatarAway">Assente</string> - <string name="AvatarDoNotDisturb">Non disturbare</string> - <string name="AvatarMuted">Mutato</string> - <string name="anim_express_afraid">Dispiaciuto</string> - <string name="anim_express_anger">Arrabbiato</string> - <string name="anim_away">Assente</string> - <string name="anim_backflip">Salto all'indietro</string> - <string name="anim_express_laugh">Ridere a crepapelle</string> - <string name="anim_express_toothsmile">Gran sorriso</string> - <string name="anim_blowkiss">Lancia un bacio</string> - <string name="anim_express_bored">Noia</string> - <string name="anim_bow">Inchino</string> - <string name="anim_clap">Applauso</string> - <string name="anim_courtbow">Inchino a corte</string> - <string name="anim_express_cry">Pianto</string> - <string name="anim_dance1">Ballo 1</string> - <string name="anim_dance2">Ballo 2</string> - <string name="anim_dance3">Ballo 3</string> - <string name="anim_dance4">Ballo 4</string> - <string name="anim_dance5">Ballo 5</string> - <string name="anim_dance6">Ballo 6</string> - <string name="anim_dance7">Ballo 7</string> - <string name="anim_dance8">Dance 8</string> - <string name="anim_express_disdain">Sdegno</string> - <string name="anim_drink">Bere</string> - <string name="anim_express_embarrased">Imbarazzo</string> - <string name="anim_angry_fingerwag">Negare col dito</string> - <string name="anim_fist_pump">Esultare con pugno</string> - <string name="anim_yoga_float">Yoga fluttuante</string> - <string name="anim_express_frown">Acciglio</string> - <string name="anim_impatient">Impazienza</string> - <string name="anim_jumpforjoy">Salto di gioia</string> - <string name="anim_kissmybutt">Baciami il sedere</string> - <string name="anim_express_kiss">Bacio</string> - <string name="anim_laugh_short">Risata</string> - <string name="anim_musclebeach">Muscoli da spiaggia</string> - <string name="anim_no_unhappy">No (Scontento)</string> - <string name="anim_no_head">No</string> - <string name="anim_nyanya">Na-na-na</string> - <string name="anim_punch_onetwo">Uno-due pugno</string> - <string name="anim_express_open_mouth">Bocca aperta</string> - <string name="anim_peace">Pace</string> - <string name="anim_point_you">Indicare altri</string> - <string name="anim_point_me">Indicare te stesso</string> - <string name="anim_punch_l">Pugno a sinistra</string> - <string name="anim_punch_r">Pugno a destra</string> - <string name="anim_rps_countdown">Contare nella morra cinese</string> - <string name="anim_rps_paper">Carta nella morra cinese</string> - <string name="anim_rps_rock">Sasso nella morra cinese</string> - <string name="anim_rps_scissors">Forbici nella morra cinese</string> - <string name="anim_express_repulsed">Repulsione</string> - <string name="anim_kick_roundhouse_r">Calcio con rotazione</string> - <string name="anim_express_sad">Triste</string> - <string name="anim_salute">Saluto</string> - <string name="anim_shout">Urlo</string> - <string name="anim_express_shrug">Spallucce</string> - <string name="anim_express_smile">Sorriso</string> - <string name="anim_smoke_idle">Fumare</string> - <string name="anim_smoke_inhale">Fumare inspirazione</string> - <string name="anim_smoke_throw_down">Fumare mandando giù</string> - <string name="anim_express_surprise">Sorpresa</string> - <string name="anim_sword_strike_r">Colpo di spada</string> - <string name="anim_angry_tantrum">Collera</string> - <string name="anim_express_tongue_out">Linguaccia</string> - <string name="anim_hello">Saluto con mano</string> - <string name="anim_whisper">Sussurro</string> - <string name="anim_whistle">Fischio</string> - <string name="anim_express_wink">Ammicca</string> - <string name="anim_wink_hollywood">Ammicca (Hollywood)</string> - <string name="anim_express_worry">Preoccupato</string> - <string name="anim_yes_happy">Si (Felice)</string> - <string name="anim_yes_head">Si</string> - <string name="multiple_textures">Multiple</string> - <string name="use_texture">Usa texture</string> - <string name="manip_hint1">Sposta il cursore sul righello</string> - <string name="manip_hint2">per bloccare sulla griglia</string> - <string name="texture_loading">Caricamento in corso...</string> - <string name="worldmap_offline">Offline</string> - <string name="worldmap_item_tooltip_format">L$ [PRICE] - [AREA] m²</string> - <string name="worldmap_results_none_found">Nessun risultato.</string> - <string name="Ok">OK</string> - <string name="Premature end of file">Fine prematura del file</string> - <string name="ST_NO_JOINT">Impossibile trovare ROOT o JOINT.</string> - <string name="NearbyChatTitle">Chat nei dintorni</string> - <string name="NearbyChatLabel">(Chat nei dintorni)</string> - <string name="whisper">sussurra:</string> - <string name="shout">grida:</string> - <string name="ringing">In connessione alla Voice Chat in-world...</string> - <string name="connected">Connesso</string> - <string name="unavailable">Il voice non è disponibile nel posto dove ti trovi ora</string> - <string name="hang_up">Disconnesso dalla Voice Chat in-world</string> - <string name="reconnect_nearby">Sarai riconnesso alla chat vocale nei dintorni</string> - <string name="ScriptQuestionCautionChatGranted">A '[OBJECTNAME]', un oggetto di proprietà di '[OWNERNAME]', situato in [REGIONNAME] [REGIONPOS], è stato concesso il permesso di: [PERMISSIONS].</string> - <string name="ScriptQuestionCautionChatDenied">A '[OBJECTNAME]', un oggetto di proprietà di '[OWNERNAME]', situato in [REGIONNAME] [REGIONPOS], è stato negato il permesso di: [PERMISSIONS].</string> - <string name="AdditionalPermissionsRequestHeader">Se consenti l'accesso al tuo account, consentirai anche all'oggetto di:</string> - <string name="ScriptTakeMoney">Prendere dollari Linden (L$) da te</string> - <string name="ActOnControlInputs">Agire sul tuo controllo degli input</string> - <string name="RemapControlInputs">Rimappare il tuo controllo degli input</string> - <string name="AnimateYourAvatar">Animare il tuo avatar</string> - <string name="AttachToYourAvatar">Far indossare al tuo avatar</string> - <string name="ReleaseOwnership">Rilasciare la propietà è far diventare pubblico.</string> - <string name="LinkAndDelink">Collegare e scollegare dagli altri oggetti</string> - <string name="AddAndRemoveJoints">Aggiungere e rimuovere le giunzioni insieme con gli altri oggetti</string> - <string name="ChangePermissions">Cambiare i permessi</string> - <string name="TrackYourCamera">Tracciare la fotocamera</string> - <string name="ControlYourCamera">Controllare la tua fotocamera</string> - <string name="TeleportYourAgent">Teleportarti</string> - <string name="ForceSitAvatar">Forza l'avatar a sedersi</string> - <string name="ChangeEnvSettings">Cambia le impostazioni dell’ambiente</string> - <string name="AgentNameSubst">(Tu)</string> +possono essere allegati ai biglietti. + </string> + <string name="Searching"> + Ricerca in corso... + </string> + <string name="NoneFound"> + Nessun risultato. + </string> + <string name="RetrievingData"> + Recupero dati in corso... + </string> + <string name="ReleaseNotes"> + Note sulla versione + </string> + <string name="RELEASE_NOTES_BASE_URL"> + https://releasenotes.secondlife.com/viewer/ + </string> + <string name="LoadingData"> + In caricamento... + </string> + <string name="AvatarNameNobody"> + (nessuno) + </string> + <string name="AvatarNameWaiting"> + (in attesa) + </string> + <string name="GroupNameNone"> + (nessuno) + </string> + <string name="AssetErrorNone"> + Nessun errore + </string> + <string name="AssetErrorRequestFailed"> + Richiesta risorsa: fallita + </string> + <string name="AssetErrorNonexistentFile"> + Richiesta risorsa: file non esistente + </string> + <string name="AssetErrorNotInDatabase"> + Richiesta risorsa: risorsa non trovata nel database + </string> + <string name="AssetErrorEOF"> + Fine del file + </string> + <string name="AssetErrorCannotOpenFile"> + Apertura del file non possibile + </string> + <string name="AssetErrorFileNotFound"> + File non trovato + </string> + <string name="AssetErrorTCPTimeout"> + Tempo esaurito per il trasferimento file + </string> + <string name="AssetErrorCircuitGone"> + Circuito perso + </string> + <string name="AssetErrorPriceMismatch"> + Il programma e il server non combaciano nel prezzo + </string> + <string name="AssetErrorUnknownStatus"> + Stato sconosciuto + </string> + <string name="AssetUploadServerUnreacheble"> + Servizio non raggiungibile. + </string> + <string name="AssetUploadServerDifficulties"> + Il servizio sta riscontrando difficoltà inaspettate. + </string> + <string name="AssetUploadServerUnavaliable"> + Servizio non disponibile o limite di tempo per il caricamento raggiunto. + </string> + <string name="AssetUploadRequestInvalid"> + Errore nella richiesta di caricamento. Vai alla pagina +http://secondlife.com/support per risolvere il problema. + </string> + <string name="SettingValidationError"> + Impossibile convalidare le impostazioni importate [NAME] + </string> + <string name="SettingImportFileError"> + Impossibile aprire il file [FILE] + </string> + <string name="SettingParseFileError"> + Impossibile aprire il file [FILE] + </string> + <string name="SettingTranslateError"> + Impossibile tradurre la legacy vento e luce [NAME] + </string> + <string name="texture"> + texture + </string> + <string name="sound"> + suono + </string> + <string name="calling card"> + biglietto da visita + </string> + <string name="landmark"> + punto di riferimento + </string> + <string name="legacy script"> + script (vecchia versione) + </string> + <string name="clothing"> + vestiario + </string> + <string name="object"> + oggetto + </string> + <string name="note card"> + biglietto + </string> + <string name="folder"> + cartella + </string> + <string name="root"> + cartella principale + </string> + <string name="lsl2 script"> + script LSL2 + </string> + <string name="lsl bytecode"> + bytecode LSL + </string> + <string name="tga texture"> + tga texture + </string> + <string name="body part"> + parte del corpo + </string> + <string name="snapshot"> + fotografia + </string> + <string name="lost and found"> + oggetti smarriti + </string> + <string name="targa image"> + immagine targa + </string> + <string name="trash"> + Cestino + </string> + <string name="jpeg image"> + immagine jpeg + </string> + <string name="animation"> + animazione + </string> + <string name="gesture"> + gesture + </string> + <string name="simstate"> + simstate + </string> + <string name="favorite"> + preferiti + </string> + <string name="symbolic link"> + link + </string> + <string name="symbolic folder link"> + link alla cartella + </string> + <string name="settings blob"> + impostazioni + </string> + <string name="mesh"> + reticolo + </string> + <string name="AvatarEditingAppearance"> + (Modifica Aspetto) + </string> + <string name="AvatarAway"> + Assente + </string> + <string name="AvatarDoNotDisturb"> + Non disturbare + </string> + <string name="AvatarMuted"> + Mutato + </string> + <string name="anim_express_afraid"> + Dispiaciuto + </string> + <string name="anim_express_anger"> + Arrabbiato + </string> + <string name="anim_away"> + Assente + </string> + <string name="anim_backflip"> + Salto all'indietro + </string> + <string name="anim_express_laugh"> + Ridere a crepapelle + </string> + <string name="anim_express_toothsmile"> + Gran sorriso + </string> + <string name="anim_blowkiss"> + Lancia un bacio + </string> + <string name="anim_express_bored"> + Noia + </string> + <string name="anim_bow"> + Inchino + </string> + <string name="anim_clap"> + Applauso + </string> + <string name="anim_courtbow"> + Inchino a corte + </string> + <string name="anim_express_cry"> + Pianto + </string> + <string name="anim_dance1"> + Ballo 1 + </string> + <string name="anim_dance2"> + Ballo 2 + </string> + <string name="anim_dance3"> + Ballo 3 + </string> + <string name="anim_dance4"> + Ballo 4 + </string> + <string name="anim_dance5"> + Ballo 5 + </string> + <string name="anim_dance6"> + Ballo 6 + </string> + <string name="anim_dance7"> + Ballo 7 + </string> + <string name="anim_dance8"> + Dance 8 + </string> + <string name="anim_express_disdain"> + Sdegno + </string> + <string name="anim_drink"> + Bere + </string> + <string name="anim_express_embarrased"> + Imbarazzo + </string> + <string name="anim_angry_fingerwag"> + Negare col dito + </string> + <string name="anim_fist_pump"> + Esultare con pugno + </string> + <string name="anim_yoga_float"> + Yoga fluttuante + </string> + <string name="anim_express_frown"> + Acciglio + </string> + <string name="anim_impatient"> + Impazienza + </string> + <string name="anim_jumpforjoy"> + Salto di gioia + </string> + <string name="anim_kissmybutt"> + Baciami il sedere + </string> + <string name="anim_express_kiss"> + Bacio + </string> + <string name="anim_laugh_short"> + Risata + </string> + <string name="anim_musclebeach"> + Muscoli da spiaggia + </string> + <string name="anim_no_unhappy"> + No (Scontento) + </string> + <string name="anim_no_head"> + No + </string> + <string name="anim_nyanya"> + Na-na-na + </string> + <string name="anim_punch_onetwo"> + Uno-due pugno + </string> + <string name="anim_express_open_mouth"> + Bocca aperta + </string> + <string name="anim_peace"> + Pace + </string> + <string name="anim_point_you"> + Indicare altri + </string> + <string name="anim_point_me"> + Indicare te stesso + </string> + <string name="anim_punch_l"> + Pugno a sinistra + </string> + <string name="anim_punch_r"> + Pugno a destra + </string> + <string name="anim_rps_countdown"> + Contare nella morra cinese + </string> + <string name="anim_rps_paper"> + Carta nella morra cinese + </string> + <string name="anim_rps_rock"> + Sasso nella morra cinese + </string> + <string name="anim_rps_scissors"> + Forbici nella morra cinese + </string> + <string name="anim_express_repulsed"> + Repulsione + </string> + <string name="anim_kick_roundhouse_r"> + Calcio con rotazione + </string> + <string name="anim_express_sad"> + Triste + </string> + <string name="anim_salute"> + Saluto + </string> + <string name="anim_shout"> + Urlo + </string> + <string name="anim_express_shrug"> + Spallucce + </string> + <string name="anim_express_smile"> + Sorriso + </string> + <string name="anim_smoke_idle"> + Fumare + </string> + <string name="anim_smoke_inhale"> + Fumare inspirazione + </string> + <string name="anim_smoke_throw_down"> + Fumare mandando giù + </string> + <string name="anim_express_surprise"> + Sorpresa + </string> + <string name="anim_sword_strike_r"> + Colpo di spada + </string> + <string name="anim_angry_tantrum"> + Collera + </string> + <string name="anim_express_tongue_out"> + Linguaccia + </string> + <string name="anim_hello"> + Saluto con mano + </string> + <string name="anim_whisper"> + Sussurro + </string> + <string name="anim_whistle"> + Fischio + </string> + <string name="anim_express_wink"> + Ammicca + </string> + <string name="anim_wink_hollywood"> + Ammicca (Hollywood) + </string> + <string name="anim_express_worry"> + Preoccupato + </string> + <string name="anim_yes_happy"> + Si (Felice) + </string> + <string name="anim_yes_head"> + Si + </string> + <string name="multiple_textures"> + Multiple + </string> + <string name="use_texture"> + Usa texture + </string> + <string name="manip_hint1"> + Sposta il cursore sul righello + </string> + <string name="manip_hint2"> + per bloccare sulla griglia + </string> + <string name="texture_loading"> + Caricamento in corso... + </string> + <string name="worldmap_offline"> + Offline + </string> + <string name="worldmap_item_tooltip_format"> + L$ [PRICE] - [AREA] m² + </string> + <string name="worldmap_results_none_found"> + Nessun risultato. + </string> + <string name="Ok"> + OK + </string> + <string name="Premature end of file"> + Fine prematura del file + </string> + <string name="ST_NO_JOINT"> + Impossibile trovare ROOT o JOINT. + </string> + <string name="NearbyChatTitle"> + Chat nei dintorni + </string> + <string name="NearbyChatLabel"> + (Chat nei dintorni) + </string> + <string name="whisper"> + sussurra: + </string> + <string name="shout"> + grida: + </string> + <string name="ringing"> + In connessione alla Voice Chat in-world... + </string> + <string name="connected"> + Connesso + </string> + <string name="unavailable"> + Il voice non è disponibile nel posto dove ti trovi ora + </string> + <string name="hang_up"> + Disconnesso dalla Voice Chat in-world + </string> + <string name="reconnect_nearby"> + Sarai riconnesso alla chat vocale nei dintorni + </string> + <string name="ScriptQuestionCautionChatGranted"> + A '[OBJECTNAME]', un oggetto di proprietà di '[OWNERNAME]', situato in [REGIONNAME] [REGIONPOS], è stato concesso il permesso di: [PERMISSIONS]. + </string> + <string name="ScriptQuestionCautionChatDenied"> + A '[OBJECTNAME]', un oggetto di proprietà di '[OWNERNAME]', situato in [REGIONNAME] [REGIONPOS], è stato negato il permesso di: [PERMISSIONS]. + </string> + <string name="AdditionalPermissionsRequestHeader"> + Se consenti l'accesso al tuo account, consentirai anche all'oggetto di: + </string> + <string name="ScriptTakeMoney"> + Prendere dollari Linden (L$) da te + </string> + <string name="ActOnControlInputs"> + Agire sul tuo controllo degli input + </string> + <string name="RemapControlInputs"> + Rimappare il tuo controllo degli input + </string> + <string name="AnimateYourAvatar"> + Animare il tuo avatar + </string> + <string name="AttachToYourAvatar"> + Far indossare al tuo avatar + </string> + <string name="ReleaseOwnership"> + Rilasciare la propietà è far diventare pubblico. + </string> + <string name="LinkAndDelink"> + Collegare e scollegare dagli altri oggetti + </string> + <string name="AddAndRemoveJoints"> + Aggiungere e rimuovere le giunzioni insieme con gli altri oggetti + </string> + <string name="ChangePermissions"> + Cambiare i permessi + </string> + <string name="TrackYourCamera"> + Tracciare la fotocamera + </string> + <string name="ControlYourCamera"> + Controllare la tua fotocamera + </string> + <string name="TeleportYourAgent"> + Teleportarti + </string> + <string name="ForceSitAvatar"> + Forza l'avatar a sedersi + </string> + <string name="ChangeEnvSettings"> + Cambia le impostazioni dell’ambiente + </string> + <string name="AgentNameSubst"> + (Tu) + </string> <string name="JoinAnExperience"/> - <string name="SilentlyManageEstateAccess">Omette gli avvisi durante la gestione degli elenchi di accesso alle proprietà immobiliari</string> - <string name="OverrideYourAnimations">Sostituisce le animazioni predefinite</string> - <string name="ScriptReturnObjects">Restituisce oggetti per conto tuo</string> - <string name="UnknownScriptPermission">(sconosciuto)!</string> - <string name="SIM_ACCESS_PG">Generale</string> - <string name="SIM_ACCESS_MATURE">Moderato</string> - <string name="SIM_ACCESS_ADULT">Adulti</string> - <string name="SIM_ACCESS_DOWN">Offline</string> - <string name="SIM_ACCESS_MIN">Sconosciuto</string> - <string name="land_type_unknown">(sconosciuto)</string> - <string name="Estate / Full Region">Proprietà immobiliare / Regione completa</string> - <string name="Estate / Homestead">Proprietà immobiliare / Homestead</string> - <string name="Mainland / Homestead">Continente / Homestead</string> - <string name="Mainland / Full Region">Continente / Regione completa</string> - <string name="all_files">Tutti i file</string> - <string name="sound_files">Suoni</string> - <string name="animation_files">Animazioni</string> - <string name="image_files">Immagini</string> - <string name="save_file_verb">Salva</string> - <string name="load_file_verb">Carica</string> - <string name="targa_image_files">Immagini Targa</string> - <string name="bitmap_image_files">Immagini Bitmap</string> - <string name="png_image_files">Immagini PNG</string> - <string name="save_texture_image_files">Immagini Targa o PNG</string> - <string name="avi_movie_file">File video AVI</string> - <string name="xaf_animation_file">File animazione XAF</string> - <string name="xml_file">File XML</string> - <string name="raw_file">File RAW</string> - <string name="compressed_image_files">Immagini compresse</string> - <string name="load_files">Carica i file</string> - <string name="choose_the_directory">Scegli la cartella</string> - <string name="script_files">Script</string> - <string name="dictionary_files">Dizionari</string> - <string name="shape">Figura corporea</string> - <string name="skin">Pelle</string> - <string name="hair">Capigliature</string> - <string name="eyes">Occhi</string> - <string name="shirt">Camicia</string> - <string name="pants">Pantaloni</string> - <string name="shoes">Scarpe</string> - <string name="socks">Calzini</string> - <string name="jacket">Giacca</string> - <string name="gloves">Guanti</string> - <string name="undershirt">Maglietta intima</string> - <string name="underpants">Slip</string> - <string name="skirt">Gonna</string> - <string name="alpha">Alfa (Trasparenza)</string> - <string name="tattoo">Tatuaggio</string> - <string name="universal">Universale</string> - <string name="physics">Fisica</string> - <string name="invalid">non valido</string> - <string name="none">nessuno</string> - <string name="shirt_not_worn">Camicia non indossata</string> - <string name="pants_not_worn">Pantaloni non indossati</string> - <string name="shoes_not_worn">Scarpe non indossate</string> - <string name="socks_not_worn">Calzini non indossati</string> - <string name="jacket_not_worn">Giacca non indossata</string> - <string name="gloves_not_worn">Guanti non indossati</string> - <string name="undershirt_not_worn">Maglietta intima non indossata</string> - <string name="underpants_not_worn">Slip non indossati</string> - <string name="skirt_not_worn">Gonna non indossata</string> - <string name="alpha_not_worn">Alpha non portato</string> - <string name="tattoo_not_worn">Tatuaggio non portato</string> - <string name="universal_not_worn">Universale non indossato</string> - <string name="physics_not_worn">Fisica non indossata</string> - <string name="invalid_not_worn">non valido</string> - <string name="create_new_shape">Crea nuova figura corporea</string> - <string name="create_new_skin">Crea nuova pelle</string> - <string name="create_new_hair">Crea nuovi capelli</string> - <string name="create_new_eyes">Crea nuovi occhi</string> - <string name="create_new_shirt">Crea nuova camicia</string> - <string name="create_new_pants">Crea nuovi pantaloni</string> - <string name="create_new_shoes">Crea nuove scarpe</string> - <string name="create_new_socks">Crea nuove calze</string> - <string name="create_new_jacket">Crea nuova giacca</string> - <string name="create_new_gloves">Crea nuovi guanti</string> - <string name="create_new_undershirt">Crea nuova maglietta intima</string> - <string name="create_new_underpants">Crea nuovi slip</string> - <string name="create_new_skirt">Crea nuova gonna</string> - <string name="create_new_alpha">Crea nuovo Alpha</string> - <string name="create_new_tattoo">Crea un nuovo tatuaggio</string> - <string name="create_new_universal">Crea nuovo universale</string> - <string name="create_new_physics">Crea nuova fisica</string> - <string name="create_new_invalid">non valido</string> - <string name="NewWearable">Nuovo [WEARABLE_ITEM]</string> - <string name="next">Avanti</string> - <string name="ok">OK</string> - <string name="GroupNotifyGroupNotice">Avviso di gruppo</string> - <string name="GroupNotifyGroupNotices">Avvisi di gruppo</string> - <string name="GroupNotifySentBy">Inviato da</string> - <string name="GroupNotifyAttached">Allegato:</string> - <string name="GroupNotifyViewPastNotices">Visualizza gli avvisi precedenti o scegli qui di non riceverne.</string> - <string name="GroupNotifyOpenAttachment">Apri l'allegato</string> - <string name="GroupNotifySaveAttachment">Salva l'allegato</string> - <string name="TeleportOffer">Offerta di Teleport</string> - <string name="StartUpNotifications">Mentre eri assente sono arrivate nuove notifiche...</string> - <string name="OverflowInfoChannelString">Hai ancora [%d] notifiche</string> - <string name="BodyPartsRightArm">Braccio destro</string> - <string name="BodyPartsHead">Testa</string> - <string name="BodyPartsLeftArm">Braccio sinistro</string> - <string name="BodyPartsLeftLeg">Gamba sinistra</string> - <string name="BodyPartsTorso">Torace</string> - <string name="BodyPartsRightLeg">Gamba destra</string> - <string name="BodyPartsEnhancedSkeleton">Scheletro avanzato</string> - <string name="GraphicsQualityLow">Basso</string> - <string name="GraphicsQualityMid">Medio</string> - <string name="GraphicsQualityHigh">Alto</string> - <string name="LeaveMouselook">Premi ESC per tornare in visualizzazione normale</string> - <string name="InventoryNoMatchingItems">Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/all/[SEARCH_TERM] Cerca].</string> - <string name="InventoryNoMatchingRecentItems">Non hai trovato ció che cercavi? Prova [secondlife:///app/inventory/filters Show filters].</string> - <string name="PlacesNoMatchingItems">Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/places/[SEARCH_TERM] Cerca].</string> - <string name="FavoritesNoMatchingItems">Trascina qui un punto di riferimento per aggiungerlo ai Preferiti.</string> - <string name="MarketplaceNoMatchingItems">Nessun articolo trovato. Controlla di aver digitato la stringa di ricerca correttamente e riprova.</string> - <string name="InventoryNoTexture">Non hai una copia di questa texture nel tuo inventario</string> - <string name="InventoryInboxNoItems">Gli acquissti dal mercato verranno mostrati qui. Potrai quindi trascinarli nel tuo inventario per usarli.</string> - <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> - <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3</string> - <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string> - <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string> - <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string> - <string name="InventoryPlayAnimationTooltip">Apri finestra con opzioni di Gioco.</string> - <string name="InventoryPlayGestureTooltip">Esegui il movimento selezionato nel mondo virtuale.</string> - <string name="InventoryPlaySoundTooltip">Apri finestra con opzioni di Gioco.</string> - <string name="InventoryOutboxNotMerchantTitle">Chiunque può vendere oggetti nel Marketplace.</string> + <string name="SilentlyManageEstateAccess"> + Omette gli avvisi durante la gestione degli elenchi di accesso alle proprietà immobiliari + </string> + <string name="OverrideYourAnimations"> + Sostituisce le animazioni predefinite + </string> + <string name="ScriptReturnObjects"> + Restituisce oggetti per conto tuo + </string> + <string name="UnknownScriptPermission"> + (sconosciuto)! + </string> + <string name="SIM_ACCESS_PG"> + Generale + </string> + <string name="SIM_ACCESS_MATURE"> + Moderato + </string> + <string name="SIM_ACCESS_ADULT"> + Adulti + </string> + <string name="SIM_ACCESS_DOWN"> + Offline + </string> + <string name="SIM_ACCESS_MIN"> + Sconosciuto + </string> + <string name="land_type_unknown"> + (sconosciuto) + </string> + <string name="Estate / Full Region"> + Proprietà immobiliare / Regione completa + </string> + <string name="Estate / Homestead"> + Proprietà immobiliare / Homestead + </string> + <string name="Mainland / Homestead"> + Continente / Homestead + </string> + <string name="Mainland / Full Region"> + Continente / Regione completa + </string> + <string name="all_files"> + Tutti i file + </string> + <string name="sound_files"> + Suoni + </string> + <string name="animation_files"> + Animazioni + </string> + <string name="image_files"> + Immagini + </string> + <string name="save_file_verb"> + Salva + </string> + <string name="load_file_verb"> + Carica + </string> + <string name="targa_image_files"> + Immagini Targa + </string> + <string name="bitmap_image_files"> + Immagini Bitmap + </string> + <string name="png_image_files"> + Immagini PNG + </string> + <string name="save_texture_image_files"> + Immagini Targa o PNG + </string> + <string name="avi_movie_file"> + File video AVI + </string> + <string name="xaf_animation_file"> + File animazione XAF + </string> + <string name="xml_file"> + File XML + </string> + <string name="raw_file"> + File RAW + </string> + <string name="compressed_image_files"> + Immagini compresse + </string> + <string name="load_files"> + Carica i file + </string> + <string name="choose_the_directory"> + Scegli la cartella + </string> + <string name="script_files"> + Script + </string> + <string name="dictionary_files"> + Dizionari + </string> + <string name="shape"> + Figura corporea + </string> + <string name="skin"> + Pelle + </string> + <string name="hair"> + Capigliature + </string> + <string name="eyes"> + Occhi + </string> + <string name="shirt"> + Camicia + </string> + <string name="pants"> + Pantaloni + </string> + <string name="shoes"> + Scarpe + </string> + <string name="socks"> + Calzini + </string> + <string name="jacket"> + Giacca + </string> + <string name="gloves"> + Guanti + </string> + <string name="undershirt"> + Maglietta intima + </string> + <string name="underpants"> + Slip + </string> + <string name="skirt"> + Gonna + </string> + <string name="alpha"> + Alfa (Trasparenza) + </string> + <string name="tattoo"> + Tatuaggio + </string> + <string name="universal"> + Universale + </string> + <string name="physics"> + Fisica + </string> + <string name="invalid"> + non valido + </string> + <string name="none"> + nessuno + </string> + <string name="shirt_not_worn"> + Camicia non indossata + </string> + <string name="pants_not_worn"> + Pantaloni non indossati + </string> + <string name="shoes_not_worn"> + Scarpe non indossate + </string> + <string name="socks_not_worn"> + Calzini non indossati + </string> + <string name="jacket_not_worn"> + Giacca non indossata + </string> + <string name="gloves_not_worn"> + Guanti non indossati + </string> + <string name="undershirt_not_worn"> + Maglietta intima non indossata + </string> + <string name="underpants_not_worn"> + Slip non indossati + </string> + <string name="skirt_not_worn"> + Gonna non indossata + </string> + <string name="alpha_not_worn"> + Alpha non portato + </string> + <string name="tattoo_not_worn"> + Tatuaggio non portato + </string> + <string name="universal_not_worn"> + Universale non indossato + </string> + <string name="physics_not_worn"> + Fisica non indossata + </string> + <string name="invalid_not_worn"> + non valido + </string> + <string name="create_new_shape"> + Crea nuova figura corporea + </string> + <string name="create_new_skin"> + Crea nuova pelle + </string> + <string name="create_new_hair"> + Crea nuovi capelli + </string> + <string name="create_new_eyes"> + Crea nuovi occhi + </string> + <string name="create_new_shirt"> + Crea nuova camicia + </string> + <string name="create_new_pants"> + Crea nuovi pantaloni + </string> + <string name="create_new_shoes"> + Crea nuove scarpe + </string> + <string name="create_new_socks"> + Crea nuove calze + </string> + <string name="create_new_jacket"> + Crea nuova giacca + </string> + <string name="create_new_gloves"> + Crea nuovi guanti + </string> + <string name="create_new_undershirt"> + Crea nuova maglietta intima + </string> + <string name="create_new_underpants"> + Crea nuovi slip + </string> + <string name="create_new_skirt"> + Crea nuova gonna + </string> + <string name="create_new_alpha"> + Crea nuovo Alpha + </string> + <string name="create_new_tattoo"> + Crea un nuovo tatuaggio + </string> + <string name="create_new_universal"> + Crea nuovo universale + </string> + <string name="create_new_physics"> + Crea nuova fisica + </string> + <string name="create_new_invalid"> + non valido + </string> + <string name="NewWearable"> + Nuovo [WEARABLE_ITEM] + </string> + <string name="next"> + Avanti + </string> + <string name="ok"> + OK + </string> + <string name="GroupNotifyGroupNotice"> + Avviso di gruppo + </string> + <string name="GroupNotifyGroupNotices"> + Avvisi di gruppo + </string> + <string name="GroupNotifySentBy"> + Inviato da + </string> + <string name="GroupNotifyAttached"> + Allegato: + </string> + <string name="GroupNotifyViewPastNotices"> + Visualizza gli avvisi precedenti o scegli qui di non riceverne. + </string> + <string name="GroupNotifyOpenAttachment"> + Apri l'allegato + </string> + <string name="GroupNotifySaveAttachment"> + Salva l'allegato + </string> + <string name="TeleportOffer"> + Offerta di Teleport + </string> + <string name="StartUpNotifications"> + Mentre eri assente sono arrivate nuove notifiche... + </string> + <string name="OverflowInfoChannelString"> + Hai ancora [%d] notifiche + </string> + <string name="BodyPartsRightArm"> + Braccio destro + </string> + <string name="BodyPartsHead"> + Testa + </string> + <string name="BodyPartsLeftArm"> + Braccio sinistro + </string> + <string name="BodyPartsLeftLeg"> + Gamba sinistra + </string> + <string name="BodyPartsTorso"> + Torace + </string> + <string name="BodyPartsRightLeg"> + Gamba destra + </string> + <string name="BodyPartsEnhancedSkeleton"> + Scheletro avanzato + </string> + <string name="GraphicsQualityLow"> + Basso + </string> + <string name="GraphicsQualityMid"> + Medio + </string> + <string name="GraphicsQualityHigh"> + Alto + </string> + <string name="LeaveMouselook"> + Premi ESC per tornare in visualizzazione normale + </string> + <string name="InventoryNoMatchingItems"> + Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/all/[SEARCH_TERM] Cerca]. + </string> + <string name="InventoryNoMatchingRecentItems"> + Non hai trovato ció che cercavi? Prova [secondlife:///app/inventory/filters Show filters]. + </string> + <string name="PlacesNoMatchingItems"> + Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/places/[SEARCH_TERM] Cerca]. + </string> + <string name="FavoritesNoMatchingItems"> + Trascina qui un punto di riferimento per aggiungerlo ai Preferiti. + </string> + <string name="MarketplaceNoMatchingItems"> + Nessun articolo trovato. Controlla di aver digitato la stringa di ricerca correttamente e riprova. + </string> + <string name="InventoryNoTexture"> + Non hai una copia di questa texture nel tuo inventario + </string> + <string name="InventoryInboxNoItems"> + Gli acquissti dal mercato verranno mostrati qui. Potrai quindi trascinarli nel tuo inventario per usarli. + </string> + <string name="MarketplaceURL"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ + </string> + <string name="MarketplaceURL_CreateStore"> + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3 + </string> + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard + </string> + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports + </string> + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more + </string> + <string name="InventoryPlayAnimationTooltip"> + Apri finestra con opzioni di Gioco. + </string> + <string name="InventoryPlayGestureTooltip"> + Esegui il movimento selezionato nel mondo virtuale. + </string> + <string name="InventoryPlaySoundTooltip"> + Apri finestra con opzioni di Gioco. + </string> + <string name="InventoryOutboxNotMerchantTitle"> + Chiunque può vendere oggetti nel Marketplace. + </string> <string name="InventoryOutboxNotMerchantTooltip"/> - <string name="InventoryOutboxNotMerchant">Per diventare un venditore, devi [[MARKETPLACE_CREATE_STORE_URL] creare un negozio nel Marketplace].</string> - <string name="InventoryOutboxNoItemsTitle">La tua casella in uscita è vuota.</string> + <string name="InventoryOutboxNotMerchant"> + Per diventare un venditore, devi [[MARKETPLACE_CREATE_STORE_URL] creare un negozio nel Marketplace]. + </string> + <string name="InventoryOutboxNoItemsTitle"> + La tua casella in uscita è vuota. + </string> <string name="InventoryOutboxNoItemsTooltip"/> - <string name="InventoryOutboxNoItems">Trascina le cartelle in questa area e clicca su "Invia a Marketplace" per metterle in vendita su [[MARKETPLACE_DASHBOARD_URL] Marketplace].</string> - <string name="InventoryOutboxInitializingTitle">Inizializzazione Marketplace.in corso</string> - <string name="InventoryOutboxInitializing">Stiamo eseguendo l'accesso al tuo account sul [[MARKETPLACE_CREATE_STORE_URL] negozio Marketplace].</string> - <string name="InventoryOutboxErrorTitle">Errori in Marketplace.</string> - <string name="InventoryOutboxError">Il [[MARKETPLACE_CREATE_STORE_URL] negozio nel Marketplace] ha riportato errori.</string> - <string name="InventoryMarketplaceError">Errore nell'apertura degli annunci di Marketplace. -Se continui a ricevere questo messaggio, contatta l'assistenza Second Life su http://support.secondlife.com.</string> - <string name="InventoryMarketplaceListingsNoItemsTitle">La cartella degli annunci di Marketplace è vuota.</string> - <string name="InventoryMarketplaceListingsNoItems">Trascina le cartelle in questa area per metterle in vendita su [[MARKETPLACE_DASHBOARD_URL] Marketplace].</string> - <string name="InventoryItemsCount">( [ITEMS_COUNT] oggetti )</string> - <string name="Marketplace Validation Warning Stock">la cartella di magazzino deve essere inclusa in una cartella di versione</string> - <string name="Marketplace Validation Error Mixed Stock">: Errore: tutti gli articoli un una cartella di magazzino devono essere non copiabili e dello stesso tipo</string> - <string name="Marketplace Validation Error Subfolder In Stock">: Errore: la cartella di magazzino non può contenere sottocartelle</string> - <string name="Marketplace Validation Warning Empty">: Avviso: la cartella non contiene alcun articolo</string> - <string name="Marketplace Validation Warning Create Stock">: Avviso: creazione cartella di magazzino in corso</string> - <string name="Marketplace Validation Warning Create Version">: Avviso: creazione cartella di versione in corso</string> - <string name="Marketplace Validation Warning Move">: Avviso: spostamento articoli in corso</string> - <string name="Marketplace Validation Warning Delete">: Avviso: il contenuto della cartella è stato trasferito alla cartella di magazzino e la cartella vuota sta per essere rimossa</string> - <string name="Marketplace Validation Error Stock Item">: Errore: gli articoli di cui non è permessa la copia devono essere all'interno di una cartella di magazzino</string> - <string name="Marketplace Validation Warning Unwrapped Item">: Avviso: gli articoli devono essere inclusi in una cartella di versione</string> - <string name="Marketplace Validation Error">: Errore:</string> - <string name="Marketplace Validation Warning">: Avviso:</string> - <string name="Marketplace Validation Error Empty Version">: Avviso: la cartella di versione deve contenere almeno 1 articolo</string> - <string name="Marketplace Validation Error Empty Stock">: Avviso: la cartella di magazzino deve contenere almeno 1 articolo</string> - <string name="Marketplace Validation No Error">Nessun errore o avviso da segnalare</string> - <string name="Marketplace Error None">Nessun errore</string> - <string name="Marketplace Error Prefix">Errore:</string> - <string name="Marketplace Error Not Merchant">Prima di inviare gli articoli al Marketplace devi essere impostato come rivenditore (gratis).</string> - <string name="Marketplace Error Not Accepted">L'articolo non può essere spostato in quella cartella.</string> - <string name="Marketplace Error Unsellable Item">Questo articolo non può essere venduto nel Marketplace.</string> - <string name="MarketplaceNoID">no Mkt ID</string> - <string name="MarketplaceLive">in elenco</string> - <string name="MarketplaceActive">attivi</string> - <string name="MarketplaceMax">massimo</string> - <string name="MarketplaceStock">magazzino</string> - <string name="MarketplaceNoStock">non in magazzino</string> - <string name="MarketplaceUpdating">in aggiornamento...</string> - <string name="UploadFeeInfo">La tariffa è basata sul tuo livello di membership. Più alto è il livello più bassa sarà la tariffa. [https://secondlife.com/my/account/membership.php? Per saperne di più]</string> - <string name="Open landmarks">Luoghi aperti</string> - <string name="Unconstrained">Senza limitazioni</string> + <string name="InventoryOutboxNoItems"> + Trascina le cartelle in questa area e clicca su "Invia a Marketplace" per metterle in vendita su [[MARKETPLACE_DASHBOARD_URL] Marketplace]. + </string> + <string name="InventoryOutboxInitializingTitle"> + Inizializzazione Marketplace.in corso + </string> + <string name="InventoryOutboxInitializing"> + Stiamo eseguendo l'accesso al tuo account sul [[MARKETPLACE_CREATE_STORE_URL] negozio Marketplace]. + </string> + <string name="InventoryOutboxErrorTitle"> + Errori in Marketplace. + </string> + <string name="InventoryOutboxError"> + Il [[MARKETPLACE_CREATE_STORE_URL] negozio nel Marketplace] ha riportato errori. + </string> + <string name="InventoryMarketplaceError"> + Errore nell'apertura degli annunci di Marketplace. +Se continui a ricevere questo messaggio, contatta l'assistenza Second Life su http://support.secondlife.com. + </string> + <string name="InventoryMarketplaceListingsNoItemsTitle"> + La cartella degli annunci di Marketplace è vuota. + </string> + <string name="InventoryMarketplaceListingsNoItems"> + Trascina le cartelle in questa area per metterle in vendita su [[MARKETPLACE_DASHBOARD_URL] Marketplace]. + </string> + <string name="InventoryItemsCount"> + ( [ITEMS_COUNT] oggetti ) + </string> + <string name="Marketplace Validation Warning Stock"> + la cartella di magazzino deve essere inclusa in una cartella di versione + </string> + <string name="Marketplace Validation Error Mixed Stock"> + : Errore: tutti gli articoli un una cartella di magazzino devono essere non copiabili e dello stesso tipo + </string> + <string name="Marketplace Validation Error Subfolder In Stock"> + : Errore: la cartella di magazzino non può contenere sottocartelle + </string> + <string name="Marketplace Validation Warning Empty"> + : Avviso: la cartella non contiene alcun articolo + </string> + <string name="Marketplace Validation Warning Create Stock"> + : Avviso: creazione cartella di magazzino in corso + </string> + <string name="Marketplace Validation Warning Create Version"> + : Avviso: creazione cartella di versione in corso + </string> + <string name="Marketplace Validation Warning Move"> + : Avviso: spostamento articoli in corso + </string> + <string name="Marketplace Validation Warning Delete"> + : Avviso: il contenuto della cartella è stato trasferito alla cartella di magazzino e la cartella vuota sta per essere rimossa + </string> + <string name="Marketplace Validation Error Stock Item"> + : Errore: gli articoli di cui non è permessa la copia devono essere all'interno di una cartella di magazzino + </string> + <string name="Marketplace Validation Warning Unwrapped Item"> + : Avviso: gli articoli devono essere inclusi in una cartella di versione + </string> + <string name="Marketplace Validation Error"> + : Errore: + </string> + <string name="Marketplace Validation Warning"> + : Avviso: + </string> + <string name="Marketplace Validation Error Empty Version"> + : Avviso: la cartella di versione deve contenere almeno 1 articolo + </string> + <string name="Marketplace Validation Error Empty Stock"> + : Avviso: la cartella di magazzino deve contenere almeno 1 articolo + </string> + <string name="Marketplace Validation No Error"> + Nessun errore o avviso da segnalare + </string> + <string name="Marketplace Error None"> + Nessun errore + </string> + <string name="Marketplace Error Prefix"> + Errore: + </string> + <string name="Marketplace Error Not Merchant"> + Prima di inviare gli articoli al Marketplace devi essere impostato come rivenditore (gratis). + </string> + <string name="Marketplace Error Not Accepted"> + L'articolo non può essere spostato in quella cartella. + </string> + <string name="Marketplace Error Unsellable Item"> + Questo articolo non può essere venduto nel Marketplace. + </string> + <string name="MarketplaceNoID"> + no Mkt ID + </string> + <string name="MarketplaceLive"> + in elenco + </string> + <string name="MarketplaceActive"> + attivi + </string> + <string name="MarketplaceMax"> + massimo + </string> + <string name="MarketplaceStock"> + magazzino + </string> + <string name="MarketplaceNoStock"> + non in magazzino + </string> + <string name="MarketplaceUpdating"> + in aggiornamento... + </string> + <string name="UploadFeeInfo"> + La tariffa è basata sul tuo livello di membership. Più alto è il livello più bassa sarà la tariffa. [https://secondlife.com/my/account/membership.php? Per saperne di più] + </string> + <string name="Open landmarks"> + Luoghi aperti + </string> + <string name="Unconstrained"> + Senza limitazioni + </string> <string name="no_transfer" value="(nessun trasferimento)"/> <string name="no_modify" value="(nessuna modifica)"/> <string name="no_copy" value="(nessuna copia)"/> <string name="worn" value="(indossato)"/> <string name="link" value="(link)"/> <string name="broken_link" value="(broken_link)""/> - <string name="LoadingContents">Caricamento del contenuto...</string> - <string name="NoContents">Nessun contenuto</string> + <string name="LoadingContents"> + Caricamento del contenuto... + </string> + <string name="NoContents"> + Nessun contenuto + </string> <string name="WornOnAttachmentPoint" value="(indossato su [ATTACHMENT_POINT])"/> <string name="AttachmentErrorMessage" value="([ATTACHMENT_ERROR])"/> <string name="ActiveGesture" value="[GESLABEL] (attivo)"/> @@ -631,1416 +1689,4146 @@ Se continui a ricevere questo messaggio, contatta l'assistenza Second Life su ht <string name="Snapshots" value="Fotografie,"/> <string name="No Filters" value="No"/> <string name="Since Logoff" value="- Dall'uscita"/> - <string name="InvFolder My Inventory">Il mio inventario</string> - <string name="InvFolder Library">Libreria</string> - <string name="InvFolder Textures">Texture</string> - <string name="InvFolder Sounds">Suoni</string> - <string name="InvFolder Calling Cards">Biglietti da visita</string> - <string name="InvFolder Landmarks">Punti di riferimento</string> - <string name="InvFolder Scripts">Script</string> - <string name="InvFolder Clothing">Vestiario</string> - <string name="InvFolder Objects">Oggetti</string> - <string name="InvFolder Notecards">Biglietti</string> - <string name="InvFolder New Folder">Nuova cartella</string> - <string name="InvFolder Inventory">Inventario</string> - <string name="InvFolder Uncompressed Images">Immagini non compresse</string> - <string name="InvFolder Body Parts">Parti del corpo</string> - <string name="InvFolder Trash">Cestino</string> - <string name="InvFolder Photo Album">Album fotografico</string> - <string name="InvFolder Lost And Found">Oggetti smarriti</string> - <string name="InvFolder Uncompressed Sounds">Suoni non compressi</string> - <string name="InvFolder Animations">Animazioni</string> - <string name="InvFolder Gestures">Gesture</string> - <string name="InvFolder Favorite">I miei preferiti</string> - <string name="InvFolder favorite">I miei preferiti</string> - <string name="InvFolder Favorites">I miei preferiti</string> - <string name="InvFolder favorites">I miei preferiti</string> - <string name="InvFolder Current Outfit">Abbigliamento attuale</string> - <string name="InvFolder Initial Outfits">Vestiario iniziale</string> - <string name="InvFolder My Outfits">Il mio vestiario</string> - <string name="InvFolder Accessories">Accessori</string> - <string name="InvFolder Meshes">Reticoli</string> - <string name="InvFolder Received Items">Oggetti ricevuti</string> - <string name="InvFolder Merchant Outbox">Casella venditore in uscita</string> - <string name="InvFolder Friends">Amici</string> - <string name="InvFolder All">Tutto</string> - <string name="no_attachments">Nessun allegato indossato</string> - <string name="Attachments remain">Allegati ([COUNT] spazi restanti)</string> - <string name="Buy">Acquista</string> - <string name="BuyforL$">Acquista per L$</string> - <string name="Stone">Pietra</string> - <string name="Metal">Metallo</string> - <string name="Glass">Vetro</string> - <string name="Wood">Legno</string> - <string name="Flesh">Carne</string> - <string name="Plastic">Plastica</string> - <string name="Rubber">Gomma</string> - <string name="Light">Luce</string> - <string name="KBShift">Maiusc</string> - <string name="KBCtrl">Ctrl</string> - <string name="Chest">Petto</string> - <string name="Skull">Cranio</string> - <string name="Left Shoulder">Spalla sinistra</string> - <string name="Right Shoulder">Spalla destra</string> - <string name="Left Hand">Mano sinistra</string> - <string name="Right Hand">Mano destra</string> - <string name="Left Foot">Piede sinisto</string> - <string name="Right Foot">Piede destro</string> - <string name="Spine">Spina dorsale</string> - <string name="Pelvis">Pelvi</string> - <string name="Mouth">Bocca</string> - <string name="Chin">Mento</string> - <string name="Left Ear">Orecchio sinistro</string> - <string name="Right Ear">Orecchio destro</string> - <string name="Left Eyeball">Bulbo sinistro</string> - <string name="Right Eyeball">Bulbo destro</string> - <string name="Nose">Naso</string> - <string name="R Upper Arm">Avambraccio destro</string> - <string name="R Forearm">Braccio destro</string> - <string name="L Upper Arm">Avambraccio sinistro</string> - <string name="L Forearm">Braccio sinistro</string> - <string name="Right Hip">Anca destra</string> - <string name="R Upper Leg">Coscia destra</string> - <string name="R Lower Leg">Gamba destra</string> - <string name="Left Hip">Anca sinista</string> - <string name="L Upper Leg">Coscia sinistra</string> - <string name="L Lower Leg">Gamba sinistra</string> - <string name="Stomach">Stomaco</string> - <string name="Left Pec">Petto sinistro</string> - <string name="Right Pec">Petto destro</string> - <string name="Neck">Collo</string> - <string name="Avatar Center">Centro avatar</string> - <string name="Left Ring Finger">Anulare sinistro</string> - <string name="Right Ring Finger">Anulare destro</string> - <string name="Tail Base">Base della coda</string> - <string name="Tail Tip">Punta della coda</string> - <string name="Left Wing">Ala sinistra</string> - <string name="Right Wing">Ala destra</string> - <string name="Jaw">Mandibola</string> - <string name="Alt Left Ear">Altro orecchio sinistro</string> - <string name="Alt Right Ear">Altro orecchio destro</string> - <string name="Alt Left Eye">Altro occhio sinistro</string> - <string name="Alt Right Eye">Altro occhio destro</string> - <string name="Tongue">Lingua</string> - <string name="Groin">Inguine</string> - <string name="Left Hind Foot">Piede posteriore sinistro</string> - <string name="Right Hind Foot">Piede posteriore destro</string> - <string name="Invalid Attachment">Punto di collegamento non valido</string> - <string name="ATTACHMENT_MISSING_ITEM">Errore: articolo mancante</string> - <string name="ATTACHMENT_MISSING_BASE_ITEM">Errore: articolo di base mancante</string> - <string name="ATTACHMENT_NOT_ATTACHED">Errore: l'oggetto è nel vestiario corrente ma non è collegato</string> - <string name="YearsMonthsOld">Nato da [AGEYEARS] [AGEMONTHS]</string> - <string name="YearsOld">Nato da [AGEYEARS]</string> - <string name="MonthsOld">Nato da [AGEMONTHS]</string> - <string name="WeeksOld">Nato da [AGEWEEKS]</string> - <string name="DaysOld">Nato da [AGEDAYS]</string> - <string name="TodayOld">Iscritto oggi</string> - <string name="av_render_everyone_now">Ora ti possono vedere tutti.</string> - <string name="av_render_not_everyone">Alcune persone vicine a te potrebbero non eseguire il tuo rendering.</string> - <string name="av_render_over_half">La maggioranza delle persone vicine a te potrebbe non eseguire il tuo rendering.</string> - <string name="av_render_most_of">La gran parte delle persone vicine a te potrebbe non eseguire il tuo rendering.</string> - <string name="av_render_anyone">Tutte le persone vicine a te potrebbero non eseguire il tuo rendering.</string> - <string name="hud_description_total">Il tuo HUD</string> - <string name="hud_name_with_joint">[OBJ_NAME] (indossato su [JNT_NAME])</string> - <string name="hud_render_memory_warning">[HUD_DETAILS] fa uso di molta memoria texture</string> - <string name="hud_render_cost_warning">[HUD_DETAILS] contiene molti oggetti e texture che occupano una grande quantità di risorse</string> - <string name="hud_render_heavy_textures_warning">[HUD_DETAILS] contiene molte texture di grandi dimensioni</string> - <string name="hud_render_cramped_warning">[HUD_DETAILS] contiene troppi oggetti</string> - <string name="hud_render_textures_warning">[HUD_DETAILS] contiene troppe texture</string> - <string name="AgeYearsA">[COUNT] anno</string> - <string name="AgeYearsB">[COUNT] anni</string> - <string name="AgeYearsC">[COUNT] anni</string> - <string name="AgeMonthsA">[COUNT] mese</string> - <string name="AgeMonthsB">[COUNT] mesi</string> - <string name="AgeMonthsC">[COUNT] mesi</string> - <string name="AgeWeeksA">[COUNT] settimana</string> - <string name="AgeWeeksB">[COUNT] settimane</string> - <string name="AgeWeeksC">[COUNT] settimane</string> - <string name="AgeDaysA">[COUNT] giorno</string> - <string name="AgeDaysB">[COUNT] giorni</string> - <string name="AgeDaysC">[COUNT] giorni</string> - <string name="GroupMembersA">[COUNT] iscritto</string> - <string name="GroupMembersB">[COUNT] iscritti</string> - <string name="GroupMembersC">[COUNT] iscritti</string> - <string name="AcctTypeResident">Residente</string> - <string name="AcctTypeTrial">In prova</string> - <string name="AcctTypeCharterMember">Socio onorario</string> - <string name="AcctTypeEmployee">Dipendente Linden Lab</string> - <string name="PaymentInfoUsed">Informazioni di pagamento usate</string> - <string name="PaymentInfoOnFile">Informazioni di pagamento registrate</string> - <string name="NoPaymentInfoOnFile">Nessuna informazione di pagamento disponibile</string> - <string name="AgeVerified">Età verificata</string> - <string name="NotAgeVerified">Età non verificata</string> - <string name="Center 2">Centro 2</string> - <string name="Top Right">In alto a destra</string> - <string name="Top">in alto</string> - <string name="Top Left">In alto a sinistra</string> - <string name="Center">Al centro</string> - <string name="Bottom Left">In basso a sinistra</string> - <string name="Bottom">In basso</string> - <string name="Bottom Right">In basso a destra</string> - <string name="CompileQueueDownloadedCompiling">Scaricato, in compilazione</string> - <string name="CompileQueueServiceUnavailable">Il servizio di compilazione degli script non è disponibile</string> - <string name="CompileQueueScriptNotFound">Script non trovato sul server.</string> - <string name="CompileQueueProblemDownloading">Problema nel download</string> - <string name="CompileQueueInsufficientPermDownload">Permessi insufficenti per scaricare lo script.</string> - <string name="CompileQueueInsufficientPermFor">Permessi insufficenti per</string> - <string name="CompileQueueUnknownFailure">Errore di dowload sconosciuto</string> - <string name="CompileNoExperiencePerm">Saltato lo script [SCRIPT] con l'esperienza [EXPERIENCE].</string> - <string name="CompileQueueTitle">Avanzamento ricompilazione</string> - <string name="CompileQueueStart">ricompila</string> - <string name="ResetQueueTitle">Azzera avanzamento</string> - <string name="ResetQueueStart">azzera</string> - <string name="RunQueueTitle">Attiva avanzamento</string> - <string name="RunQueueStart">attiva</string> - <string name="NotRunQueueTitle">Disattiva avanzamento</string> - <string name="NotRunQueueStart">disattiva</string> - <string name="CompileSuccessful">Compilazione riuscita!</string> - <string name="CompileSuccessfulSaving">Compilazione riuscita, in salvataggio...</string> - <string name="SaveComplete">Salvataggio completato.</string> - <string name="UploadFailed">Caricamento file non riuscito:</string> - <string name="ObjectOutOfRange">Script (oggetto fuori portata)</string> - <string name="ScriptWasDeleted">Script (eliminato da inventario)</string> - <string name="GodToolsObjectOwnedBy">Oggetto [OBJECT] di proprietà di [OWNER]</string> - <string name="GroupsNone">nessuno</string> + <string name="InvFolder My Inventory"> + Il mio inventario + </string> + <string name="InvFolder Library"> + Libreria + </string> + <string name="InvFolder Textures"> + Texture + </string> + <string name="InvFolder Sounds"> + Suoni + </string> + <string name="InvFolder Calling Cards"> + Biglietti da visita + </string> + <string name="InvFolder Landmarks"> + Punti di riferimento + </string> + <string name="InvFolder Scripts"> + Script + </string> + <string name="InvFolder Clothing"> + Vestiario + </string> + <string name="InvFolder Objects"> + Oggetti + </string> + <string name="InvFolder Notecards"> + Biglietti + </string> + <string name="InvFolder New Folder"> + Nuova cartella + </string> + <string name="InvFolder Inventory"> + Inventario + </string> + <string name="InvFolder Uncompressed Images"> + Immagini non compresse + </string> + <string name="InvFolder Body Parts"> + Parti del corpo + </string> + <string name="InvFolder Trash"> + Cestino + </string> + <string name="InvFolder Photo Album"> + Album fotografico + </string> + <string name="InvFolder Lost And Found"> + Oggetti smarriti + </string> + <string name="InvFolder Uncompressed Sounds"> + Suoni non compressi + </string> + <string name="InvFolder Animations"> + Animazioni + </string> + <string name="InvFolder Gestures"> + Gesture + </string> + <string name="InvFolder Favorite"> + I miei preferiti + </string> + <string name="InvFolder favorite"> + I miei preferiti + </string> + <string name="InvFolder Favorites"> + I miei preferiti + </string> + <string name="InvFolder favorites"> + I miei preferiti + </string> + <string name="InvFolder Current Outfit"> + Abbigliamento attuale + </string> + <string name="InvFolder Initial Outfits"> + Vestiario iniziale + </string> + <string name="InvFolder My Outfits"> + Il mio vestiario + </string> + <string name="InvFolder Accessories"> + Accessori + </string> + <string name="InvFolder Meshes"> + Reticoli + </string> + <string name="InvFolder Received Items"> + Oggetti ricevuti + </string> + <string name="InvFolder Merchant Outbox"> + Casella venditore in uscita + </string> + <string name="InvFolder Friends"> + Amici + </string> + <string name="InvFolder All"> + Tutto + </string> + <string name="no_attachments"> + Nessun allegato indossato + </string> + <string name="Attachments remain"> + Allegati ([COUNT] spazi restanti) + </string> + <string name="Buy"> + Acquista + </string> + <string name="BuyforL$"> + Acquista per L$ + </string> + <string name="Stone"> + Pietra + </string> + <string name="Metal"> + Metallo + </string> + <string name="Glass"> + Vetro + </string> + <string name="Wood"> + Legno + </string> + <string name="Flesh"> + Carne + </string> + <string name="Plastic"> + Plastica + </string> + <string name="Rubber"> + Gomma + </string> + <string name="Light"> + Luce + </string> + <string name="KBShift"> + Maiusc + </string> + <string name="KBCtrl"> + Ctrl + </string> + <string name="Chest"> + Petto + </string> + <string name="Skull"> + Cranio + </string> + <string name="Left Shoulder"> + Spalla sinistra + </string> + <string name="Right Shoulder"> + Spalla destra + </string> + <string name="Left Hand"> + Mano sinistra + </string> + <string name="Right Hand"> + Mano destra + </string> + <string name="Left Foot"> + Piede sinisto + </string> + <string name="Right Foot"> + Piede destro + </string> + <string name="Spine"> + Spina dorsale + </string> + <string name="Pelvis"> + Pelvi + </string> + <string name="Mouth"> + Bocca + </string> + <string name="Chin"> + Mento + </string> + <string name="Left Ear"> + Orecchio sinistro + </string> + <string name="Right Ear"> + Orecchio destro + </string> + <string name="Left Eyeball"> + Bulbo sinistro + </string> + <string name="Right Eyeball"> + Bulbo destro + </string> + <string name="Nose"> + Naso + </string> + <string name="R Upper Arm"> + Avambraccio destro + </string> + <string name="R Forearm"> + Braccio destro + </string> + <string name="L Upper Arm"> + Avambraccio sinistro + </string> + <string name="L Forearm"> + Braccio sinistro + </string> + <string name="Right Hip"> + Anca destra + </string> + <string name="R Upper Leg"> + Coscia destra + </string> + <string name="R Lower Leg"> + Gamba destra + </string> + <string name="Left Hip"> + Anca sinista + </string> + <string name="L Upper Leg"> + Coscia sinistra + </string> + <string name="L Lower Leg"> + Gamba sinistra + </string> + <string name="Stomach"> + Stomaco + </string> + <string name="Left Pec"> + Petto sinistro + </string> + <string name="Right Pec"> + Petto destro + </string> + <string name="Neck"> + Collo + </string> + <string name="Avatar Center"> + Centro avatar + </string> + <string name="Left Ring Finger"> + Anulare sinistro + </string> + <string name="Right Ring Finger"> + Anulare destro + </string> + <string name="Tail Base"> + Base della coda + </string> + <string name="Tail Tip"> + Punta della coda + </string> + <string name="Left Wing"> + Ala sinistra + </string> + <string name="Right Wing"> + Ala destra + </string> + <string name="Jaw"> + Mandibola + </string> + <string name="Alt Left Ear"> + Altro orecchio sinistro + </string> + <string name="Alt Right Ear"> + Altro orecchio destro + </string> + <string name="Alt Left Eye"> + Altro occhio sinistro + </string> + <string name="Alt Right Eye"> + Altro occhio destro + </string> + <string name="Tongue"> + Lingua + </string> + <string name="Groin"> + Inguine + </string> + <string name="Left Hind Foot"> + Piede posteriore sinistro + </string> + <string name="Right Hind Foot"> + Piede posteriore destro + </string> + <string name="Invalid Attachment"> + Punto di collegamento non valido + </string> + <string name="ATTACHMENT_MISSING_ITEM"> + Errore: articolo mancante + </string> + <string name="ATTACHMENT_MISSING_BASE_ITEM"> + Errore: articolo di base mancante + </string> + <string name="ATTACHMENT_NOT_ATTACHED"> + Errore: l'oggetto è nel vestiario corrente ma non è collegato + </string> + <string name="YearsMonthsOld"> + Nato da [AGEYEARS] [AGEMONTHS] + </string> + <string name="YearsOld"> + Nato da [AGEYEARS] + </string> + <string name="MonthsOld"> + Nato da [AGEMONTHS] + </string> + <string name="WeeksOld"> + Nato da [AGEWEEKS] + </string> + <string name="DaysOld"> + Nato da [AGEDAYS] + </string> + <string name="TodayOld"> + Iscritto oggi + </string> + <string name="av_render_everyone_now"> + Ora ti possono vedere tutti. + </string> + <string name="av_render_not_everyone"> + Alcune persone vicine a te potrebbero non eseguire il tuo rendering. + </string> + <string name="av_render_over_half"> + La maggioranza delle persone vicine a te potrebbe non eseguire il tuo rendering. + </string> + <string name="av_render_most_of"> + La gran parte delle persone vicine a te potrebbe non eseguire il tuo rendering. + </string> + <string name="av_render_anyone"> + Tutte le persone vicine a te potrebbero non eseguire il tuo rendering. + </string> + <string name="hud_description_total"> + Il tuo HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (indossato su [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] fa uso di molta memoria texture + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contiene molti oggetti e texture che occupano una grande quantità di risorse + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contiene molte texture di grandi dimensioni + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contiene troppi oggetti + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contiene troppe texture + </string> + <string name="AgeYearsA"> + [COUNT] anno + </string> + <string name="AgeYearsB"> + [COUNT] anni + </string> + <string name="AgeYearsC"> + [COUNT] anni + </string> + <string name="AgeMonthsA"> + [COUNT] mese + </string> + <string name="AgeMonthsB"> + [COUNT] mesi + </string> + <string name="AgeMonthsC"> + [COUNT] mesi + </string> + <string name="AgeWeeksA"> + [COUNT] settimana + </string> + <string name="AgeWeeksB"> + [COUNT] settimane + </string> + <string name="AgeWeeksC"> + [COUNT] settimane + </string> + <string name="AgeDaysA"> + [COUNT] giorno + </string> + <string name="AgeDaysB"> + [COUNT] giorni + </string> + <string name="AgeDaysC"> + [COUNT] giorni + </string> + <string name="GroupMembersA"> + [COUNT] iscritto + </string> + <string name="GroupMembersB"> + [COUNT] iscritti + </string> + <string name="GroupMembersC"> + [COUNT] iscritti + </string> + <string name="AcctTypeResident"> + Residente + </string> + <string name="AcctTypeTrial"> + In prova + </string> + <string name="AcctTypeCharterMember"> + Socio onorario + </string> + <string name="AcctTypeEmployee"> + Dipendente Linden Lab + </string> + <string name="PaymentInfoUsed"> + Informazioni di pagamento usate + </string> + <string name="PaymentInfoOnFile"> + Informazioni di pagamento registrate + </string> + <string name="NoPaymentInfoOnFile"> + Nessuna informazione di pagamento disponibile + </string> + <string name="AgeVerified"> + Età verificata + </string> + <string name="NotAgeVerified"> + Età non verificata + </string> + <string name="Center 2"> + Centro 2 + </string> + <string name="Top Right"> + In alto a destra + </string> + <string name="Top"> + in alto + </string> + <string name="Top Left"> + In alto a sinistra + </string> + <string name="Center"> + Al centro + </string> + <string name="Bottom Left"> + In basso a sinistra + </string> + <string name="Bottom"> + In basso + </string> + <string name="Bottom Right"> + In basso a destra + </string> + <string name="CompileQueueDownloadedCompiling"> + Scaricato, in compilazione + </string> + <string name="CompileQueueServiceUnavailable"> + Il servizio di compilazione degli script non è disponibile + </string> + <string name="CompileQueueScriptNotFound"> + Script non trovato sul server. + </string> + <string name="CompileQueueProblemDownloading"> + Problema nel download + </string> + <string name="CompileQueueInsufficientPermDownload"> + Permessi insufficenti per scaricare lo script. + </string> + <string name="CompileQueueInsufficientPermFor"> + Permessi insufficenti per + </string> + <string name="CompileQueueUnknownFailure"> + Errore di dowload sconosciuto + </string> + <string name="CompileNoExperiencePerm"> + Saltato lo script [SCRIPT] con l'esperienza [EXPERIENCE]. + </string> + <string name="CompileQueueTitle"> + Avanzamento ricompilazione + </string> + <string name="CompileQueueStart"> + ricompila + </string> + <string name="ResetQueueTitle"> + Azzera avanzamento + </string> + <string name="ResetQueueStart"> + azzera + </string> + <string name="RunQueueTitle"> + Attiva avanzamento + </string> + <string name="RunQueueStart"> + attiva + </string> + <string name="NotRunQueueTitle"> + Disattiva avanzamento + </string> + <string name="NotRunQueueStart"> + disattiva + </string> + <string name="CompileSuccessful"> + Compilazione riuscita! + </string> + <string name="CompileSuccessfulSaving"> + Compilazione riuscita, in salvataggio... + </string> + <string name="SaveComplete"> + Salvataggio completato. + </string> + <string name="UploadFailed"> + Caricamento file non riuscito: + </string> + <string name="ObjectOutOfRange"> + Script (oggetto fuori portata) + </string> + <string name="ScriptWasDeleted"> + Script (eliminato da inventario) + </string> + <string name="GodToolsObjectOwnedBy"> + Oggetto [OBJECT] di proprietà di [OWNER] + </string> + <string name="GroupsNone"> + nessuno + </string> <string name="Group" value="(gruppo)"/> - <string name="Unknown">(Sconosciuto)</string> + <string name="Unknown"> + (Sconosciuto) + </string> <string name="SummaryForTheWeek" value="Riassunto della settimana, partendo dal "/> <string name="NextStipendDay" value=". Il prossimo giorno di stipendio è "/> - <string name="GroupPlanningDate">[mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc]</string> + <string name="GroupPlanningDate"> + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + </string> <string name="GroupIndividualShare" value="Gruppo Dividendi individuali"/> <string name="GroupColumn" value="Gruppo"/> - <string name="Balance">Saldo</string> - <string name="Credits">Ringraziamenti</string> - <string name="Debits">Debiti</string> - <string name="Total">Totale</string> - <string name="NoGroupDataFound">Nessun dato trovato per questo gruppo</string> - <string name="IMParentEstate">Proprietà principale</string> - <string name="IMMainland">continente</string> - <string name="IMTeen">teen</string> - <string name="Anyone">chiunque</string> - <string name="RegionInfoError">errore</string> - <string name="RegionInfoAllEstatesOwnedBy">tutte le proprietà immobiliari di [OWNER]</string> - <string name="RegionInfoAllEstatesYouOwn">tutte le tue proprietà immobiliari</string> - <string name="RegionInfoAllEstatesYouManage">tutte le proprietà immobiliari che gestisci per conto di [OWNER]</string> - <string name="RegionInfoAllowedResidents">Sempre consentiti: ([ALLOWEDAGENTS], max [MAXACCESS])</string> - <string name="RegionInfoAllowedGroups">Gruppi sempre consentiti: ([ALLOWEDGROUPS], max [MAXACCESS])</string> - <string name="RegionInfoBannedResidents">Sempre esclusi: ([BANNEDAGENTS], max [MAXBANNED])</string> - <string name="RegionInfoListTypeAllowedAgents">Sempre consentiti:</string> - <string name="RegionInfoListTypeBannedAgents">Sempre esclusi:</string> - <string name="RegionInfoAllEstates">tutte le proprietà immobiliari</string> - <string name="RegionInfoManagedEstates">proprietà immobiliari che gestisci</string> - <string name="RegionInfoThisEstate">questa proprietà immobiliare</string> - <string name="AndNMore">e [EXTRA_COUNT] ancora</string> - <string name="ScriptLimitsParcelScriptMemory">Memoria dello script del lotto</string> - <string name="ScriptLimitsParcelsOwned">Lotti in elenco: [PARCELS]</string> - <string name="ScriptLimitsMemoryUsed">Memoria utilizzata: [COUNT] kb di [MAX] kb; [AVAILABLE] kb disponibili</string> - <string name="ScriptLimitsMemoryUsedSimple">Memoria utilizzata: [COUNT] kb</string> - <string name="ScriptLimitsParcelScriptURLs">URL degli script lotti</string> - <string name="ScriptLimitsURLsUsed">URL utilizzati: [COUNT] di [MAX]; [AVAILABLE] disponibili</string> - <string name="ScriptLimitsURLsUsedSimple">URL utilizzati: [COUNT]</string> - <string name="ScriptLimitsRequestError">Errore nella richiesta di informazioni</string> - <string name="ScriptLimitsRequestNoParcelSelected">Nessun lotto selezionato</string> - <string name="ScriptLimitsRequestWrongRegion">Errore: le informazioni sullo script sono disponibili solo nella tua regione attuale</string> - <string name="ScriptLimitsRequestWaiting">Recupero informazioni in corso...</string> - <string name="ScriptLimitsRequestDontOwnParcel">Non hai il permesso di visionare questo lotto</string> - <string name="SITTING_ON">Seduto su</string> - <string name="ATTACH_CHEST">Petto</string> - <string name="ATTACH_HEAD">Cranio</string> - <string name="ATTACH_LSHOULDER">Spalla sinistra</string> - <string name="ATTACH_RSHOULDER">Spalla destra</string> - <string name="ATTACH_LHAND">Mano sinistra</string> - <string name="ATTACH_RHAND">Mano destra</string> - <string name="ATTACH_LFOOT">Piede sinisto</string> - <string name="ATTACH_RFOOT">Piede destro</string> - <string name="ATTACH_BACK">Spina dorsale</string> - <string name="ATTACH_PELVIS">Pelvi</string> - <string name="ATTACH_MOUTH">Bocca</string> - <string name="ATTACH_CHIN">Mento</string> - <string name="ATTACH_LEAR">Orecchio sinistro</string> - <string name="ATTACH_REAR">Orecchio destro</string> - <string name="ATTACH_LEYE">Occhio sinistro</string> - <string name="ATTACH_REYE">Occhio destro</string> - <string name="ATTACH_NOSE">Naso</string> - <string name="ATTACH_RUARM">Braccio destro</string> - <string name="ATTACH_RLARM">Avambraccio destro</string> - <string name="ATTACH_LUARM">Braccio sinistro</string> - <string name="ATTACH_LLARM">Avambraccio sinistro</string> - <string name="ATTACH_RHIP">Anca destra</string> - <string name="ATTACH_RULEG">Coscia destra</string> - <string name="ATTACH_RLLEG">Coscia destra</string> - <string name="ATTACH_LHIP">Anca sinista</string> - <string name="ATTACH_LULEG">Coscia sinistra</string> - <string name="ATTACH_LLLEG">Polpaccio sinistro</string> - <string name="ATTACH_BELLY">Stomaco</string> - <string name="ATTACH_LEFT_PEC">Petto sinistro</string> - <string name="ATTACH_RIGHT_PEC">Petto destro</string> - <string name="ATTACH_HUD_CENTER_2">HUD in centro 2</string> - <string name="ATTACH_HUD_TOP_RIGHT">HUD alto a destra</string> - <string name="ATTACH_HUD_TOP_CENTER">HUD alto in centro</string> - <string name="ATTACH_HUD_TOP_LEFT">HUD alto a sinistra</string> - <string name="ATTACH_HUD_CENTER_1">HUD in centro 1</string> - <string name="ATTACH_HUD_BOTTOM_LEFT">HUD basso a sinistra</string> - <string name="ATTACH_HUD_BOTTOM">HUD basso</string> - <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD basso a destra</string> - <string name="ATTACH_NECK">Collo</string> - <string name="ATTACH_AVATAR_CENTER">Centro avatar</string> - <string name="ATTACH_LHAND_RING1">Anulare sinistro</string> - <string name="ATTACH_RHAND_RING1">Anulare destro</string> - <string name="ATTACH_TAIL_BASE">Base della coda</string> - <string name="ATTACH_TAIL_TIP">Punta della coda</string> - <string name="ATTACH_LWING">Ala sinistra</string> - <string name="ATTACH_RWING">Ala destra</string> - <string name="ATTACH_FACE_JAW">Mandibola</string> - <string name="ATTACH_FACE_LEAR">Altro orecchio sinistro</string> - <string name="ATTACH_FACE_REAR">Altro orecchio destro</string> - <string name="ATTACH_FACE_LEYE">Altro occhio sinistro</string> - <string name="ATTACH_FACE_REYE">Altro occhio destro</string> - <string name="ATTACH_FACE_TONGUE">Lingua</string> - <string name="ATTACH_GROIN">Inguine</string> - <string name="ATTACH_HIND_LFOOT">Piede posteriore sinistro</string> - <string name="ATTACH_HIND_RFOOT">Piede posteriore destro</string> - <string name="CursorPos">Riga [LINE], Colonna [COLUMN]</string> - <string name="PanelDirCountFound">[COUNT] trovato/i</string> - <string name="PanelContentsTooltip">Contenuto dell'oggetto</string> - <string name="PanelContentsNewScript">Nuovo script</string> - <string name="DoNotDisturbModeResponseDefault">Questo residente ha attivato la modalità 'Non disturbare' e vedrà il tuo messaggio più tardi.</string> - <string name="MuteByName">(In base al nome)</string> - <string name="MuteAgent">(Residente)</string> - <string name="MuteObject">(Oggetto)</string> - <string name="MuteGroup">(Gruppo)</string> - <string name="MuteExternal">(esterno)</string> - <string name="RegionNoCovenant">Non esiste alcun regolamento per questa proprietà.</string> - <string name="RegionNoCovenantOtherOwner">Non esiste alcun regolamento per questa proprietà. Il terreno di questa proprietà è messo in vendita dal proprietario, non dalla Linden Lab. Contatta il proprietario del terreno per i dettagli della vendita.</string> + <string name="Balance"> + Saldo + </string> + <string name="Credits"> + Ringraziamenti + </string> + <string name="Debits"> + Debiti + </string> + <string name="Total"> + Totale + </string> + <string name="NoGroupDataFound"> + Nessun dato trovato per questo gruppo + </string> + <string name="IMParentEstate"> + Proprietà principale + </string> + <string name="IMMainland"> + continente + </string> + <string name="IMTeen"> + teen + </string> + <string name="Anyone"> + chiunque + </string> + <string name="RegionInfoError"> + errore + </string> + <string name="RegionInfoAllEstatesOwnedBy"> + tutte le proprietà immobiliari di [OWNER] + </string> + <string name="RegionInfoAllEstatesYouOwn"> + tutte le tue proprietà immobiliari + </string> + <string name="RegionInfoAllEstatesYouManage"> + tutte le proprietà immobiliari che gestisci per conto di [OWNER] + </string> + <string name="RegionInfoAllowedResidents"> + Sempre consentiti: ([ALLOWEDAGENTS], max [MAXACCESS]) + </string> + <string name="RegionInfoAllowedGroups"> + Gruppi sempre consentiti: ([ALLOWEDGROUPS], max [MAXACCESS]) + </string> + <string name="RegionInfoBannedResidents"> + Sempre esclusi: ([BANNEDAGENTS], max [MAXBANNED]) + </string> + <string name="RegionInfoListTypeAllowedAgents"> + Sempre consentiti: + </string> + <string name="RegionInfoListTypeBannedAgents"> + Sempre esclusi: + </string> + <string name="RegionInfoAllEstates"> + tutte le proprietà immobiliari + </string> + <string name="RegionInfoManagedEstates"> + proprietà immobiliari che gestisci + </string> + <string name="RegionInfoThisEstate"> + questa proprietà immobiliare + </string> + <string name="AndNMore"> + e [EXTRA_COUNT] ancora + </string> + <string name="ScriptLimitsParcelScriptMemory"> + Memoria dello script del lotto + </string> + <string name="ScriptLimitsParcelsOwned"> + Lotti in elenco: [PARCELS] + </string> + <string name="ScriptLimitsMemoryUsed"> + Memoria utilizzata: [COUNT] kb di [MAX] kb; [AVAILABLE] kb disponibili + </string> + <string name="ScriptLimitsMemoryUsedSimple"> + Memoria utilizzata: [COUNT] kb + </string> + <string name="ScriptLimitsParcelScriptURLs"> + URL degli script lotti + </string> + <string name="ScriptLimitsURLsUsed"> + URL utilizzati: [COUNT] di [MAX]; [AVAILABLE] disponibili + </string> + <string name="ScriptLimitsURLsUsedSimple"> + URL utilizzati: [COUNT] + </string> + <string name="ScriptLimitsRequestError"> + Errore nella richiesta di informazioni + </string> + <string name="ScriptLimitsRequestNoParcelSelected"> + Nessun lotto selezionato + </string> + <string name="ScriptLimitsRequestWrongRegion"> + Errore: le informazioni sullo script sono disponibili solo nella tua regione attuale + </string> + <string name="ScriptLimitsRequestWaiting"> + Recupero informazioni in corso... + </string> + <string name="ScriptLimitsRequestDontOwnParcel"> + Non hai il permesso di visionare questo lotto + </string> + <string name="SITTING_ON"> + Seduto su + </string> + <string name="ATTACH_CHEST"> + Petto + </string> + <string name="ATTACH_HEAD"> + Cranio + </string> + <string name="ATTACH_LSHOULDER"> + Spalla sinistra + </string> + <string name="ATTACH_RSHOULDER"> + Spalla destra + </string> + <string name="ATTACH_LHAND"> + Mano sinistra + </string> + <string name="ATTACH_RHAND"> + Mano destra + </string> + <string name="ATTACH_LFOOT"> + Piede sinisto + </string> + <string name="ATTACH_RFOOT"> + Piede destro + </string> + <string name="ATTACH_BACK"> + Spina dorsale + </string> + <string name="ATTACH_PELVIS"> + Pelvi + </string> + <string name="ATTACH_MOUTH"> + Bocca + </string> + <string name="ATTACH_CHIN"> + Mento + </string> + <string name="ATTACH_LEAR"> + Orecchio sinistro + </string> + <string name="ATTACH_REAR"> + Orecchio destro + </string> + <string name="ATTACH_LEYE"> + Occhio sinistro + </string> + <string name="ATTACH_REYE"> + Occhio destro + </string> + <string name="ATTACH_NOSE"> + Naso + </string> + <string name="ATTACH_RUARM"> + Braccio destro + </string> + <string name="ATTACH_RLARM"> + Avambraccio destro + </string> + <string name="ATTACH_LUARM"> + Braccio sinistro + </string> + <string name="ATTACH_LLARM"> + Avambraccio sinistro + </string> + <string name="ATTACH_RHIP"> + Anca destra + </string> + <string name="ATTACH_RULEG"> + Coscia destra + </string> + <string name="ATTACH_RLLEG"> + Coscia destra + </string> + <string name="ATTACH_LHIP"> + Anca sinista + </string> + <string name="ATTACH_LULEG"> + Coscia sinistra + </string> + <string name="ATTACH_LLLEG"> + Polpaccio sinistro + </string> + <string name="ATTACH_BELLY"> + Stomaco + </string> + <string name="ATTACH_LEFT_PEC"> + Petto sinistro + </string> + <string name="ATTACH_RIGHT_PEC"> + Petto destro + </string> + <string name="ATTACH_HUD_CENTER_2"> + HUD in centro 2 + </string> + <string name="ATTACH_HUD_TOP_RIGHT"> + HUD alto a destra + </string> + <string name="ATTACH_HUD_TOP_CENTER"> + HUD alto in centro + </string> + <string name="ATTACH_HUD_TOP_LEFT"> + HUD alto a sinistra + </string> + <string name="ATTACH_HUD_CENTER_1"> + HUD in centro 1 + </string> + <string name="ATTACH_HUD_BOTTOM_LEFT"> + HUD basso a sinistra + </string> + <string name="ATTACH_HUD_BOTTOM"> + HUD basso + </string> + <string name="ATTACH_HUD_BOTTOM_RIGHT"> + HUD basso a destra + </string> + <string name="ATTACH_NECK"> + Collo + </string> + <string name="ATTACH_AVATAR_CENTER"> + Centro avatar + </string> + <string name="ATTACH_LHAND_RING1"> + Anulare sinistro + </string> + <string name="ATTACH_RHAND_RING1"> + Anulare destro + </string> + <string name="ATTACH_TAIL_BASE"> + Base della coda + </string> + <string name="ATTACH_TAIL_TIP"> + Punta della coda + </string> + <string name="ATTACH_LWING"> + Ala sinistra + </string> + <string name="ATTACH_RWING"> + Ala destra + </string> + <string name="ATTACH_FACE_JAW"> + Mandibola + </string> + <string name="ATTACH_FACE_LEAR"> + Altro orecchio sinistro + </string> + <string name="ATTACH_FACE_REAR"> + Altro orecchio destro + </string> + <string name="ATTACH_FACE_LEYE"> + Altro occhio sinistro + </string> + <string name="ATTACH_FACE_REYE"> + Altro occhio destro + </string> + <string name="ATTACH_FACE_TONGUE"> + Lingua + </string> + <string name="ATTACH_GROIN"> + Inguine + </string> + <string name="ATTACH_HIND_LFOOT"> + Piede posteriore sinistro + </string> + <string name="ATTACH_HIND_RFOOT"> + Piede posteriore destro + </string> + <string name="CursorPos"> + Riga [LINE], Colonna [COLUMN] + </string> + <string name="PanelDirCountFound"> + [COUNT] trovato/i + </string> + <string name="PanelContentsTooltip"> + Contenuto dell'oggetto + </string> + <string name="PanelContentsNewScript"> + Nuovo script + </string> + <string name="DoNotDisturbModeResponseDefault"> + Questo residente ha attivato la modalità 'Non disturbare' e vedrà il tuo messaggio più tardi. + </string> + <string name="MuteByName"> + (In base al nome) + </string> + <string name="MuteAgent"> + (Residente) + </string> + <string name="MuteObject"> + (Oggetto) + </string> + <string name="MuteGroup"> + (Gruppo) + </string> + <string name="MuteExternal"> + (esterno) + </string> + <string name="RegionNoCovenant"> + Non esiste alcun regolamento per questa proprietà. + </string> + <string name="RegionNoCovenantOtherOwner"> + Non esiste alcun regolamento per questa proprietà. Il terreno di questa proprietà è messo in vendita dal proprietario, non dalla Linden Lab. Contatta il proprietario del terreno per i dettagli della vendita. + </string> <string name="covenant_last_modified" value="Ultima modifica: "/> <string name="none_text" value="(nessuno)"/> <string name="never_text" value="(mai)"/> - <string name="GroupOwned">Di proprietà di un gruppo</string> - <string name="Public">Pubblica</string> - <string name="LocalSettings">Impostazioni locali</string> - <string name="RegionSettings">Impostazioni regione</string> - <string name="NoEnvironmentSettings">Questa regione non supporta le impostazioni per l’ambiente.</string> - <string name="EnvironmentSun">Sole</string> - <string name="EnvironmentMoon">Luna</string> - <string name="EnvironmentBloom">Fioritura</string> - <string name="EnvironmentCloudNoise">Rumore nuvole</string> - <string name="EnvironmentNormalMap">Mappa normale</string> - <string name="EnvironmentTransparent">Transparent</string> - <string name="ClassifiedClicksTxt">Clicca: [TELEPORT] teleport, [MAP] mappa, [PROFILE] profilo</string> - <string name="ClassifiedUpdateAfterPublish">(si aggiornerà dopo la pubblicazione)</string> - <string name="NoPicksClassifiedsText">Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un'inserzione.</string> - <string name="NoPicksText">Non hai creato Luoghi preferiti. Fai clic sul pulsante Nuovo per creare un Luogo preferito.</string> - <string name="NoClassifiedsText">Non hai creato Annunci. Fai clic sul pulsante Nuovo per creare un Annuncio.</string> - <string name="NoAvatarPicksClassifiedsText">L'utente non ha luoghi preferiti né inserzioni</string> - <string name="NoAvatarPicksText">L'utente non ha luoghi preferiti</string> - <string name="NoAvatarClassifiedsText">L'utente non ha annunci</string> - <string name="PicksClassifiedsLoadingText">Caricamento in corso...</string> - <string name="MultiPreviewTitle">Anteprima</string> - <string name="MultiPropertiesTitle">Beni immobiliari</string> - <string name="InvOfferAnObjectNamed">Un oggetto denominato</string> - <string name="InvOfferOwnedByGroup">di proprietà del gruppo</string> - <string name="InvOfferOwnedByUnknownGroup">di proprietà di un gruppo sconosciuto</string> - <string name="InvOfferOwnedBy">di proprietà di</string> - <string name="InvOfferOwnedByUnknownUser">di proprietà di un utente sconosciuto</string> - <string name="InvOfferGaveYou">Ti ha offerto</string> - <string name="InvOfferDecline">Non hai accettato [DESC] da <nolink>[NAME]</nolink>.</string> - <string name="GroupMoneyTotal">Totale</string> - <string name="GroupMoneyBought">comprato</string> - <string name="GroupMoneyPaidYou">ti ha pagato</string> - <string name="GroupMoneyPaidInto">ha pagato</string> - <string name="GroupMoneyBoughtPassTo">ha comprato il pass</string> - <string name="GroupMoneyPaidFeeForEvent">pagato la tassa per l'evento</string> - <string name="GroupMoneyPaidPrizeForEvent">pagato il premio per l'evento</string> - <string name="GroupMoneyBalance">Saldo</string> - <string name="GroupMoneyCredits">Ringraziamenti</string> - <string name="GroupMoneyDebits">Debiti</string> - <string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string> - <string name="AcquiredItems">Oggetti acquisiti</string> - <string name="Cancel">Annulla</string> - <string name="UploadingCosts">Il caricamento di [NAME] costa L$ [AMOUNT]</string> - <string name="BuyingCosts">L'acquisto di [NAME] costa L$ [AMOUNT]</string> - <string name="UnknownFileExtension">Estensione del file sconosciuta [.%s] -Tipi conosciuti .wav, .tga, .bmp, .jpg, .jpeg, or .bvh</string> - <string name="MuteObject2">Blocca</string> - <string name="AddLandmarkNavBarMenu">Aggiungi punto di riferimento...</string> - <string name="EditLandmarkNavBarMenu">Modifica punto di riferimento...</string> - <string name="accel-mac-control">⌃</string> - <string name="accel-mac-command">⌘</string> - <string name="accel-mac-option">⌥</string> - <string name="accel-mac-shift">⇧</string> - <string name="accel-win-control">Ctrl+</string> - <string name="accel-win-alt">Alt+</string> - <string name="accel-win-shift">Shift+</string> - <string name="FileSaved">File salvato</string> - <string name="Receiving">In ricezione</string> - <string name="AM">antemeridiane</string> - <string name="PM">pomeridiane</string> - <string name="PST">Ora Pacifico</string> - <string name="PDT">Ora legale Pacifico</string> - <string name="Direction_Forward">Avanti</string> - <string name="Direction_Left">Sinistra</string> - <string name="Direction_Right">Destra</string> - <string name="Direction_Back">Indietro</string> - <string name="Direction_North">Nord</string> - <string name="Direction_South">Sud</string> - <string name="Direction_West">Ovest</string> - <string name="Direction_East">Est</string> - <string name="Direction_Up">Su</string> - <string name="Direction_Down">Giù</string> - <string name="Any Category">Qualsiasi categoria</string> - <string name="Shopping">Acquisti</string> - <string name="Land Rental">Affitto terreno</string> - <string name="Property Rental">Affitto proprietà</string> - <string name="Special Attraction">Attrazioni speciali</string> - <string name="New Products">Nuovi prodotti</string> - <string name="Employment">Lavoro</string> - <string name="Wanted">Cercasi</string> - <string name="Service">Servizio</string> - <string name="Personal">Personale</string> - <string name="None">Nessuno</string> - <string name="Linden Location">Luogo dei Linden</string> - <string name="Adult">Adult</string> - <string name="Arts&Culture">Arte & Cultura</string> - <string name="Business">Affari</string> - <string name="Educational">Educazione</string> - <string name="Gaming">Gioco</string> - <string name="Hangout">Divertimento</string> - <string name="Newcomer Friendly">Accoglienza nuovi residenti</string> - <string name="Parks&Nature">Parchi & Natura</string> - <string name="Residential">Residenziale</string> - <string name="Stage">Fase</string> - <string name="Other">Altro</string> - <string name="Rental">Affitto</string> - <string name="Any">Tutti</string> - <string name="You">Tu</string> - <string name="Multiple Media">Più supporti</string> - <string name="Play Media">Riproduci/Pausa supporto</string> - <string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string> - <string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=en-us</string> - <string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string> - <string name="MBCmdLineError">Un errore è stato riscontrato analizzando la linea di comando. + <string name="GroupOwned"> + Di proprietà di un gruppo + </string> + <string name="Public"> + Pubblica + </string> + <string name="LocalSettings"> + Impostazioni locali + </string> + <string name="RegionSettings"> + Impostazioni regione + </string> + <string name="NoEnvironmentSettings"> + Questa regione non supporta le impostazioni per l’ambiente. + </string> + <string name="EnvironmentSun"> + Sole + </string> + <string name="EnvironmentMoon"> + Luna + </string> + <string name="EnvironmentBloom"> + Fioritura + </string> + <string name="EnvironmentCloudNoise"> + Rumore nuvole + </string> + <string name="EnvironmentNormalMap"> + Mappa normale + </string> + <string name="EnvironmentTransparent"> + Transparent + </string> + <string name="ClassifiedClicksTxt"> + Clicca: [TELEPORT] teleport, [MAP] mappa, [PROFILE] profilo + </string> + <string name="ClassifiedUpdateAfterPublish"> + (si aggiornerà dopo la pubblicazione) + </string> + <string name="NoPicksClassifiedsText"> + Non hai creato luoghi preferiti né inserzioni. Clicca il pulsante + qui sotto per creare un luogo preferito o un'inserzione. + </string> + <string name="NoPicksText"> + Non hai creato Luoghi preferiti. Fai clic sul pulsante Nuovo per creare un Luogo preferito. + </string> + <string name="NoClassifiedsText"> + Non hai creato Annunci. Fai clic sul pulsante Nuovo per creare un Annuncio. + </string> + <string name="NoAvatarPicksClassifiedsText"> + L'utente non ha luoghi preferiti né inserzioni + </string> + <string name="NoAvatarPicksText"> + L'utente non ha luoghi preferiti + </string> + <string name="NoAvatarClassifiedsText"> + L'utente non ha annunci + </string> + <string name="PicksClassifiedsLoadingText"> + Caricamento in corso... + </string> + <string name="MultiPreviewTitle"> + Anteprima + </string> + <string name="MultiPropertiesTitle"> + Beni immobiliari + </string> + <string name="InvOfferAnObjectNamed"> + Un oggetto denominato + </string> + <string name="InvOfferOwnedByGroup"> + di proprietà del gruppo + </string> + <string name="InvOfferOwnedByUnknownGroup"> + di proprietà di un gruppo sconosciuto + </string> + <string name="InvOfferOwnedBy"> + di proprietà di + </string> + <string name="InvOfferOwnedByUnknownUser"> + di proprietà di un utente sconosciuto + </string> + <string name="InvOfferGaveYou"> + Ti ha offerto + </string> + <string name="InvOfferDecline"> + Non hai accettato [DESC] da <nolink>[NAME]</nolink>. + </string> + <string name="GroupMoneyTotal"> + Totale + </string> + <string name="GroupMoneyBought"> + comprato + </string> + <string name="GroupMoneyPaidYou"> + ti ha pagato + </string> + <string name="GroupMoneyPaidInto"> + ha pagato + </string> + <string name="GroupMoneyBoughtPassTo"> + ha comprato il pass + </string> + <string name="GroupMoneyPaidFeeForEvent"> + pagato la tassa per l'evento + </string> + <string name="GroupMoneyPaidPrizeForEvent"> + pagato il premio per l'evento + </string> + <string name="GroupMoneyBalance"> + Saldo + </string> + <string name="GroupMoneyCredits"> + Ringraziamenti + </string> + <string name="GroupMoneyDebits"> + Debiti + </string> + <string name="GroupMoneyDate"> + [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc] + </string> + <string name="AcquiredItems"> + Oggetti acquisiti + </string> + <string name="Cancel"> + Annulla + </string> + <string name="UploadingCosts"> + Il caricamento di [NAME] costa L$ [AMOUNT] + </string> + <string name="BuyingCosts"> + L'acquisto di [NAME] costa L$ [AMOUNT] + </string> + <string name="UnknownFileExtension"> + Estensione del file sconosciuta [.%s] +Tipi conosciuti .wav, .tga, .bmp, .jpg, .jpeg, or .bvh + </string> + <string name="MuteObject2"> + Blocca + </string> + <string name="AddLandmarkNavBarMenu"> + Aggiungi punto di riferimento... + </string> + <string name="EditLandmarkNavBarMenu"> + Modifica punto di riferimento... + </string> + <string name="accel-mac-control"> + ⌃ + </string> + <string name="accel-mac-command"> + ⌘ + </string> + <string name="accel-mac-option"> + ⌥ + </string> + <string name="accel-mac-shift"> + ⇧ + </string> + <string name="accel-win-control"> + Ctrl+ + </string> + <string name="accel-win-alt"> + Alt+ + </string> + <string name="accel-win-shift"> + Shift+ + </string> + <string name="FileSaved"> + File salvato + </string> + <string name="Receiving"> + In ricezione + </string> + <string name="AM"> + antemeridiane + </string> + <string name="PM"> + pomeridiane + </string> + <string name="PST"> + Ora Pacifico + </string> + <string name="PDT"> + Ora legale Pacifico + </string> + <string name="Direction_Forward"> + Avanti + </string> + <string name="Direction_Left"> + Sinistra + </string> + <string name="Direction_Right"> + Destra + </string> + <string name="Direction_Back"> + Indietro + </string> + <string name="Direction_North"> + Nord + </string> + <string name="Direction_South"> + Sud + </string> + <string name="Direction_West"> + Ovest + </string> + <string name="Direction_East"> + Est + </string> + <string name="Direction_Up"> + Su + </string> + <string name="Direction_Down"> + Giù + </string> + <string name="Any Category"> + Qualsiasi categoria + </string> + <string name="Shopping"> + Acquisti + </string> + <string name="Land Rental"> + Affitto terreno + </string> + <string name="Property Rental"> + Affitto proprietà + </string> + <string name="Special Attraction"> + Attrazioni speciali + </string> + <string name="New Products"> + Nuovi prodotti + </string> + <string name="Employment"> + Lavoro + </string> + <string name="Wanted"> + Cercasi + </string> + <string name="Service"> + Servizio + </string> + <string name="Personal"> + Personale + </string> + <string name="None"> + Nessuno + </string> + <string name="Linden Location"> + Luogo dei Linden + </string> + <string name="Adult"> + Adult + </string> + <string name="Arts&Culture"> + Arte & Cultura + </string> + <string name="Business"> + Affari + </string> + <string name="Educational"> + Educazione + </string> + <string name="Gaming"> + Gioco + </string> + <string name="Hangout"> + Divertimento + </string> + <string name="Newcomer Friendly"> + Accoglienza nuovi residenti + </string> + <string name="Parks&Nature"> + Parchi & Natura + </string> + <string name="Residential"> + Residenziale + </string> + <string name="Stage"> + Fase + </string> + <string name="Other"> + Altro + </string> + <string name="Rental"> + Affitto + </string> + <string name="Any"> + Tutti + </string> + <string name="You"> + Tu + </string> + <string name="Multiple Media"> + Più supporti + </string> + <string name="Play Media"> + Riproduci/Pausa supporto + </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com/Download/index.aspx?lang=en-us + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> + <string name="MBCmdLineError"> + Un errore è stato riscontrato analizzando la linea di comando. Per informazioni: http://wiki.secondlife.com/wiki/Client_parameters -Errore:</string> - <string name="MBCmdLineUsg">Uso linea di comando del programma [APP_NAME] :</string> - <string name="MBUnableToAccessFile">Il programma [APP_NAME] non è in grado di accedere ad un file necessario. +Errore: + </string> + <string name="MBCmdLineUsg"> + Uso linea di comando del programma [APP_NAME] : + </string> + <string name="MBUnableToAccessFile"> + Il programma [APP_NAME] non è in grado di accedere ad un file necessario. Potrebbe darsi che tu abbia copie multiple attivate o che il tuo sistema reputi erroneamente che il file sia già aperto. Se il problema persiste, riavvia il computer e riprova. -Se il problema continua ancora, dovresti completamente disinstallare l'applicazione [APP_NAME] e reinstallarla.</string> - <string name="MBFatalError">Errore critico</string> - <string name="MBRequiresAltiVec">Il programma [APP_NAME] richiede un processore con AltiVec (G4 o superiore).</string> - <string name="MBAlreadyRunning">Il programma [APP_NAME] è già attivo. +Se il problema continua ancora, dovresti completamente disinstallare l'applicazione [APP_NAME] e reinstallarla. + </string> + <string name="MBFatalError"> + Errore critico + </string> + <string name="MBRequiresAltiVec"> + Il programma [APP_NAME] richiede un processore con AltiVec (G4 o superiore). + </string> + <string name="MBAlreadyRunning"> + Il programma [APP_NAME] è già attivo. Controlla che il programma non sia minimizzato nella tua barra degli strumenti. -Se il messaggio persiste, riavvia il computer.</string> - <string name="MBFrozenCrashed">Sembra che [APP_NAME] si sia bloccata o interrotta nella sessione precedente. -Vuoi mandare un crash report?</string> - <string name="MBAlert">Avviso</string> - <string name="MBNoDirectX">Il programmma [APP_NAME] non riesce a trovare una DirectX 9.0b o superiore. +Se il messaggio persiste, riavvia il computer. + </string> + <string name="MBFrozenCrashed"> + Sembra che [APP_NAME] si sia bloccata o interrotta nella sessione precedente. +Vuoi mandare un crash report? + </string> + <string name="MBAlert"> + Avviso + </string> + <string name="MBNoDirectX"> + Il programmma [APP_NAME] non riesce a trovare una DirectX 9.0b o superiore. [APP_NAME] usa DirectX per rilevare hardware e/o i driver non aggiornati che possono causare problemi di stabilità, scarsa performance e interruzioni. Benché tu possa avviare il programma [APP_NAME] senza di esse, consigliamo caldamente l'esecuzione con DirectX 9.0b. -Vuoi continuare?</string> - <string name="MBWarning">Attenzione</string> - <string name="MBNoAutoUpdate">L'aggiornamento automatico non è stato ancora realizzato per Linux. -Consigliamo di scaricare l'ultima versione direttamente da www.secondlife.com.</string> - <string name="MBRegClassFailed">RegisterClass non riuscito</string> - <string name="MBError">Errore</string> - <string name="MBFullScreenErr">Impossibile visualizzare a schermo intero con risoluzione [WIDTH] x [HEIGHT]. -Visualizzazione corrente in modalità finestra.</string> - <string name="MBDestroyWinFailed">Errore di arresto durante il tentativo di chiusura della finestra (DestroyWindow() non riuscito)</string> - <string name="MBShutdownErr">Errore di arresto</string> - <string name="MBDevContextErr">Impossibile caricare i driver GL</string> - <string name="MBPixelFmtErr">Impossibile trovare un formato pixel adatto</string> - <string name="MBPixelFmtDescErr">Impossibile ottenere una descrizione del formato pixel</string> - <string name="MBTrueColorWindow">[APP_NAME] richiede True Color (32 bit) per funzionare. -Vai alle impostazioni dello schermo del tuo computer e imposta il colore in modalità 32 bit.</string> - <string name="MBAlpha">[APP_NAME] non funziona poichè è impossibile trovare un canale alpha a 8 bit. Questo problema normalmente deriva dai driver della scheda video. +Vuoi continuare? + </string> + <string name="MBWarning"> + Attenzione + </string> + <string name="MBNoAutoUpdate"> + L'aggiornamento automatico non è stato ancora realizzato per Linux. +Consigliamo di scaricare l'ultima versione direttamente da www.secondlife.com. + </string> + <string name="MBRegClassFailed"> + RegisterClass non riuscito + </string> + <string name="MBError"> + Errore + </string> + <string name="MBFullScreenErr"> + Impossibile visualizzare a schermo intero con risoluzione [WIDTH] x [HEIGHT]. +Visualizzazione corrente in modalità finestra. + </string> + <string name="MBDestroyWinFailed"> + Errore di arresto durante il tentativo di chiusura della finestra (DestroyWindow() non riuscito) + </string> + <string name="MBShutdownErr"> + Errore di arresto + </string> + <string name="MBDevContextErr"> + Impossibile caricare i driver GL + </string> + <string name="MBPixelFmtErr"> + Impossibile trovare un formato pixel adatto + </string> + <string name="MBPixelFmtDescErr"> + Impossibile ottenere una descrizione del formato pixel + </string> + <string name="MBTrueColorWindow"> + [APP_NAME] richiede True Color (32 bit) per funzionare. +Vai alle impostazioni dello schermo del tuo computer e imposta il colore in modalità 32 bit. + </string> + <string name="MBAlpha"> + [APP_NAME] non funziona poichè è impossibile trovare un canale alpha a 8 bit. Questo problema normalmente deriva dai driver della scheda video. Assicurati di avere installato i driver della scheda video più recenti. Assicurati anche che il monitor sia impostato a True Color (32 bit) nel Pannello di controllo > Schermo > Impostazioni. -Se il messaggio persiste, contatta [SUPPORT_SITE].</string> - <string name="MBPixelFmtSetErr">Impossibile impostare il formato pixel</string> - <string name="MBGLContextErr">Impossibile creare il GL rendering</string> - <string name="MBGLContextActErr">Impossibile attivare il GL rendering</string> - <string name="MBVideoDrvErr">[APP_NAME] Non riesce ad avviarsi perchè i driver della tua scheda video non sono stati installati correttamente, non sono aggiornati, o sono per un hardware non supportato. Assicurati di avere i driver della scheda video più recenti e anche se li hai installati, prova a installarli di nuovo. +Se il messaggio persiste, contatta [SUPPORT_SITE]. + </string> + <string name="MBPixelFmtSetErr"> + Impossibile impostare il formato pixel + </string> + <string name="MBGLContextErr"> + Impossibile creare il GL rendering + </string> + <string name="MBGLContextActErr"> + Impossibile attivare il GL rendering + </string> + <string name="MBVideoDrvErr"> + [APP_NAME] Non riesce ad avviarsi perchè i driver della tua scheda video non sono stati installati correttamente, non sono aggiornati, o sono per un hardware non supportato. Assicurati di avere i driver della scheda video più recenti e anche se li hai installati, prova a installarli di nuovo. -Se il messaggio persiste, contatta [SUPPORT_SITE].</string> - <string name="5 O'Clock Shadow">Barba leggera</string> - <string name="All White">Tutti bianchi</string> - <string name="Anime Eyes">Occhi grandi</string> - <string name="Arced">Arcuato</string> - <string name="Arm Length">Lunghezza braccia</string> - <string name="Attached">Attaccato</string> - <string name="Attached Earlobes">Lobi attaccati</string> - <string name="Back Fringe">Frangetta all'indietro</string> - <string name="Baggy">Larghi</string> - <string name="Bangs">Frange</string> - <string name="Beady Eyes">Occhi piccoli</string> - <string name="Belly Size">Punto vita</string> - <string name="Big">Grande</string> - <string name="Big Butt">Sedere grande</string> - <string name="Big Hair Back">Capigliatura grande: Indietro</string> - <string name="Big Hair Front">Capigliatura grande: anteriore</string> - <string name="Big Hair Top">Capigliatura grande: in alto</string> - <string name="Big Head">Grande testa</string> - <string name="Big Pectorals">Grandi pettorali</string> - <string name="Big Spikes">Capelli con punte</string> - <string name="Black">Nero</string> - <string name="Blonde">Biondo</string> - <string name="Blonde Hair">Capelli biondi</string> - <string name="Blush">Fard</string> - <string name="Blush Color">Colore fard</string> - <string name="Blush Opacity">Opacità fard</string> - <string name="Body Definition">Definizione muscolare</string> - <string name="Body Fat">Grasso corporeo</string> - <string name="Body Freckles">Lentiggini e nei</string> - <string name="Body Thick">Corpo più robusto</string> - <string name="Body Thickness">Robustezza del corpo</string> - <string name="Body Thin">Corpo più magro</string> - <string name="Bow Legged">Gambe arcuate</string> - <string name="Breast Buoyancy">Altezza del seno</string> - <string name="Breast Cleavage">Décolleté</string> - <string name="Breast Size">Grandezza del seno</string> - <string name="Bridge Width">Larghezza setto</string> - <string name="Broad">Largo</string> - <string name="Brow Size">Grandezza delle sopracciglia</string> - <string name="Bug Eyes">Occhi sporgenti</string> - <string name="Bugged Eyes">Occhi sporgenti</string> - <string name="Bulbous">Bulboso</string> - <string name="Bulbous Nose">Naso bulboso</string> - <string name="Breast Physics Mass">Massa seno</string> - <string name="Breast Physics Smoothing">Lisciatura seno</string> - <string name="Breast Physics Gravity">Gravità seno</string> - <string name="Breast Physics Drag">Resistenza seno</string> - <string name="Breast Physics InOut Max Effect">Massimo effetto</string> - <string name="Breast Physics InOut Spring">Elasticità</string> - <string name="Breast Physics InOut Gain">Guadagno</string> - <string name="Breast Physics InOut Damping">Attenuazione</string> - <string name="Breast Physics UpDown Max Effect">Massimo effetto</string> - <string name="Breast Physics UpDown Spring">Elasticità</string> - <string name="Breast Physics UpDown Gain">Guadagno</string> - <string name="Breast Physics UpDown Damping">Attenuazione</string> - <string name="Breast Physics LeftRight Max Effect">Massimo effetto</string> - <string name="Breast Physics LeftRight Spring">Elasticità</string> - <string name="Breast Physics LeftRight Gain">Guadagno</string> - <string name="Breast Physics LeftRight Damping">Attenuazione</string> - <string name="Belly Physics Mass">Massa pancia</string> - <string name="Belly Physics Smoothing">Lisciatura pancia</string> - <string name="Belly Physics Gravity">Gravità pancia</string> - <string name="Belly Physics Drag">Resistenza pancia</string> - <string name="Belly Physics UpDown Max Effect">Massimo effetto</string> - <string name="Belly Physics UpDown Spring">Elasticità</string> - <string name="Belly Physics UpDown Gain">Guadagno</string> - <string name="Belly Physics UpDown Damping">Attenuazione</string> - <string name="Butt Physics Mass">Massa natiche</string> - <string name="Butt Physics Smoothing">Lisciatura natiche</string> - <string name="Butt Physics Gravity">Gravità natiche</string> - <string name="Butt Physics Drag">Resistenza natiche</string> - <string name="Butt Physics UpDown Max Effect">Massimo effetto</string> - <string name="Butt Physics UpDown Spring">Elasticità</string> - <string name="Butt Physics UpDown Gain">Guadagno</string> - <string name="Butt Physics UpDown Damping">Attenuazione</string> - <string name="Butt Physics LeftRight Max Effect">Massimo effetto</string> - <string name="Butt Physics LeftRight Spring">Elasticità</string> - <string name="Butt Physics LeftRight Gain">Guadagno</string> - <string name="Butt Physics LeftRight Damping">Attenuazione</string> - <string name="Bushy Eyebrows">Sopracciglia cespugliose</string> - <string name="Bushy Hair">Capelli a cespuglio</string> - <string name="Butt Size">Grandezza del sedere</string> - <string name="Butt Gravity">Gravità natiche</string> - <string name="bustle skirt">Crinolina</string> - <string name="no bustle">Nessuna crinolina</string> - <string name="more bustle">Più crinolina</string> - <string name="Chaplin">Baffetti</string> - <string name="Cheek Bones">Zigomi</string> - <string name="Chest Size">Ampiezza del torace</string> - <string name="Chin Angle">Angolo del mento</string> - <string name="Chin Cleft">Fossetta sul mento</string> - <string name="Chin Curtains">Barba sottomento</string> - <string name="Chin Depth">Profondità mento</string> - <string name="Chin Heavy">Mento forte</string> - <string name="Chin In">Mento in dentro</string> - <string name="Chin Out">Mento sporgente</string> - <string name="Chin-Neck">Mento-collo</string> - <string name="Clear">Trasparente</string> - <string name="Cleft">Fossetta</string> - <string name="Close Set Eyes">Occhi ravvicinati</string> - <string name="Closed">Chiusa</string> - <string name="Closed Back">Chiuso dietro</string> - <string name="Closed Front">Chiuso davanti</string> - <string name="Closed Left">Chiuso sinistra</string> - <string name="Closed Right">Chiuso destra</string> - <string name="Coin Purse">Meno pronunciati</string> - <string name="Collar Back">Colletto posteriore</string> - <string name="Collar Front">Colletto anteriore</string> - <string name="Corner Down">Angolo all'ingiù</string> - <string name="Corner Up">Angolo all'insù</string> - <string name="Creased">Piega</string> - <string name="Crooked Nose">Naso storto</string> - <string name="Cuff Flare">Svasato con risvolto</string> - <string name="Dark">Scuro</string> - <string name="Dark Green">Verde scuro</string> - <string name="Darker">Più scuro</string> - <string name="Deep">Profondo</string> - <string name="Default Heels">Tacchi standard</string> - <string name="Dense">Folti</string> - <string name="Double Chin">Doppio mento</string> - <string name="Downturned">All'ingiù</string> - <string name="Duffle Bag">Più pronunciati</string> - <string name="Ear Angle">Angolo orecchie</string> - <string name="Ear Size">Grandezza orecchie</string> - <string name="Ear Tips">Estremità orecchie</string> - <string name="Egg Head">Ovalizzazione testa</string> - <string name="Eye Bags">Occhiaie</string> - <string name="Eye Color">Colore degli occhi</string> - <string name="Eye Depth">Profondità degli occhi</string> - <string name="Eye Lightness">Luminosità degli occhi</string> - <string name="Eye Opening">Apertura degli occhi</string> - <string name="Eye Pop">Prominenza degli occhi</string> - <string name="Eye Size">Grandezza occhi</string> - <string name="Eye Spacing">Distanza occhi</string> - <string name="Eyebrow Arc">Arco delle sopracciglia</string> - <string name="Eyebrow Density">Densità delle sopracciglia</string> - <string name="Eyebrow Height">Altezza delle sopracciglia</string> - <string name="Eyebrow Points">Sopracciglia appuntite</string> - <string name="Eyebrow Size">Grandezza sopracciglia</string> - <string name="Eyelash Length">Lunghezza delle ciglia</string> - <string name="Eyeliner">Eyeliner</string> - <string name="Eyeliner Color">Colore dell'eyeliner</string> - <string name="Eyes Bugged">Occhi sporgenti</string> - <string name="Face Shear">Taglio del viso</string> - <string name="Facial Definition">Definizione del viso</string> - <string name="Far Set Eyes">Occhi distanti</string> - <string name="Fat Lips">Labbra carnose</string> - <string name="Female">Femmina</string> - <string name="Fingerless">Senza dita</string> - <string name="Fingers">Dita</string> - <string name="Flared Cuffs">Risvolti svasati</string> - <string name="Flat">Piatto</string> - <string name="Flat Butt">Sedere piatto</string> - <string name="Flat Head">Testa piatta</string> - <string name="Flat Toe">Punta piatta</string> - <string name="Foot Size">Misura piede</string> - <string name="Forehead Angle">Angolo della fronte</string> - <string name="Forehead Heavy">Fronte sporgente</string> - <string name="Freckles">Lentiggini</string> - <string name="Front Fringe">Frangetta</string> - <string name="Full Back">Dietro gonfi</string> - <string name="Full Eyeliner">Eyeliner marcato</string> - <string name="Full Front">Anteriore gonfio</string> - <string name="Full Hair Sides">Lati capelli gonfi</string> - <string name="Full Sides">Lati gonfi</string> - <string name="Glossy">Lucido</string> - <string name="Glove Fingers">Dita con guanti</string> - <string name="Glove Length">Lunghezza guanti</string> - <string name="Hair">Capigliature</string> - <string name="Hair Back">Capelli: Indietro</string> - <string name="Hair Front">Capelli: anteriore</string> - <string name="Hair Sides">Capelli: lati</string> - <string name="Hair Sweep">Direzione capigliatura</string> - <string name="Hair Thickess">Foltezza</string> - <string name="Hair Thickness">Foltezza</string> - <string name="Hair Tilt">Inclinazione</string> - <string name="Hair Tilted Left">Verso sinistra</string> - <string name="Hair Tilted Right">Verso destra</string> - <string name="Hair Volume">Capelli: Volume</string> - <string name="Hand Size">Grandezza mani</string> - <string name="Handlebars">Baffi a manubrio</string> - <string name="Head Length">Lunghezza testa</string> - <string name="Head Shape">Forma della testa</string> - <string name="Head Size">Grandezza della testa</string> - <string name="Head Stretch">Allungamento testa</string> - <string name="Heel Height">Altezza tacchi</string> - <string name="Heel Shape">Forma tacchi</string> - <string name="Height">Altezza</string> - <string name="High">Alto</string> - <string name="High Heels">Tacchi alti</string> - <string name="High Jaw">Mandibola alta</string> - <string name="High Platforms">Alta</string> - <string name="High and Tight">Alto e stretto</string> - <string name="Higher">Più alto</string> - <string name="Hip Length">Altezza bacino</string> - <string name="Hip Width">Larghezza bacino</string> - <string name="Hover">Muovi sopra</string> - <string name="In">Dentro</string> - <string name="In Shdw Color">Colore ombretto interno</string> - <string name="In Shdw Opacity">Opacità ombretto interno</string> - <string name="Inner Eye Corner">Angolo interno</string> - <string name="Inner Eye Shadow">Ombretto interno</string> - <string name="Inner Shadow">Ombretto interno</string> - <string name="Jacket Length">Lunghezza giacca</string> - <string name="Jacket Wrinkles">Grinze della giacca</string> - <string name="Jaw Angle">Angolo mandibola</string> - <string name="Jaw Jut">Prognatismo mento</string> - <string name="Jaw Shape">Forma del mento</string> - <string name="Join">Iscriviti</string> - <string name="Jowls">Guance</string> - <string name="Knee Angle">Angolo ginocchia</string> - <string name="Knock Kneed">Gambe ad X</string> - <string name="Large">Grande</string> - <string name="Large Hands">Mani grandi</string> - <string name="Left Part">Riga a sinistra</string> - <string name="Leg Length">Lunghezza gambe</string> - <string name="Leg Muscles">Muscoli gambe</string> - <string name="Less">Meno</string> - <string name="Less Body Fat">Meno grasso corporeo</string> - <string name="Less Curtains">Meno</string> - <string name="Less Freckles">Meno lentiggini</string> - <string name="Less Full">Meno piene</string> - <string name="Less Gravity">Più alto</string> - <string name="Less Love">Meno maniglie</string> - <string name="Less Muscles">Meno muscoli</string> - <string name="Less Muscular">Meno muscolari</string> - <string name="Less Rosy">Meno rosato</string> - <string name="Less Round">Meno rotondo</string> - <string name="Less Saddle">Meno a sella</string> - <string name="Less Square">Meno quadrato</string> - <string name="Less Volume">Meno volume</string> - <string name="Less soul">Meno</string> - <string name="Lighter">Più leggero</string> - <string name="Lip Cleft">Distanza fossetta labbro</string> - <string name="Lip Cleft Depth">Prof. fossetta labbro</string> - <string name="Lip Fullness">Volume labbra</string> - <string name="Lip Pinkness">Tonalità rosa labbra</string> - <string name="Lip Ratio">Proporzione labbra</string> - <string name="Lip Thickness">Carnosità labbra</string> - <string name="Lip Width">Larghezza labbra</string> - <string name="Lipgloss">Lipgloss</string> - <string name="Lipstick">Rossetto</string> - <string name="Lipstick Color">Colore rossetto</string> - <string name="Long">Lungo</string> - <string name="Long Head">Testa lunga</string> - <string name="Long Hips">Bacino alto</string> - <string name="Long Legs">Gambe lunghe</string> - <string name="Long Neck">Collo lungo</string> - <string name="Long Pigtails">Codini lunghi</string> - <string name="Long Ponytail">Codino lungo</string> - <string name="Long Torso">Torace lungo</string> - <string name="Long arms">Braccia lunghe</string> - <string name="Loose Pants">Pantaloni ampi</string> - <string name="Loose Shirt">Camicia ampia</string> - <string name="Loose Sleeves">Maniche non attillate</string> - <string name="Love Handles">Maniglie dell'amore</string> - <string name="Low">Basso</string> - <string name="Low Heels">Tacchi bassi</string> - <string name="Low Jaw">Mandibola bassa</string> - <string name="Low Platforms">Bassa</string> - <string name="Low and Loose">Basso e ampio</string> - <string name="Lower">Più basso</string> - <string name="Lower Bridge">Parte bassa del setto</string> - <string name="Lower Cheeks">Guance inferiori</string> - <string name="Male">Maschio</string> - <string name="Middle Part">Riga nel mezzo</string> - <string name="More">Altro</string> - <string name="More Blush">Più fard</string> - <string name="More Body Fat">Più grasso corporeo</string> - <string name="More Curtains">Più</string> - <string name="More Eyeshadow">Più ombretto</string> - <string name="More Freckles">Più lentiggini</string> - <string name="More Full">Più piene</string> - <string name="More Gravity">Più calato</string> - <string name="More Lipstick">Più rossetto</string> - <string name="More Love">Più maniglie</string> - <string name="More Lower Lip">Labbro inf. pronunciato</string> - <string name="More Muscles">Più muscoli</string> - <string name="More Muscular">Più muscolatura</string> - <string name="More Rosy">Più rosato</string> - <string name="More Round">Più rotondo</string> - <string name="More Saddle">Più a sella</string> - <string name="More Sloped">Più orizzontale</string> - <string name="More Square">Più quadrato</string> - <string name="More Upper Lip">Labbro sup. pronunciato</string> - <string name="More Vertical">Più verticale</string> - <string name="More Volume">Più volume</string> - <string name="More soul">Più</string> - <string name="Moustache">Baffi</string> - <string name="Mouth Corner">Angolo della bocca</string> - <string name="Mouth Position">Posizione della bocca</string> - <string name="Mowhawk">Moicana</string> - <string name="Muscular">Muscolatura</string> - <string name="Mutton Chops">Basette lunghe</string> - <string name="Nail Polish">Smalto</string> - <string name="Nail Polish Color">Colore smalto</string> - <string name="Narrow">Socchiusi</string> - <string name="Narrow Back">Laterali post. vicini</string> - <string name="Narrow Front">Laterali ant. vicini</string> - <string name="Narrow Lips">Labbra strette</string> - <string name="Natural">Naturale</string> - <string name="Neck Length">Lunghezza del collo</string> - <string name="Neck Thickness">Grandezza del collo</string> - <string name="No Blush">Senza fard</string> - <string name="No Eyeliner">Senza eyeliner</string> - <string name="No Eyeshadow">Senza ombretto</string> - <string name="No Lipgloss">Senza lipgloss</string> - <string name="No Lipstick">Senza rossetto</string> - <string name="No Part">Senza riga</string> - <string name="No Polish">Senza smalto</string> - <string name="No Red">Senza rosso</string> - <string name="No Spikes">Senza punte</string> - <string name="No White">Senza bianco</string> - <string name="No Wrinkles">Senza pieghe</string> - <string name="Normal Lower">Inferiore normale</string> - <string name="Normal Upper">Superiore normale</string> - <string name="Nose Left">Naso a sinistra</string> - <string name="Nose Right">Naso a destra</string> - <string name="Nose Size">Grandezza naso</string> - <string name="Nose Thickness">Spessore naso</string> - <string name="Nose Tip Angle">Angolo punta naso</string> - <string name="Nose Tip Shape">Forma punta naso</string> - <string name="Nose Width">Larghezza naso</string> - <string name="Nostril Division">Divisione narici</string> - <string name="Nostril Width">Larghezza narici</string> - <string name="Opaque">Opaco</string> - <string name="Open">Apri</string> - <string name="Open Back">Retro aperto</string> - <string name="Open Front">Davanti aperto</string> - <string name="Open Left">Lato sin. aperto</string> - <string name="Open Right">Lato des. aperto</string> - <string name="Orange">Arancio</string> - <string name="Out">Fuori</string> - <string name="Out Shdw Color">Colore ombretto esterno</string> - <string name="Out Shdw Opacity">Opacità ombretto esterno</string> - <string name="Outer Eye Corner">Angolo esterno occhio</string> - <string name="Outer Eye Shadow">Ombretto esterno</string> - <string name="Outer Shadow">Ombreggiatura esterna</string> - <string name="Overbite">Denti sup. in fuori</string> - <string name="Package">Genitali</string> - <string name="Painted Nails">Unghie smaltate</string> - <string name="Pale">Pallido</string> - <string name="Pants Crotch">Cavallo</string> - <string name="Pants Fit">Vestibilità pantaloni</string> - <string name="Pants Length">Lunghezza pantaloni</string> - <string name="Pants Waist">Taglia pantalone</string> - <string name="Pants Wrinkles">Pantaloni con le grinze</string> - <string name="Part">Con riga</string> - <string name="Part Bangs">Frangetta divisa</string> - <string name="Pectorals">Pettorali</string> - <string name="Pigment">Pigmento</string> - <string name="Pigtails">Codini</string> - <string name="Pink">Rosa</string> - <string name="Pinker">Più rosato</string> - <string name="Platform Height">Altezza pianta</string> - <string name="Platform Width">Larghezza pianta</string> - <string name="Pointy">Appuntito</string> - <string name="Pointy Heels">Tacchi a spillo</string> - <string name="Ponytail">Codino</string> - <string name="Poofy Skirt">Gonna gonfia</string> - <string name="Pop Left Eye">Sinistro più aperto</string> - <string name="Pop Right Eye">Destro più aperto</string> - <string name="Puffy">Paffute</string> - <string name="Puffy Eyelids">Palpebre gonfie</string> - <string name="Rainbow Color">Tonalità</string> - <string name="Red Hair">Presenza di rosso nei capelli</string> - <string name="Regular">Normale</string> - <string name="Right Part">Riga a destra</string> - <string name="Rosy Complexion">Incarnato</string> - <string name="Round">Rotondo</string> - <string name="Ruddiness">Rossore</string> - <string name="Ruddy">Rosse</string> - <string name="Rumpled Hair">Capelli mossi</string> - <string name="Saddle Bags">Rotondità fianchi</string> - <string name="Scrawny Leg">Gambe magre</string> - <string name="Separate">Separati</string> - <string name="Shallow">Meno pronunciato</string> - <string name="Shear Back">Taglio posteriore</string> - <string name="Shear Face">Taglio del viso</string> - <string name="Shear Front">Taglio anteriore</string> - <string name="Shear Left Up">Distorto a sinistra</string> - <string name="Shear Right Up">Distorto a destra</string> - <string name="Sheared Back">Taglio verso dietro</string> - <string name="Sheared Front">Taglio verso davanti</string> - <string name="Shift Left">A sinistra</string> - <string name="Shift Mouth">Spostamento bocca</string> - <string name="Shift Right">A destra</string> - <string name="Shirt Bottom">Parte inferiore camicia</string> - <string name="Shirt Fit">Vestibilità camicia</string> - <string name="Shirt Wrinkles">Camicia con le grinze</string> - <string name="Shoe Height">Altezza scarpe</string> - <string name="Short">Basso</string> - <string name="Short Arms">Braccia corte</string> - <string name="Short Legs">Gambe corte</string> - <string name="Short Neck">Collo corto</string> - <string name="Short Pigtails">Codini corti</string> - <string name="Short Ponytail">Codino corto</string> - <string name="Short Sideburns">Basette corte</string> - <string name="Short Torso">Torace corto</string> - <string name="Short hips">Bacino corto</string> - <string name="Shoulders">Spalle</string> - <string name="Side Fringe">Ciuffi laterali</string> - <string name="Sideburns">Basette</string> - <string name="Sides Hair">Capigliatura di lato</string> - <string name="Sides Hair Down">Capigliatura di lato sciolta</string> - <string name="Sides Hair Up">Capigliatura di lato raccolta</string> - <string name="Skinny Neck">Collo fino</string> - <string name="Skirt Fit">Vestibilità gonna</string> - <string name="Skirt Length">Lunghezza gonna</string> - <string name="Slanted Forehead">Fronte inclinata</string> - <string name="Sleeve Length">Lunghezza maniche</string> - <string name="Sleeve Looseness">Morbidezza maniche</string> - <string name="Slit Back">Spacco: Indietro</string> - <string name="Slit Front">Spacco: anteriore</string> - <string name="Slit Left">Spacco: Sinistra</string> - <string name="Slit Right">Spacco: Destra</string> - <string name="Small">Piccola</string> - <string name="Small Hands">Mani piccole</string> - <string name="Small Head">Testa piccola</string> - <string name="Smooth">Liscio</string> - <string name="Smooth Hair">Capelli lisci</string> - <string name="Socks Length">Lunghezza calze</string> - <string name="Soulpatch">Pizzetto labbro inferiore</string> - <string name="Sparse">Piu rade</string> - <string name="Spiked Hair">Capelli a punta</string> - <string name="Square">Quadrato</string> - <string name="Square Toe">Punta quadrata</string> - <string name="Squash Head">Testa schiacciata</string> - <string name="Stretch Head">Testa allungata</string> - <string name="Sunken">Scarne</string> - <string name="Sunken Chest">Senza pettorali</string> - <string name="Sunken Eyes">Occhi infossati</string> - <string name="Sweep Back">Indietro</string> - <string name="Sweep Forward">Avanti</string> - <string name="Tall">Alto</string> - <string name="Taper Back">Ravv. lat. posteriore</string> - <string name="Taper Front">Ravv. lat. frontale</string> - <string name="Thick Heels">Tacchi spessi</string> - <string name="Thick Neck">Collo grosso</string> - <string name="Thick Toe">Punta spessa</string> - <string name="Thin">Sottili</string> - <string name="Thin Eyebrows">Sopracciglia sottili</string> - <string name="Thin Lips">Labbra sottili</string> - <string name="Thin Nose">Naso sottile</string> - <string name="Tight Chin">Mento stretto</string> - <string name="Tight Cuffs">Fondo stretto</string> - <string name="Tight Pants">Pantaloni attillati</string> - <string name="Tight Shirt">Camicia attillata</string> - <string name="Tight Skirt">Gonna attillata</string> - <string name="Tight Sleeves">Maniche strette</string> - <string name="Toe Shape">Forma della punta</string> - <string name="Toe Thickness">Spessore della punta</string> - <string name="Torso Length">Lunghezza del torace</string> - <string name="Torso Muscles">Muscoli del torace</string> - <string name="Torso Scrawny">Torso Scrawny</string> - <string name="Unattached">Distaccato</string> - <string name="Uncreased">Senza piega</string> - <string name="Underbite">Denti inf. in fuori</string> - <string name="Unnatural">Innaturale</string> - <string name="Upper Bridge">Parte alta del setto</string> - <string name="Upper Cheeks">Parte alta degli zigomi</string> - <string name="Upper Chin Cleft">Fossetta sup. del mento</string> - <string name="Upper Eyelid Fold">Piega palpebra sup.</string> - <string name="Upturned">All'insù</string> - <string name="Very Red">Molto rossi</string> - <string name="Waist Height">Vita alta</string> - <string name="Well-Fed">Pienotte</string> - <string name="White Hair">Capelli bianchi</string> - <string name="Wide">Largo</string> - <string name="Wide Back">Dietro largo</string> - <string name="Wide Front">Davanti largo</string> - <string name="Wide Lips">Labbra larghe</string> - <string name="Wild">Colorati</string> - <string name="Wrinkles">Grinze</string> - <string name="LocationCtrlAddLandmarkTooltip">Aggiungi ai miei punti di riferimento</string> - <string name="LocationCtrlEditLandmarkTooltip">Modifica i miei punti di riferimento</string> - <string name="LocationCtrlInfoBtnTooltip">Maggiori informazioni sulla posizione attuale</string> - <string name="LocationCtrlComboBtnTooltip">La cronologia delle mie posizioni</string> - <string name="LocationCtrlAdultIconTooltip">Regione con categoria adulti</string> - <string name="LocationCtrlModerateIconTooltip">Regione con categoria moderata</string> - <string name="LocationCtrlGeneralIconTooltip">Regione generale</string> - <string name="LocationCtrlSeeAVsTooltip">Gli avatar in questo lotto non possono essere visti o sentiti da avatar all'esterno del lotto</string> - <string name="LocationCtrlPathfindingDirtyTooltip">Gli oggetti che si muovono potrebbero non comportarsi correttamente in questa regione fino a quando non viene eseguito il rebake della regione.</string> - <string name="LocationCtrlPathfindingDisabledTooltip">Il pathfinding dinamico non è attivato in questa regione.</string> - <string name="UpdaterWindowTitle">Aggiornamento [APP_NAME]</string> - <string name="UpdaterNowUpdating">Aggiornamento di [APP_NAME]...</string> - <string name="UpdaterNowInstalling">Installazione di [APP_NAME]...</string> - <string name="UpdaterUpdatingDescriptive">Il Viewer del programma [APP_NAME] si sta aggiornando all'ultima versione. Potrebbe volerci del tempo, attendi.</string> - <string name="UpdaterProgressBarTextWithEllipses">Download dell'aggiornamento...</string> - <string name="UpdaterProgressBarText">Download dell'aggiornamento</string> - <string name="UpdaterFailDownloadTitle">Download dell'aggiornamento non riuscito</string> - <string name="UpdaterFailUpdateDescriptive">Il programma [APP_NAME] ha riscontrato un'errore durante il tentativo di aggiornamento. Consigliamo di scaricare l'ultima versione direttamente da www.secondlife.com.</string> - <string name="UpdaterFailInstallTitle">Installazione dell'aggiornamento non riuscita</string> - <string name="UpdaterFailStartTitle">Errore nell'avvio del viewer</string> - <string name="ItemsComingInTooFastFrom">[APP_NAME]: Oggetti in arrivo troppo velocemente da [FROM_NAME], anteprima automatica disattivata per [TIME] secondi</string> - <string name="ItemsComingInTooFast">[APP_NAME]: Oggetti in arrivo troppo velocemente, anteprima automatica disattivata per [TIME] secondi</string> - <string name="IM_logging_string">-- Registrazione messaggi instantanei abilitata --</string> - <string name="IM_typing_start_string">[NAME] sta scrivendo...</string> - <string name="Unnamed">(anonimo)</string> - <string name="IM_moderated_chat_label">(Moderato: Voci disattivate di default)</string> - <string name="IM_unavailable_text_label">La chat di testo non è disponibile per questa chiamata.</string> - <string name="IM_muted_text_label">La chat di testo è stata disabilitata da un moderatore di gruppo.</string> - <string name="IM_default_text_label">Clicca qui per inviare un messaggio instantaneo.</string> - <string name="IM_to_label">A</string> - <string name="IM_moderator_label">(Moderatore)</string> - <string name="Saved_message">(Salvato [LONG_TIMESTAMP])</string> - <string name="IM_unblock_only_groups_friends">Per vedere questo messaggio, devi deselezionare 'Solo amici e gruppi possono chiamarmi o mandarmi IM' in Preferenze/Privacy.</string> - <string name="OnlineStatus">Online</string> - <string name="OfflineStatus">Offline</string> - <string name="not_online_msg">Utente non online - il messaggio verrà memorizzato e inviato più tardi.</string> - <string name="not_online_inventory">Utente non online - l'inventario è stato salvato</string> - <string name="answered_call">Risposto alla chiamata</string> - <string name="you_started_call">Hai iniziato una chiamata vocale</string> - <string name="you_joined_call">Ti sei collegato alla chiamata in voce</string> - <string name="you_auto_rejected_call-im">Hai rifiutato automaticamente la chiamata voce mentre era attivata la modalità 'Non disturbare'.</string> - <string name="name_started_call">[NAME] ha iniziato una chiamata vocale</string> - <string name="ringing-im">Collegamento alla chiamata vocale...</string> - <string name="connected-im">Collegato, clicca Chiudi chiamata per agganciare</string> - <string name="hang_up-im">Chiusa la chiamata</string> - <string name="conference-title">Chat con più persone</string> - <string name="conference-title-incoming">Chiamata in conferenza con [AGENT_NAME]</string> - <string name="inventory_item_offered-im">Offerto oggetto di inventario "[ITEM_NAME]"</string> - <string name="inventory_folder_offered-im">Offerta cartella di inventario "[ITEM_NAME]"</string> - <string name="facebook_post_success">Hai pubblicato su Facebook.</string> - <string name="flickr_post_success">Hai pubblicato su Flickr.</string> - <string name="twitter_post_success">Hai pubblicato su Twitter.</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> - <string name="offline_message">[NAME] è offline</string> - <string name="invite_message">Clicca il tasto [BUTTON NAME] per accettare/connetterti a questa voice chat.</string> - <string name="muted_message">Hai bloccato questo residente. Quando gli invii un messaggio, verrà automaticamente sbloccato.</string> - <string name="generic">Errore nella richiesta, riprova più tardi.</string> - <string name="generic_request_error">Errore durante la richiesta, riprova più tardi.</string> - <string name="insufficient_perms_error">Non hai sufficienti permessi.</string> - <string name="session_does_not_exist_error">Questa sessione non esiste più</string> - <string name="no_ability_error">Non hai questa abilitazione.</string> - <string name="no_ability">Non hai questa abilitazione.</string> - <string name="not_a_mod_error">Non sei un moderatore.</string> - <string name="muted">Il moderatore del gruppo ha disattivato la tua chat di testo.</string> - <string name="muted_error">Un moderatore di gruppo ti ha disabilitato dalla chat di testo.</string> - <string name="add_session_event">Impossibile aggiungere utenti alla chat con [RECIPIENT].</string> - <string name="message">Impossibile spedire il tuo messaggio nella sessione chat con [RECIPIENT].</string> - <string name="message_session_event">Impossibile inviare il messaggio nella chat con [RECIPIENT].</string> - <string name="mute">Errore durante la moderazione.</string> - <string name="removed">Sei stato rimosso dal gruppo.</string> - <string name="removed_from_group">Sei stato espulso dal gruppo.</string> - <string name="close_on_no_ability">Non hai più le abilitazioni per rimanere nella sessione chat.</string> - <string name="unread_chat_single">[SOURCES] ha detto qualcosa di nuovo</string> - <string name="unread_chat_multiple">[SOURCES] ha detto qualcosa di nuovo</string> - <string name="session_initialization_timed_out_error">Sessione di inizializzazione scaduta</string> - <string name="Home position set.">Posizione di base impostata.</string> - <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string> - <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string> - <string name="paid_you_ldollars">[NAME] ti ha inviato un pagamento di L$[AMOUNT] [REASON].</string> - <string name="paid_you_ldollars_gift">[NAME] ti ha inviato un pagamento di L$ [AMOUNT]: [REASON]</string> - <string name="paid_you_ldollars_no_reason">[NAME] ti ha inviato un pagamento di L$[AMOUNT].</string> - <string name="you_paid_ldollars">Hai inviato un pagamento di L$[AMOUNT] a [NAME] [REASON].</string> - <string name="you_paid_ldollars_gift">Hai inviato un pagamento di L$ [AMOUNT] a [NAME]: [REASON]</string> - <string name="you_paid_ldollars_no_info">Hai pagato L$ [AMOUNT].</string> - <string name="you_paid_ldollars_no_reason">Hai inviato un pagamento di L$[AMOUNT] a [NAME].</string> - <string name="you_paid_ldollars_no_name">Hai pagato L$ [AMOUNT] [REASON].</string> - <string name="you_paid_failure_ldollars">Non hai pagato [NAME] L$[AMOUNT] [REASON].</string> - <string name="you_paid_failure_ldollars_gift">Non hai inviato un pagamento di L$ [AMOUNT] a [NAME]: [REASON]</string> - <string name="you_paid_failure_ldollars_no_info">Non hai pagato L$ [AMOUNT].</string> - <string name="you_paid_failure_ldollars_no_reason">Non hai pagato [NAME] L$[AMOUNT].</string> - <string name="you_paid_failure_ldollars_no_name">Non hai pagato L$ [AMOUNT] [REASON].</string> - <string name="for item">per [ITEM]</string> - <string name="for a parcel of land">per un lotto di terreno</string> - <string name="for a land access pass">per un permesso di accesso al terreno</string> - <string name="for deeding land">per la cessione di terreno</string> - <string name="to create a group">per creare un gruppo</string> - <string name="to join a group">per aderire a un gruppo</string> - <string name="to upload">per caricare</string> - <string name="to publish a classified ad">per pubblicare un annuncio</string> - <string name="giving">Contributo di L$ [AMOUNT]</string> - <string name="uploading_costs">Il costo per il caricamento è di L$ [AMOUNT]</string> - <string name="this_costs">Il costo è L$ [AMOUNT]</string> - <string name="buying_selected_land">L'acquisto del terreno prescelto costa L$ [AMOUNT]</string> - <string name="this_object_costs">Il costo dell'oggetto è L$ [AMOUNT]</string> - <string name="group_role_everyone">Tutti</string> - <string name="group_role_officers">Funzionari</string> - <string name="group_role_owners">Proprietari</string> - <string name="group_member_status_online">Online</string> - <string name="uploading_abuse_report">Caricamento in corso... +Se il messaggio persiste, contatta [SUPPORT_SITE]. + </string> + <string name="5 O'Clock Shadow"> + Barba leggera + </string> + <string name="All White"> + Tutti bianchi + </string> + <string name="Anime Eyes"> + Occhi grandi + </string> + <string name="Arced"> + Arcuato + </string> + <string name="Arm Length"> + Lunghezza braccia + </string> + <string name="Attached"> + Attaccato + </string> + <string name="Attached Earlobes"> + Lobi attaccati + </string> + <string name="Back Fringe"> + Frangetta all'indietro + </string> + <string name="Baggy"> + Larghi + </string> + <string name="Bangs"> + Frange + </string> + <string name="Beady Eyes"> + Occhi piccoli + </string> + <string name="Belly Size"> + Punto vita + </string> + <string name="Big"> + Grande + </string> + <string name="Big Butt"> + Sedere grande + </string> + <string name="Big Hair Back"> + Capigliatura grande: Indietro + </string> + <string name="Big Hair Front"> + Capigliatura grande: anteriore + </string> + <string name="Big Hair Top"> + Capigliatura grande: in alto + </string> + <string name="Big Head"> + Grande testa + </string> + <string name="Big Pectorals"> + Grandi pettorali + </string> + <string name="Big Spikes"> + Capelli con punte + </string> + <string name="Black"> + Nero + </string> + <string name="Blonde"> + Biondo + </string> + <string name="Blonde Hair"> + Capelli biondi + </string> + <string name="Blush"> + Fard + </string> + <string name="Blush Color"> + Colore fard + </string> + <string name="Blush Opacity"> + Opacità fard + </string> + <string name="Body Definition"> + Definizione muscolare + </string> + <string name="Body Fat"> + Grasso corporeo + </string> + <string name="Body Freckles"> + Lentiggini e nei + </string> + <string name="Body Thick"> + Corpo più robusto + </string> + <string name="Body Thickness"> + Robustezza del corpo + </string> + <string name="Body Thin"> + Corpo più magro + </string> + <string name="Bow Legged"> + Gambe arcuate + </string> + <string name="Breast Buoyancy"> + Altezza del seno + </string> + <string name="Breast Cleavage"> + Décolleté + </string> + <string name="Breast Size"> + Grandezza del seno + </string> + <string name="Bridge Width"> + Larghezza setto + </string> + <string name="Broad"> + Largo + </string> + <string name="Brow Size"> + Grandezza delle sopracciglia + </string> + <string name="Bug Eyes"> + Occhi sporgenti + </string> + <string name="Bugged Eyes"> + Occhi sporgenti + </string> + <string name="Bulbous"> + Bulboso + </string> + <string name="Bulbous Nose"> + Naso bulboso + </string> + <string name="Breast Physics Mass"> + Massa seno + </string> + <string name="Breast Physics Smoothing"> + Lisciatura seno + </string> + <string name="Breast Physics Gravity"> + Gravità seno + </string> + <string name="Breast Physics Drag"> + Resistenza seno + </string> + <string name="Breast Physics InOut Max Effect"> + Massimo effetto + </string> + <string name="Breast Physics InOut Spring"> + Elasticità + </string> + <string name="Breast Physics InOut Gain"> + Guadagno + </string> + <string name="Breast Physics InOut Damping"> + Attenuazione + </string> + <string name="Breast Physics UpDown Max Effect"> + Massimo effetto + </string> + <string name="Breast Physics UpDown Spring"> + Elasticità + </string> + <string name="Breast Physics UpDown Gain"> + Guadagno + </string> + <string name="Breast Physics UpDown Damping"> + Attenuazione + </string> + <string name="Breast Physics LeftRight Max Effect"> + Massimo effetto + </string> + <string name="Breast Physics LeftRight Spring"> + Elasticità + </string> + <string name="Breast Physics LeftRight Gain"> + Guadagno + </string> + <string name="Breast Physics LeftRight Damping"> + Attenuazione + </string> + <string name="Belly Physics Mass"> + Massa pancia + </string> + <string name="Belly Physics Smoothing"> + Lisciatura pancia + </string> + <string name="Belly Physics Gravity"> + Gravità pancia + </string> + <string name="Belly Physics Drag"> + Resistenza pancia + </string> + <string name="Belly Physics UpDown Max Effect"> + Massimo effetto + </string> + <string name="Belly Physics UpDown Spring"> + Elasticità + </string> + <string name="Belly Physics UpDown Gain"> + Guadagno + </string> + <string name="Belly Physics UpDown Damping"> + Attenuazione + </string> + <string name="Butt Physics Mass"> + Massa natiche + </string> + <string name="Butt Physics Smoothing"> + Lisciatura natiche + </string> + <string name="Butt Physics Gravity"> + Gravità natiche + </string> + <string name="Butt Physics Drag"> + Resistenza natiche + </string> + <string name="Butt Physics UpDown Max Effect"> + Massimo effetto + </string> + <string name="Butt Physics UpDown Spring"> + Elasticità + </string> + <string name="Butt Physics UpDown Gain"> + Guadagno + </string> + <string name="Butt Physics UpDown Damping"> + Attenuazione + </string> + <string name="Butt Physics LeftRight Max Effect"> + Massimo effetto + </string> + <string name="Butt Physics LeftRight Spring"> + Elasticità + </string> + <string name="Butt Physics LeftRight Gain"> + Guadagno + </string> + <string name="Butt Physics LeftRight Damping"> + Attenuazione + </string> + <string name="Bushy Eyebrows"> + Sopracciglia cespugliose + </string> + <string name="Bushy Hair"> + Capelli a cespuglio + </string> + <string name="Butt Size"> + Grandezza del sedere + </string> + <string name="Butt Gravity"> + Gravità natiche + </string> + <string name="bustle skirt"> + Crinolina + </string> + <string name="no bustle"> + Nessuna crinolina + </string> + <string name="more bustle"> + Più crinolina + </string> + <string name="Chaplin"> + Baffetti + </string> + <string name="Cheek Bones"> + Zigomi + </string> + <string name="Chest Size"> + Ampiezza del torace + </string> + <string name="Chin Angle"> + Angolo del mento + </string> + <string name="Chin Cleft"> + Fossetta sul mento + </string> + <string name="Chin Curtains"> + Barba sottomento + </string> + <string name="Chin Depth"> + Profondità mento + </string> + <string name="Chin Heavy"> + Mento forte + </string> + <string name="Chin In"> + Mento in dentro + </string> + <string name="Chin Out"> + Mento sporgente + </string> + <string name="Chin-Neck"> + Mento-collo + </string> + <string name="Clear"> + Trasparente + </string> + <string name="Cleft"> + Fossetta + </string> + <string name="Close Set Eyes"> + Occhi ravvicinati + </string> + <string name="Closed"> + Chiusa + </string> + <string name="Closed Back"> + Chiuso dietro + </string> + <string name="Closed Front"> + Chiuso davanti + </string> + <string name="Closed Left"> + Chiuso sinistra + </string> + <string name="Closed Right"> + Chiuso destra + </string> + <string name="Coin Purse"> + Meno pronunciati + </string> + <string name="Collar Back"> + Colletto posteriore + </string> + <string name="Collar Front"> + Colletto anteriore + </string> + <string name="Corner Down"> + Angolo all'ingiù + </string> + <string name="Corner Up"> + Angolo all'insù + </string> + <string name="Creased"> + Piega + </string> + <string name="Crooked Nose"> + Naso storto + </string> + <string name="Cuff Flare"> + Svasato con risvolto + </string> + <string name="Dark"> + Scuro + </string> + <string name="Dark Green"> + Verde scuro + </string> + <string name="Darker"> + Più scuro + </string> + <string name="Deep"> + Profondo + </string> + <string name="Default Heels"> + Tacchi standard + </string> + <string name="Dense"> + Folti + </string> + <string name="Double Chin"> + Doppio mento + </string> + <string name="Downturned"> + All'ingiù + </string> + <string name="Duffle Bag"> + Più pronunciati + </string> + <string name="Ear Angle"> + Angolo orecchie + </string> + <string name="Ear Size"> + Grandezza orecchie + </string> + <string name="Ear Tips"> + Estremità orecchie + </string> + <string name="Egg Head"> + Ovalizzazione testa + </string> + <string name="Eye Bags"> + Occhiaie + </string> + <string name="Eye Color"> + Colore degli occhi + </string> + <string name="Eye Depth"> + Profondità degli occhi + </string> + <string name="Eye Lightness"> + Luminosità degli occhi + </string> + <string name="Eye Opening"> + Apertura degli occhi + </string> + <string name="Eye Pop"> + Prominenza degli occhi + </string> + <string name="Eye Size"> + Grandezza occhi + </string> + <string name="Eye Spacing"> + Distanza occhi + </string> + <string name="Eyebrow Arc"> + Arco delle sopracciglia + </string> + <string name="Eyebrow Density"> + Densità delle sopracciglia + </string> + <string name="Eyebrow Height"> + Altezza delle sopracciglia + </string> + <string name="Eyebrow Points"> + Sopracciglia appuntite + </string> + <string name="Eyebrow Size"> + Grandezza sopracciglia + </string> + <string name="Eyelash Length"> + Lunghezza delle ciglia + </string> + <string name="Eyeliner"> + Eyeliner + </string> + <string name="Eyeliner Color"> + Colore dell'eyeliner + </string> + <string name="Eyes Bugged"> + Occhi sporgenti + </string> + <string name="Face Shear"> + Taglio del viso + </string> + <string name="Facial Definition"> + Definizione del viso + </string> + <string name="Far Set Eyes"> + Occhi distanti + </string> + <string name="Fat Lips"> + Labbra carnose + </string> + <string name="Female"> + Femmina + </string> + <string name="Fingerless"> + Senza dita + </string> + <string name="Fingers"> + Dita + </string> + <string name="Flared Cuffs"> + Risvolti svasati + </string> + <string name="Flat"> + Piatto + </string> + <string name="Flat Butt"> + Sedere piatto + </string> + <string name="Flat Head"> + Testa piatta + </string> + <string name="Flat Toe"> + Punta piatta + </string> + <string name="Foot Size"> + Misura piede + </string> + <string name="Forehead Angle"> + Angolo della fronte + </string> + <string name="Forehead Heavy"> + Fronte sporgente + </string> + <string name="Freckles"> + Lentiggini + </string> + <string name="Front Fringe"> + Frangetta + </string> + <string name="Full Back"> + Dietro gonfi + </string> + <string name="Full Eyeliner"> + Eyeliner marcato + </string> + <string name="Full Front"> + Anteriore gonfio + </string> + <string name="Full Hair Sides"> + Lati capelli gonfi + </string> + <string name="Full Sides"> + Lati gonfi + </string> + <string name="Glossy"> + Lucido + </string> + <string name="Glove Fingers"> + Dita con guanti + </string> + <string name="Glove Length"> + Lunghezza guanti + </string> + <string name="Hair"> + Capigliature + </string> + <string name="Hair Back"> + Capelli: Indietro + </string> + <string name="Hair Front"> + Capelli: anteriore + </string> + <string name="Hair Sides"> + Capelli: lati + </string> + <string name="Hair Sweep"> + Direzione capigliatura + </string> + <string name="Hair Thickess"> + Foltezza + </string> + <string name="Hair Thickness"> + Foltezza + </string> + <string name="Hair Tilt"> + Inclinazione + </string> + <string name="Hair Tilted Left"> + Verso sinistra + </string> + <string name="Hair Tilted Right"> + Verso destra + </string> + <string name="Hair Volume"> + Capelli: Volume + </string> + <string name="Hand Size"> + Grandezza mani + </string> + <string name="Handlebars"> + Baffi a manubrio + </string> + <string name="Head Length"> + Lunghezza testa + </string> + <string name="Head Shape"> + Forma della testa + </string> + <string name="Head Size"> + Grandezza della testa + </string> + <string name="Head Stretch"> + Allungamento testa + </string> + <string name="Heel Height"> + Altezza tacchi + </string> + <string name="Heel Shape"> + Forma tacchi + </string> + <string name="Height"> + Altezza + </string> + <string name="High"> + Alto + </string> + <string name="High Heels"> + Tacchi alti + </string> + <string name="High Jaw"> + Mandibola alta + </string> + <string name="High Platforms"> + Alta + </string> + <string name="High and Tight"> + Alto e stretto + </string> + <string name="Higher"> + Più alto + </string> + <string name="Hip Length"> + Altezza bacino + </string> + <string name="Hip Width"> + Larghezza bacino + </string> + <string name="Hover"> + Muovi sopra + </string> + <string name="In"> + Dentro + </string> + <string name="In Shdw Color"> + Colore ombretto interno + </string> + <string name="In Shdw Opacity"> + Opacità ombretto interno + </string> + <string name="Inner Eye Corner"> + Angolo interno + </string> + <string name="Inner Eye Shadow"> + Ombretto interno + </string> + <string name="Inner Shadow"> + Ombretto interno + </string> + <string name="Jacket Length"> + Lunghezza giacca + </string> + <string name="Jacket Wrinkles"> + Grinze della giacca + </string> + <string name="Jaw Angle"> + Angolo mandibola + </string> + <string name="Jaw Jut"> + Prognatismo mento + </string> + <string name="Jaw Shape"> + Forma del mento + </string> + <string name="Join"> + Iscriviti + </string> + <string name="Jowls"> + Guance + </string> + <string name="Knee Angle"> + Angolo ginocchia + </string> + <string name="Knock Kneed"> + Gambe ad X + </string> + <string name="Large"> + Grande + </string> + <string name="Large Hands"> + Mani grandi + </string> + <string name="Left Part"> + Riga a sinistra + </string> + <string name="Leg Length"> + Lunghezza gambe + </string> + <string name="Leg Muscles"> + Muscoli gambe + </string> + <string name="Less"> + Meno + </string> + <string name="Less Body Fat"> + Meno grasso corporeo + </string> + <string name="Less Curtains"> + Meno + </string> + <string name="Less Freckles"> + Meno lentiggini + </string> + <string name="Less Full"> + Meno piene + </string> + <string name="Less Gravity"> + Più alto + </string> + <string name="Less Love"> + Meno maniglie + </string> + <string name="Less Muscles"> + Meno muscoli + </string> + <string name="Less Muscular"> + Meno muscolari + </string> + <string name="Less Rosy"> + Meno rosato + </string> + <string name="Less Round"> + Meno rotondo + </string> + <string name="Less Saddle"> + Meno a sella + </string> + <string name="Less Square"> + Meno quadrato + </string> + <string name="Less Volume"> + Meno volume + </string> + <string name="Less soul"> + Meno + </string> + <string name="Lighter"> + Più leggero + </string> + <string name="Lip Cleft"> + Distanza fossetta labbro + </string> + <string name="Lip Cleft Depth"> + Prof. fossetta labbro + </string> + <string name="Lip Fullness"> + Volume labbra + </string> + <string name="Lip Pinkness"> + Tonalità rosa labbra + </string> + <string name="Lip Ratio"> + Proporzione labbra + </string> + <string name="Lip Thickness"> + Carnosità labbra + </string> + <string name="Lip Width"> + Larghezza labbra + </string> + <string name="Lipgloss"> + Lipgloss + </string> + <string name="Lipstick"> + Rossetto + </string> + <string name="Lipstick Color"> + Colore rossetto + </string> + <string name="Long"> + Lungo + </string> + <string name="Long Head"> + Testa lunga + </string> + <string name="Long Hips"> + Bacino alto + </string> + <string name="Long Legs"> + Gambe lunghe + </string> + <string name="Long Neck"> + Collo lungo + </string> + <string name="Long Pigtails"> + Codini lunghi + </string> + <string name="Long Ponytail"> + Codino lungo + </string> + <string name="Long Torso"> + Torace lungo + </string> + <string name="Long arms"> + Braccia lunghe + </string> + <string name="Loose Pants"> + Pantaloni ampi + </string> + <string name="Loose Shirt"> + Camicia ampia + </string> + <string name="Loose Sleeves"> + Maniche non attillate + </string> + <string name="Love Handles"> + Maniglie dell'amore + </string> + <string name="Low"> + Basso + </string> + <string name="Low Heels"> + Tacchi bassi + </string> + <string name="Low Jaw"> + Mandibola bassa + </string> + <string name="Low Platforms"> + Bassa + </string> + <string name="Low and Loose"> + Basso e ampio + </string> + <string name="Lower"> + Più basso + </string> + <string name="Lower Bridge"> + Parte bassa del setto + </string> + <string name="Lower Cheeks"> + Guance inferiori + </string> + <string name="Male"> + Maschio + </string> + <string name="Middle Part"> + Riga nel mezzo + </string> + <string name="More"> + Altro + </string> + <string name="More Blush"> + Più fard + </string> + <string name="More Body Fat"> + Più grasso corporeo + </string> + <string name="More Curtains"> + Più + </string> + <string name="More Eyeshadow"> + Più ombretto + </string> + <string name="More Freckles"> + Più lentiggini + </string> + <string name="More Full"> + Più piene + </string> + <string name="More Gravity"> + Più calato + </string> + <string name="More Lipstick"> + Più rossetto + </string> + <string name="More Love"> + Più maniglie + </string> + <string name="More Lower Lip"> + Labbro inf. pronunciato + </string> + <string name="More Muscles"> + Più muscoli + </string> + <string name="More Muscular"> + Più muscolatura + </string> + <string name="More Rosy"> + Più rosato + </string> + <string name="More Round"> + Più rotondo + </string> + <string name="More Saddle"> + Più a sella + </string> + <string name="More Sloped"> + Più orizzontale + </string> + <string name="More Square"> + Più quadrato + </string> + <string name="More Upper Lip"> + Labbro sup. pronunciato + </string> + <string name="More Vertical"> + Più verticale + </string> + <string name="More Volume"> + Più volume + </string> + <string name="More soul"> + Più + </string> + <string name="Moustache"> + Baffi + </string> + <string name="Mouth Corner"> + Angolo della bocca + </string> + <string name="Mouth Position"> + Posizione della bocca + </string> + <string name="Mowhawk"> + Moicana + </string> + <string name="Muscular"> + Muscolatura + </string> + <string name="Mutton Chops"> + Basette lunghe + </string> + <string name="Nail Polish"> + Smalto + </string> + <string name="Nail Polish Color"> + Colore smalto + </string> + <string name="Narrow"> + Socchiusi + </string> + <string name="Narrow Back"> + Laterali post. vicini + </string> + <string name="Narrow Front"> + Laterali ant. vicini + </string> + <string name="Narrow Lips"> + Labbra strette + </string> + <string name="Natural"> + Naturale + </string> + <string name="Neck Length"> + Lunghezza del collo + </string> + <string name="Neck Thickness"> + Grandezza del collo + </string> + <string name="No Blush"> + Senza fard + </string> + <string name="No Eyeliner"> + Senza eyeliner + </string> + <string name="No Eyeshadow"> + Senza ombretto + </string> + <string name="No Lipgloss"> + Senza lipgloss + </string> + <string name="No Lipstick"> + Senza rossetto + </string> + <string name="No Part"> + Senza riga + </string> + <string name="No Polish"> + Senza smalto + </string> + <string name="No Red"> + Senza rosso + </string> + <string name="No Spikes"> + Senza punte + </string> + <string name="No White"> + Senza bianco + </string> + <string name="No Wrinkles"> + Senza pieghe + </string> + <string name="Normal Lower"> + Inferiore normale + </string> + <string name="Normal Upper"> + Superiore normale + </string> + <string name="Nose Left"> + Naso a sinistra + </string> + <string name="Nose Right"> + Naso a destra + </string> + <string name="Nose Size"> + Grandezza naso + </string> + <string name="Nose Thickness"> + Spessore naso + </string> + <string name="Nose Tip Angle"> + Angolo punta naso + </string> + <string name="Nose Tip Shape"> + Forma punta naso + </string> + <string name="Nose Width"> + Larghezza naso + </string> + <string name="Nostril Division"> + Divisione narici + </string> + <string name="Nostril Width"> + Larghezza narici + </string> + <string name="Opaque"> + Opaco + </string> + <string name="Open"> + Apri + </string> + <string name="Open Back"> + Retro aperto + </string> + <string name="Open Front"> + Davanti aperto + </string> + <string name="Open Left"> + Lato sin. aperto + </string> + <string name="Open Right"> + Lato des. aperto + </string> + <string name="Orange"> + Arancio + </string> + <string name="Out"> + Fuori + </string> + <string name="Out Shdw Color"> + Colore ombretto esterno + </string> + <string name="Out Shdw Opacity"> + Opacità ombretto esterno + </string> + <string name="Outer Eye Corner"> + Angolo esterno occhio + </string> + <string name="Outer Eye Shadow"> + Ombretto esterno + </string> + <string name="Outer Shadow"> + Ombreggiatura esterna + </string> + <string name="Overbite"> + Denti sup. in fuori + </string> + <string name="Package"> + Genitali + </string> + <string name="Painted Nails"> + Unghie smaltate + </string> + <string name="Pale"> + Pallido + </string> + <string name="Pants Crotch"> + Cavallo + </string> + <string name="Pants Fit"> + Vestibilità pantaloni + </string> + <string name="Pants Length"> + Lunghezza pantaloni + </string> + <string name="Pants Waist"> + Taglia pantalone + </string> + <string name="Pants Wrinkles"> + Pantaloni con le grinze + </string> + <string name="Part"> + Con riga + </string> + <string name="Part Bangs"> + Frangetta divisa + </string> + <string name="Pectorals"> + Pettorali + </string> + <string name="Pigment"> + Pigmento + </string> + <string name="Pigtails"> + Codini + </string> + <string name="Pink"> + Rosa + </string> + <string name="Pinker"> + Più rosato + </string> + <string name="Platform Height"> + Altezza pianta + </string> + <string name="Platform Width"> + Larghezza pianta + </string> + <string name="Pointy"> + Appuntito + </string> + <string name="Pointy Heels"> + Tacchi a spillo + </string> + <string name="Ponytail"> + Codino + </string> + <string name="Poofy Skirt"> + Gonna gonfia + </string> + <string name="Pop Left Eye"> + Sinistro più aperto + </string> + <string name="Pop Right Eye"> + Destro più aperto + </string> + <string name="Puffy"> + Paffute + </string> + <string name="Puffy Eyelids"> + Palpebre gonfie + </string> + <string name="Rainbow Color"> + Tonalità + </string> + <string name="Red Hair"> + Presenza di rosso nei capelli + </string> + <string name="Regular"> + Normale + </string> + <string name="Right Part"> + Riga a destra + </string> + <string name="Rosy Complexion"> + Incarnato + </string> + <string name="Round"> + Rotondo + </string> + <string name="Ruddiness"> + Rossore + </string> + <string name="Ruddy"> + Rosse + </string> + <string name="Rumpled Hair"> + Capelli mossi + </string> + <string name="Saddle Bags"> + Rotondità fianchi + </string> + <string name="Scrawny Leg"> + Gambe magre + </string> + <string name="Separate"> + Separati + </string> + <string name="Shallow"> + Meno pronunciato + </string> + <string name="Shear Back"> + Taglio posteriore + </string> + <string name="Shear Face"> + Taglio del viso + </string> + <string name="Shear Front"> + Taglio anteriore + </string> + <string name="Shear Left Up"> + Distorto a sinistra + </string> + <string name="Shear Right Up"> + Distorto a destra + </string> + <string name="Sheared Back"> + Taglio verso dietro + </string> + <string name="Sheared Front"> + Taglio verso davanti + </string> + <string name="Shift Left"> + A sinistra + </string> + <string name="Shift Mouth"> + Spostamento bocca + </string> + <string name="Shift Right"> + A destra + </string> + <string name="Shirt Bottom"> + Parte inferiore camicia + </string> + <string name="Shirt Fit"> + Vestibilità camicia + </string> + <string name="Shirt Wrinkles"> + Camicia con le grinze + </string> + <string name="Shoe Height"> + Altezza scarpe + </string> + <string name="Short"> + Basso + </string> + <string name="Short Arms"> + Braccia corte + </string> + <string name="Short Legs"> + Gambe corte + </string> + <string name="Short Neck"> + Collo corto + </string> + <string name="Short Pigtails"> + Codini corti + </string> + <string name="Short Ponytail"> + Codino corto + </string> + <string name="Short Sideburns"> + Basette corte + </string> + <string name="Short Torso"> + Torace corto + </string> + <string name="Short hips"> + Bacino corto + </string> + <string name="Shoulders"> + Spalle + </string> + <string name="Side Fringe"> + Ciuffi laterali + </string> + <string name="Sideburns"> + Basette + </string> + <string name="Sides Hair"> + Capigliatura di lato + </string> + <string name="Sides Hair Down"> + Capigliatura di lato sciolta + </string> + <string name="Sides Hair Up"> + Capigliatura di lato raccolta + </string> + <string name="Skinny Neck"> + Collo fino + </string> + <string name="Skirt Fit"> + Vestibilità gonna + </string> + <string name="Skirt Length"> + Lunghezza gonna + </string> + <string name="Slanted Forehead"> + Fronte inclinata + </string> + <string name="Sleeve Length"> + Lunghezza maniche + </string> + <string name="Sleeve Looseness"> + Morbidezza maniche + </string> + <string name="Slit Back"> + Spacco: Indietro + </string> + <string name="Slit Front"> + Spacco: anteriore + </string> + <string name="Slit Left"> + Spacco: Sinistra + </string> + <string name="Slit Right"> + Spacco: Destra + </string> + <string name="Small"> + Piccola + </string> + <string name="Small Hands"> + Mani piccole + </string> + <string name="Small Head"> + Testa piccola + </string> + <string name="Smooth"> + Liscio + </string> + <string name="Smooth Hair"> + Capelli lisci + </string> + <string name="Socks Length"> + Lunghezza calze + </string> + <string name="Soulpatch"> + Pizzetto labbro inferiore + </string> + <string name="Sparse"> + Piu rade + </string> + <string name="Spiked Hair"> + Capelli a punta + </string> + <string name="Square"> + Quadrato + </string> + <string name="Square Toe"> + Punta quadrata + </string> + <string name="Squash Head"> + Testa schiacciata + </string> + <string name="Stretch Head"> + Testa allungata + </string> + <string name="Sunken"> + Scarne + </string> + <string name="Sunken Chest"> + Senza pettorali + </string> + <string name="Sunken Eyes"> + Occhi infossati + </string> + <string name="Sweep Back"> + Indietro + </string> + <string name="Sweep Forward"> + Avanti + </string> + <string name="Tall"> + Alto + </string> + <string name="Taper Back"> + Ravv. lat. posteriore + </string> + <string name="Taper Front"> + Ravv. lat. frontale + </string> + <string name="Thick Heels"> + Tacchi spessi + </string> + <string name="Thick Neck"> + Collo grosso + </string> + <string name="Thick Toe"> + Punta spessa + </string> + <string name="Thin"> + Sottili + </string> + <string name="Thin Eyebrows"> + Sopracciglia sottili + </string> + <string name="Thin Lips"> + Labbra sottili + </string> + <string name="Thin Nose"> + Naso sottile + </string> + <string name="Tight Chin"> + Mento stretto + </string> + <string name="Tight Cuffs"> + Fondo stretto + </string> + <string name="Tight Pants"> + Pantaloni attillati + </string> + <string name="Tight Shirt"> + Camicia attillata + </string> + <string name="Tight Skirt"> + Gonna attillata + </string> + <string name="Tight Sleeves"> + Maniche strette + </string> + <string name="Toe Shape"> + Forma della punta + </string> + <string name="Toe Thickness"> + Spessore della punta + </string> + <string name="Torso Length"> + Lunghezza del torace + </string> + <string name="Torso Muscles"> + Muscoli del torace + </string> + <string name="Torso Scrawny"> + Torso Scrawny + </string> + <string name="Unattached"> + Distaccato + </string> + <string name="Uncreased"> + Senza piega + </string> + <string name="Underbite"> + Denti inf. in fuori + </string> + <string name="Unnatural"> + Innaturale + </string> + <string name="Upper Bridge"> + Parte alta del setto + </string> + <string name="Upper Cheeks"> + Parte alta degli zigomi + </string> + <string name="Upper Chin Cleft"> + Fossetta sup. del mento + </string> + <string name="Upper Eyelid Fold"> + Piega palpebra sup. + </string> + <string name="Upturned"> + All'insù + </string> + <string name="Very Red"> + Molto rossi + </string> + <string name="Waist Height"> + Vita alta + </string> + <string name="Well-Fed"> + Pienotte + </string> + <string name="White Hair"> + Capelli bianchi + </string> + <string name="Wide"> + Largo + </string> + <string name="Wide Back"> + Dietro largo + </string> + <string name="Wide Front"> + Davanti largo + </string> + <string name="Wide Lips"> + Labbra larghe + </string> + <string name="Wild"> + Colorati + </string> + <string name="Wrinkles"> + Grinze + </string> + <string name="LocationCtrlAddLandmarkTooltip"> + Aggiungi ai miei punti di riferimento + </string> + <string name="LocationCtrlEditLandmarkTooltip"> + Modifica i miei punti di riferimento + </string> + <string name="LocationCtrlInfoBtnTooltip"> + Maggiori informazioni sulla posizione attuale + </string> + <string name="LocationCtrlComboBtnTooltip"> + La cronologia delle mie posizioni + </string> + <string name="LocationCtrlAdultIconTooltip"> + Regione con categoria adulti + </string> + <string name="LocationCtrlModerateIconTooltip"> + Regione con categoria moderata + </string> + <string name="LocationCtrlGeneralIconTooltip"> + Regione generale + </string> + <string name="LocationCtrlSeeAVsTooltip"> + Gli avatar in questo lotto non possono essere visti o sentiti da avatar all'esterno del lotto + </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Gli oggetti che si muovono potrebbero non comportarsi correttamente in questa regione fino a quando non viene eseguito il rebake della regione. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + Il pathfinding dinamico non è attivato in questa regione. + </string> + <string name="UpdaterWindowTitle"> + Aggiornamento [APP_NAME] + </string> + <string name="UpdaterNowUpdating"> + Aggiornamento di [APP_NAME]... + </string> + <string name="UpdaterNowInstalling"> + Installazione di [APP_NAME]... + </string> + <string name="UpdaterUpdatingDescriptive"> + Il Viewer del programma [APP_NAME] si sta aggiornando all'ultima versione. Potrebbe volerci del tempo, attendi. + </string> + <string name="UpdaterProgressBarTextWithEllipses"> + Download dell'aggiornamento... + </string> + <string name="UpdaterProgressBarText"> + Download dell'aggiornamento + </string> + <string name="UpdaterFailDownloadTitle"> + Download dell'aggiornamento non riuscito + </string> + <string name="UpdaterFailUpdateDescriptive"> + Il programma [APP_NAME] ha riscontrato un'errore durante il tentativo di aggiornamento. Consigliamo di scaricare l'ultima versione direttamente da www.secondlife.com. + </string> + <string name="UpdaterFailInstallTitle"> + Installazione dell'aggiornamento non riuscita + </string> + <string name="UpdaterFailStartTitle"> + Errore nell'avvio del viewer + </string> + <string name="ItemsComingInTooFastFrom"> + [APP_NAME]: Oggetti in arrivo troppo velocemente da [FROM_NAME], anteprima automatica disattivata per [TIME] secondi + </string> + <string name="ItemsComingInTooFast"> + [APP_NAME]: Oggetti in arrivo troppo velocemente, anteprima automatica disattivata per [TIME] secondi + </string> + <string name="IM_logging_string"> + -- Registrazione messaggi instantanei abilitata -- + </string> + <string name="IM_typing_start_string"> + [NAME] sta scrivendo... + </string> + <string name="Unnamed"> + (anonimo) + </string> + <string name="IM_moderated_chat_label"> + (Moderato: Voci disattivate di default) + </string> + <string name="IM_unavailable_text_label"> + La chat di testo non è disponibile per questa chiamata. + </string> + <string name="IM_muted_text_label"> + La chat di testo è stata disabilitata da un moderatore di gruppo. + </string> + <string name="IM_default_text_label"> + Clicca qui per inviare un messaggio instantaneo. + </string> + <string name="IM_to_label"> + A + </string> + <string name="IM_moderator_label"> + (Moderatore) + </string> + <string name="Saved_message"> + (Salvato [LONG_TIMESTAMP]) + </string> + <string name="IM_unblock_only_groups_friends"> + Per vedere questo messaggio, devi deselezionare 'Solo amici e gruppi possono chiamarmi o mandarmi IM' in Preferenze/Privacy. + </string> + <string name="OnlineStatus"> + Online + </string> + <string name="OfflineStatus"> + Offline + </string> + <string name="not_online_msg"> + Utente non online - il messaggio verrà memorizzato e inviato più tardi. + </string> + <string name="not_online_inventory"> + Utente non online - l'inventario è stato salvato + </string> + <string name="answered_call"> + Risposto alla chiamata + </string> + <string name="you_started_call"> + Hai iniziato una chiamata vocale + </string> + <string name="you_joined_call"> + Ti sei collegato alla chiamata in voce + </string> + <string name="you_auto_rejected_call-im"> + Hai rifiutato automaticamente la chiamata voce mentre era attivata la modalità 'Non disturbare'. + </string> + <string name="name_started_call"> + [NAME] ha iniziato una chiamata vocale + </string> + <string name="ringing-im"> + Collegamento alla chiamata vocale... + </string> + <string name="connected-im"> + Collegato, clicca Chiudi chiamata per agganciare + </string> + <string name="hang_up-im"> + Chiusa la chiamata + </string> + <string name="conference-title"> + Chat con più persone + </string> + <string name="conference-title-incoming"> + Chiamata in conferenza con [AGENT_NAME] + </string> + <string name="inventory_item_offered-im"> + Offerto oggetto di inventario "[ITEM_NAME]" + </string> + <string name="inventory_folder_offered-im"> + Offerta cartella di inventario "[ITEM_NAME]" + </string> + <string name="bot_warning"> + Stai parlando con un bot, [NAME]. Non condividere informazioni personali. +Scopri di più su https://second.life/scripted-agents. + </string> + <string name="facebook_post_success"> + Hai pubblicato su Facebook. + </string> + <string name="flickr_post_success"> + Hai pubblicato su Flickr. + </string> + <string name="twitter_post_success"> + Hai pubblicato su Twitter. + </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> + <string name="offline_message"> + [NAME] è offline + </string> + <string name="invite_message"> + Clicca il tasto [BUTTON NAME] per accettare/connetterti a questa voice chat. + </string> + <string name="muted_message"> + Hai bloccato questo residente. Quando gli invii un messaggio, verrà automaticamente sbloccato. + </string> + <string name="generic"> + Errore nella richiesta, riprova più tardi. + </string> + <string name="generic_request_error"> + Errore durante la richiesta, riprova più tardi. + </string> + <string name="insufficient_perms_error"> + Non hai sufficienti permessi. + </string> + <string name="session_does_not_exist_error"> + Questa sessione non esiste più + </string> + <string name="no_ability_error"> + Non hai questa abilitazione. + </string> + <string name="no_ability"> + Non hai questa abilitazione. + </string> + <string name="not_a_mod_error"> + Non sei un moderatore. + </string> + <string name="muted"> + Il moderatore del gruppo ha disattivato la tua chat di testo. + </string> + <string name="muted_error"> + Un moderatore di gruppo ti ha disabilitato dalla chat di testo. + </string> + <string name="add_session_event"> + Impossibile aggiungere utenti alla chat con [RECIPIENT]. + </string> + <string name="message"> + Impossibile spedire il tuo messaggio nella sessione chat con [RECIPIENT]. + </string> + <string name="message_session_event"> + Impossibile inviare il messaggio nella chat con [RECIPIENT]. + </string> + <string name="mute"> + Errore durante la moderazione. + </string> + <string name="removed"> + Sei stato rimosso dal gruppo. + </string> + <string name="removed_from_group"> + Sei stato espulso dal gruppo. + </string> + <string name="close_on_no_ability"> + Non hai più le abilitazioni per rimanere nella sessione chat. + </string> + <string name="unread_chat_single"> + [SOURCES] ha detto qualcosa di nuovo + </string> + <string name="unread_chat_multiple"> + [SOURCES] ha detto qualcosa di nuovo + </string> + <string name="session_initialization_timed_out_error"> + Sessione di inizializzazione scaduta + </string> + <string name="Home position set."> + Posizione di base impostata. + </string> + <string name="voice_morphing_url"> + https://secondlife.com/destination/voice-island + </string> + <string name="premium_voice_morphing_url"> + https://secondlife.com/destination/voice-morphing-premium + </string> + <string name="paid_you_ldollars"> + [NAME] ti ha inviato un pagamento di L$[AMOUNT] [REASON]. + </string> + <string name="paid_you_ldollars_gift"> + [NAME] ti ha inviato un pagamento di L$ [AMOUNT]: [REASON] + </string> + <string name="paid_you_ldollars_no_reason"> + [NAME] ti ha inviato un pagamento di L$[AMOUNT]. + </string> + <string name="you_paid_ldollars"> + Hai inviato un pagamento di L$[AMOUNT] a [NAME] [REASON]. + </string> + <string name="you_paid_ldollars_gift"> + Hai inviato un pagamento di L$ [AMOUNT] a [NAME]: [REASON] + </string> + <string name="you_paid_ldollars_no_info"> + Hai pagato L$ [AMOUNT]. + </string> + <string name="you_paid_ldollars_no_reason"> + Hai inviato un pagamento di L$[AMOUNT] a [NAME]. + </string> + <string name="you_paid_ldollars_no_name"> + Hai pagato L$ [AMOUNT] [REASON]. + </string> + <string name="you_paid_failure_ldollars"> + Non hai pagato [NAME] L$[AMOUNT] [REASON]. + </string> + <string name="you_paid_failure_ldollars_gift"> + Non hai inviato un pagamento di L$ [AMOUNT] a [NAME]: [REASON] + </string> + <string name="you_paid_failure_ldollars_no_info"> + Non hai pagato L$ [AMOUNT]. + </string> + <string name="you_paid_failure_ldollars_no_reason"> + Non hai pagato [NAME] L$[AMOUNT]. + </string> + <string name="you_paid_failure_ldollars_no_name"> + Non hai pagato L$ [AMOUNT] [REASON]. + </string> + <string name="for item"> + per [ITEM] + </string> + <string name="for a parcel of land"> + per un lotto di terreno + </string> + <string name="for a land access pass"> + per un permesso di accesso al terreno + </string> + <string name="for deeding land"> + per la cessione di terreno + </string> + <string name="to create a group"> + per creare un gruppo + </string> + <string name="to join a group"> + per aderire a un gruppo + </string> + <string name="to upload"> + per caricare + </string> + <string name="to publish a classified ad"> + per pubblicare un annuncio + </string> + <string name="giving"> + Contributo di L$ [AMOUNT] + </string> + <string name="uploading_costs"> + Il costo per il caricamento è di L$ [AMOUNT] + </string> + <string name="this_costs"> + Il costo è L$ [AMOUNT] + </string> + <string name="buying_selected_land"> + L'acquisto del terreno prescelto costa L$ [AMOUNT] + </string> + <string name="this_object_costs"> + Il costo dell'oggetto è L$ [AMOUNT] + </string> + <string name="group_role_everyone"> + Tutti + </string> + <string name="group_role_officers"> + Funzionari + </string> + <string name="group_role_owners"> + Proprietari + </string> + <string name="group_member_status_online"> + Online + </string> + <string name="uploading_abuse_report"> + Caricamento in corso... -Segnala abuso</string> - <string name="New Shape">Nuova figura corporea</string> - <string name="New Skin">Nuova pelle</string> - <string name="New Hair">Nuovi capelli</string> - <string name="New Eyes">Nuovi occhi</string> - <string name="New Shirt">Nuova camicia</string> - <string name="New Pants">Nuovi pantaloni</string> - <string name="New Shoes">Nuove scarpe</string> - <string name="New Socks">Nuove calze</string> - <string name="New Jacket">Nuova giacca</string> - <string name="New Gloves">Nuovi guanti</string> - <string name="New Undershirt">Nuova maglietta intima</string> - <string name="New Underpants">Nuovi slip</string> - <string name="New Skirt">Nuova gonna</string> - <string name="New Alpha">Nuovo Alpha (trasparenza)</string> - <string name="New Tattoo">Nuovo tatuaggio</string> - <string name="New Universal">Nuovo Universale</string> - <string name="New Physics">Nuova fisica</string> - <string name="Invalid Wearable">Capo da indossare non valido</string> - <string name="New Gesture">Nuova gesture</string> - <string name="New Script">Nuovo script</string> - <string name="New Note">Nuovo appunto</string> - <string name="New Folder">Nuova cartella</string> - <string name="Contents">Contenuto</string> - <string name="Gesture">Gesture</string> - <string name="Male Gestures">Gesture maschili</string> - <string name="Female Gestures">Gesture femminili</string> - <string name="Other Gestures">Altre gesture</string> - <string name="Speech Gestures">Gesture del parlato</string> - <string name="Common Gestures">Gesture comuni</string> - <string name="Male - Excuse me">Maschio - Chiedere scusa</string> - <string name="Male - Get lost">Maschio - Levati dai piedi!</string> - <string name="Male - Blow kiss">Maschio - Butta un bacio</string> - <string name="Male - Boo">Maschio - Bu</string> - <string name="Male - Bored">Maschio - Annoiato</string> - <string name="Male - Hey">Maschio - Ehi</string> - <string name="Male - Laugh">Maschio - Ridere</string> - <string name="Male - Repulsed">Maschio - Disgustato</string> - <string name="Male - Shrug">Maschio - Spallucce</string> - <string name="Male - Stick tougue out">Maschio - Tira fuori la lingua</string> - <string name="Male - Wow">Maschio - Accipicchia</string> - <string name="Female - Chuckle">Femmina - Risatina</string> - <string name="Female - Cry">Femmina - Pianto</string> - <string name="Female - Embarrassed">Femmina - Imbarazzata</string> - <string name="Female - Excuse me">Femmina - Chiedere scusa</string> - <string name="Female - Get lost">Femmina - Levati dai piedi!</string> - <string name="Female - Blow kiss">Femmina - Butta un bacio</string> - <string name="Female - Boo">Femmina - Bu</string> - <string name="Female - Bored">Femmina - Annoiata</string> - <string name="Female - Hey">Femmina - Ehi</string> - <string name="Female - Hey baby">Femmina - Ehi tu</string> - <string name="Female - Laugh">Femmina - Ridere</string> - <string name="Female - Looking good">Femmina - Sei in forma</string> - <string name="Female - Over here">Femmina - Per di qua</string> - <string name="Female - Please">Femmina - Per cortesia</string> - <string name="Female - Repulsed">Femmina - Disgustata</string> - <string name="Female - Shrug">Femmina - Spallucce</string> - <string name="Female - Stick tougue out">Femmina - Tira fuori la lingua</string> - <string name="Female - Wow">Femmina - Accipicchia</string> - <string name="New Daycycle">Nuovo ciclo giornata</string> - <string name="New Water">Nuova acqua</string> - <string name="New Sky">Nuovo cielo</string> - <string name="/bow">/inchino</string> - <string name="/clap">/applausi</string> - <string name="/count">/numero</string> - <string name="/extinguish">/estingui</string> - <string name="/kmb">/chissene</string> - <string name="/muscle">/muscolo</string> - <string name="/no">/no</string> - <string name="/no!">/no!</string> - <string name="/paper">/carta</string> - <string name="/pointme">/indicome</string> - <string name="/pointyou">/indicotu</string> - <string name="/rock">/sasso</string> - <string name="/scissor">/forbici</string> - <string name="/smoke">/fumo</string> - <string name="/stretch">/stiracchiata</string> - <string name="/whistle">/fischietto</string> - <string name="/yes">/si</string> - <string name="/yes!">/si!</string> - <string name="afk">non alla tastiera</string> - <string name="dance1">danza1</string> - <string name="dance2">danza2</string> - <string name="dance3">danza3</string> - <string name="dance4">danza4</string> - <string name="dance5">danza5</string> - <string name="dance6">danza6</string> - <string name="dance7">danza7</string> - <string name="dance8">danza8</string> - <string name="AvatarBirthDateFormat">[day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt]</string> - <string name="DefaultMimeType">nessuna/nessuna</string> - <string name="texture_load_dimensions_error">Impossibile caricare immagini di dimensioni superiori a [WIDTH]*[HEIGHT]</string> - <string name="outfit_photo_load_dimensions_error">Le dimensioni massime delle foto di vestiario sono [WIDTH]*[HEIGHT]. Ridimensiona l'immagine o usane un'altra</string> - <string name="outfit_photo_select_dimensions_error">Le dimensioni massime delle foto di vestiario sono [WIDTH]*[HEIGHT]. Seleziona un'altra texture</string> - <string name="outfit_photo_verify_dimensions_error">Impossibile verificare le dimensioni della foto. Attendi che le dimensioni siano visualizzate nel selettore.</string> +Segnala abuso + </string> + <string name="New Shape"> + Nuova figura corporea + </string> + <string name="New Skin"> + Nuova pelle + </string> + <string name="New Hair"> + Nuovi capelli + </string> + <string name="New Eyes"> + Nuovi occhi + </string> + <string name="New Shirt"> + Nuova camicia + </string> + <string name="New Pants"> + Nuovi pantaloni + </string> + <string name="New Shoes"> + Nuove scarpe + </string> + <string name="New Socks"> + Nuove calze + </string> + <string name="New Jacket"> + Nuova giacca + </string> + <string name="New Gloves"> + Nuovi guanti + </string> + <string name="New Undershirt"> + Nuova maglietta intima + </string> + <string name="New Underpants"> + Nuovi slip + </string> + <string name="New Skirt"> + Nuova gonna + </string> + <string name="New Alpha"> + Nuovo Alpha (trasparenza) + </string> + <string name="New Tattoo"> + Nuovo tatuaggio + </string> + <string name="New Universal"> + Nuovo Universale + </string> + <string name="New Physics"> + Nuova fisica + </string> + <string name="Invalid Wearable"> + Capo da indossare non valido + </string> + <string name="New Gesture"> + Nuova gesture + </string> + <string name="New Script"> + Nuovo script + </string> + <string name="New Note"> + Nuovo appunto + </string> + <string name="New Folder"> + Nuova cartella + </string> + <string name="Contents"> + Contenuto + </string> + <string name="Gesture"> + Gesture + </string> + <string name="Male Gestures"> + Gesture maschili + </string> + <string name="Female Gestures"> + Gesture femminili + </string> + <string name="Other Gestures"> + Altre gesture + </string> + <string name="Speech Gestures"> + Gesture del parlato + </string> + <string name="Common Gestures"> + Gesture comuni + </string> + <string name="Male - Excuse me"> + Maschio - Chiedere scusa + </string> + <string name="Male - Get lost"> + Maschio - Levati dai piedi! + </string> + <string name="Male - Blow kiss"> + Maschio - Butta un bacio + </string> + <string name="Male - Boo"> + Maschio - Bu + </string> + <string name="Male - Bored"> + Maschio - Annoiato + </string> + <string name="Male - Hey"> + Maschio - Ehi + </string> + <string name="Male - Laugh"> + Maschio - Ridere + </string> + <string name="Male - Repulsed"> + Maschio - Disgustato + </string> + <string name="Male - Shrug"> + Maschio - Spallucce + </string> + <string name="Male - Stick tougue out"> + Maschio - Tira fuori la lingua + </string> + <string name="Male - Wow"> + Maschio - Accipicchia + </string> + <string name="Female - Chuckle"> + Femmina - Risatina + </string> + <string name="Female - Cry"> + Femmina - Pianto + </string> + <string name="Female - Embarrassed"> + Femmina - Imbarazzata + </string> + <string name="Female - Excuse me"> + Femmina - Chiedere scusa + </string> + <string name="Female - Get lost"> + Femmina - Levati dai piedi! + </string> + <string name="Female - Blow kiss"> + Femmina - Butta un bacio + </string> + <string name="Female - Boo"> + Femmina - Bu + </string> + <string name="Female - Bored"> + Femmina - Annoiata + </string> + <string name="Female - Hey"> + Femmina - Ehi + </string> + <string name="Female - Hey baby"> + Femmina - Ehi tu + </string> + <string name="Female - Laugh"> + Femmina - Ridere + </string> + <string name="Female - Looking good"> + Femmina - Sei in forma + </string> + <string name="Female - Over here"> + Femmina - Per di qua + </string> + <string name="Female - Please"> + Femmina - Per cortesia + </string> + <string name="Female - Repulsed"> + Femmina - Disgustata + </string> + <string name="Female - Shrug"> + Femmina - Spallucce + </string> + <string name="Female - Stick tougue out"> + Femmina - Tira fuori la lingua + </string> + <string name="Female - Wow"> + Femmina - Accipicchia + </string> + <string name="New Daycycle"> + Nuovo ciclo giornata + </string> + <string name="New Water"> + Nuova acqua + </string> + <string name="New Sky"> + Nuovo cielo + </string> + <string name="/bow"> + /inchino + </string> + <string name="/clap"> + /applausi + </string> + <string name="/count"> + /numero + </string> + <string name="/extinguish"> + /estingui + </string> + <string name="/kmb"> + /chissene + </string> + <string name="/muscle"> + /muscolo + </string> + <string name="/no"> + /no + </string> + <string name="/no!"> + /no! + </string> + <string name="/paper"> + /carta + </string> + <string name="/pointme"> + /indicome + </string> + <string name="/pointyou"> + /indicotu + </string> + <string name="/rock"> + /sasso + </string> + <string name="/scissor"> + /forbici + </string> + <string name="/smoke"> + /fumo + </string> + <string name="/stretch"> + /stiracchiata + </string> + <string name="/whistle"> + /fischietto + </string> + <string name="/yes"> + /si + </string> + <string name="/yes!"> + /si! + </string> + <string name="afk"> + non alla tastiera + </string> + <string name="dance1"> + danza1 + </string> + <string name="dance2"> + danza2 + </string> + <string name="dance3"> + danza3 + </string> + <string name="dance4"> + danza4 + </string> + <string name="dance5"> + danza5 + </string> + <string name="dance6"> + danza6 + </string> + <string name="dance7"> + danza7 + </string> + <string name="dance8"> + danza8 + </string> + <string name="AvatarBirthDateFormat"> + [day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt] + </string> + <string name="DefaultMimeType"> + nessuna/nessuna + </string> + <string name="texture_load_dimensions_error"> + Impossibile caricare immagini di dimensioni superiori a [WIDTH]*[HEIGHT] + </string> + <string name="outfit_photo_load_dimensions_error"> + Le dimensioni massime delle foto di vestiario sono [WIDTH]*[HEIGHT]. Ridimensiona l'immagine o usane un'altra + </string> + <string name="outfit_photo_select_dimensions_error"> + Le dimensioni massime delle foto di vestiario sono [WIDTH]*[HEIGHT]. Seleziona un'altra texture + </string> + <string name="outfit_photo_verify_dimensions_error"> + Impossibile verificare le dimensioni della foto. Attendi che le dimensioni siano visualizzate nel selettore. + </string> <string name="words_separator" value=","/> - <string name="server_is_down">Nonostante i nostri tentativi, si è verificato un errore imprevisto. + <string name="server_is_down"> + Nonostante i nostri tentativi, si è verificato un errore imprevisto. Consulta la pagina http://status.secondlifegrid.net per determinare se il problema del servizio è già stato riscontrato. - Se il problema continua, ti consigliamo di controllare le tue impostazioni di rete e del firewall.</string> - <string name="dateTimeWeekdaysNames">lunedì:martedì:mercoledì:giovedì:venerdì:sabato:domenica</string> - <string name="dateTimeWeekdaysShortNames">lun:mar:mer:gio:ven:sab:dom</string> - <string name="dateTimeMonthNames">gennaio:febbraio:marzo:aprile:maggio:giugno:luglio:agosto:settembre:ottobre:novembre:dicembre</string> - <string name="dateTimeMonthShortNames">gen:feb:mar:apr:mag:giu:lug:ago:sett:ott:nov:dic</string> - <string name="dateTimeDayFormat">[MDAY]</string> - <string name="dateTimeAM">antemeridiane</string> - <string name="dateTimePM">pomeridiane</string> - <string name="LocalEstimateUSD">US$ [AMOUNT]</string> - <string name="Group Ban">Espulsione di gruppo</string> - <string name="Membership">Abbonamento</string> - <string name="Roles">Ruoli</string> - <string name="Group Identity">Identità gruppo</string> - <string name="Parcel Management">Gestione lotto</string> - <string name="Parcel Identity">Identità lotto</string> - <string name="Parcel Settings">Impostazioni lotto</string> - <string name="Parcel Powers">Poteri lotto</string> - <string name="Parcel Access">Accesso al lotto</string> - <string name="Parcel Content">Contenuto lotto</string> - <string name="Object Management">Gestione oggetti</string> - <string name="Accounting">Contabilità</string> - <string name="Notices">Avvisi</string> - <string name="Chat" value="Chat :">Chat</string> - <string name="BaseMembership">Base</string> - <string name="PremiumMembership">Premium</string> - <string name="Premium_PlusMembership">Premium Plus</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> - <string name="ExternalEditorNotSet">Seleziona un editor usando le impostazioni ExternalEditor.</string> - <string name="ExternalEditorNotFound">L'editor esterno specificato non è stato trovato. + Se il problema continua, ti consigliamo di controllare le tue impostazioni di rete e del firewall. + </string> + <string name="dateTimeWeekdaysNames"> + lunedì:martedì:mercoledì:giovedì:venerdì:sabato:domenica + </string> + <string name="dateTimeWeekdaysShortNames"> + lun:mar:mer:gio:ven:sab:dom + </string> + <string name="dateTimeMonthNames"> + gennaio:febbraio:marzo:aprile:maggio:giugno:luglio:agosto:settembre:ottobre:novembre:dicembre + </string> + <string name="dateTimeMonthShortNames"> + gen:feb:mar:apr:mag:giu:lug:ago:sett:ott:nov:dic + </string> + <string name="dateTimeDayFormat"> + [MDAY] + </string> + <string name="dateTimeAM"> + antemeridiane + </string> + <string name="dateTimePM"> + pomeridiane + </string> + <string name="LocalEstimateUSD"> + US$ [AMOUNT] + </string> + <string name="Group Ban"> + Espulsione di gruppo + </string> + <string name="Membership"> + Abbonamento + </string> + <string name="Roles"> + Ruoli + </string> + <string name="Group Identity"> + Identità gruppo + </string> + <string name="Parcel Management"> + Gestione lotto + </string> + <string name="Parcel Identity"> + Identità lotto + </string> + <string name="Parcel Settings"> + Impostazioni lotto + </string> + <string name="Parcel Powers"> + Poteri lotto + </string> + <string name="Parcel Access"> + Accesso al lotto + </string> + <string name="Parcel Content"> + Contenuto lotto + </string> + <string name="Object Management"> + Gestione oggetti + </string> + <string name="Accounting"> + Contabilità + </string> + <string name="Notices"> + Avvisi + </string> + <string name="Chat" value="Chat :"> + Chat + </string> + <string name="BaseMembership"> + Base + </string> + <string name="PremiumMembership"> + Premium + </string> + <string name="Premium_PlusMembership"> + Premium Plus + </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> + <string name="ExternalEditorNotSet"> + Seleziona un editor usando le impostazioni ExternalEditor. + </string> + <string name="ExternalEditorNotFound"> + L'editor esterno specificato non è stato trovato. Prova a racchiudere il percorso dell'editor in doppie virgolette. -(per es. "/percorso per il mio/editor" "%s")</string> - <string name="ExternalEditorCommandParseError">Errore nell'elaborazione del comando dell'editor esterno.</string> - <string name="ExternalEditorFailedToRun">L'editor esterno non è stato avviato.</string> - <string name="TranslationFailed">Traduzione non riuscita: [REASON]</string> - <string name="TranslationResponseParseError">Errore di elaborazione della risposta della traduzione.</string> - <string name="Esc">Esc</string> - <string name="Space">Space</string> - <string name="Enter">Enter</string> - <string name="Tab">Tab</string> - <string name="Ins">Ins</string> - <string name="Del">Del</string> - <string name="Backsp">Backsp</string> - <string name="Shift">Shift</string> - <string name="Ctrl">Ctrl</string> - <string name="Alt">Alt</string> - <string name="CapsLock">CapsLock</string> - <string name="Home">Home</string> - <string name="End">End</string> - <string name="PgUp">PgUp</string> - <string name="PgDn">PgDn</string> - <string name="F1">F1</string> - <string name="F2">F2</string> - <string name="F3">F3</string> - <string name="F4">F4</string> - <string name="F5">F5</string> - <string name="F6">F6</string> - <string name="F7">F7</string> - <string name="F8">F8</string> - <string name="F9">F9</string> - <string name="F10">F10</string> - <string name="F11">F11</string> - <string name="F12">F12</string> - <string name="Add">Aggiungi</string> - <string name="Subtract">Sottrai</string> - <string name="Multiply">Moltiplica</string> - <string name="Divide">Dividi</string> - <string name="PAD_DIVIDE">PAD_DIVIDE</string> - <string name="PAD_LEFT">PAD_LEFT</string> - <string name="PAD_RIGHT">PAD_RIGHT</string> - <string name="PAD_DOWN">PAD_DOWN</string> - <string name="PAD_UP">PAD_UP</string> - <string name="PAD_HOME">PAD_HOME</string> - <string name="PAD_END">PAD_END</string> - <string name="PAD_PGUP">PAD_PGUP</string> - <string name="PAD_PGDN">PAD_PGDN</string> - <string name="PAD_CENTER">PAD_CENTER</string> - <string name="PAD_INS">PAD_INS</string> - <string name="PAD_DEL">PAD_DEL</string> - <string name="PAD_Enter">PAD_Enter</string> - <string name="PAD_BUTTON0">PAD_BUTTON0</string> - <string name="PAD_BUTTON1">PAD_BUTTON1</string> - <string name="PAD_BUTTON2">PAD_BUTTON2</string> - <string name="PAD_BUTTON3">PAD_BUTTON3</string> - <string name="PAD_BUTTON4">PAD_BUTTON4</string> - <string name="PAD_BUTTON5">PAD_BUTTON5</string> - <string name="PAD_BUTTON6">PAD_BUTTON6</string> - <string name="PAD_BUTTON7">PAD_BUTTON7</string> - <string name="PAD_BUTTON8">PAD_BUTTON8</string> - <string name="PAD_BUTTON9">PAD_BUTTON9</string> - <string name="PAD_BUTTON10">PAD_BUTTON10</string> - <string name="PAD_BUTTON11">PAD_BUTTON11</string> - <string name="PAD_BUTTON12">PAD_BUTTON12</string> - <string name="PAD_BUTTON13">PAD_BUTTON13</string> - <string name="PAD_BUTTON14">PAD_BUTTON14</string> - <string name="PAD_BUTTON15">PAD_BUTTON15</string> - <string name="-">-</string> - <string name="=">=</string> - <string name="`">`</string> - <string name=";">;</string> - <string name="[">[</string> - <string name="]">]</string> - <string name="\">\</string> - <string name="0">0</string> - <string name="1">1</string> - <string name="2">2</string> - <string name="3">3</string> - <string name="4">4</string> - <string name="5">5</string> - <string name="6">6</string> - <string name="7">7</string> - <string name="8">8</string> - <string name="9">9</string> - <string name="A">A</string> - <string name="B">B</string> - <string name="C">C</string> - <string name="D">D</string> - <string name="E">E</string> - <string name="F">F</string> - <string name="G">G</string> - <string name="H">H</string> - <string name="I">I</string> - <string name="J">J</string> - <string name="K">K</string> - <string name="L">L</string> - <string name="M">M</string> - <string name="N">N</string> - <string name="O">O</string> - <string name="P">P</string> - <string name="Q">Q</string> - <string name="R">R</string> - <string name="S">S</string> - <string name="T">T</string> - <string name="U">U</string> - <string name="V">V</string> - <string name="W">W</string> - <string name="X">X</string> - <string name="Y">Y</string> - <string name="Z">Z</string> - <string name="BeaconParticle">Visualizzazione marcatori particelle (blu)</string> - <string name="BeaconPhysical">Visualizzazione marcatori oggetti fisici (verde)</string> - <string name="BeaconScripted">Visualizzazione marcatori oggetti scriptati (rosso)</string> - <string name="BeaconScriptedTouch">Visualizzazione marcatori oggetti scriptati con funzione tocco (rosso)</string> - <string name="BeaconSound">Visualizzazione marcatori suoni (giallo)</string> - <string name="BeaconMedia">Visualizzazione marcatori multimedia (bianco)</string> - <string name="BeaconSun">Marcatore visualizza direzione sole (arancione)</string> - <string name="BeaconMoon">Marcatore visualizza direzione luna (viola)</string> - <string name="ParticleHiding">Particelle nascoste</string> - <string name="Command_AboutLand_Label">Informazioni sul terreno</string> - <string name="Command_Appearance_Label">Aspetto fisico</string> - <string name="Command_Avatar_Label">Avatar</string> - <string name="Command_Build_Label">Costruisci</string> - <string name="Command_Chat_Label">Chat</string> - <string name="Command_Conversations_Label">Conversazioni</string> - <string name="Command_Compass_Label">Bussola</string> - <string name="Command_Destinations_Label">Destinazioni</string> - <string name="Command_Environments_Label">I miei ambienti</string> - <string name="Command_Facebook_Label">Facebook</string> - <string name="Command_Flickr_Label">Flickr</string> - <string name="Command_Gestures_Label">Gesture</string> - <string name="Command_Grid_Status_Label">Stato della griglia</string> - <string name="Command_HowTo_Label">Istruzioni</string> - <string name="Command_Inventory_Label">Inventario</string> - <string name="Command_Map_Label">Mappa</string> - <string name="Command_Marketplace_Label">Mercato</string> - <string name="Command_MarketplaceListings_Label">Marketplace</string> - <string name="Command_MiniMap_Label">Mini mappa</string> - <string name="Command_Move_Label">Cammina / corri / vola</string> - <string name="Command_Outbox_Label">Casella in uscita del rivenditore</string> - <string name="Command_People_Label">Persone</string> - <string name="Command_Picks_Label">Preferiti</string> - <string name="Command_Places_Label">Luoghi</string> - <string name="Command_Preferences_Label">Preferenze</string> - <string name="Command_Profile_Label">Profilo</string> - <string name="Command_Report_Abuse_Label">Segnala abuso</string> - <string name="Command_Search_Label">Ricerca</string> - <string name="Command_Snapshot_Label">Istantanea</string> - <string name="Command_Speak_Label">Parla</string> - <string name="Command_Twitter_Label">Twitter</string> - <string name="Command_View_Label">Controlli fotocamera</string> - <string name="Command_Voice_Label">Impostazioni voce</string> - <string name="Command_AboutLand_Tooltip">Informazioni sul terreno che visiti</string> - <string name="Command_Appearance_Tooltip">Cambia l'avatar</string> - <string name="Command_Avatar_Tooltip">Seleziona un avatar completo</string> - <string name="Command_Build_Tooltip">Costruzione oggetti e modifica terreno</string> - <string name="Command_Chat_Tooltip">Chatta con persone vicine usando il testo</string> - <string name="Command_Conversations_Tooltip">Conversa con chiunque</string> - <string name="Command_Compass_Tooltip">Bussola</string> - <string name="Command_Destinations_Tooltip">Destinazioni interessanti</string> - <string name="Command_Environments_Tooltip">I miei ambienti</string> - <string name="Command_Facebook_Tooltip">Pubblica su Facebook</string> - <string name="Command_Flickr_Tooltip">Carica su Flickr</string> - <string name="Command_Gestures_Tooltip">Gesti per il tuo avatar</string> - <string name="Command_Grid_Status_Tooltip">Mostra stato griglia corrente</string> - <string name="Command_HowTo_Tooltip">Come eseguire le attività più comuni</string> - <string name="Command_Inventory_Tooltip">Visualizza e usa le tue cose</string> - <string name="Command_Map_Tooltip">Mappa del mondo</string> - <string name="Command_Marketplace_Tooltip">Vai allo shopping</string> - <string name="Command_MarketplaceListings_Tooltip">Vendi le tue creazioni</string> - <string name="Command_MiniMap_Tooltip">Mostra le persone vicine</string> - <string name="Command_Move_Tooltip">Movimento avatar</string> - <string name="Command_Outbox_Tooltip">Trasferisci elementi al tuo mercato per la vendita</string> - <string name="Command_People_Tooltip">Amici, gruppi e persone vicine</string> - <string name="Command_Picks_Tooltip">Luoghi da mostrare come preferiti nel profilo</string> - <string name="Command_Places_Tooltip">Luoghi salvati</string> - <string name="Command_Preferences_Tooltip">Preferenze</string> - <string name="Command_Profile_Tooltip">Modifica o visualizza il tuo profilo</string> - <string name="Command_Report_Abuse_Tooltip">Segnala abuso</string> - <string name="Command_Search_Tooltip">Trova luoghi, eventi, persone</string> - <string name="Command_Snapshot_Tooltip">Scatta una foto</string> - <string name="Command_Speak_Tooltip">Parla con persone vicine usando il microfono</string> - <string name="Command_Twitter_Tooltip">Twitter</string> - <string name="Command_View_Tooltip">Modifica angolo fotocamera</string> - <string name="Command_Voice_Tooltip">I controlli per il volume per le chiamate e per le persone nelle vicinanze nel mondo virtuale</string> - <string name="Toolbar_Bottom_Tooltip">attualmente nella barra degli strumenti in basso</string> - <string name="Toolbar_Left_Tooltip">attualmente nella barra degli strumenti a sinistra</string> - <string name="Toolbar_Right_Tooltip">attualmente nella barra degli strumenti a destra</string> - <string name="Retain%">Mantieni%</string> - <string name="Detail">Dettagli</string> - <string name="Better Detail">Migliori dettagli</string> - <string name="Surface">Superficie</string> - <string name="Solid">Solido</string> - <string name="Wrap">Involucro</string> - <string name="Preview">Anteprima</string> - <string name="Normal">Normale</string> - <string name="Pathfinding_Wiki_URL">http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer</string> - <string name="Pathfinding_Object_Attr_None">Nessuno</string> - <string name="Pathfinding_Object_Attr_Permanent">Influenza il navmesh</string> - <string name="Pathfinding_Object_Attr_Character">Personaggio</string> - <string name="Pathfinding_Object_Attr_MultiSelect">(Multiple)</string> - <string name="snapshot_quality_very_low">Molto basso</string> - <string name="snapshot_quality_low">Basso</string> - <string name="snapshot_quality_medium">Medio</string> - <string name="snapshot_quality_high">Alto</string> - <string name="snapshot_quality_very_high">Molto alto</string> - <string name="TeleportMaturityExceeded">Il Residente non può visitare questa regione.</string> - <string name="UserDictionary">[User]</string> - <string name="experience_tools_experience">Esperienza</string> - <string name="ExperienceNameNull">(nessuna esperienza)</string> - <string name="ExperienceNameUntitled">(esperienza senza titolo)</string> - <string name="Land-Scope">A livello di terreno</string> - <string name="Grid-Scope">A livello di griglia</string> - <string name="Allowed_Experiences_Tab">CONSENTITO</string> - <string name="Blocked_Experiences_Tab">BLOCCATO</string> - <string name="Contrib_Experiences_Tab">FORNITORE</string> - <string name="Admin_Experiences_Tab">AMMINISTRATORE</string> - <string name="Recent_Experiences_Tab">RECENTE</string> - <string name="Owned_Experiences_Tab">DI PROPRIETÀ</string> - <string name="ExperiencesCounter">([EXPERIENCES], massimo [MAXEXPERIENCES])</string> - <string name="ExperiencePermission1">gestione dei tuoi comandi</string> - <string name="ExperiencePermission3">attivazione di animazioni per il tuo avatar</string> - <string name="ExperiencePermission4">collegamento al tuo avatar</string> - <string name="ExperiencePermission9">monitoraggio della tua videocamera</string> - <string name="ExperiencePermission10">controllo della tua videocamera</string> - <string name="ExperiencePermission11">ti teletrasporta</string> - <string name="ExperiencePermission12">accettazione automatica delle autorizzazioni per le esperienze</string> - <string name="ExperiencePermission16">obbliga l'avatar a sedersi</string> - <string name="ExperiencePermission17">cambia le impostazioni dell’ambiente</string> - <string name="ExperiencePermissionShortUnknown">ha eseguito un'operazione sconosciuta: [Permission]</string> - <string name="ExperiencePermissionShort1">Gestione dei comandi</string> - <string name="ExperiencePermissionShort3">Attivazione di animazioni</string> - <string name="ExperiencePermissionShort4">Collegamento</string> - <string name="ExperiencePermissionShort9">Monitoraggio videocamera</string> - <string name="ExperiencePermissionShort10">Controllo videocamera</string> - <string name="ExperiencePermissionShort11">Teleport</string> - <string name="ExperiencePermissionShort12">Autorizzazione</string> - <string name="ExperiencePermissionShort16">Siediti</string> - <string name="ExperiencePermissionShort17">Ambiente</string> - <string name="logging_calls_disabled_log_empty">Le conversazioni non vengono registrate. Per iniziare a registrare, seleziona "Salva: Solo registro" oppure "Salva: Registri e trascrizioni" in Preferenze > Chat.</string> - <string name="logging_calls_disabled_log_not_empty">Non verranno registrate più le conversazioni. Per riprendere a registrare, seleziona "Salva: Solo registro" oppure "Salva: Registri e trascrizioni" in Preferenze > Chat.</string> - <string name="logging_calls_enabled_log_empty">Nessuna conversazione in registro. Dopo che hai contattato qualcuno o se qualcuno ti contatta, una voce del registro verrà mostrata qui.</string> - <string name="loading_chat_logs">Caricamento in corso...</string> - <string name="na">n/d</string> - <string name="preset_combo_label">-Lista vuota-</string> - <string name="Default">Predefinita</string> - <string name="none_paren_cap">(Nulla)</string> - <string name="no_limit">Senza limite</string> - <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">La forma della fisica contiene triangoli troppo piccoli. Prova a semplificare il modello della fisica.</string> - <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH">La forma della fisica contiene dati di conferma errati. Prova a correggere il modello della fisica.</string> - <string name="Mav_Details_MAV_UNKNOWN_VERSION">La versione della forma fisica non è corretta. Imposta la versione corretta per il modello della fisica.</string> - <string name="couldnt_resolve_host">Il DNS non ha potuto risolvere il nome dell’host([HOSTNAME]). +(per es. "/percorso per il mio/editor" "%s") + </string> + <string name="ExternalEditorCommandParseError"> + Errore nell'elaborazione del comando dell'editor esterno. + </string> + <string name="ExternalEditorFailedToRun"> + L'editor esterno non è stato avviato. + </string> + <string name="TranslationFailed"> + Traduzione non riuscita: [REASON] + </string> + <string name="TranslationResponseParseError"> + Errore di elaborazione della risposta della traduzione. + </string> + <string name="Esc"> + Esc + </string> + <string name="Space"> + Space + </string> + <string name="Enter"> + Enter + </string> + <string name="Tab"> + Tab + </string> + <string name="Ins"> + Ins + </string> + <string name="Del"> + Del + </string> + <string name="Backsp"> + Backsp + </string> + <string name="Shift"> + Shift + </string> + <string name="Ctrl"> + Ctrl + </string> + <string name="Alt"> + Alt + </string> + <string name="CapsLock"> + CapsLock + </string> + <string name="Home"> + Home + </string> + <string name="End"> + End + </string> + <string name="PgUp"> + PgUp + </string> + <string name="PgDn"> + PgDn + </string> + <string name="F1"> + F1 + </string> + <string name="F2"> + F2 + </string> + <string name="F3"> + F3 + </string> + <string name="F4"> + F4 + </string> + <string name="F5"> + F5 + </string> + <string name="F6"> + F6 + </string> + <string name="F7"> + F7 + </string> + <string name="F8"> + F8 + </string> + <string name="F9"> + F9 + </string> + <string name="F10"> + F10 + </string> + <string name="F11"> + F11 + </string> + <string name="F12"> + F12 + </string> + <string name="Add"> + Aggiungi + </string> + <string name="Subtract"> + Sottrai + </string> + <string name="Multiply"> + Moltiplica + </string> + <string name="Divide"> + Dividi + </string> + <string name="PAD_DIVIDE"> + PAD_DIVIDE + </string> + <string name="PAD_LEFT"> + PAD_LEFT + </string> + <string name="PAD_RIGHT"> + PAD_RIGHT + </string> + <string name="PAD_DOWN"> + PAD_DOWN + </string> + <string name="PAD_UP"> + PAD_UP + </string> + <string name="PAD_HOME"> + PAD_HOME + </string> + <string name="PAD_END"> + PAD_END + </string> + <string name="PAD_PGUP"> + PAD_PGUP + </string> + <string name="PAD_PGDN"> + PAD_PGDN + </string> + <string name="PAD_CENTER"> + PAD_CENTER + </string> + <string name="PAD_INS"> + PAD_INS + </string> + <string name="PAD_DEL"> + PAD_DEL + </string> + <string name="PAD_Enter"> + PAD_Enter + </string> + <string name="PAD_BUTTON0"> + PAD_BUTTON0 + </string> + <string name="PAD_BUTTON1"> + PAD_BUTTON1 + </string> + <string name="PAD_BUTTON2"> + PAD_BUTTON2 + </string> + <string name="PAD_BUTTON3"> + PAD_BUTTON3 + </string> + <string name="PAD_BUTTON4"> + PAD_BUTTON4 + </string> + <string name="PAD_BUTTON5"> + PAD_BUTTON5 + </string> + <string name="PAD_BUTTON6"> + PAD_BUTTON6 + </string> + <string name="PAD_BUTTON7"> + PAD_BUTTON7 + </string> + <string name="PAD_BUTTON8"> + PAD_BUTTON8 + </string> + <string name="PAD_BUTTON9"> + PAD_BUTTON9 + </string> + <string name="PAD_BUTTON10"> + PAD_BUTTON10 + </string> + <string name="PAD_BUTTON11"> + PAD_BUTTON11 + </string> + <string name="PAD_BUTTON12"> + PAD_BUTTON12 + </string> + <string name="PAD_BUTTON13"> + PAD_BUTTON13 + </string> + <string name="PAD_BUTTON14"> + PAD_BUTTON14 + </string> + <string name="PAD_BUTTON15"> + PAD_BUTTON15 + </string> + <string name="-"> + - + </string> + <string name="="> + = + </string> + <string name="`"> + ` + </string> + <string name=";"> + ; + </string> + <string name="["> + [ + </string> + <string name="]"> + ] + </string> + <string name="\"> + \ + </string> + <string name="0"> + 0 + </string> + <string name="1"> + 1 + </string> + <string name="2"> + 2 + </string> + <string name="3"> + 3 + </string> + <string name="4"> + 4 + </string> + <string name="5"> + 5 + </string> + <string name="6"> + 6 + </string> + <string name="7"> + 7 + </string> + <string name="8"> + 8 + </string> + <string name="9"> + 9 + </string> + <string name="A"> + A + </string> + <string name="B"> + B + </string> + <string name="C"> + C + </string> + <string name="D"> + D + </string> + <string name="E"> + E + </string> + <string name="F"> + F + </string> + <string name="G"> + G + </string> + <string name="H"> + H + </string> + <string name="I"> + I + </string> + <string name="J"> + J + </string> + <string name="K"> + K + </string> + <string name="L"> + L + </string> + <string name="M"> + M + </string> + <string name="N"> + N + </string> + <string name="O"> + O + </string> + <string name="P"> + P + </string> + <string name="Q"> + Q + </string> + <string name="R"> + R + </string> + <string name="S"> + S + </string> + <string name="T"> + T + </string> + <string name="U"> + U + </string> + <string name="V"> + V + </string> + <string name="W"> + W + </string> + <string name="X"> + X + </string> + <string name="Y"> + Y + </string> + <string name="Z"> + Z + </string> + <string name="BeaconParticle"> + Visualizzazione marcatori particelle (blu) + </string> + <string name="BeaconPhysical"> + Visualizzazione marcatori oggetti fisici (verde) + </string> + <string name="BeaconScripted"> + Visualizzazione marcatori oggetti scriptati (rosso) + </string> + <string name="BeaconScriptedTouch"> + Visualizzazione marcatori oggetti scriptati con funzione tocco (rosso) + </string> + <string name="BeaconSound"> + Visualizzazione marcatori suoni (giallo) + </string> + <string name="BeaconMedia"> + Visualizzazione marcatori multimedia (bianco) + </string> + <string name="BeaconSun"> + Marcatore visualizza direzione sole (arancione) + </string> + <string name="BeaconMoon"> + Marcatore visualizza direzione luna (viola) + </string> + <string name="ParticleHiding"> + Particelle nascoste + </string> + <string name="Command_AboutLand_Label"> + Informazioni sul terreno + </string> + <string name="Command_Appearance_Label"> + Aspetto fisico + </string> + <string name="Command_Avatar_Label"> + Avatar + </string> + <string name="Command_Build_Label"> + Costruisci + </string> + <string name="Command_Chat_Label"> + Chat + </string> + <string name="Command_Conversations_Label"> + Conversazioni + </string> + <string name="Command_Compass_Label"> + Bussola + </string> + <string name="Command_Destinations_Label"> + Destinazioni + </string> + <string name="Command_Environments_Label"> + I miei ambienti + </string> + <string name="Command_Facebook_Label"> + Facebook + </string> + <string name="Command_Flickr_Label"> + Flickr + </string> + <string name="Command_Gestures_Label"> + Gesture + </string> + <string name="Command_Grid_Status_Label"> + Stato della griglia + </string> + <string name="Command_HowTo_Label"> + Istruzioni + </string> + <string name="Command_Inventory_Label"> + Inventario + </string> + <string name="Command_Map_Label"> + Mappa + </string> + <string name="Command_Marketplace_Label"> + Mercato + </string> + <string name="Command_MarketplaceListings_Label"> + Marketplace + </string> + <string name="Command_MiniMap_Label"> + Mini mappa + </string> + <string name="Command_Move_Label"> + Cammina / corri / vola + </string> + <string name="Command_Outbox_Label"> + Casella in uscita del rivenditore + </string> + <string name="Command_People_Label"> + Persone + </string> + <string name="Command_Picks_Label"> + Preferiti + </string> + <string name="Command_Places_Label"> + Luoghi + </string> + <string name="Command_Preferences_Label"> + Preferenze + </string> + <string name="Command_Profile_Label"> + Profilo + </string> + <string name="Command_Report_Abuse_Label"> + Segnala abuso + </string> + <string name="Command_Search_Label"> + Ricerca + </string> + <string name="Command_Snapshot_Label"> + Istantanea + </string> + <string name="Command_Speak_Label"> + Parla + </string> + <string name="Command_Twitter_Label"> + Twitter + </string> + <string name="Command_View_Label"> + Controlli fotocamera + </string> + <string name="Command_Voice_Label"> + Impostazioni voce + </string> + <string name="Command_AboutLand_Tooltip"> + Informazioni sul terreno che visiti + </string> + <string name="Command_Appearance_Tooltip"> + Cambia l'avatar + </string> + <string name="Command_Avatar_Tooltip"> + Seleziona un avatar completo + </string> + <string name="Command_Build_Tooltip"> + Costruzione oggetti e modifica terreno + </string> + <string name="Command_Chat_Tooltip"> + Chatta con persone vicine usando il testo + </string> + <string name="Command_Conversations_Tooltip"> + Conversa con chiunque + </string> + <string name="Command_Compass_Tooltip"> + Bussola + </string> + <string name="Command_Destinations_Tooltip"> + Destinazioni interessanti + </string> + <string name="Command_Environments_Tooltip"> + I miei ambienti + </string> + <string name="Command_Facebook_Tooltip"> + Pubblica su Facebook + </string> + <string name="Command_Flickr_Tooltip"> + Carica su Flickr + </string> + <string name="Command_Gestures_Tooltip"> + Gesti per il tuo avatar + </string> + <string name="Command_Grid_Status_Tooltip"> + Mostra stato griglia corrente + </string> + <string name="Command_HowTo_Tooltip"> + Come eseguire le attività più comuni + </string> + <string name="Command_Inventory_Tooltip"> + Visualizza e usa le tue cose + </string> + <string name="Command_Map_Tooltip"> + Mappa del mondo + </string> + <string name="Command_Marketplace_Tooltip"> + Vai allo shopping + </string> + <string name="Command_MarketplaceListings_Tooltip"> + Vendi le tue creazioni + </string> + <string name="Command_MiniMap_Tooltip"> + Mostra le persone vicine + </string> + <string name="Command_Move_Tooltip"> + Movimento avatar + </string> + <string name="Command_Outbox_Tooltip"> + Trasferisci elementi al tuo mercato per la vendita + </string> + <string name="Command_People_Tooltip"> + Amici, gruppi e persone vicine + </string> + <string name="Command_Picks_Tooltip"> + Luoghi da mostrare come preferiti nel profilo + </string> + <string name="Command_Places_Tooltip"> + Luoghi salvati + </string> + <string name="Command_Preferences_Tooltip"> + Preferenze + </string> + <string name="Command_Profile_Tooltip"> + Modifica o visualizza il tuo profilo + </string> + <string name="Command_Report_Abuse_Tooltip"> + Segnala abuso + </string> + <string name="Command_Search_Tooltip"> + Trova luoghi, eventi, persone + </string> + <string name="Command_Snapshot_Tooltip"> + Scatta una foto + </string> + <string name="Command_Speak_Tooltip"> + Parla con persone vicine usando il microfono + </string> + <string name="Command_Twitter_Tooltip"> + Twitter + </string> + <string name="Command_View_Tooltip"> + Modifica angolo fotocamera + </string> + <string name="Command_Voice_Tooltip"> + I controlli per il volume per le chiamate e per le persone nelle vicinanze nel mondo virtuale + </string> + <string name="Toolbar_Bottom_Tooltip"> + attualmente nella barra degli strumenti in basso + </string> + <string name="Toolbar_Left_Tooltip"> + attualmente nella barra degli strumenti a sinistra + </string> + <string name="Toolbar_Right_Tooltip"> + attualmente nella barra degli strumenti a destra + </string> + <string name="Retain%"> + Mantieni% + </string> + <string name="Detail"> + Dettagli + </string> + <string name="Better Detail"> + Migliori dettagli + </string> + <string name="Surface"> + Superficie + </string> + <string name="Solid"> + Solido + </string> + <string name="Wrap"> + Involucro + </string> + <string name="Preview"> + Anteprima + </string> + <string name="Normal"> + Normale + </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Nessuno + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Influenza il navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personaggio + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Multiple) + </string> + <string name="snapshot_quality_very_low"> + Molto basso + </string> + <string name="snapshot_quality_low"> + Basso + </string> + <string name="snapshot_quality_medium"> + Medio + </string> + <string name="snapshot_quality_high"> + Alto + </string> + <string name="snapshot_quality_very_high"> + Molto alto + </string> + <string name="TeleportMaturityExceeded"> + Il Residente non può visitare questa regione. + </string> + <string name="UserDictionary"> + [User] + </string> + <string name="experience_tools_experience"> + Esperienza + </string> + <string name="ExperienceNameNull"> + (nessuna esperienza) + </string> + <string name="ExperienceNameUntitled"> + (esperienza senza titolo) + </string> + <string name="Land-Scope"> + A livello di terreno + </string> + <string name="Grid-Scope"> + A livello di griglia + </string> + <string name="Allowed_Experiences_Tab"> + CONSENTITO + </string> + <string name="Blocked_Experiences_Tab"> + BLOCCATO + </string> + <string name="Contrib_Experiences_Tab"> + FORNITORE + </string> + <string name="Admin_Experiences_Tab"> + AMMINISTRATORE + </string> + <string name="Recent_Experiences_Tab"> + RECENTE + </string> + <string name="Owned_Experiences_Tab"> + DI PROPRIETÀ + </string> + <string name="ExperiencesCounter"> + ([EXPERIENCES], massimo [MAXEXPERIENCES]) + </string> + <string name="ExperiencePermission1"> + gestione dei tuoi comandi + </string> + <string name="ExperiencePermission3"> + attivazione di animazioni per il tuo avatar + </string> + <string name="ExperiencePermission4"> + collegamento al tuo avatar + </string> + <string name="ExperiencePermission9"> + monitoraggio della tua videocamera + </string> + <string name="ExperiencePermission10"> + controllo della tua videocamera + </string> + <string name="ExperiencePermission11"> + ti teletrasporta + </string> + <string name="ExperiencePermission12"> + accettazione automatica delle autorizzazioni per le esperienze + </string> + <string name="ExperiencePermission16"> + obbliga l'avatar a sedersi + </string> + <string name="ExperiencePermission17"> + cambia le impostazioni dell’ambiente + </string> + <string name="ExperiencePermissionShortUnknown"> + ha eseguito un'operazione sconosciuta: [Permission] + </string> + <string name="ExperiencePermissionShort1"> + Gestione dei comandi + </string> + <string name="ExperiencePermissionShort3"> + Attivazione di animazioni + </string> + <string name="ExperiencePermissionShort4"> + Collegamento + </string> + <string name="ExperiencePermissionShort9"> + Monitoraggio videocamera + </string> + <string name="ExperiencePermissionShort10"> + Controllo videocamera + </string> + <string name="ExperiencePermissionShort11"> + Teleport + </string> + <string name="ExperiencePermissionShort12"> + Autorizzazione + </string> + <string name="ExperiencePermissionShort16"> + Siediti + </string> + <string name="ExperiencePermissionShort17"> + Ambiente + </string> + <string name="logging_calls_disabled_log_empty"> + Le conversazioni non vengono registrate. Per iniziare a registrare, seleziona "Salva: Solo registro" oppure "Salva: Registri e trascrizioni" in Preferenze > Chat. + </string> + <string name="logging_calls_disabled_log_not_empty"> + Non verranno registrate più le conversazioni. Per riprendere a registrare, seleziona "Salva: Solo registro" oppure "Salva: Registri e trascrizioni" in Preferenze > Chat. + </string> + <string name="logging_calls_enabled_log_empty"> + Nessuna conversazione in registro. Dopo che hai contattato qualcuno o se qualcuno ti contatta, una voce del registro verrà mostrata qui. + </string> + <string name="loading_chat_logs"> + Caricamento in corso... + </string> + <string name="na"> + n/d + </string> + <string name="preset_combo_label"> + -Lista vuota- + </string> + <string name="Default"> + Predefinita + </string> + <string name="none_paren_cap"> + (Nulla) + </string> + <string name="no_limit"> + Senza limite + </string> + <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES"> + La forma della fisica contiene triangoli troppo piccoli. Prova a semplificare il modello della fisica. + </string> + <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH"> + La forma della fisica contiene dati di conferma errati. Prova a correggere il modello della fisica. + </string> + <string name="Mav_Details_MAV_UNKNOWN_VERSION"> + La versione della forma fisica non è corretta. Imposta la versione corretta per il modello della fisica. + </string> + <string name="couldnt_resolve_host"> + Il DNS non ha potuto risolvere il nome dell’host([HOSTNAME]). Verifica di riuscire a connetterti al sito web www.secondlife.com. Se riesci ma continui a ricevere questo errore, visita la sezione -Assistenza e segnala il problema.</string> - <string name="ssl_peer_certificate">Il server per il login non ha potuto effettuare la verifica tramite SSL. +Assistenza e segnala il problema. + </string> + <string name="ssl_peer_certificate"> + Il server per il login non ha potuto effettuare la verifica tramite SSL. Se continui a ricevere questo errore, visita la sezione Assistenza nel sito SecondLife.com -e segnala il problema.</string> - <string name="ssl_connect_error">Spesso l’errore è dovuto all’orologio del computer, impostato incorrettamente. +e segnala il problema. + </string> + <string name="ssl_connect_error"> + Spesso l’errore è dovuto all’orologio del computer, impostato incorrettamente. Vai al Pannello di Controllo e assicurati che data e ora siano esatte. Controlla anche che il network e il firewall siano impostati correttamente. Se continui a ricevere questo errore, visita la sezione Assistenza nel sito SecondLife.com e segnala il problema. -[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base conoscenze]</string> +[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base conoscenze] + </string> </strings> diff --git a/indra/newview/skins/default/xui/it/teleport_strings.xml b/indra/newview/skins/default/xui/it/teleport_strings.xml index 4a089fe7c3..b8a7bc8112 100644 --- a/indra/newview/skins/default/xui/it/teleport_strings.xml +++ b/indra/newview/skins/default/xui/it/teleport_strings.xml @@ -1,38 +1,94 @@ <?xml version="1.0" ?> <teleport_messages> <message_set name="errors"> - <message name="invalid_tport">C'è stato un problema nell'elaborare la tua richiesta di teleport. Potresti dover effettuare nuovamente l'accesso prima di poter usare il teleport. -Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE].</message> - <message name="invalid_region_handoff">Si è verificato un problema nel tentativo di attraversare regioni. È possibile che per potere attraversare le regioni, tu debba effettuare nuovamente l'accesso. -Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE].</message> - <message name="blocked_tport">Spiacenti, il teletrasporto è bloccato al momento. Prova di nuovo tra pochi istanti. Se ancora non potrai teletrasportarti, per favore scollegati e ricollegati per risolvere il problema.</message> - <message name="nolandmark_tport">Spiacenti, ma il sistema non riesce a localizzare la destinazione del landmark</message> - <message name="timeout_tport">Spiacenti, il sistema non riesce a completare il teletrasporto. Riprova tra un attimo.</message> - <message name="NoHelpIslandTP">Non puoi teleportarti nuovamente a Welcome Island. -Per ripetere l'esercitazione, visita 'Welcome Island Public'.</message> - <message name="noaccess_tport">Spiacenti, ma non hai accesso nel luogo di destinazione richiesto.</message> - <message name="missing_attach_tport">Gli oggetti da te indossati non sono ancoa arrivati. Attendi ancora qualche secondo o scollegati e ricollegati prima di provare a teleportarti.</message> - <message name="too_many_uploads_tport">Il server della regione è al momento occupato e la tua richiesta di teletrasporto non può essere soddisfatta entro breve tempo. Per favore prova di nuovo tra qualche minuto o spostati in un'area meno affollata.</message> - <message name="expired_tport">Spiacenti, il sistema non riesce a soddisfare la tua richiesta di teletrasporto entro un tempo ragionevole. Riprova tra qualche minuto.</message> - <message name="expired_region_handoff">Spiacenti, il sistema non riesce a completare il cambio di regione entro un tempo ragionevole. Riprova tra qualche minuto.</message> - <message name="no_host">Impossibile trovare la destinazione del teletrasporto; potrebbe essere temporaneamente non accessibile o non esistere più. Riprovaci tra qualche minuto.</message> - <message name="no_inventory_host">L'inventario è temporaneamente inaccessibile.</message> - <message name="MustGetAgeRegion">Per poter entrare in questa regione devi avere almeno 18 anni.</message> - <message name="RegionTPSpecialUsageBlocked">Impossibile entrare nella regione. '[REGION_NAME]' è una regione per giochi di abilità e per entrare è necessario soddisfare alcuni requisiti. Per dettagli, leggi le [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life domande frequenti sui giochi di abilità].</message> - <message name="preexisting_tport">Mi dispiace, ma il sistema non è stato in grado di avviare il teletrasporto. Ti preghiamo di riprovare tra qualche minuto.</message> + <message name="invalid_tport"> + C'è stato un problema nell'elaborare la tua richiesta di teleport. Potresti dover effettuare nuovamente l'accesso prima di poter usare il teleport. +Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE]. + </message> + <message name="invalid_region_handoff"> + Si è verificato un problema nel tentativo di attraversare regioni. È possibile che per potere attraversare le regioni, tu debba effettuare nuovamente l'accesso. +Se si continua a visualizzare questo messaggio, consulta la pagina [SUPPORT_SITE]. + </message> + <message name="blocked_tport"> + Spiacenti, il teletrasporto è bloccato al momento. Prova di nuovo tra pochi istanti. Se ancora non potrai teletrasportarti, per favore scollegati e ricollegati per risolvere il problema. + </message> + <message name="nolandmark_tport"> + Spiacenti, ma il sistema non riesce a localizzare la destinazione del landmark + </message> + <message name="timeout_tport"> + Spiacenti, il sistema non riesce a completare il teletrasporto. Riprova tra un attimo. + </message> + <message name="NoHelpIslandTP"> + Non puoi teleportarti nuovamente a Welcome Island. +Per ripetere l'esercitazione, visita 'Welcome Island Public'. + </message> + <message name="noaccess_tport"> + Spiacenti, ma non hai accesso nel luogo di destinazione richiesto. + </message> + <message name="missing_attach_tport"> + Gli oggetti da te indossati non sono ancoa arrivati. Attendi ancora qualche secondo o scollegati e ricollegati prima di provare a teleportarti. + </message> + <message name="too_many_uploads_tport"> + Il server della regione è al momento occupato e la tua richiesta di teletrasporto non può essere soddisfatta entro breve tempo. Per favore prova di nuovo tra qualche minuto o spostati in un'area meno affollata. + </message> + <message name="expired_tport"> + Spiacenti, il sistema non riesce a soddisfare la tua richiesta di teletrasporto entro un tempo ragionevole. Riprova tra qualche minuto. + </message> + <message name="expired_region_handoff"> + Spiacenti, il sistema non riesce a completare il cambio di regione entro un tempo ragionevole. Riprova tra qualche minuto. + </message> + <message name="no_host"> + Impossibile trovare la destinazione del teletrasporto; potrebbe essere temporaneamente non accessibile o non esistere più. Riprovaci tra qualche minuto. + </message> + <message name="no_inventory_host"> + L'inventario è temporaneamente inaccessibile. + </message> + <message name="MustGetAgeRegion"> + Per poter entrare in questa regione devi avere almeno 18 anni. + </message> + <message name="RegionTPSpecialUsageBlocked"> + Impossibile entrare nella regione. '[REGION_NAME]' è una regione per giochi di abilità e per entrare è necessario soddisfare alcuni requisiti. Per dettagli, leggi le [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life domande frequenti sui giochi di abilità]. + </message> + <message name="preexisting_tport"> + Mi dispiace, ma il sistema non è stato in grado di avviare il teletrasporto. Ti preghiamo di riprovare tra qualche minuto. + </message> </message_set> <message_set name="progress"> - <message name="sending_dest">In invio a destinazione.</message> - <message name="redirecting">In reindirizzamento ad una nuova destinazione.</message> - <message name="relaying">In reinvio a destinazione.</message> - <message name="sending_home">In invio verso la destinazione casa.</message> - <message name="sending_landmark">In invio verso la destinazione del landmark.</message> - <message name="completing">Teletrasporto completato</message> - <message name="completed_from">Teleport completato da [T_SLURL]</message> - <message name="resolving">Elaborazione della destinazione in corso...</message> - <message name="contacting">Contatto in corso con la nuova regione.</message> - <message name="arriving">In arrivo a destinazione...</message> - <message name="requesting">Avvio teletrasporto....</message> - <message name="pending">Teleport in sospeso...</message> + <message name="sending_dest"> + In invio a destinazione. + </message> + <message name="redirecting"> + In reindirizzamento ad una nuova destinazione. + </message> + <message name="relaying"> + In reinvio a destinazione. + </message> + <message name="sending_home"> + In invio verso la destinazione casa. + </message> + <message name="sending_landmark"> + In invio verso la destinazione del landmark. + </message> + <message name="completing"> + Teletrasporto completato + </message> + <message name="completed_from"> + Teleport completato da [T_SLURL] + </message> + <message name="resolving"> + Elaborazione della destinazione in corso... + </message> + <message name="contacting"> + Contatto in corso con la nuova regione. + </message> + <message name="arriving"> + In arrivo a destinazione... + </message> + <message name="requesting"> + Avvio teletrasporto.... + </message> + <message name="pending"> + Teleport in sospeso... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/ja/panel_login_first.xml b/indra/newview/skins/default/xui/ja/panel_login_first.xml deleted file mode 100644 index 0f987fc816..0000000000 --- a/indra/newview/skins/default/xui/ja/panel_login_first.xml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - https://secondlife.com/my/account/request.php?lang=ja-JP - </panel.string> - <panel.string name="sign_up_url"> - https://join.secondlife.com/?lang=ja - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="page_top"/> - <layout_panel name="parent_panel"> - <layout_stack name="logo_stack"> - <layout_panel name="logo_left"/> - <layout_panel name="logo_container"> - <icon name="sl_logo"/> - </layout_panel> - <layout_panel auto_resize="true"/> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_left"/> - <layout_panel name="widget_container"> - <combo_box label="ユーザ名" tool_tip="登録時に自分で選んだユーザー名(例:bobsmith12、Steller Sunshineなど)" name="username_combo"> - <combo_box.combo_editor/> - <combo_box.combo_button/> - <combo_box.drop_down_button/> - </combo_box> - <line_editor name="password_edit" label="パスワード"/> - <button label="ログイン" name="connect_btn"/> - <text name="sign_up_text" valign="center"> - サインアップ - </text> - <check_box label="ユーザ名を記憶" name="remember_name" tool_tip="すでに記憶されているユーザーは、「私」>「初期設定」>「詳細設定」>「記憶されたユーザー名」から削除できます。"/> - <check_box label="パスワード記憶" name="remember_password"/> - <text name="forgot_password_text"> - パスワードを忘れましたか? - </text> - </layout_panel> - <layout_panel name="widget_right"/> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_left"/> - <layout_panel name="images_container"> - <icon name="image_left"/> - </layout_panel> - <layout_panel name="images_right"/> - </layout_stack> - </layout_panel> - <layout_panel name="page_bottom"/> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml index f8837c40a7..844a556af1 100644 --- a/indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml +++ b/indra/newview/skins/default/xui/ja/panel_settings_sky_sunmoon.xml @@ -44,8 +44,6 @@ <check_box label="ビーコンを表示" name="sunbeacon"/> </layout_panel> <layout_panel name="moon_layout"> - <layout_stack name="moon_stack"> - <layout_panel name="moon_layout"> <text name="moon_label"> 月 </text> @@ -74,8 +72,6 @@ </text> <slider name="moon_brightness"/> <check_box label="ビーコンを表示" name="moonbeacon"/> - </layout_panel> - </layout_stack> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml index 30542378cc..04ecba4264 100644 --- a/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml +++ b/indra/newview/skins/default/xui/ja/panel_snapshot_inventory.xml @@ -16,7 +16,7 @@ <spinner label="" name="inventory_snapshot_height"/> <check_box label="縦横比の固定" name="inventory_keep_aspect_check"/> <text name="hint_lbl"> - 画像をテクスチャとして保存する場合は、いずれかの正方形を選択してください。 + 画像をインベントリに保存するには L$[UPLOAD_COST] の費用がかかります。画像をテクスチャとして保存するには平方形式の 1 つを選択してください。 </text> <button label="キャンセル" name="cancel_btn"/> <button label="保存" name="save_btn"/> diff --git a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml index 7a1aa280ec..a979e31c9a 100644 --- a/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/ja/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="ディスクに保存" name="save_to_computer_btn"/> - <button label="インベントリに保存(L$ [AMOUNT])" name="save_to_inventory_btn"/> + <button label="インベントリに保存" name="save_to_inventory_btn"/> <button label="プロフィールフィードで共有する" name="save_to_profile_btn"/> <button label="メールで送信" name="save_to_email_btn"/> <text name="fee_hint_lbl"> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index df19f3678f..2a338123f3 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -6149,6 +6149,10 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ <string name="inventory_folder_offered-im"> フォルダ「[ITEM_NAME]」がインベントリに送られてきました。 </string> + <string name="bot_warning"> + [NAME]とチャットしています。個人情報を共有しないでください。 +詳細は https://second.life/scripted-agents をご覧ください。 + </string> <string name="share_alert"> インベントリからここにアイテムをドラッグします。 </string> diff --git a/indra/newview/skins/default/xui/pl/panel_login_first.xml b/indra/newview/skins/default/xui/pl/panel_login_first.xml deleted file mode 100644 index 0604ecbcff..0000000000 --- a/indra/newview/skins/default/xui/pl/panel_login_first.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="panel_login"> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Użytkownik" tool_tip="Nazwa użytkownika wybrana przy rejestracji, np. bobsmith12 lub Steller Sunshine" name="username_combo" /> - <line_editor name="password_edit" label="Hasło" /> - <button label="Zaloguj" name="connect_btn" /> - <check_box label="Zapamiętaj mnie" name="remember_check" /> - <text name="forgot_password_text"> - Zapomniałem/am hasła - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Wyspa Nauki to Twój pierwszy krok. Znajdź portal z wyjściem! - </text> - <text name="image_caption_right"> - Potem zwiedź Wyspę Towarzyską i poznaj innych nowych rezydentów! - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pl/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/pl/panel_settings_sky_sunmoon.xml index f807148617..7f9dee2369 100644 --- a/indra/newview/skins/default/xui/pl/panel_settings_sky_sunmoon.xml +++ b/indra/newview/skins/default/xui/pl/panel_settings_sky_sunmoon.xml @@ -35,8 +35,6 @@ <check_box label="Pokaż emiter" name="sunbeacon" /> </layout_panel> <layout_panel name="moon_layout"> - <layout_stack name="moon_stack"> - <layout_panel name="moon_layout"> <text name="moon_label"> Księżyc </text> @@ -59,8 +57,6 @@ Jasność: </text> <check_box label="Pokaż emiter" name="moonbeacon" /> - </layout_panel> - </layout_stack> </layout_panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml b/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml index 016b9ca197..04c01940e1 100644 --- a/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/pl/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="panel_snapshot_options"> <button label="Zapisz na dysku twardym" name="save_to_computer_btn" /> - <button label="Zapisz do Szafy ([AMOUNT]L$)" name="save_to_inventory_btn" /> + <button label="Zapisz do Szafy" name="save_to_inventory_btn" /> <button label="Wyślij na mój Kanał" name="save_to_profile_btn" /> <button label="Załaduj na Facebook" name="send_to_facebook_btn" /> <button label="Załaduj na Twitter" name="send_to_twitter_btn" /> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 8032443020..7a61878618 100644 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -22,14 +22,14 @@ Konfiguracja budowania: [BUILD_CONFIG] </string> <string name="AboutPosition"> -Położenie [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] w [REGION] zlokalizowanym w <nolink>[HOSTNAME]</nolink> + Położenie [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] w [REGION] zlokalizowanym w <nolink>[HOSTNAME]</nolink> SLURL: <nolink>[SLURL]</nolink> (koordynaty globalne [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] [SERVER_RELEASE_NOTES_URL] </string> <string name="AboutSystem"> -Procesor (CPU): [CPU] + Procesor (CPU): [CPU] Pamięć (Memory): [MEMORY_MB] MB System operacyjny (OS Version): [OS_VERSION] Dostawca karty graficznej (Graphics Card Vendor): [GRAPHICS_CARD_VENDOR] @@ -42,7 +42,7 @@ Karta graficzna (Graphics Card): [GRAPHICS_CARD] Wersja OpenGL: [OPENGL_VERSION] </string> <string name="AboutSettings"> -Rozmiar okna (Window size): [WINDOW_WIDTH]x[WINDOW_HEIGHT] + Rozmiar okna (Window size): [WINDOW_WIDTH]x[WINDOW_HEIGHT] Dostrojenie rozmiaru czcionki: [FONT_SIZE_ADJUSTMENT]pt Skalowanie interfejsu (UI Scaling): [UI_SCALE] Pole widzenia (Draw Distance): [DRAW_DISTANCE]m @@ -56,7 +56,7 @@ Pamięć podręczna dysku (Disk cache): [DISK_CACHE_INFO] Tryb obrazu HiDPI: [HIDPI] </string> <string name="AboutLibs"> -Wersja dekodera J2C: [J2C_VERSION] + Wersja dekodera J2C: [J2C_VERSION] Wersja sterownika dźwięku (Audio Driver): [AUDIO_DRIVER_VERSION] [LIBCEF_VERSION] Wersja LibVLC: [LIBVLC_VERSION] @@ -572,7 +572,7 @@ Jeśli myślisz, że to błąd skontaktuj się z support@secondlife.com Usunięcie znajomego </string> <string name="BUTTON_CLOSE_DARWIN"> - Zamknij (⌘W) + Zamknij (⌘W) </string> <string name="BUTTON_CLOSE_WIN"> Zamknij (Ctrl+W) @@ -596,11 +596,11 @@ Jeśli myślisz, że to błąd skontaktuj się z support@secondlife.com Pokaż Pomoc </string> <string name="TooltipNotecardNotAllowedTypeDrop"> -Przedmioty tego typu nie mogą być dołączane + Przedmioty tego typu nie mogą być dołączane do notek z tego regionu. </string> <string name="TooltipNotecardOwnerRestrictedDrop"> -Tylko przedmioty z nieograniczonymi + Tylko przedmioty z nieograniczonymi uprawnieniami 'następnego właściciela' mogą być dołączane do notek. </string> @@ -1622,7 +1622,7 @@ Jeśli ciągle otrzymujesz tą wiadomość, to skontaktuj się z pomocą technic <string name="Scripts" value=" Skrypty,"/> <string name="Sounds" value=" Dźwięki,"/> <string name="Textures" value=" Tekstury,"/> - <string name="Settings" value=" Otoczenia," /> + <string name="Settings" value=" Otoczenia,"/> <string name="Snapshots" value=" Zdjęcia,"/> <string name="No Filters" value="Nie "/> <string name="Since Logoff" value=" - od wylogowania"/> @@ -4359,7 +4359,7 @@ Jeżeli nadal otrzymujesz ten komunikat, skontaktuj się z [SUPPORT_SITE]. (Zapisano [LONG_TIMESTAMP]) </string> <string name="IM_unblock_only_groups_friends"> - Aby zobaczyć tą wiadomość musisz odznaczyć 'Tylko znajomi i grupy mogą wysyłać mi wiad. prywatne (IM) oraz rozmowy głosowe' w Ustawieniach/Prywatności. + Aby zobaczyć tą wiadomość musisz odznaczyć 'Tylko znajomi i grupy mogą wysyłać mi wiad. prywatne (IM) oraz rozmowy głosowe' w Ustawieniach/Prywatności. </string> <string name="OnlineStatus"> dostępny/a @@ -4412,6 +4412,10 @@ Jeżeli nadal otrzymujesz ten komunikat, skontaktuj się z [SUPPORT_SITE]. <string name="inventory_folder_offered-im"> Zaoferowano folder: '[ITEM_NAME]' </string> + <string name="bot_warning"> + Rozmawiasz z botem [NAME]. Nie udostępniaj żadnych danych osobowych. +Dowiedz się więcej na https://second.life/scripted-agents. + </string> <string name="share_alert"> Przeciągaj tutaj rzeczy z Szafy </string> @@ -5286,10 +5290,10 @@ Spróbuj załączyć ścieżkę do edytora w cytowaniu. Otoczenie </string> <string name="logging_calls_disabled_log_empty"> - Rozmowy nie są zapisywane do dziennika. Jeśli chcesz zacząć je logować wybierz "Zapisywanie: tylko dziennik" lub "Zapisywanie: dziennik i logi rozmów" w Preferencje > Czat. + Rozmowy nie są zapisywane do dziennika. Jeśli chcesz zacząć je logować wybierz "Zapisywanie: tylko dziennik" lub "Zapisywanie: dziennik i logi rozmów" w Preferencje > Czat. </string> <string name="logging_calls_disabled_log_not_empty"> - Rozmowy nie będą więcej zapisywane. Jeśli chcesz kontynuować ich logowanie wybierz "Zapisywanie: tylko dziennik" lub "Zapisywanie: dziennik i logi rozmów" w Preferencje > Czat. + Rozmowy nie będą więcej zapisywane. Jeśli chcesz kontynuować ich logowanie wybierz "Zapisywanie: tylko dziennik" lub "Zapisywanie: dziennik i logi rozmów" w Preferencje > Czat. </string> <string name="logging_calls_enabled_log_empty"> Nie ma zapisanych rozmów. Jeśli skontaktujesz się z kimś, lub ktoś z Tobą, to wpis dziennika pojawi się tutaj. diff --git a/indra/newview/skins/default/xui/pl/teleport_strings.xml b/indra/newview/skins/default/xui/pl/teleport_strings.xml index e86255100e..e091f79fe4 100644 --- a/indra/newview/skins/default/xui/pl/teleport_strings.xml +++ b/indra/newview/skins/default/xui/pl/teleport_strings.xml @@ -22,7 +22,7 @@ Spróbuj jeszcze raz. </message> <message name="NoHelpIslandTP"> Brak możliwości ponownej teleportacji do Welcome Island. -Odwiedź 'Welcome Island Public' by powtórzyć szkolenie. +Odwiedź 'Welcome Island Public' by powtórzyć szkolenie. </message> <message name="noaccess_tport"> Przepraszamy, ale nie masz dostępu do miejsca docelowego. diff --git a/indra/newview/skins/default/xui/pt/panel_login_first.xml b/indra/newview/skins/default/xui/pt/panel_login_first.xml deleted file mode 100644 index 86c61163bc..0000000000 --- a/indra/newview/skins/default/xui/pt/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php?lang=pt - </panel.string> - <panel.string name="sign_up_url"> - https://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Nome de usuário" name="username_combo" tool_tip="O nome de usuário que você escolheu ao fazer seu cadastro, como zecazc12 ou Magia Solar"/> - <line_editor label="Senha" name="password_edit"/> - <button label="Login" name="connect_btn"/> - <check_box label="Lembrar-me" name="remember_check"/> - <text name="forgot_password_text"> - Senha esquecida - </text> - <text name="sign_up_text"> - Cadastre-se - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Sua primeira parada é a Ilha da Educação. Encontre o portal de saída! - </text> - <text name="image_caption_right"> - Em seguida, explore a Ilha Social e encontre novos residentes! - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml index 067e5dbd76..f71bc7cd12 100644 --- a/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/pt/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="Salvar no disco" name="save_to_computer_btn"/> - <button label="Salvar em inventário (L$[AMOUNT])" name="save_to_inventory_btn"/> + <button label="Salvar em inventário" name="save_to_inventory_btn"/> <button label="Compartilhar no feed do perfil" name="save_to_profile_btn"/> <button label="Compartilhar no Facebook" name="send_to_facebook_btn"/> <button label="Compartilhar no Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 509b3d72a0..543fd45573 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -1,574 +1,1628 @@ <?xml version="1.0" ?> <strings> - <string name="CAPITALIZED_APP_NAME">SECOND LIFE</string> - <string name="SUPPORT_SITE">Portal de Supporte Second Life</string> - <string name="StartupDetectingHardware">Detectando hardware...</string> - <string name="StartupLoading">Carregando [APP_NAME]...</string> - <string name="StartupClearingCache">Limpando o cache...</string> - <string name="StartupInitializingTextureCache">Iniciando cache de texturas...</string> - <string name="StartupRequireDriverUpdate">Falha na inicialização dos gráficos. Atualize seu driver gráfico!</string> - <string name="AboutHeader">[CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) -[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]]</string> - <string name="BuildConfig">Configuração do corpo [BUILD_CONFIG]</string> - <string name="AboutPosition">Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em <nolink>[HOSTNAME]</nolink> + <string name="CAPITALIZED_APP_NAME"> + SECOND LIFE + </string> + <string name="SUPPORT_SITE"> + Portal de Supporte Second Life + </string> + <string name="StartupDetectingHardware"> + Detectando hardware... + </string> + <string name="StartupLoading"> + Carregando [APP_NAME]... + </string> + <string name="StartupClearingCache"> + Limpando o cache... + </string> + <string name="StartupInitializingTextureCache"> + Iniciando cache de texturas... + </string> + <string name="StartupRequireDriverUpdate"> + Falha na inicialização dos gráficos. Atualize seu driver gráfico! + </string> + <string name="AboutHeader"> + [CHANNEL] [VIEWER_VERSION_0].[VIEWER_VERSION_1].[VIEWER_VERSION_2].[VIEWER_VERSION_3] ([ADDRESS_SIZE]bit) +[[VIEWER_RELEASE_NOTES_URL] [ReleaseNotes]] + </string> + <string name="BuildConfig"> + Configuração do corpo [BUILD_CONFIG] + </string> + <string name="AboutPosition"> + Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em <nolink>[HOSTNAME]</nolink> SLURL: <nolink>[SLURL]</nolink> (coordenadas globais [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] -[SERVER_RELEASE_NOTES_URL]</string> - <string name="AboutSystem">CPU: [CPU] +[SERVER_RELEASE_NOTES_URL] + </string> + <string name="AboutSystem"> + CPU: [CPU] Memória: [MEMORY_MB] MBs Versão OS: [OS_VERSION] Placa de vídeo: [GRAPHICS_CARD_VENDOR] -Placa gráfica: [GRAPHICS_CARD]</string> - <string name="AboutDriver">Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION]</string> - <string name="AboutOGL">Versão do OpenGL: [OPENGL_VERSION]</string> - <string name="AboutSettings">Tamanho da janela: [WINDOW_WIDTH]x[WINDOW_HEIGHT] +Placa gráfica: [GRAPHICS_CARD] + </string> + <string name="AboutDriver"> + Versão do driver de vídeo Windows: [GRAPHICS_DRIVER_VERSION] + </string> + <string name="AboutOGL"> + Versão do OpenGL: [OPENGL_VERSION] + </string> + <string name="AboutSettings"> + Tamanho da janela: [WINDOW_WIDTH]x[WINDOW_HEIGHT] Ajuste do tamanho da fonte: [FONT_SIZE_ADJUSTMENT]pt UI Escala: [UI_SCALE] Estabelecer a distância: [DRAW_DISTANCE]m Largura da banda: [NET_BANDWITH]kbit/s LOD fator: [LOD_FACTOR] Qualidade de renderização: [RENDER_QUALITY] -Memória de textura: [TEXTURE_MEMORY]MB</string> - <string name="AboutOSXHiDPI">HiDPI modo de exibição: [HIDPI]</string> - <string name="AboutLibs">Versão do J2C Decoder: [J2C_VERSION] +Memória de textura: [TEXTURE_MEMORY]MB + </string> + <string name="AboutOSXHiDPI"> + HiDPI modo de exibição: [HIDPI] + </string> + <string name="AboutLibs"> + Versão do J2C Decoder: [J2C_VERSION] Versão do driver de áudio: [AUDIO_DRIVER_VERSION] [LIBCEF_VERSION] Versão do LibVLC: [LIBVLC_VERSION] -Versão do servidor de voz: [VOICE_VERSION]</string> - <string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string> - <string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string> - <string name="ErrorFetchingServerReleaseNotesURL">Erro ao obter URL de notas de versão do servidor.</string> - <string name="BuildConfiguration">Configuração do corpo</string> - <string name="ProgressRestoring">Restaurando...</string> - <string name="ProgressChangingResolution">Alterando a resolução...</string> - <string name="Fullbright">Fullbright (antigo)</string> - <string name="LoginInProgress">Fazendo login. [APP_NAME] pode parecer congelado. Por favor, aguarde.</string> - <string name="LoginInProgressNoFrozen">Logando...</string> - <string name="LoginAuthenticating">Autenticando</string> - <string name="LoginMaintenance">Executando manutenção da conta...</string> - <string name="LoginAttempt">Falha na tentativa anterior de login. Login, tentativa [NUMBER]</string> - <string name="LoginPrecaching">Carregando mundo...</string> - <string name="LoginInitializingBrowser">Inicializando navegador embutido...</string> - <string name="LoginInitializingMultimedia">Inicializando multimídia...</string> - <string name="LoginInitializingFonts">Carregando fontes...</string> - <string name="LoginVerifyingCache">Verificando arquivos cache (pode levar de 60-90 segundos)...</string> - <string name="LoginProcessingResponse">Processando resposta...</string> - <string name="LoginInitializingWorld">Inicializando mundo...</string> - <string name="LoginDecodingImages">Decodificando imagens...</string> - <string name="LoginInitializingQuicktime">Inicializando o QuickTime...</string> - <string name="LoginQuicktimeNotFound">O QuickTime não foi encontrado - falha ao iniciar.</string> - <string name="LoginQuicktimeOK">O QuickTime foi inicializado com sucesso.</string> - <string name="LoginRequestSeedCapGrant">Solicitando recursos da região...</string> - <string name="LoginRetrySeedCapGrant">Solicitando recursos da região, tentativa [NUMBER]...</string> - <string name="LoginWaitingForRegionHandshake">Aguardando handshake com a região...</string> - <string name="LoginConnectingToRegion">Conectando à região...</string> - <string name="LoginDownloadingClothing">Baixando roupas...</string> - <string name="InvalidCertificate">O servidor respondeu com um certificado inválido ou corrompido. Por favor contate o administrador do Grid.</string> - <string name="CertInvalidHostname">Um hostname inválido foi usado para acessar o servidor. Verifique o SLURL ou hostname do Grid.</string> - <string name="CertExpired">O certificado dado pelo Grid parece estar vencido. Verifique o relógio do sistema ou contate o administrador do Grid.</string> - <string name="CertKeyUsage">O certificado dado pelo servidor não pôde ser usado para SSL. Por favor contate o administrador do Grid.</string> - <string name="CertBasicConstraints">A cadeia de certificados do servidor tinha certificados demais. Por favor contate o administrador do Grid.</string> - <string name="CertInvalidSignature">A assinatura do certificado dado pelo servidor do Grid não pôde ser verificada. Contate o administrador do seu Grid.</string> - <string name="LoginFailedNoNetwork">Erro de rede: Falha de conexão: verifique sua conexão à internet.</string> - <string name="LoginFailedHeader">Falha do login.</string> - <string name="Quit">Sair</string> - <string name="create_account_url">http://join.secondlife.com/?sourceid=[sourceid]</string> - <string name="AgniGridLabel">Grade principal do Second Life (Agni)</string> - <string name="AditiGridLabel">Grade de teste beta do Second Life (Aditi)</string> - <string name="ViewerDownloadURL">http://secondlife.com/download</string> - <string name="LoginFailedViewerNotPermitted">O visualizador utilizado já não é compatível com o Second Life. Visite a página abaixo para baixar uma versão atual: http://secondlife.com/download +Versão do servidor de voz: [VOICE_VERSION] + </string> + <string name="AboutTraffic"> + Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%) + </string> + <string name="AboutTime"> + [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] + </string> + <string name="ErrorFetchingServerReleaseNotesURL"> + Erro ao obter URL de notas de versão do servidor. + </string> + <string name="BuildConfiguration"> + Configuração do corpo + </string> + <string name="ProgressRestoring"> + Restaurando... + </string> + <string name="ProgressChangingResolution"> + Alterando a resolução... + </string> + <string name="Fullbright"> + Fullbright (antigo) + </string> + <string name="LoginInProgress"> + Fazendo login. [APP_NAME] pode parecer congelado. Por favor, aguarde. + </string> + <string name="LoginInProgressNoFrozen"> + Logando... + </string> + <string name="LoginAuthenticating"> + Autenticando + </string> + <string name="LoginMaintenance"> + Executando manutenção da conta... + </string> + <string name="LoginAttempt"> + Falha na tentativa anterior de login. Login, tentativa [NUMBER] + </string> + <string name="LoginPrecaching"> + Carregando mundo... + </string> + <string name="LoginInitializingBrowser"> + Inicializando navegador embutido... + </string> + <string name="LoginInitializingMultimedia"> + Inicializando multimídia... + </string> + <string name="LoginInitializingFonts"> + Carregando fontes... + </string> + <string name="LoginVerifyingCache"> + Verificando arquivos cache (pode levar de 60-90 segundos)... + </string> + <string name="LoginProcessingResponse"> + Processando resposta... + </string> + <string name="LoginInitializingWorld"> + Inicializando mundo... + </string> + <string name="LoginDecodingImages"> + Decodificando imagens... + </string> + <string name="LoginInitializingQuicktime"> + Inicializando o QuickTime... + </string> + <string name="LoginQuicktimeNotFound"> + O QuickTime não foi encontrado - falha ao iniciar. + </string> + <string name="LoginQuicktimeOK"> + O QuickTime foi inicializado com sucesso. + </string> + <string name="LoginRequestSeedCapGrant"> + Solicitando recursos da região... + </string> + <string name="LoginRetrySeedCapGrant"> + Solicitando recursos da região, tentativa [NUMBER]... + </string> + <string name="LoginWaitingForRegionHandshake"> + Aguardando handshake com a região... + </string> + <string name="LoginConnectingToRegion"> + Conectando à região... + </string> + <string name="LoginDownloadingClothing"> + Baixando roupas... + </string> + <string name="InvalidCertificate"> + O servidor respondeu com um certificado inválido ou corrompido. Por favor contate o administrador do Grid. + </string> + <string name="CertInvalidHostname"> + Um hostname inválido foi usado para acessar o servidor. Verifique o SLURL ou hostname do Grid. + </string> + <string name="CertExpired"> + O certificado dado pelo Grid parece estar vencido. Verifique o relógio do sistema ou contate o administrador do Grid. + </string> + <string name="CertKeyUsage"> + O certificado dado pelo servidor não pôde ser usado para SSL. Por favor contate o administrador do Grid. + </string> + <string name="CertBasicConstraints"> + A cadeia de certificados do servidor tinha certificados demais. Por favor contate o administrador do Grid. + </string> + <string name="CertInvalidSignature"> + A assinatura do certificado dado pelo servidor do Grid não pôde ser verificada. Contate o administrador do seu Grid. + </string> + <string name="LoginFailedNoNetwork"> + Erro de rede: Falha de conexão: verifique sua conexão à internet. + </string> + <string name="LoginFailedHeader"> + Falha do login. + </string> + <string name="Quit"> + Sair + </string> + <string name="create_account_url"> + http://join.secondlife.com/?sourceid=[sourceid] + </string> + <string name="AgniGridLabel"> + Grade principal do Second Life (Agni) + </string> + <string name="AditiGridLabel"> + Grade de teste beta do Second Life (Aditi) + </string> + <string name="ViewerDownloadURL"> + http://secondlife.com/download + </string> + <string name="LoginFailedViewerNotPermitted"> + O visualizador utilizado já não é compatível com o Second Life. Visite a página abaixo para baixar uma versão atual: http://secondlife.com/download -Para saber mais, visite as perguntas frequentes abaixo: http://secondlife.com/viewer-access-faq</string> - <string name="LoginIntermediateOptionalUpdateAvailable">Existe uma versão atualizada do seu visualizador: [VERSION]</string> - <string name="LoginFailedRequiredUpdate">Atualização de visualizador obrigatória: [VERSION]</string> - <string name="LoginFailedAlreadyLoggedIn">Este agente já fez login.</string> - <string name="LoginFailedAuthenticationFailed">Desculpe! Não foi possível fazer seu login. Verifique se digitou o nome de usuário correto* (como kiki45 ou astro.física) * e senha. Verifique também que a tecla Maiúscula está desativada.</string> - <string name="LoginFailedPasswordChanged">Como medida de precaução, sua senha foi alterada. Visite sua conta em http://secondlife.com/password e responda a pergunta de segurança para mudar sua senha. Lamentamos qualquer inconveniente.</string> - <string name="LoginFailedPasswordReset">Fizemos algumas alterações a seu sistema. Você precisa selecionar outra senha. Visite sua conta em http://secondlife.com/password e responda a pergunta de segurança para mudar sua senha. Lamentamos qualquer inconveniente.</string> - <string name="LoginFailedEmployeesOnly">O Second Life está fechado para manutenção no momento. Somente funcionários podem acessá-lo. Consulte www.secondlife.com/status para as últimas atualizações.</string> - <string name="LoginFailedPremiumOnly">Logons do Second Life estão temporariamente restritos para garantir a melhor experiência possível para os usuários no mundo virtual. +Para saber mais, visite as perguntas frequentes abaixo: http://secondlife.com/viewer-access-faq + </string> + <string name="LoginIntermediateOptionalUpdateAvailable"> + Existe uma versão atualizada do seu visualizador: [VERSION] + </string> + <string name="LoginFailedRequiredUpdate"> + Atualização de visualizador obrigatória: [VERSION] + </string> + <string name="LoginFailedAlreadyLoggedIn"> + Este agente já fez login. + </string> + <string name="LoginFailedAuthenticationFailed"> + Desculpe! Não foi possível fazer seu login. Verifique se digitou o nome de usuário correto* (como kiki45 ou astro.física) * e senha. Verifique também que a tecla Maiúscula está desativada. + </string> + <string name="LoginFailedPasswordChanged"> + Como medida de precaução, sua senha foi alterada. Visite sua conta em http://secondlife.com/password e responda a pergunta de segurança para mudar sua senha. Lamentamos qualquer inconveniente. + </string> + <string name="LoginFailedPasswordReset"> + Fizemos algumas alterações a seu sistema. Você precisa selecionar outra senha. Visite sua conta em http://secondlife.com/password e responda a pergunta de segurança para mudar sua senha. Lamentamos qualquer inconveniente. + </string> + <string name="LoginFailedEmployeesOnly"> + O Second Life está fechado para manutenção no momento. Somente funcionários podem acessá-lo. Consulte www.secondlife.com/status para as últimas atualizações. + </string> + <string name="LoginFailedPremiumOnly"> + Logons do Second Life estão temporariamente restritos para garantir a melhor experiência possível para os usuários no mundo virtual. -Pessoas com contas gratuitas não poderão acessar o Second Life no momento para dar espaço para aquelas que pagaram pelo Second Life.</string> - <string name="LoginFailedComputerProhibited">O Second Life não pode ser acessado deste computador. Se você acredita que houve algum equívoco, contate support@secondlife.com.</string> - <string name="LoginFailedAcountSuspended">Sua conta não está disponível para acesso até [TIME], horário do Pacífico nos EUA (GMT-08).</string> - <string name="LoginFailedAccountDisabled">Não é possível concluir a solicitação neste momento. -Entre em contato com o suporte do Second Life para obter ajuda em http://support.secondlife.com.</string> - <string name="LoginFailedTransformError">Dados discrepantes detectados durante o login. Contate support@secondlife.com.</string> - <string name="LoginFailedAccountMaintenance">Sua conta está passando por um breve período de manutenção. Sua conta não está disponível para acesso até [TIME], horário do Pacífico nos EUA (GMT-08). Se você acredita que houve algum equívoco, contate support@secondlife.com.</string> - <string name="LoginFailedPendingLogoutFault">Reação à solicitação de saída foi uma falha do simulador.</string> - <string name="LoginFailedPendingLogout">O sistema o está desconectando no momento. -Aguarde um minuto antes que tentar logar-se novamente.</string> - <string name="LoginFailedUnableToCreateSession">Impossível criar sessão válida.</string> - <string name="LoginFailedUnableToConnectToSimulator">Não foi possível conectar o simulador.</string> - <string name="LoginFailedRestrictedHours">Sua conta possui acesso ao Second Life das [START] às [END], horário da costa leste dos EUA. Volte novamente durante seu horário de acesso. Se você acredita que houve algum equívoco, contate support@secondlife.com.</string> - <string name="LoginFailedIncorrectParameters">Parâmetros incorretos. Se você acredita que houve algum equívoco, contate support@secondlife.com.</string> - <string name="LoginFailedFirstNameNotAlphanumeric">O parâmetro de primeiro nome deve ser alfanumérico. Se você acredita que houve algum equívoco, contate support@secondlife.com.</string> - <string name="LoginFailedLastNameNotAlphanumeric">O parâmetro de sobrenome deve ser alfanumérico. Se você acredita que houve algum equívoco, contate support@secondlife.com.</string> - <string name="LogoutFailedRegionGoingOffline">Região passando para modo offline. Tente novamente dentro de alguns instantes.</string> - <string name="LogoutFailedAgentNotInRegion">Não há agente na região. Tente novamente dentro de alguns instantes.</string> - <string name="LogoutFailedPendingLogin">A região estava acessada por outra sessão. Tente novamente dentro de alguns instantes.</string> - <string name="LogoutFailedLoggingOut">A região estava passando para o modo offline na sessão anterior. Tente novamente dentro de alguns instantes.</string> - <string name="LogoutFailedStillLoggingOut">A região estava passando para o modo offline na sessão anterior. Tente novamente dentro de alguns instantes.</string> - <string name="LogoutSucceeded">A região passou para o modo offline na última sessão. Tente novamente dentro de alguns instantes.</string> - <string name="LogoutFailedLogoutBegun">A região inicou o modo offline. Tente novamente dentro de alguns instantes.</string> - <string name="LoginFailedLoggingOutSession">O sistema iniciou o modo offline em sua sessão anterior. Tente novamente dentro de alguns instantes.</string> - <string name="AgentLostConnection">Esta região pode estar passando por problemas. Por favor, verifique sua conexão com a internet.</string> - <string name="SavingSettings">Salvando configurações...</string> - <string name="LoggingOut">Saindo...</string> - <string name="ShuttingDown">Fechando...</string> - <string name="YouHaveBeenDisconnected">Você foi desconectado da região onde estava.</string> - <string name="SentToInvalidRegion">Você foi enviado para uma região inválida.</string> - <string name="TestingDisconnect">Teste de desconexão</string> - <string name="SocialFacebookConnecting">Conectando ao Facebook...</string> - <string name="SocialFacebookPosting">Publicando...</string> - <string name="SocialFacebookDisconnecting">Desconectando do Facebook...</string> - <string name="SocialFacebookErrorConnecting">Problema ao conectar ao Facebook</string> - <string name="SocialFacebookErrorPosting">Problema ao publicar no Facebook</string> - <string name="SocialFacebookErrorDisconnecting">Problema ao desconectar do Facebook</string> - <string name="SocialFlickrConnecting">Conectando ao Flickr...</string> - <string name="SocialFlickrPosting">Publicando...</string> - <string name="SocialFlickrDisconnecting">Desconectando do Flickr...</string> - <string name="SocialFlickrErrorConnecting">Problema ao conectar ao Flickr</string> - <string name="SocialFlickrErrorPosting">Problema ao publicar no Flickr</string> - <string name="SocialFlickrErrorDisconnecting">Problema ao desconectar do Flickr</string> - <string name="SocialTwitterConnecting">Conectando ao Twitter...</string> - <string name="SocialTwitterPosting">Publicando...</string> - <string name="SocialTwitterDisconnecting">Desconectando do Twitter...</string> - <string name="SocialTwitterErrorConnecting">Problema ao conectar ao Twitter</string> - <string name="SocialTwitterErrorPosting">Problema ao publicar no Twitter</string> - <string name="SocialTwitterErrorDisconnecting">Problema ao desconectar do Twitter</string> - <string name="BlackAndWhite">Preto e branco</string> - <string name="Colors1970">Cores dos anos 1970</string> - <string name="Intense">Intenso</string> - <string name="Newspaper">Retícula</string> - <string name="Sepia">Sépia</string> - <string name="Spotlight">Destaque</string> - <string name="Video">Vídeo</string> - <string name="Autocontrast">Autocontraste</string> - <string name="LensFlare">Reflexo de flash</string> - <string name="Miniature">Miniatura</string> - <string name="Toycamera">Câmera de brinquedo</string> - <string name="TooltipPerson">Pessoa</string> - <string name="TooltipNoName">(sem nome)</string> - <string name="TooltipOwner">Proprietário:</string> - <string name="TooltipPublic">Público</string> - <string name="TooltipIsGroup">(Grupo)</string> - <string name="TooltipForSaleL$">À venda: L$[AMOUNT]</string> - <string name="TooltipFlagGroupBuild">Construído por Grupo</string> - <string name="TooltipFlagNoBuild">Não é permitido construir</string> - <string name="TooltipFlagNoEdit">Construído por Grupo</string> - <string name="TooltipFlagNotSafe">Não é seguro</string> - <string name="TooltipFlagNoFly">Não é permitido voar</string> - <string name="TooltipFlagGroupScripts">Scripts de Grupo</string> - <string name="TooltipFlagNoScripts">Não são permitidos scripts</string> - <string name="TooltipLand">Terreno:</string> - <string name="TooltipMustSingleDrop">Apenas um item único pode ser arrastado para este local</string> - <string name="TooltipTooManyWearables">Você não pode usar uma pasta que contenha mais de [AMOUNT] itens. Você pode mudar esse limite em Avançado > Mostrar configurações de depuração > WearFolderLimit.</string> +Pessoas com contas gratuitas não poderão acessar o Second Life no momento para dar espaço para aquelas que pagaram pelo Second Life. + </string> + <string name="LoginFailedComputerProhibited"> + O Second Life não pode ser acessado deste computador. Se você acredita que houve algum equívoco, contate support@secondlife.com. + </string> + <string name="LoginFailedAcountSuspended"> + Sua conta não está disponível para acesso até [TIME], horário do Pacífico nos EUA (GMT-08). + </string> + <string name="LoginFailedAccountDisabled"> + Não é possível concluir a solicitação neste momento. +Entre em contato com o suporte do Second Life para obter ajuda em http://support.secondlife.com. + </string> + <string name="LoginFailedTransformError"> + Dados discrepantes detectados durante o login. Contate support@secondlife.com. + </string> + <string name="LoginFailedAccountMaintenance"> + Sua conta está passando por um breve período de manutenção. Sua conta não está disponível para acesso até [TIME], horário do Pacífico nos EUA (GMT-08). Se você acredita que houve algum equívoco, contate support@secondlife.com. + </string> + <string name="LoginFailedPendingLogoutFault"> + Reação à solicitação de saída foi uma falha do simulador. + </string> + <string name="LoginFailedPendingLogout"> + O sistema o está desconectando no momento. +Aguarde um minuto antes que tentar logar-se novamente. + </string> + <string name="LoginFailedUnableToCreateSession"> + Impossível criar sessão válida. + </string> + <string name="LoginFailedUnableToConnectToSimulator"> + Não foi possível conectar o simulador. + </string> + <string name="LoginFailedRestrictedHours"> + Sua conta possui acesso ao Second Life das [START] às [END], horário da costa leste dos EUA. Volte novamente durante seu horário de acesso. Se você acredita que houve algum equívoco, contate support@secondlife.com. + </string> + <string name="LoginFailedIncorrectParameters"> + Parâmetros incorretos. Se você acredita que houve algum equívoco, contate support@secondlife.com. + </string> + <string name="LoginFailedFirstNameNotAlphanumeric"> + O parâmetro de primeiro nome deve ser alfanumérico. Se você acredita que houve algum equívoco, contate support@secondlife.com. + </string> + <string name="LoginFailedLastNameNotAlphanumeric"> + O parâmetro de sobrenome deve ser alfanumérico. Se você acredita que houve algum equívoco, contate support@secondlife.com. + </string> + <string name="LogoutFailedRegionGoingOffline"> + Região passando para modo offline. Tente novamente dentro de alguns instantes. + </string> + <string name="LogoutFailedAgentNotInRegion"> + Não há agente na região. Tente novamente dentro de alguns instantes. + </string> + <string name="LogoutFailedPendingLogin"> + A região estava acessada por outra sessão. Tente novamente dentro de alguns instantes. + </string> + <string name="LogoutFailedLoggingOut"> + A região estava passando para o modo offline na sessão anterior. Tente novamente dentro de alguns instantes. + </string> + <string name="LogoutFailedStillLoggingOut"> + A região estava passando para o modo offline na sessão anterior. Tente novamente dentro de alguns instantes. + </string> + <string name="LogoutSucceeded"> + A região passou para o modo offline na última sessão. Tente novamente dentro de alguns instantes. + </string> + <string name="LogoutFailedLogoutBegun"> + A região inicou o modo offline. Tente novamente dentro de alguns instantes. + </string> + <string name="LoginFailedLoggingOutSession"> + O sistema iniciou o modo offline em sua sessão anterior. Tente novamente dentro de alguns instantes. + </string> + <string name="AgentLostConnection"> + Esta região pode estar passando por problemas. Por favor, verifique sua conexão com a internet. + </string> + <string name="SavingSettings"> + Salvando configurações... + </string> + <string name="LoggingOut"> + Saindo... + </string> + <string name="ShuttingDown"> + Fechando... + </string> + <string name="YouHaveBeenDisconnected"> + Você foi desconectado da região onde estava. + </string> + <string name="SentToInvalidRegion"> + Você foi enviado para uma região inválida. + </string> + <string name="TestingDisconnect"> + Teste de desconexão + </string> + <string name="SocialFacebookConnecting"> + Conectando ao Facebook... + </string> + <string name="SocialFacebookPosting"> + Publicando... + </string> + <string name="SocialFacebookDisconnecting"> + Desconectando do Facebook... + </string> + <string name="SocialFacebookErrorConnecting"> + Problema ao conectar ao Facebook + </string> + <string name="SocialFacebookErrorPosting"> + Problema ao publicar no Facebook + </string> + <string name="SocialFacebookErrorDisconnecting"> + Problema ao desconectar do Facebook + </string> + <string name="SocialFlickrConnecting"> + Conectando ao Flickr... + </string> + <string name="SocialFlickrPosting"> + Publicando... + </string> + <string name="SocialFlickrDisconnecting"> + Desconectando do Flickr... + </string> + <string name="SocialFlickrErrorConnecting"> + Problema ao conectar ao Flickr + </string> + <string name="SocialFlickrErrorPosting"> + Problema ao publicar no Flickr + </string> + <string name="SocialFlickrErrorDisconnecting"> + Problema ao desconectar do Flickr + </string> + <string name="SocialTwitterConnecting"> + Conectando ao Twitter... + </string> + <string name="SocialTwitterPosting"> + Publicando... + </string> + <string name="SocialTwitterDisconnecting"> + Desconectando do Twitter... + </string> + <string name="SocialTwitterErrorConnecting"> + Problema ao conectar ao Twitter + </string> + <string name="SocialTwitterErrorPosting"> + Problema ao publicar no Twitter + </string> + <string name="SocialTwitterErrorDisconnecting"> + Problema ao desconectar do Twitter + </string> + <string name="BlackAndWhite"> + Preto e branco + </string> + <string name="Colors1970"> + Cores dos anos 1970 + </string> + <string name="Intense"> + Intenso + </string> + <string name="Newspaper"> + Retícula + </string> + <string name="Sepia"> + Sépia + </string> + <string name="Spotlight"> + Destaque + </string> + <string name="Video"> + Vídeo + </string> + <string name="Autocontrast"> + Autocontraste + </string> + <string name="LensFlare"> + Reflexo de flash + </string> + <string name="Miniature"> + Miniatura + </string> + <string name="Toycamera"> + Câmera de brinquedo + </string> + <string name="TooltipPerson"> + Pessoa + </string> + <string name="TooltipNoName"> + (sem nome) + </string> + <string name="TooltipOwner"> + Proprietário: + </string> + <string name="TooltipPublic"> + Público + </string> + <string name="TooltipIsGroup"> + (Grupo) + </string> + <string name="TooltipForSaleL$"> + À venda: L$[AMOUNT] + </string> + <string name="TooltipFlagGroupBuild"> + Construído por Grupo + </string> + <string name="TooltipFlagNoBuild"> + Não é permitido construir + </string> + <string name="TooltipFlagNoEdit"> + Construído por Grupo + </string> + <string name="TooltipFlagNotSafe"> + Não é seguro + </string> + <string name="TooltipFlagNoFly"> + Não é permitido voar + </string> + <string name="TooltipFlagGroupScripts"> + Scripts de Grupo + </string> + <string name="TooltipFlagNoScripts"> + Não são permitidos scripts + </string> + <string name="TooltipLand"> + Terreno: + </string> + <string name="TooltipMustSingleDrop"> + Apenas um item único pode ser arrastado para este local + </string> + <string name="TooltipTooManyWearables"> + Você não pode usar uma pasta que contenha mais de [AMOUNT] itens. Você pode mudar esse limite em Avançado > Mostrar configurações de depuração > WearFolderLimit. + </string> <string name="TooltipPrice" value="L$[AMOUNT]"/> - <string name="TooltipSLIcon">Isso contém um link para uma página no domínio oficial do SecondLife.com ou LindenLab.com.</string> - <string name="TooltipOutboxDragToWorld">Não é possível fazer rez de itens da pasta Listagens do Marketplace</string> - <string name="TooltipOutboxWorn">Não é possível colocar itens que você estiver usando na pasta Listagens do Marketplace</string> - <string name="TooltipOutboxFolderLevels">A profundidade das pastas aninhadas excede [AMOUNT]. Diminua a profundidade das pastas dentro de pastas. Agrupe os itens se necessário.</string> - <string name="TooltipOutboxTooManyFolders">O número de subpastas excede [AMOUNT]. Diminua a o número de pastas em sua listagem. Agrupe os itens se necessário.</string> - <string name="TooltipOutboxTooManyObjects">O número de itens excede [AMOUNT]. Para vender mais que [AMOUNT] itens em uma listagem, você deve agrupar alguns deles.</string> - <string name="TooltipOutboxTooManyStockItems">O número de itens de estoque excede [AMOUNT].</string> - <string name="TooltipOutboxCannotDropOnRoot">Você pode soltar somente itens ou pastas na aba TUDO ou NÃO ASSOCIADOS. Selecione uma dessas abas e mova seus itens ou pastas novamente.</string> - <string name="TooltipOutboxNoTransfer">Um ou mais objetos não podem ser vendidos ou transferidos</string> - <string name="TooltipOutboxNotInInventory">É possível colocar somente itens do seu inventário no Marketplace</string> - <string name="TooltipOutboxLinked">Não é possível colocar itens ou pastas vinculadas no Marketplace</string> - <string name="TooltipOutboxCallingCard">Não é possível colocar cartões de visitas no Marketplace</string> - <string name="TooltipOutboxDragActive">Não é possível mover uma listagem publicada</string> - <string name="TooltipOutboxCannotMoveRoot">Não é possível mover a pasta raiz das listagens do Marketplace</string> - <string name="TooltipOutboxMixedStock">Todos os itens em uma pasta de estoque têm o mesmo tipo e permissão</string> - <string name="TooltipDragOntoOwnChild">Não é possível mover uma pasta para seu filho</string> - <string name="TooltipDragOntoSelf">Não é possível mover uma pasta para dentro dela mesma</string> - <string name="TooltipHttpUrl">Clique para ver a página web</string> - <string name="TooltipSLURL">Clique para ver os dados desta localização</string> - <string name="TooltipAgentUrl">Clique para ver o perfil deste residente</string> - <string name="TooltipAgentInspect">Saiba mais sobre este residente</string> - <string name="TooltipAgentMute">Clique para silenciar este residente</string> - <string name="TooltipAgentUnmute">Clique para desfazer silenciar neste residente</string> - <string name="TooltipAgentIM">Clique para enviar uma MI para este residente</string> - <string name="TooltipAgentPay">Clique para pagar este residente</string> - <string name="TooltipAgentOfferTeleport">Clique para enviar um pedido de amizade a este residente</string> - <string name="TooltipAgentRequestFriend">Clique para enviar um pedido de amizade a este residente</string> - <string name="TooltipGroupUrl">Clique para ver a descrição deste Grupo</string> - <string name="TooltipEventUrl">Clique para ver a descrição deste evento</string> - <string name="TooltipClassifiedUrl">Clique para ver este anúncio</string> - <string name="TooltipParcelUrl">Clique para ver a descrição desta parcela</string> - <string name="TooltipTeleportUrl">Clique para teletransportar para esta localização</string> - <string name="TooltipObjectIMUrl">Clique para ver a descrição deste objeto</string> - <string name="TooltipMapUrl">Clique para ver esta localização no mapa</string> - <string name="TooltipSLAPP">Clique para ativar no secondlife:// comando</string> + <string name="TooltipSLIcon"> + Isso contém um link para uma página no domínio oficial do SecondLife.com ou LindenLab.com. + </string> + <string name="TooltipOutboxDragToWorld"> + Não é possível fazer rez de itens da pasta Listagens do Marketplace + </string> + <string name="TooltipOutboxWorn"> + Não é possível colocar itens que você estiver usando na pasta Listagens do Marketplace + </string> + <string name="TooltipOutboxFolderLevels"> + A profundidade das pastas aninhadas excede [AMOUNT]. Diminua a profundidade das pastas dentro de pastas. Agrupe os itens se necessário. + </string> + <string name="TooltipOutboxTooManyFolders"> + O número de subpastas excede [AMOUNT]. Diminua a o número de pastas em sua listagem. Agrupe os itens se necessário. + </string> + <string name="TooltipOutboxTooManyObjects"> + O número de itens excede [AMOUNT]. Para vender mais que [AMOUNT] itens em uma listagem, você deve agrupar alguns deles. + </string> + <string name="TooltipOutboxTooManyStockItems"> + O número de itens de estoque excede [AMOUNT]. + </string> + <string name="TooltipOutboxCannotDropOnRoot"> + Você pode soltar somente itens ou pastas na aba TUDO ou NÃO ASSOCIADOS. Selecione uma dessas abas e mova seus itens ou pastas novamente. + </string> + <string name="TooltipOutboxNoTransfer"> + Um ou mais objetos não podem ser vendidos ou transferidos + </string> + <string name="TooltipOutboxNotInInventory"> + É possível colocar somente itens do seu inventário no Marketplace + </string> + <string name="TooltipOutboxLinked"> + Não é possível colocar itens ou pastas vinculadas no Marketplace + </string> + <string name="TooltipOutboxCallingCard"> + Não é possível colocar cartões de visitas no Marketplace + </string> + <string name="TooltipOutboxDragActive"> + Não é possível mover uma listagem publicada + </string> + <string name="TooltipOutboxCannotMoveRoot"> + Não é possível mover a pasta raiz das listagens do Marketplace + </string> + <string name="TooltipOutboxMixedStock"> + Todos os itens em uma pasta de estoque têm o mesmo tipo e permissão + </string> + <string name="TooltipDragOntoOwnChild"> + Não é possível mover uma pasta para seu filho + </string> + <string name="TooltipDragOntoSelf"> + Não é possível mover uma pasta para dentro dela mesma + </string> + <string name="TooltipHttpUrl"> + Clique para ver a página web + </string> + <string name="TooltipSLURL"> + Clique para ver os dados desta localização + </string> + <string name="TooltipAgentUrl"> + Clique para ver o perfil deste residente + </string> + <string name="TooltipAgentInspect"> + Saiba mais sobre este residente + </string> + <string name="TooltipAgentMute"> + Clique para silenciar este residente + </string> + <string name="TooltipAgentUnmute"> + Clique para desfazer silenciar neste residente + </string> + <string name="TooltipAgentIM"> + Clique para enviar uma MI para este residente + </string> + <string name="TooltipAgentPay"> + Clique para pagar este residente + </string> + <string name="TooltipAgentOfferTeleport"> + Clique para enviar um pedido de amizade a este residente + </string> + <string name="TooltipAgentRequestFriend"> + Clique para enviar um pedido de amizade a este residente + </string> + <string name="TooltipGroupUrl"> + Clique para ver a descrição deste Grupo + </string> + <string name="TooltipEventUrl"> + Clique para ver a descrição deste evento + </string> + <string name="TooltipClassifiedUrl"> + Clique para ver este anúncio + </string> + <string name="TooltipParcelUrl"> + Clique para ver a descrição desta parcela + </string> + <string name="TooltipTeleportUrl"> + Clique para teletransportar para esta localização + </string> + <string name="TooltipObjectIMUrl"> + Clique para ver a descrição deste objeto + </string> + <string name="TooltipMapUrl"> + Clique para ver esta localização no mapa + </string> + <string name="TooltipSLAPP"> + Clique para ativar no secondlife:// comando + </string> <string name="CurrentURL" value="URL atual: [CurrentURL]"/> - <string name="TooltipEmail">Clique para escrever um email</string> - <string name="SLurlLabelTeleport">Teletransportar para</string> - <string name="SLurlLabelShowOnMap">Mostrar no mapa para</string> - <string name="SLappAgentMute">Silenciar</string> - <string name="SLappAgentUnmute">Desfazer silenciar</string> - <string name="SLappAgentIM">MI</string> - <string name="SLappAgentPay">Pagar</string> - <string name="SLappAgentOfferTeleport">Oferecer teletransporte para</string> - <string name="SLappAgentRequestFriend">Pedido de amizade</string> - <string name="SLappAgentRemoveFriend">Remoção de amigo</string> - <string name="BUTTON_CLOSE_DARWIN">Fechar (⌘W)</string> - <string name="BUTTON_CLOSE_WIN">Fechar (Ctrl+W)</string> - <string name="BUTTON_CLOSE_CHROME">Fechar</string> - <string name="BUTTON_RESTORE">Restaurar</string> - <string name="BUTTON_MINIMIZE">Minimizar</string> - <string name="BUTTON_TEAR_OFF">Separar-se da janela</string> - <string name="BUTTON_DOCK">conectar-se à barra</string> - <string name="BUTTON_HELP">Mostrar ajuda</string> - <string name="TooltipNotecardNotAllowedTypeDrop">Os itens deste tipo não podem ser anexados -às anotações desta região.</string> - <string name="TooltipNotecardOwnerRestrictedDrop">Somente itens com permissões irrestritas + <string name="TooltipEmail"> + Clique para escrever um email + </string> + <string name="SLurlLabelTeleport"> + Teletransportar para + </string> + <string name="SLurlLabelShowOnMap"> + Mostrar no mapa para + </string> + <string name="SLappAgentMute"> + Silenciar + </string> + <string name="SLappAgentUnmute"> + Desfazer silenciar + </string> + <string name="SLappAgentIM"> + MI + </string> + <string name="SLappAgentPay"> + Pagar + </string> + <string name="SLappAgentOfferTeleport"> + Oferecer teletransporte para + </string> + <string name="SLappAgentRequestFriend"> + Pedido de amizade + </string> + <string name="SLappAgentRemoveFriend"> + Remoção de amigo + </string> + <string name="BUTTON_CLOSE_DARWIN"> + Fechar (⌘W) + </string> + <string name="BUTTON_CLOSE_WIN"> + Fechar (Ctrl+W) + </string> + <string name="BUTTON_CLOSE_CHROME"> + Fechar + </string> + <string name="BUTTON_RESTORE"> + Restaurar + </string> + <string name="BUTTON_MINIMIZE"> + Minimizar + </string> + <string name="BUTTON_TEAR_OFF"> + Separar-se da janela + </string> + <string name="BUTTON_DOCK"> + conectar-se à barra + </string> + <string name="BUTTON_HELP"> + Mostrar ajuda + </string> + <string name="TooltipNotecardNotAllowedTypeDrop"> + Os itens deste tipo não podem ser anexados +às anotações desta região. + </string> + <string name="TooltipNotecardOwnerRestrictedDrop"> + Somente itens com permissões irrestritas do 'próximo proprietário’ pode -ser anexado às anotações.</string> - <string name="Searching">Buscando...</string> - <string name="NoneFound">Não encontrado.</string> - <string name="RetrievingData">Buscando...</string> - <string name="ReleaseNotes">Notas de versão</string> - <string name="RELEASE_NOTES_BASE_URL">https://releasenotes.secondlife.com/viewer/</string> - <string name="LoadingData">Carregando...</string> - <string name="AvatarNameNobody">(ninguém)</string> - <string name="AvatarNameWaiting">(aguardando)</string> - <string name="GroupNameNone">(nenhum)</string> - <string name="AssetErrorNone">Nenhum erro</string> - <string name="AssetErrorRequestFailed">Item pedido falhou</string> - <string name="AssetErrorNonexistentFile">Item pedido: arquivo inexistente</string> - <string name="AssetErrorNotInDatabase">Item pedido: item não encontrado na base de dados.</string> - <string name="AssetErrorEOF">Fim do arquivo</string> - <string name="AssetErrorCannotOpenFile">Não é possível abrir arquivo</string> - <string name="AssetErrorFileNotFound">Arquivo não encontrado</string> - <string name="AssetErrorTCPTimeout">Tempo de transferência de arquivo expirado</string> - <string name="AssetErrorCircuitGone">Circuito caiu</string> - <string name="AssetErrorPriceMismatch">Visualizador e servidor não concordam no preço</string> - <string name="AssetErrorUnknownStatus">Status desconhecido</string> - <string name="AssetUploadServerUnreacheble">Serviço não disponível.</string> - <string name="AssetUploadServerDifficulties">O servidor está enfrentando dificuldades inesperadas.</string> - <string name="AssetUploadServerUnavaliable">Serviço não disponível ou o tempo final para upload foi atingido.</string> - <string name="AssetUploadRequestInvalid">Erro na solicitação de upload. Acesso -http://secondlife.com/support para ajuda ao resolver este problema.</string> - <string name="SettingValidationError">Falha na validação para importação das configurações [NAME]</string> - <string name="SettingImportFileError">Não foi possível abrir o arquivo [FILE]</string> - <string name="SettingParseFileError">Não foi possível abrir o arquivo [FILE]</string> - <string name="SettingTranslateError">Não foi possível traduzir o vento antigo [NAME]</string> - <string name="texture">textura</string> - <string name="sound">som</string> - <string name="calling card">cartão de visitas</string> - <string name="landmark">landmark</string> - <string name="legacy script">script obsoleto</string> - <string name="clothing">roupas</string> - <string name="object">objeto</string> - <string name="note card">anotação</string> - <string name="folder">pasta</string> - <string name="root">raiz</string> - <string name="lsl2 script">script LSL2</string> - <string name="lsl bytecode">bytecode LSL</string> - <string name="tga texture">textura tga</string> - <string name="body part">parte do corpo</string> - <string name="snapshot">fotografia</string> - <string name="lost and found">Achados e Perdidos</string> - <string name="targa image">imagem targa</string> - <string name="trash">Lixo</string> - <string name="jpeg image">imagem jpeg</string> - <string name="animation">animação</string> - <string name="gesture">gesto</string> - <string name="simstate">simstate</string> - <string name="favorite">favorito</string> - <string name="symbolic link">link</string> - <string name="symbolic folder link">link da pasta</string> - <string name="settings blob">configurações</string> - <string name="mesh">mesh</string> - <string name="AvatarEditingAppearance">(Edição Aparência)</string> - <string name="AvatarAway">Distante</string> - <string name="AvatarDoNotDisturb">Não perturbe</string> - <string name="AvatarMuted">Mudo</string> - <string name="anim_express_afraid">Temeroso</string> - <string name="anim_express_anger">Bravo</string> - <string name="anim_away">Distante</string> - <string name="anim_backflip">Virar para trás</string> - <string name="anim_express_laugh">Rir segurando a barriga</string> - <string name="anim_express_toothsmile">Sorriso largo</string> - <string name="anim_blowkiss">Mandar beijo</string> - <string name="anim_express_bored">Entediado</string> - <string name="anim_bow">Reverência</string> - <string name="anim_clap">Aplaudir</string> - <string name="anim_courtbow">Saudação formal</string> - <string name="anim_express_cry">Chorar</string> - <string name="anim_dance1">Dança 1</string> - <string name="anim_dance2">Dança 2</string> - <string name="anim_dance3">Dança 3</string> - <string name="anim_dance4">Dança 4</string> - <string name="anim_dance5">Dança 5</string> - <string name="anim_dance6">Dança 6</string> - <string name="anim_dance7">Dança 7</string> - <string name="anim_dance8">Dança 8</string> - <string name="anim_express_disdain">Desdém</string> - <string name="anim_drink">Beber</string> - <string name="anim_express_embarrased">Envergonhado</string> - <string name="anim_angry_fingerwag">Negar com o dedo.</string> - <string name="anim_fist_pump">Vibrar provocando</string> - <string name="anim_yoga_float">Levitar Yoga</string> - <string name="anim_express_frown">Careta</string> - <string name="anim_impatient">Impaciente</string> - <string name="anim_jumpforjoy">Pular de alegria</string> - <string name="anim_kissmybutt">Beije meu bumbum</string> - <string name="anim_express_kiss">Beijar</string> - <string name="anim_laugh_short">Rir</string> - <string name="anim_musclebeach">Exibir músculos</string> - <string name="anim_no_unhappy">Não (descontente)</string> - <string name="anim_no_head">Não</string> - <string name="anim_nyanya">Nya-nya-nya</string> - <string name="anim_punch_onetwo">Soco um-dois</string> - <string name="anim_express_open_mouth">Abrir a boca</string> - <string name="anim_peace">Paz</string> - <string name="anim_point_you">Apontar para o outro</string> - <string name="anim_point_me">Apontar para si</string> - <string name="anim_punch_l">Soco esquerdo</string> - <string name="anim_punch_r">Soco direito</string> - <string name="anim_rps_countdown">RPS contar</string> - <string name="anim_rps_paper">RPS papel</string> - <string name="anim_rps_rock">RPS pedra</string> - <string name="anim_rps_scissors">RPS tesoura</string> - <string name="anim_express_repulsed">Repulsa</string> - <string name="anim_kick_roundhouse_r">Chute giratório</string> - <string name="anim_express_sad">Triste</string> - <string name="anim_salute">Saúde</string> - <string name="anim_shout">Gritar</string> - <string name="anim_express_shrug">Encolher ombros</string> - <string name="anim_express_smile">Sorrir</string> - <string name="anim_smoke_idle">Fumar à toa</string> - <string name="anim_smoke_inhale">Inalar fumaça</string> - <string name="anim_smoke_throw_down">Expelir fumaça</string> - <string name="anim_express_surprise">Surpresa</string> - <string name="anim_sword_strike_r">Golpe de espada</string> - <string name="anim_angry_tantrum">Enraivecer</string> - <string name="anim_express_tongue_out">Mostrar a língua</string> - <string name="anim_hello">Onda</string> - <string name="anim_whisper">Sussurrar</string> - <string name="anim_whistle">Assobiar</string> - <string name="anim_express_wink">Piscar</string> - <string name="anim_wink_hollywood">Piscar (Hollywood)</string> - <string name="anim_express_worry">Preocupar-se</string> - <string name="anim_yes_happy">Sim (Feliz)</string> - <string name="anim_yes_head">Sim</string> - <string name="multiple_textures">Múltiplo</string> - <string name="use_texture">Usar textura</string> - <string name="manip_hint1">Mova o cursor do mouse sobre a regra</string> - <string name="manip_hint2">para ajustar à grade</string> - <string name="texture_loading">Carregando...</string> - <string name="worldmap_offline">Offline</string> - <string name="worldmap_item_tooltip_format">L$[PRICE] por [AREA] m²</string> - <string name="worldmap_results_none_found">Nenhum encontrado.</string> - <string name="Ok">OK</string> - <string name="Premature end of file">término prematuro do arquivo</string> - <string name="ST_NO_JOINT">Não é possível encontrar a raiz (ROOT) ou junção (JOINT).</string> - <string name="NearbyChatTitle">Bate-papo local</string> - <string name="NearbyChatLabel">(Bate-papo local)</string> - <string name="whisper">sussurra:</string> - <string name="shout">grita:</string> - <string name="ringing">Conectando à conversa de voz no mundo</string> - <string name="connected">Conectado</string> - <string name="unavailable">Voz não disponível na sua localização atual</string> - <string name="hang_up">Desconectado da conversa de Voz no mundo</string> - <string name="reconnect_nearby">Agora você será reconectado ao bate-papo local.</string> - <string name="ScriptQuestionCautionChatGranted">'[OBJECTNAME]', um objeto de '[OWNERNAME]', localizado em [REGIONNAME] a [REGIONPOS], obteve permissão para: [PERMISSIONS].</string> - <string name="ScriptQuestionCautionChatDenied">'[OBJECTNAME]', um objeto de '[OWNERNAME]', localizado em [REGIONNAME] a [REGIONPOS], teve permissão negada para: [PERMISSIONS].</string> - <string name="AdditionalPermissionsRequestHeader">Se você permitir acesso à sua conta, o objeto também poderá:</string> - <string name="ScriptTakeMoney">Tomar linden dólares (L$) de você</string> - <string name="ActOnControlInputs">Atue nas suas entradas de controle</string> - <string name="RemapControlInputs">Remapeie suas entradas de controle</string> - <string name="AnimateYourAvatar">Faça uma animação para o seu avatar</string> - <string name="AttachToYourAvatar">Anexe ao seu avatar</string> - <string name="ReleaseOwnership">Libere a propriedade e torne-a pública</string> - <string name="LinkAndDelink">Una e desuna de outros objetos</string> - <string name="AddAndRemoveJoints">Adicione e remova junções com outros objetos</string> - <string name="ChangePermissions">Modifique as permissões</string> - <string name="TrackYourCamera">Acompanhe sua câmera</string> - <string name="ControlYourCamera">Controle sua camera</string> - <string name="TeleportYourAgent">Teletransportá-lo</string> - <string name="ForceSitAvatar">Forçar o avatar a sentar</string> - <string name="ChangeEnvSettings">Alterar sua configurações de ambiente</string> - <string name="AgentNameSubst">(Você)</string> +ser anexado às anotações. + </string> + <string name="Searching"> + Buscando... + </string> + <string name="NoneFound"> + Não encontrado. + </string> + <string name="RetrievingData"> + Buscando... + </string> + <string name="ReleaseNotes"> + Notas de versão + </string> + <string name="RELEASE_NOTES_BASE_URL"> + https://releasenotes.secondlife.com/viewer/ + </string> + <string name="LoadingData"> + Carregando... + </string> + <string name="AvatarNameNobody"> + (ninguém) + </string> + <string name="AvatarNameWaiting"> + (aguardando) + </string> + <string name="GroupNameNone"> + (nenhum) + </string> + <string name="AssetErrorNone"> + Nenhum erro + </string> + <string name="AssetErrorRequestFailed"> + Item pedido falhou + </string> + <string name="AssetErrorNonexistentFile"> + Item pedido: arquivo inexistente + </string> + <string name="AssetErrorNotInDatabase"> + Item pedido: item não encontrado na base de dados. + </string> + <string name="AssetErrorEOF"> + Fim do arquivo + </string> + <string name="AssetErrorCannotOpenFile"> + Não é possível abrir arquivo + </string> + <string name="AssetErrorFileNotFound"> + Arquivo não encontrado + </string> + <string name="AssetErrorTCPTimeout"> + Tempo de transferência de arquivo expirado + </string> + <string name="AssetErrorCircuitGone"> + Circuito caiu + </string> + <string name="AssetErrorPriceMismatch"> + Visualizador e servidor não concordam no preço + </string> + <string name="AssetErrorUnknownStatus"> + Status desconhecido + </string> + <string name="AssetUploadServerUnreacheble"> + Serviço não disponível. + </string> + <string name="AssetUploadServerDifficulties"> + O servidor está enfrentando dificuldades inesperadas. + </string> + <string name="AssetUploadServerUnavaliable"> + Serviço não disponível ou o tempo final para upload foi atingido. + </string> + <string name="AssetUploadRequestInvalid"> + Erro na solicitação de upload. Acesso +http://secondlife.com/support para ajuda ao resolver este problema. + </string> + <string name="SettingValidationError"> + Falha na validação para importação das configurações [NAME] + </string> + <string name="SettingImportFileError"> + Não foi possível abrir o arquivo [FILE] + </string> + <string name="SettingParseFileError"> + Não foi possível abrir o arquivo [FILE] + </string> + <string name="SettingTranslateError"> + Não foi possível traduzir o vento antigo [NAME] + </string> + <string name="texture"> + textura + </string> + <string name="sound"> + som + </string> + <string name="calling card"> + cartão de visitas + </string> + <string name="landmark"> + landmark + </string> + <string name="legacy script"> + script obsoleto + </string> + <string name="clothing"> + roupas + </string> + <string name="object"> + objeto + </string> + <string name="note card"> + anotação + </string> + <string name="folder"> + pasta + </string> + <string name="root"> + raiz + </string> + <string name="lsl2 script"> + script LSL2 + </string> + <string name="lsl bytecode"> + bytecode LSL + </string> + <string name="tga texture"> + textura tga + </string> + <string name="body part"> + parte do corpo + </string> + <string name="snapshot"> + fotografia + </string> + <string name="lost and found"> + Achados e Perdidos + </string> + <string name="targa image"> + imagem targa + </string> + <string name="trash"> + Lixo + </string> + <string name="jpeg image"> + imagem jpeg + </string> + <string name="animation"> + animação + </string> + <string name="gesture"> + gesto + </string> + <string name="simstate"> + simstate + </string> + <string name="favorite"> + favorito + </string> + <string name="symbolic link"> + link + </string> + <string name="symbolic folder link"> + link da pasta + </string> + <string name="settings blob"> + configurações + </string> + <string name="mesh"> + mesh + </string> + <string name="AvatarEditingAppearance"> + (Edição Aparência) + </string> + <string name="AvatarAway"> + Distante + </string> + <string name="AvatarDoNotDisturb"> + Não perturbe + </string> + <string name="AvatarMuted"> + Mudo + </string> + <string name="anim_express_afraid"> + Temeroso + </string> + <string name="anim_express_anger"> + Bravo + </string> + <string name="anim_away"> + Distante + </string> + <string name="anim_backflip"> + Virar para trás + </string> + <string name="anim_express_laugh"> + Rir segurando a barriga + </string> + <string name="anim_express_toothsmile"> + Sorriso largo + </string> + <string name="anim_blowkiss"> + Mandar beijo + </string> + <string name="anim_express_bored"> + Entediado + </string> + <string name="anim_bow"> + Reverência + </string> + <string name="anim_clap"> + Aplaudir + </string> + <string name="anim_courtbow"> + Saudação formal + </string> + <string name="anim_express_cry"> + Chorar + </string> + <string name="anim_dance1"> + Dança 1 + </string> + <string name="anim_dance2"> + Dança 2 + </string> + <string name="anim_dance3"> + Dança 3 + </string> + <string name="anim_dance4"> + Dança 4 + </string> + <string name="anim_dance5"> + Dança 5 + </string> + <string name="anim_dance6"> + Dança 6 + </string> + <string name="anim_dance7"> + Dança 7 + </string> + <string name="anim_dance8"> + Dança 8 + </string> + <string name="anim_express_disdain"> + Desdém + </string> + <string name="anim_drink"> + Beber + </string> + <string name="anim_express_embarrased"> + Envergonhado + </string> + <string name="anim_angry_fingerwag"> + Negar com o dedo. + </string> + <string name="anim_fist_pump"> + Vibrar provocando + </string> + <string name="anim_yoga_float"> + Levitar Yoga + </string> + <string name="anim_express_frown"> + Careta + </string> + <string name="anim_impatient"> + Impaciente + </string> + <string name="anim_jumpforjoy"> + Pular de alegria + </string> + <string name="anim_kissmybutt"> + Beije meu bumbum + </string> + <string name="anim_express_kiss"> + Beijar + </string> + <string name="anim_laugh_short"> + Rir + </string> + <string name="anim_musclebeach"> + Exibir músculos + </string> + <string name="anim_no_unhappy"> + Não (descontente) + </string> + <string name="anim_no_head"> + Não + </string> + <string name="anim_nyanya"> + Nya-nya-nya + </string> + <string name="anim_punch_onetwo"> + Soco um-dois + </string> + <string name="anim_express_open_mouth"> + Abrir a boca + </string> + <string name="anim_peace"> + Paz + </string> + <string name="anim_point_you"> + Apontar para o outro + </string> + <string name="anim_point_me"> + Apontar para si + </string> + <string name="anim_punch_l"> + Soco esquerdo + </string> + <string name="anim_punch_r"> + Soco direito + </string> + <string name="anim_rps_countdown"> + RPS contar + </string> + <string name="anim_rps_paper"> + RPS papel + </string> + <string name="anim_rps_rock"> + RPS pedra + </string> + <string name="anim_rps_scissors"> + RPS tesoura + </string> + <string name="anim_express_repulsed"> + Repulsa + </string> + <string name="anim_kick_roundhouse_r"> + Chute giratório + </string> + <string name="anim_express_sad"> + Triste + </string> + <string name="anim_salute"> + Saúde + </string> + <string name="anim_shout"> + Gritar + </string> + <string name="anim_express_shrug"> + Encolher ombros + </string> + <string name="anim_express_smile"> + Sorrir + </string> + <string name="anim_smoke_idle"> + Fumar à toa + </string> + <string name="anim_smoke_inhale"> + Inalar fumaça + </string> + <string name="anim_smoke_throw_down"> + Expelir fumaça + </string> + <string name="anim_express_surprise"> + Surpresa + </string> + <string name="anim_sword_strike_r"> + Golpe de espada + </string> + <string name="anim_angry_tantrum"> + Enraivecer + </string> + <string name="anim_express_tongue_out"> + Mostrar a língua + </string> + <string name="anim_hello"> + Onda + </string> + <string name="anim_whisper"> + Sussurrar + </string> + <string name="anim_whistle"> + Assobiar + </string> + <string name="anim_express_wink"> + Piscar + </string> + <string name="anim_wink_hollywood"> + Piscar (Hollywood) + </string> + <string name="anim_express_worry"> + Preocupar-se + </string> + <string name="anim_yes_happy"> + Sim (Feliz) + </string> + <string name="anim_yes_head"> + Sim + </string> + <string name="multiple_textures"> + Múltiplo + </string> + <string name="use_texture"> + Usar textura + </string> + <string name="manip_hint1"> + Mova o cursor do mouse sobre a regra + </string> + <string name="manip_hint2"> + para ajustar à grade + </string> + <string name="texture_loading"> + Carregando... + </string> + <string name="worldmap_offline"> + Offline + </string> + <string name="worldmap_item_tooltip_format"> + L$[PRICE] por [AREA] m² + </string> + <string name="worldmap_results_none_found"> + Nenhum encontrado. + </string> + <string name="Ok"> + OK + </string> + <string name="Premature end of file"> + término prematuro do arquivo + </string> + <string name="ST_NO_JOINT"> + Não é possível encontrar a raiz (ROOT) ou junção (JOINT). + </string> + <string name="NearbyChatTitle"> + Bate-papo local + </string> + <string name="NearbyChatLabel"> + (Bate-papo local) + </string> + <string name="whisper"> + sussurra: + </string> + <string name="shout"> + grita: + </string> + <string name="ringing"> + Conectando à conversa de voz no mundo + </string> + <string name="connected"> + Conectado + </string> + <string name="unavailable"> + Voz não disponível na sua localização atual + </string> + <string name="hang_up"> + Desconectado da conversa de Voz no mundo + </string> + <string name="reconnect_nearby"> + Agora você será reconectado ao bate-papo local. + </string> + <string name="ScriptQuestionCautionChatGranted"> + '[OBJECTNAME]', um objeto de '[OWNERNAME]', localizado em [REGIONNAME] a [REGIONPOS], obteve permissão para: [PERMISSIONS]. + </string> + <string name="ScriptQuestionCautionChatDenied"> + '[OBJECTNAME]', um objeto de '[OWNERNAME]', localizado em [REGIONNAME] a [REGIONPOS], teve permissão negada para: [PERMISSIONS]. + </string> + <string name="AdditionalPermissionsRequestHeader"> + Se você permitir acesso à sua conta, o objeto também poderá: + </string> + <string name="ScriptTakeMoney"> + Tomar linden dólares (L$) de você + </string> + <string name="ActOnControlInputs"> + Atue nas suas entradas de controle + </string> + <string name="RemapControlInputs"> + Remapeie suas entradas de controle + </string> + <string name="AnimateYourAvatar"> + Faça uma animação para o seu avatar + </string> + <string name="AttachToYourAvatar"> + Anexe ao seu avatar + </string> + <string name="ReleaseOwnership"> + Libere a propriedade e torne-a pública + </string> + <string name="LinkAndDelink"> + Una e desuna de outros objetos + </string> + <string name="AddAndRemoveJoints"> + Adicione e remova junções com outros objetos + </string> + <string name="ChangePermissions"> + Modifique as permissões + </string> + <string name="TrackYourCamera"> + Acompanhe sua câmera + </string> + <string name="ControlYourCamera"> + Controle sua camera + </string> + <string name="TeleportYourAgent"> + Teletransportá-lo + </string> + <string name="ForceSitAvatar"> + Forçar o avatar a sentar + </string> + <string name="ChangeEnvSettings"> + Alterar sua configurações de ambiente + </string> + <string name="AgentNameSubst"> + (Você) + </string> <string name="JoinAnExperience"/> - <string name="SilentlyManageEstateAccess">Suprimir alertas ao gerenciar listas de acesso ao terreno</string> - <string name="OverrideYourAnimations">Substituir suas animações padrão</string> - <string name="ScriptReturnObjects">Retornar objetos em seu nome</string> - <string name="UnknownScriptPermission">(desconhecido)!</string> - <string name="SIM_ACCESS_PG">Público geral</string> - <string name="SIM_ACCESS_MATURE">Moderado</string> - <string name="SIM_ACCESS_ADULT">Adulto</string> - <string name="SIM_ACCESS_DOWN">Desconectado</string> - <string name="SIM_ACCESS_MIN">Desconhecido</string> - <string name="land_type_unknown">(desconhecido)</string> - <string name="Estate / Full Region">Propriedadade / Região inteira:</string> - <string name="Estate / Homestead">Imóvel / Homestead</string> - <string name="Mainland / Homestead">Continente / Homestead</string> - <string name="Mainland / Full Region">Continente / Região inteira:</string> - <string name="all_files">Todos os arquivos</string> - <string name="sound_files">Sons</string> - <string name="animation_files">Animações</string> - <string name="image_files">Imagens</string> - <string name="save_file_verb">Salvar</string> - <string name="load_file_verb">Carregar</string> - <string name="targa_image_files">Imagens Targa</string> - <string name="bitmap_image_files">Imagens Bitmap</string> - <string name="png_image_files">Imagens PNG</string> - <string name="save_texture_image_files">Imagens targa ou PNG</string> - <string name="avi_movie_file">Arquivo de vídeo AVI</string> - <string name="xaf_animation_file">Arquivo de animação XAF</string> - <string name="xml_file">Arquivo XML</string> - <string name="raw_file">Arquivo RAW</string> - <string name="compressed_image_files">Imagens compactadas</string> - <string name="load_files">Carregar arquivos</string> - <string name="choose_the_directory">Selecionar pasta</string> - <string name="script_files">Scripts</string> - <string name="dictionary_files">Dicionários</string> - <string name="shape">Silhueta</string> - <string name="skin">Pele</string> - <string name="hair">Cabelo</string> - <string name="eyes">Olhos</string> - <string name="shirt">Camisa</string> - <string name="pants">Calças</string> - <string name="shoes">Sapatos</string> - <string name="socks">Meias</string> - <string name="jacket">Blusa</string> - <string name="gloves">Luvas</string> - <string name="undershirt">Camiseta</string> - <string name="underpants">Roupa de baixo</string> - <string name="skirt">Saia</string> - <string name="alpha">Alpha</string> - <string name="tattoo">Tatuagem</string> - <string name="universal">Universal</string> - <string name="physics">Físico</string> - <string name="invalid">Inválido</string> - <string name="none">nenhum</string> - <string name="shirt_not_worn">Camisa não vestida</string> - <string name="pants_not_worn">Calças não vestidas</string> - <string name="shoes_not_worn">Sapatos não calçados</string> - <string name="socks_not_worn">Meias não calçadas</string> - <string name="jacket_not_worn">Jaqueta não vestida</string> - <string name="gloves_not_worn">Luvas não calçadas</string> - <string name="undershirt_not_worn">Camiseta não vestida</string> - <string name="underpants_not_worn">Roupa de baixo não vestida</string> - <string name="skirt_not_worn">Saia não vestida</string> - <string name="alpha_not_worn">Alpha não vestido</string> - <string name="tattoo_not_worn">Tatuagem não usada</string> - <string name="universal_not_worn">Universal não usado</string> - <string name="physics_not_worn">Físico não usado</string> - <string name="invalid_not_worn">inválido</string> - <string name="create_new_shape">Criar novo físico</string> - <string name="create_new_skin">Criar pele nova</string> - <string name="create_new_hair">Criar cabelo novo</string> - <string name="create_new_eyes">Criar olhos novos</string> - <string name="create_new_shirt">Criar camisa nova</string> - <string name="create_new_pants">Criar calças novas</string> - <string name="create_new_shoes">Criar sapatos novos</string> - <string name="create_new_socks">Criar meias novas</string> - <string name="create_new_jacket">Criar jaqueta nova</string> - <string name="create_new_gloves">Criar luvas novas</string> - <string name="create_new_undershirt">Criar camiseta nova</string> - <string name="create_new_underpants">Criar roupa de baixo nova</string> - <string name="create_new_skirt">Criar saia nova</string> - <string name="create_new_alpha">Criar Alpha novo</string> - <string name="create_new_tattoo">Criar nova tatuagem</string> - <string name="create_new_universal">Criar um novo universal</string> - <string name="create_new_physics">Criar novo físico</string> - <string name="create_new_invalid">inválido</string> - <string name="NewWearable">Novo [WEARABLE_ITEM]</string> - <string name="next">Próximo</string> - <string name="ok">OK</string> - <string name="GroupNotifyGroupNotice">Anúncio de grupo</string> - <string name="GroupNotifyGroupNotices">Anúncios do grupo</string> - <string name="GroupNotifySentBy">Enviado por</string> - <string name="GroupNotifyAttached">Anexo:</string> - <string name="GroupNotifyViewPastNotices">Ver últimos anúncios ou optar por não receber essas mensagens aqui.</string> - <string name="GroupNotifyOpenAttachment">Abrir anexo</string> - <string name="GroupNotifySaveAttachment">Salvar anexo</string> - <string name="TeleportOffer">Oferta de teletransporte</string> - <string name="StartUpNotifications">Novas notificações chegaram enquanto você estava fora...</string> - <string name="OverflowInfoChannelString">Você tem mais [%d] notificações</string> - <string name="BodyPartsRightArm">Braço direito</string> - <string name="BodyPartsHead">Cabeça</string> - <string name="BodyPartsLeftArm">Braço esquerdo</string> - <string name="BodyPartsLeftLeg">Perna esquerda</string> - <string name="BodyPartsTorso">Tronco</string> - <string name="BodyPartsRightLeg">Perna direita</string> - <string name="BodyPartsEnhancedSkeleton">Esqueleto aprimorado</string> - <string name="GraphicsQualityLow">Baixo</string> - <string name="GraphicsQualityMid">Meio</string> - <string name="GraphicsQualityHigh">Alto</string> - <string name="LeaveMouselook">Pressione ESC para retornar para visão do mundo</string> - <string name="InventoryNoMatchingItems">Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search].</string> - <string name="InventoryNoMatchingRecentItems">Não encontrou o que procura? Tente [secondlife:///app/inventory/filters Show filters].</string> - <string name="PlacesNoMatchingItems">Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search].</string> - <string name="FavoritesNoMatchingItems">Arraste um marco para adicioná-lo aos seus favoritos.</string> - <string name="MarketplaceNoMatchingItems">Nenhum item correspondente encontrado. Verifique a ortografia de sua cadeia de pesquisa e tente novamente.</string> - <string name="InventoryNoTexture">Você não possui uma cópia desta textura no seu inventário</string> - <string name="InventoryInboxNoItems">Suas compras do Marketplace aparecerão aqui. Depois, você poderá arrastá-las para seu inventário para usá-las.</string> - <string name="MarketplaceURL">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/</string> - <string name="MarketplaceURL_CreateStore">http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3</string> - <string name="MarketplaceURL_Dashboard">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard</string> - <string name="MarketplaceURL_Imports">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports</string> - <string name="MarketplaceURL_LearnMore">https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more</string> - <string name="InventoryPlayAnimationTooltip">Abrir a janela com as opções do Jogo.</string> - <string name="InventoryPlayGestureTooltip">Executar o gesto selecionado no mundo.</string> - <string name="InventoryPlaySoundTooltip">Abrir a janela com as opções do Jogo.</string> - <string name="InventoryOutboxNotMerchantTitle">Qualquer um pode vender itens no Mercado.</string> + <string name="SilentlyManageEstateAccess"> + Suprimir alertas ao gerenciar listas de acesso ao terreno + </string> + <string name="OverrideYourAnimations"> + Substituir suas animações padrão + </string> + <string name="ScriptReturnObjects"> + Retornar objetos em seu nome + </string> + <string name="UnknownScriptPermission"> + (desconhecido)! + </string> + <string name="SIM_ACCESS_PG"> + Público geral + </string> + <string name="SIM_ACCESS_MATURE"> + Moderado + </string> + <string name="SIM_ACCESS_ADULT"> + Adulto + </string> + <string name="SIM_ACCESS_DOWN"> + Desconectado + </string> + <string name="SIM_ACCESS_MIN"> + Desconhecido + </string> + <string name="land_type_unknown"> + (desconhecido) + </string> + <string name="Estate / Full Region"> + Propriedadade / Região inteira: + </string> + <string name="Estate / Homestead"> + Imóvel / Homestead + </string> + <string name="Mainland / Homestead"> + Continente / Homestead + </string> + <string name="Mainland / Full Region"> + Continente / Região inteira: + </string> + <string name="all_files"> + Todos os arquivos + </string> + <string name="sound_files"> + Sons + </string> + <string name="animation_files"> + Animações + </string> + <string name="image_files"> + Imagens + </string> + <string name="save_file_verb"> + Salvar + </string> + <string name="load_file_verb"> + Carregar + </string> + <string name="targa_image_files"> + Imagens Targa + </string> + <string name="bitmap_image_files"> + Imagens Bitmap + </string> + <string name="png_image_files"> + Imagens PNG + </string> + <string name="save_texture_image_files"> + Imagens targa ou PNG + </string> + <string name="avi_movie_file"> + Arquivo de vídeo AVI + </string> + <string name="xaf_animation_file"> + Arquivo de animação XAF + </string> + <string name="xml_file"> + Arquivo XML + </string> + <string name="raw_file"> + Arquivo RAW + </string> + <string name="compressed_image_files"> + Imagens compactadas + </string> + <string name="load_files"> + Carregar arquivos + </string> + <string name="choose_the_directory"> + Selecionar pasta + </string> + <string name="script_files"> + Scripts + </string> + <string name="dictionary_files"> + Dicionários + </string> + <string name="shape"> + Silhueta + </string> + <string name="skin"> + Pele + </string> + <string name="hair"> + Cabelo + </string> + <string name="eyes"> + Olhos + </string> + <string name="shirt"> + Camisa + </string> + <string name="pants"> + Calças + </string> + <string name="shoes"> + Sapatos + </string> + <string name="socks"> + Meias + </string> + <string name="jacket"> + Blusa + </string> + <string name="gloves"> + Luvas + </string> + <string name="undershirt"> + Camiseta + </string> + <string name="underpants"> + Roupa de baixo + </string> + <string name="skirt"> + Saia + </string> + <string name="alpha"> + Alpha + </string> + <string name="tattoo"> + Tatuagem + </string> + <string name="universal"> + Universal + </string> + <string name="physics"> + Físico + </string> + <string name="invalid"> + Inválido + </string> + <string name="none"> + nenhum + </string> + <string name="shirt_not_worn"> + Camisa não vestida + </string> + <string name="pants_not_worn"> + Calças não vestidas + </string> + <string name="shoes_not_worn"> + Sapatos não calçados + </string> + <string name="socks_not_worn"> + Meias não calçadas + </string> + <string name="jacket_not_worn"> + Jaqueta não vestida + </string> + <string name="gloves_not_worn"> + Luvas não calçadas + </string> + <string name="undershirt_not_worn"> + Camiseta não vestida + </string> + <string name="underpants_not_worn"> + Roupa de baixo não vestida + </string> + <string name="skirt_not_worn"> + Saia não vestida + </string> + <string name="alpha_not_worn"> + Alpha não vestido + </string> + <string name="tattoo_not_worn"> + Tatuagem não usada + </string> + <string name="universal_not_worn"> + Universal não usado + </string> + <string name="physics_not_worn"> + Físico não usado + </string> + <string name="invalid_not_worn"> + inválido + </string> + <string name="create_new_shape"> + Criar novo físico + </string> + <string name="create_new_skin"> + Criar pele nova + </string> + <string name="create_new_hair"> + Criar cabelo novo + </string> + <string name="create_new_eyes"> + Criar olhos novos + </string> + <string name="create_new_shirt"> + Criar camisa nova + </string> + <string name="create_new_pants"> + Criar calças novas + </string> + <string name="create_new_shoes"> + Criar sapatos novos + </string> + <string name="create_new_socks"> + Criar meias novas + </string> + <string name="create_new_jacket"> + Criar jaqueta nova + </string> + <string name="create_new_gloves"> + Criar luvas novas + </string> + <string name="create_new_undershirt"> + Criar camiseta nova + </string> + <string name="create_new_underpants"> + Criar roupa de baixo nova + </string> + <string name="create_new_skirt"> + Criar saia nova + </string> + <string name="create_new_alpha"> + Criar Alpha novo + </string> + <string name="create_new_tattoo"> + Criar nova tatuagem + </string> + <string name="create_new_universal"> + Criar um novo universal + </string> + <string name="create_new_physics"> + Criar novo físico + </string> + <string name="create_new_invalid"> + inválido + </string> + <string name="NewWearable"> + Novo [WEARABLE_ITEM] + </string> + <string name="next"> + Próximo + </string> + <string name="ok"> + OK + </string> + <string name="GroupNotifyGroupNotice"> + Anúncio de grupo + </string> + <string name="GroupNotifyGroupNotices"> + Anúncios do grupo + </string> + <string name="GroupNotifySentBy"> + Enviado por + </string> + <string name="GroupNotifyAttached"> + Anexo: + </string> + <string name="GroupNotifyViewPastNotices"> + Ver últimos anúncios ou optar por não receber essas mensagens aqui. + </string> + <string name="GroupNotifyOpenAttachment"> + Abrir anexo + </string> + <string name="GroupNotifySaveAttachment"> + Salvar anexo + </string> + <string name="TeleportOffer"> + Oferta de teletransporte + </string> + <string name="StartUpNotifications"> + Novas notificações chegaram enquanto você estava fora... + </string> + <string name="OverflowInfoChannelString"> + Você tem mais [%d] notificações + </string> + <string name="BodyPartsRightArm"> + Braço direito + </string> + <string name="BodyPartsHead"> + Cabeça + </string> + <string name="BodyPartsLeftArm"> + Braço esquerdo + </string> + <string name="BodyPartsLeftLeg"> + Perna esquerda + </string> + <string name="BodyPartsTorso"> + Tronco + </string> + <string name="BodyPartsRightLeg"> + Perna direita + </string> + <string name="BodyPartsEnhancedSkeleton"> + Esqueleto aprimorado + </string> + <string name="GraphicsQualityLow"> + Baixo + </string> + <string name="GraphicsQualityMid"> + Meio + </string> + <string name="GraphicsQualityHigh"> + Alto + </string> + <string name="LeaveMouselook"> + Pressione ESC para retornar para visão do mundo + </string> + <string name="InventoryNoMatchingItems"> + Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]. + </string> + <string name="InventoryNoMatchingRecentItems"> + Não encontrou o que procura? Tente [secondlife:///app/inventory/filters Show filters]. + </string> + <string name="PlacesNoMatchingItems"> + Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search]. + </string> + <string name="FavoritesNoMatchingItems"> + Arraste um marco para adicioná-lo aos seus favoritos. + </string> + <string name="MarketplaceNoMatchingItems"> + Nenhum item correspondente encontrado. Verifique a ortografia de sua cadeia de pesquisa e tente novamente. + </string> + <string name="InventoryNoTexture"> + Você não possui uma cópia desta textura no seu inventário + </string> + <string name="InventoryInboxNoItems"> + Suas compras do Marketplace aparecerão aqui. Depois, você poderá arrastá-las para seu inventário para usá-las. + </string> + <string name="MarketplaceURL"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/ + </string> + <string name="MarketplaceURL_CreateStore"> + http://community.secondlife.com/t5/English-Knowledge-Base/Selling-in-the-Marketplace/ta-p/700193#Section_.3 + </string> + <string name="MarketplaceURL_Dashboard"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/dashboard + </string> + <string name="MarketplaceURL_Imports"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/merchants/store/imports + </string> + <string name="MarketplaceURL_LearnMore"> + https://marketplace.[MARKETPLACE_DOMAIN_NAME]/learn_more + </string> + <string name="InventoryPlayAnimationTooltip"> + Abrir a janela com as opções do Jogo. + </string> + <string name="InventoryPlayGestureTooltip"> + Executar o gesto selecionado no mundo. + </string> + <string name="InventoryPlaySoundTooltip"> + Abrir a janela com as opções do Jogo. + </string> + <string name="InventoryOutboxNotMerchantTitle"> + Qualquer um pode vender itens no Mercado. + </string> <string name="InventoryOutboxNotMerchantTooltip"/> - <string name="InventoryOutboxNotMerchant">Se você deseja se tornar um lojista, precisará [[MARKETPLACE_CREATE_STORE_URL] criar uma loja no Mercado].</string> - <string name="InventoryOutboxNoItemsTitle">Sua caixa de saída está vazia</string> + <string name="InventoryOutboxNotMerchant"> + Se você deseja se tornar um lojista, precisará [[MARKETPLACE_CREATE_STORE_URL] criar uma loja no Mercado]. + </string> + <string name="InventoryOutboxNoItemsTitle"> + Sua caixa de saída está vazia + </string> <string name="InventoryOutboxNoItemsTooltip"/> - <string name="InventoryOutboxNoItems">Arraste as pastas para estas áreas e então clique em "Enviar para Mercado" para listar os itens para venda no [[MARKETPLACE_DASHBOARD_URL] Mercado].</string> - <string name="InventoryOutboxInitializingTitle">Inicializando o Marketplace.</string> - <string name="InventoryOutboxInitializing">Estamos acessando sua conta na [loja [MARKETPLACE_CREATE_STORE_URL] do Marketplace].</string> - <string name="InventoryOutboxErrorTitle">Erros do Marketplace.</string> - <string name="InventoryOutboxError">A loja [[MARKETPLACE_CREATE_STORE_URL] no Marketplace] está retornando erros.</string> - <string name="InventoryMarketplaceError">Erro ao abrir as listagens do Marketplace. -Se você continuar a receber essa mensagem, entre em contato com o suporte do Second Life para obter ajuda em http://support.secondlife.com</string> - <string name="InventoryMarketplaceListingsNoItemsTitle">Sua pasta Listagens do Marketplace está vazia.</string> - <string name="InventoryMarketplaceListingsNoItems">Arraste pastas para esta área para listá-las para venda no [Marketplace [MARKETPLACE_DASHBOARD_URL]].</string> - <string name="InventoryItemsCount">( [ITEMS_COUNT] Items )</string> - <string name="Marketplace Validation Warning Stock">a pasta de estoque deve estar em uma pasta de versões</string> - <string name="Marketplace Validation Error Mixed Stock">: Erro: todos os itens em uma pasta de estoque devem ser de cópia proibida e todos do mesmo tipo</string> - <string name="Marketplace Validation Error Subfolder In Stock">: Erro: a pasta de estoque não pode ter subpastas</string> - <string name="Marketplace Validation Warning Empty">: Aviso: a pasta não contém itens</string> - <string name="Marketplace Validation Warning Create Stock">: Aviso: criando pasta de estoque</string> - <string name="Marketplace Validation Warning Create Version">: Aviso: criando pasta de versões</string> - <string name="Marketplace Validation Warning Move">: Aviso: movendo itens</string> - <string name="Marketplace Validation Warning Delete">: Aviso: conteúdo da pasta transferido para pasta de estoque, removendo pasta vazia</string> - <string name="Marketplace Validation Error Stock Item">: Erro: itens de cópia proibida devem estar em uma pasta de estoque</string> - <string name="Marketplace Validation Warning Unwrapped Item">: Aviso: os itens devem estar em uma pasta de versões</string> - <string name="Marketplace Validation Error">: Erro:</string> - <string name="Marketplace Validation Warning">: Aviso:</string> - <string name="Marketplace Validation Error Empty Version">: Aviso: a pasta de versões deve conter pelo menos 1 item</string> - <string name="Marketplace Validation Error Empty Stock">: Aviso: a pasta de estoque deve conter pelo menos 1 item</string> - <string name="Marketplace Validation No Error">Não há erros ou avisos</string> - <string name="Marketplace Error None">Sem erros</string> - <string name="Marketplace Error Prefix">Erro:</string> - <string name="Marketplace Error Not Merchant">antes de enviar os itens para o Marketplace, é necessário que você se defina como um lojista (sem custos).</string> - <string name="Marketplace Error Not Accepted">Não é possível mover o item nessa pasta.</string> - <string name="Marketplace Error Unsellable Item">Este item não pode ser vendido no Marketplace.</string> - <string name="MarketplaceNoID">no Mkt ID</string> - <string name="MarketplaceLive">publicada</string> - <string name="MarketplaceActive">ativo</string> - <string name="MarketplaceMax">máx</string> - <string name="MarketplaceStock">estoque</string> - <string name="MarketplaceNoStock">esgotado</string> - <string name="MarketplaceUpdating">atualizando...</string> - <string name="UploadFeeInfo">A taxa é baseada em seu nível de inscrição. Níveis mais altos possuem taxas mais baixas. [https://secondlife.com/my/account/membership.php? Saiba mais]</string> - <string name="Open landmarks">Marcos em aberto</string> - <string name="Unconstrained">Ilimitado</string> + <string name="InventoryOutboxNoItems"> + Arraste as pastas para estas áreas e então clique em "Enviar para Mercado" para listar os itens para venda no [[MARKETPLACE_DASHBOARD_URL] Mercado]. + </string> + <string name="InventoryOutboxInitializingTitle"> + Inicializando o Marketplace. + </string> + <string name="InventoryOutboxInitializing"> + Estamos acessando sua conta na [loja [MARKETPLACE_CREATE_STORE_URL] do Marketplace]. + </string> + <string name="InventoryOutboxErrorTitle"> + Erros do Marketplace. + </string> + <string name="InventoryOutboxError"> + A loja [[MARKETPLACE_CREATE_STORE_URL] no Marketplace] está retornando erros. + </string> + <string name="InventoryMarketplaceError"> + Erro ao abrir as listagens do Marketplace. +Se você continuar a receber essa mensagem, entre em contato com o suporte do Second Life para obter ajuda em http://support.secondlife.com + </string> + <string name="InventoryMarketplaceListingsNoItemsTitle"> + Sua pasta Listagens do Marketplace está vazia. + </string> + <string name="InventoryMarketplaceListingsNoItems"> + Arraste pastas para esta área para listá-las para venda no [Marketplace [MARKETPLACE_DASHBOARD_URL]]. + </string> + <string name="InventoryItemsCount"> + ( [ITEMS_COUNT] Items ) + </string> + <string name="Marketplace Validation Warning Stock"> + a pasta de estoque deve estar em uma pasta de versões + </string> + <string name="Marketplace Validation Error Mixed Stock"> + : Erro: todos os itens em uma pasta de estoque devem ser de cópia proibida e todos do mesmo tipo + </string> + <string name="Marketplace Validation Error Subfolder In Stock"> + : Erro: a pasta de estoque não pode ter subpastas + </string> + <string name="Marketplace Validation Warning Empty"> + : Aviso: a pasta não contém itens + </string> + <string name="Marketplace Validation Warning Create Stock"> + : Aviso: criando pasta de estoque + </string> + <string name="Marketplace Validation Warning Create Version"> + : Aviso: criando pasta de versões + </string> + <string name="Marketplace Validation Warning Move"> + : Aviso: movendo itens + </string> + <string name="Marketplace Validation Warning Delete"> + : Aviso: conteúdo da pasta transferido para pasta de estoque, removendo pasta vazia + </string> + <string name="Marketplace Validation Error Stock Item"> + : Erro: itens de cópia proibida devem estar em uma pasta de estoque + </string> + <string name="Marketplace Validation Warning Unwrapped Item"> + : Aviso: os itens devem estar em uma pasta de versões + </string> + <string name="Marketplace Validation Error"> + : Erro: + </string> + <string name="Marketplace Validation Warning"> + : Aviso: + </string> + <string name="Marketplace Validation Error Empty Version"> + : Aviso: a pasta de versões deve conter pelo menos 1 item + </string> + <string name="Marketplace Validation Error Empty Stock"> + : Aviso: a pasta de estoque deve conter pelo menos 1 item + </string> + <string name="Marketplace Validation No Error"> + Não há erros ou avisos + </string> + <string name="Marketplace Error None"> + Sem erros + </string> + <string name="Marketplace Error Prefix"> + Erro: + </string> + <string name="Marketplace Error Not Merchant"> + antes de enviar os itens para o Marketplace, é necessário que você se defina como um lojista (sem custos). + </string> + <string name="Marketplace Error Not Accepted"> + Não é possível mover o item nessa pasta. + </string> + <string name="Marketplace Error Unsellable Item"> + Este item não pode ser vendido no Marketplace. + </string> + <string name="MarketplaceNoID"> + no Mkt ID + </string> + <string name="MarketplaceLive"> + publicada + </string> + <string name="MarketplaceActive"> + ativo + </string> + <string name="MarketplaceMax"> + máx + </string> + <string name="MarketplaceStock"> + estoque + </string> + <string name="MarketplaceNoStock"> + esgotado + </string> + <string name="MarketplaceUpdating"> + atualizando... + </string> + <string name="UploadFeeInfo"> + A taxa é baseada em seu nível de inscrição. Níveis mais altos possuem taxas mais baixas. [https://secondlife.com/my/account/membership.php? Saiba mais] + </string> + <string name="Open landmarks"> + Marcos em aberto + </string> + <string name="Unconstrained"> + Ilimitado + </string> <string name="no_transfer" value="(não transferível)"/> <string name="no_modify" value="(não modificável)"/> <string name="no_copy" value="(não copiável)"/> <string name="worn" value="(vestido)"/> <string name="link" value="(link)"/> <string name="broken_link" value="(link_quebrado)""/> - <string name="LoadingContents">Carregando conteúdo...</string> - <string name="NoContents">Nenhum conteúdo</string> + <string name="LoadingContents"> + Carregando conteúdo... + </string> + <string name="NoContents"> + Nenhum conteúdo + </string> <string name="WornOnAttachmentPoint" value="(vestido em [ATTACHMENT_POINT])"/> <string name="AttachmentErrorMessage" value="([ATTACHMENT_ERROR])"/> <string name="ActiveGesture" value="[GESLABEL] (ativado)"/> @@ -595,1413 +1649,4139 @@ Se você continuar a receber essa mensagem, entre em contato com o suporte do Se <string name="Snapshots" value="Fotografias"/> <string name="No Filters" value="Não"/> <string name="Since Logoff" value="- Desde desligado"/> - <string name="InvFolder My Inventory">Meu inventário</string> - <string name="InvFolder Library">Biblioteca</string> - <string name="InvFolder Textures">Texturas</string> - <string name="InvFolder Sounds">Sons</string> - <string name="InvFolder Calling Cards">Cartões de visitas</string> - <string name="InvFolder Landmarks">Marcos</string> - <string name="InvFolder Scripts">Scripts</string> - <string name="InvFolder Clothing">Vestuário</string> - <string name="InvFolder Objects">Objetos</string> - <string name="InvFolder Notecards">Anotações</string> - <string name="InvFolder New Folder">Nova pasta</string> - <string name="InvFolder Inventory">Inventário</string> - <string name="InvFolder Uncompressed Images">Imagens descompactadas</string> - <string name="InvFolder Body Parts">Corpo</string> - <string name="InvFolder Trash">Lixo</string> - <string name="InvFolder Photo Album">Álbum de fotografias</string> - <string name="InvFolder Lost And Found">Achados e Perdidos</string> - <string name="InvFolder Uncompressed Sounds">Sons descompactados</string> - <string name="InvFolder Animations">Animações</string> - <string name="InvFolder Gestures">Gestos</string> - <string name="InvFolder Favorite">Meus favoritos</string> - <string name="InvFolder favorite">Meus favoritos</string> - <string name="InvFolder Favorites">Meus favoritos</string> - <string name="InvFolder favorites">Meus favoritos</string> - <string name="InvFolder Current Outfit">Look atual</string> - <string name="InvFolder Initial Outfits">Looks iniciais</string> - <string name="InvFolder My Outfits">Meus looks</string> - <string name="InvFolder Accessories">Acessórios</string> - <string name="InvFolder Meshes">Meshes:</string> - <string name="InvFolder Received Items">Itens recebidos</string> - <string name="InvFolder Merchant Outbox">Caixa de saída do lojista</string> - <string name="InvFolder Friends">Amigos</string> - <string name="InvFolder All">Tudo</string> - <string name="no_attachments">Nenhum anexo vestido</string> - <string name="Attachments remain">Anexos ([COUNT] slots permanecem)</string> - <string name="Buy">Comprar</string> - <string name="BuyforL$">Comprar por L$</string> - <string name="Stone">Pedra</string> - <string name="Metal">Metal</string> - <string name="Glass">Vidro</string> - <string name="Wood">Madeira</string> - <string name="Flesh">Carne</string> - <string name="Plastic">Plástico</string> - <string name="Rubber">Borrracha</string> - <string name="Light">Luz</string> - <string name="KBShift">Shift</string> - <string name="KBCtrl">Ctrl</string> - <string name="Chest">Peito</string> - <string name="Skull">Crânio</string> - <string name="Left Shoulder">Ombro esquerdo</string> - <string name="Right Shoulder">Ombro direito</string> - <string name="Left Hand">Mão esquerda</string> - <string name="Right Hand">Mão direita</string> - <string name="Left Foot">Pé esquerdo</string> - <string name="Right Foot">Pé direito</string> - <string name="Spine">Espinha</string> - <string name="Pelvis">Pélvis</string> - <string name="Mouth">Boca</string> - <string name="Chin">Queixo</string> - <string name="Left Ear">Orelha esquerda</string> - <string name="Right Ear">Orelha direita</string> - <string name="Left Eyeball">Globo ocular esquerdo</string> - <string name="Right Eyeball">Globo ocular direito</string> - <string name="Nose">Nariz</string> - <string name="R Upper Arm">Braço superior D</string> - <string name="R Forearm">Antebraço D</string> - <string name="L Upper Arm">Braço superior E</string> - <string name="L Forearm">Antebraço E</string> - <string name="Right Hip">Quadril direito</string> - <string name="R Upper Leg">Coxa D</string> - <string name="R Lower Leg">Perna inferior D</string> - <string name="Left Hip">Quadril esquerdo</string> - <string name="L Upper Leg">Coxa E</string> - <string name="L Lower Leg">Perna inferior E</string> - <string name="Stomach">Estômago</string> - <string name="Left Pec">Peitoral E</string> - <string name="Right Pec">Peitoral D</string> - <string name="Neck">Pescoço</string> - <string name="Avatar Center">Centro do avatar</string> - <string name="Left Ring Finger">Anelar esquerdo</string> - <string name="Right Ring Finger">Anelar direito</string> - <string name="Tail Base">Base do rabo</string> - <string name="Tail Tip">Ponta do rabo</string> - <string name="Left Wing">Asa esquerda</string> - <string name="Right Wing">Asa direita</string> - <string name="Jaw">Maxilar</string> - <string name="Alt Left Ear">Orelha esquerda alt.</string> - <string name="Alt Right Ear">Orelha direita alt.</string> - <string name="Alt Left Eye">Olho esquerdo alt.</string> - <string name="Alt Right Eye">Olho direito alt.</string> - <string name="Tongue">Língua</string> - <string name="Groin">Virilha</string> - <string name="Left Hind Foot">Pata esq. traseira</string> - <string name="Right Hind Foot">Pata dir. traseira</string> - <string name="Invalid Attachment">Ponto de encaixe inválido</string> - <string name="ATTACHMENT_MISSING_ITEM">Erro: item ausente</string> - <string name="ATTACHMENT_MISSING_BASE_ITEM">Erro: item base ausente</string> - <string name="ATTACHMENT_NOT_ATTACHED">Erro: o objeto está no look atual, mas não foi anexado</string> - <string name="YearsMonthsOld">[AGEYEARS] [AGEMONTHS] de idade</string> - <string name="YearsOld">[AGEYEARS] de idade</string> - <string name="MonthsOld">[AGEMONTHS] de idade</string> - <string name="WeeksOld">[AGEWEEKS] de idade</string> - <string name="DaysOld">[AGEDAYS] de idade</string> - <string name="TodayOld">Cadastrado hoje</string> - <string name="av_render_everyone_now">Agora, todos podem te ver.</string> - <string name="av_render_not_everyone">Sua renderização pode não acontecer para todos ao seu redor.</string> - <string name="av_render_over_half">Sua renderização pode não acontecer para metade das pessoas ao seu redor.</string> - <string name="av_render_most_of">Sua renderização pode não acontecer para a maioria das pessoas ao seu redor.</string> - <string name="av_render_anyone">Sua renderização pode não acontecer para ninguém ao seu redor.</string> - <string name="hud_description_total">Seu HUD</string> - <string name="hud_name_with_joint">[OBJ_NAME] (vestido em [JNT_NAME])</string> - <string name="hud_render_memory_warning">[HUD_DETAILS] usa muita memória de textura</string> - <string name="hud_render_cost_warning">[HUD_DETAILS] contém muitos objetos e texturas que utilizam o máximo de recursos</string> - <string name="hud_render_heavy_textures_warning">[HUD_DETAILS] contém muitas texturas grandes</string> - <string name="hud_render_cramped_warning">[HUD_DETAILS] contém muitos objetos</string> - <string name="hud_render_textures_warning">[HUD_DETAILS] contém muitas texturas</string> - <string name="AgeYearsA">[COUNT] ano</string> - <string name="AgeYearsB">[COUNT] anos</string> - <string name="AgeYearsC">[COUNT] anos</string> - <string name="AgeMonthsA">[COUNT] mês</string> - <string name="AgeMonthsB">[COUNT] meses</string> - <string name="AgeMonthsC">[COUNT] meses</string> - <string name="AgeWeeksA">[COUNT] semana</string> - <string name="AgeWeeksB">[COUNT] semanas</string> - <string name="AgeWeeksC">[COUNT] semanas</string> - <string name="AgeDaysA">[COUNT] dia</string> - <string name="AgeDaysB">[COUNT] dias</string> - <string name="AgeDaysC">[COUNT] dias</string> - <string name="GroupMembersA">[COUNT] membro</string> - <string name="GroupMembersB">[COUNT] membros</string> - <string name="GroupMembersC">[COUNT] membros</string> - <string name="AcctTypeResident">Residente</string> - <string name="AcctTypeTrial">Prova</string> - <string name="AcctTypeCharterMember">Lista de membros</string> - <string name="AcctTypeEmployee">Empregado da Linden Lab</string> - <string name="PaymentInfoUsed">Dados de pagamento usados</string> - <string name="PaymentInfoOnFile">Dados de pagamento fornecidos</string> - <string name="NoPaymentInfoOnFile">Nenhum dado de pagamento</string> - <string name="AgeVerified">Idade comprovada</string> - <string name="NotAgeVerified">Idade não comprovada</string> - <string name="Center 2">Centro 2</string> - <string name="Top Right">Topo direita</string> - <string name="Top">Topo</string> - <string name="Top Left">Topo esquerda</string> - <string name="Center">Centro</string> - <string name="Bottom Left">Inferior esquerdo</string> - <string name="Bottom">Inferior</string> - <string name="Bottom Right">Inferior direito</string> - <string name="CompileQueueDownloadedCompiling">Baixado, agora compilando</string> - <string name="CompileQueueServiceUnavailable">Serviço de compilação de scripts não disponível</string> - <string name="CompileQueueScriptNotFound">Script não encontrado no servidor.</string> - <string name="CompileQueueProblemDownloading">Problema no download</string> - <string name="CompileQueueInsufficientPermDownload">Permissões insuficientes para fazer o download do script.</string> - <string name="CompileQueueInsufficientPermFor">Permissões insuficientes para</string> - <string name="CompileQueueUnknownFailure">Falha desconhecida para download</string> - <string name="CompileNoExperiencePerm">Pulando script [SCRIPT] com experiência [EXPERIENCE]</string> - <string name="CompileQueueTitle">Progresso do recompilamento</string> - <string name="CompileQueueStart">recompilar</string> - <string name="ResetQueueTitle">Reset Progresso</string> - <string name="ResetQueueStart">Zerar</string> - <string name="RunQueueTitle">Definir funcionamento do progresso</string> - <string name="RunQueueStart">deixar funcionando</string> - <string name="NotRunQueueTitle">Definir progresso não funcionando</string> - <string name="NotRunQueueStart">não deixar funcionando</string> - <string name="CompileSuccessful">Compilação bem sucedida</string> - <string name="CompileSuccessfulSaving">Compilação bem sucedida, salvando...</string> - <string name="SaveComplete">Salvo.</string> - <string name="UploadFailed">Falha ao carregar arquivo:</string> - <string name="ObjectOutOfRange">Script (objeto fora de alcance)</string> - <string name="ScriptWasDeleted">Script (excluído do inventário)</string> - <string name="GodToolsObjectOwnedBy">Objeto [OBJECT] de propriedade de [OWNER]</string> - <string name="GroupsNone">nenhum</string> + <string name="InvFolder My Inventory"> + Meu inventário + </string> + <string name="InvFolder Library"> + Biblioteca + </string> + <string name="InvFolder Textures"> + Texturas + </string> + <string name="InvFolder Sounds"> + Sons + </string> + <string name="InvFolder Calling Cards"> + Cartões de visitas + </string> + <string name="InvFolder Landmarks"> + Marcos + </string> + <string name="InvFolder Scripts"> + Scripts + </string> + <string name="InvFolder Clothing"> + Vestuário + </string> + <string name="InvFolder Objects"> + Objetos + </string> + <string name="InvFolder Notecards"> + Anotações + </string> + <string name="InvFolder New Folder"> + Nova pasta + </string> + <string name="InvFolder Inventory"> + Inventário + </string> + <string name="InvFolder Uncompressed Images"> + Imagens descompactadas + </string> + <string name="InvFolder Body Parts"> + Corpo + </string> + <string name="InvFolder Trash"> + Lixo + </string> + <string name="InvFolder Photo Album"> + Álbum de fotografias + </string> + <string name="InvFolder Lost And Found"> + Achados e Perdidos + </string> + <string name="InvFolder Uncompressed Sounds"> + Sons descompactados + </string> + <string name="InvFolder Animations"> + Animações + </string> + <string name="InvFolder Gestures"> + Gestos + </string> + <string name="InvFolder Favorite"> + Meus favoritos + </string> + <string name="InvFolder favorite"> + Meus favoritos + </string> + <string name="InvFolder Favorites"> + Meus favoritos + </string> + <string name="InvFolder favorites"> + Meus favoritos + </string> + <string name="InvFolder Current Outfit"> + Look atual + </string> + <string name="InvFolder Initial Outfits"> + Looks iniciais + </string> + <string name="InvFolder My Outfits"> + Meus looks + </string> + <string name="InvFolder Accessories"> + Acessórios + </string> + <string name="InvFolder Meshes"> + Meshes: + </string> + <string name="InvFolder Received Items"> + Itens recebidos + </string> + <string name="InvFolder Merchant Outbox"> + Caixa de saída do lojista + </string> + <string name="InvFolder Friends"> + Amigos + </string> + <string name="InvFolder All"> + Tudo + </string> + <string name="no_attachments"> + Nenhum anexo vestido + </string> + <string name="Attachments remain"> + Anexos ([COUNT] slots permanecem) + </string> + <string name="Buy"> + Comprar + </string> + <string name="BuyforL$"> + Comprar por L$ + </string> + <string name="Stone"> + Pedra + </string> + <string name="Metal"> + Metal + </string> + <string name="Glass"> + Vidro + </string> + <string name="Wood"> + Madeira + </string> + <string name="Flesh"> + Carne + </string> + <string name="Plastic"> + Plástico + </string> + <string name="Rubber"> + Borrracha + </string> + <string name="Light"> + Luz + </string> + <string name="KBShift"> + Shift + </string> + <string name="KBCtrl"> + Ctrl + </string> + <string name="Chest"> + Peito + </string> + <string name="Skull"> + Crânio + </string> + <string name="Left Shoulder"> + Ombro esquerdo + </string> + <string name="Right Shoulder"> + Ombro direito + </string> + <string name="Left Hand"> + Mão esquerda + </string> + <string name="Right Hand"> + Mão direita + </string> + <string name="Left Foot"> + Pé esquerdo + </string> + <string name="Right Foot"> + Pé direito + </string> + <string name="Spine"> + Espinha + </string> + <string name="Pelvis"> + Pélvis + </string> + <string name="Mouth"> + Boca + </string> + <string name="Chin"> + Queixo + </string> + <string name="Left Ear"> + Orelha esquerda + </string> + <string name="Right Ear"> + Orelha direita + </string> + <string name="Left Eyeball"> + Globo ocular esquerdo + </string> + <string name="Right Eyeball"> + Globo ocular direito + </string> + <string name="Nose"> + Nariz + </string> + <string name="R Upper Arm"> + Braço superior D + </string> + <string name="R Forearm"> + Antebraço D + </string> + <string name="L Upper Arm"> + Braço superior E + </string> + <string name="L Forearm"> + Antebraço E + </string> + <string name="Right Hip"> + Quadril direito + </string> + <string name="R Upper Leg"> + Coxa D + </string> + <string name="R Lower Leg"> + Perna inferior D + </string> + <string name="Left Hip"> + Quadril esquerdo + </string> + <string name="L Upper Leg"> + Coxa E + </string> + <string name="L Lower Leg"> + Perna inferior E + </string> + <string name="Stomach"> + Estômago + </string> + <string name="Left Pec"> + Peitoral E + </string> + <string name="Right Pec"> + Peitoral D + </string> + <string name="Neck"> + Pescoço + </string> + <string name="Avatar Center"> + Centro do avatar + </string> + <string name="Left Ring Finger"> + Anelar esquerdo + </string> + <string name="Right Ring Finger"> + Anelar direito + </string> + <string name="Tail Base"> + Base do rabo + </string> + <string name="Tail Tip"> + Ponta do rabo + </string> + <string name="Left Wing"> + Asa esquerda + </string> + <string name="Right Wing"> + Asa direita + </string> + <string name="Jaw"> + Maxilar + </string> + <string name="Alt Left Ear"> + Orelha esquerda alt. + </string> + <string name="Alt Right Ear"> + Orelha direita alt. + </string> + <string name="Alt Left Eye"> + Olho esquerdo alt. + </string> + <string name="Alt Right Eye"> + Olho direito alt. + </string> + <string name="Tongue"> + Língua + </string> + <string name="Groin"> + Virilha + </string> + <string name="Left Hind Foot"> + Pata esq. traseira + </string> + <string name="Right Hind Foot"> + Pata dir. traseira + </string> + <string name="Invalid Attachment"> + Ponto de encaixe inválido + </string> + <string name="ATTACHMENT_MISSING_ITEM"> + Erro: item ausente + </string> + <string name="ATTACHMENT_MISSING_BASE_ITEM"> + Erro: item base ausente + </string> + <string name="ATTACHMENT_NOT_ATTACHED"> + Erro: o objeto está no look atual, mas não foi anexado + </string> + <string name="YearsMonthsOld"> + [AGEYEARS] [AGEMONTHS] de idade + </string> + <string name="YearsOld"> + [AGEYEARS] de idade + </string> + <string name="MonthsOld"> + [AGEMONTHS] de idade + </string> + <string name="WeeksOld"> + [AGEWEEKS] de idade + </string> + <string name="DaysOld"> + [AGEDAYS] de idade + </string> + <string name="TodayOld"> + Cadastrado hoje + </string> + <string name="av_render_everyone_now"> + Agora, todos podem te ver. + </string> + <string name="av_render_not_everyone"> + Sua renderização pode não acontecer para todos ao seu redor. + </string> + <string name="av_render_over_half"> + Sua renderização pode não acontecer para metade das pessoas ao seu redor. + </string> + <string name="av_render_most_of"> + Sua renderização pode não acontecer para a maioria das pessoas ao seu redor. + </string> + <string name="av_render_anyone"> + Sua renderização pode não acontecer para ninguém ao seu redor. + </string> + <string name="hud_description_total"> + Seu HUD + </string> + <string name="hud_name_with_joint"> + [OBJ_NAME] (vestido em [JNT_NAME]) + </string> + <string name="hud_render_memory_warning"> + [HUD_DETAILS] usa muita memória de textura + </string> + <string name="hud_render_cost_warning"> + [HUD_DETAILS] contém muitos objetos e texturas que utilizam o máximo de recursos + </string> + <string name="hud_render_heavy_textures_warning"> + [HUD_DETAILS] contém muitas texturas grandes + </string> + <string name="hud_render_cramped_warning"> + [HUD_DETAILS] contém muitos objetos + </string> + <string name="hud_render_textures_warning"> + [HUD_DETAILS] contém muitas texturas + </string> + <string name="AgeYearsA"> + [COUNT] ano + </string> + <string name="AgeYearsB"> + [COUNT] anos + </string> + <string name="AgeYearsC"> + [COUNT] anos + </string> + <string name="AgeMonthsA"> + [COUNT] mês + </string> + <string name="AgeMonthsB"> + [COUNT] meses + </string> + <string name="AgeMonthsC"> + [COUNT] meses + </string> + <string name="AgeWeeksA"> + [COUNT] semana + </string> + <string name="AgeWeeksB"> + [COUNT] semanas + </string> + <string name="AgeWeeksC"> + [COUNT] semanas + </string> + <string name="AgeDaysA"> + [COUNT] dia + </string> + <string name="AgeDaysB"> + [COUNT] dias + </string> + <string name="AgeDaysC"> + [COUNT] dias + </string> + <string name="GroupMembersA"> + [COUNT] membro + </string> + <string name="GroupMembersB"> + [COUNT] membros + </string> + <string name="GroupMembersC"> + [COUNT] membros + </string> + <string name="AcctTypeResident"> + Residente + </string> + <string name="AcctTypeTrial"> + Prova + </string> + <string name="AcctTypeCharterMember"> + Lista de membros + </string> + <string name="AcctTypeEmployee"> + Empregado da Linden Lab + </string> + <string name="PaymentInfoUsed"> + Dados de pagamento usados + </string> + <string name="PaymentInfoOnFile"> + Dados de pagamento fornecidos + </string> + <string name="NoPaymentInfoOnFile"> + Nenhum dado de pagamento + </string> + <string name="AgeVerified"> + Idade comprovada + </string> + <string name="NotAgeVerified"> + Idade não comprovada + </string> + <string name="Center 2"> + Centro 2 + </string> + <string name="Top Right"> + Topo direita + </string> + <string name="Top"> + Topo + </string> + <string name="Top Left"> + Topo esquerda + </string> + <string name="Center"> + Centro + </string> + <string name="Bottom Left"> + Inferior esquerdo + </string> + <string name="Bottom"> + Inferior + </string> + <string name="Bottom Right"> + Inferior direito + </string> + <string name="CompileQueueDownloadedCompiling"> + Baixado, agora compilando + </string> + <string name="CompileQueueServiceUnavailable"> + Serviço de compilação de scripts não disponível + </string> + <string name="CompileQueueScriptNotFound"> + Script não encontrado no servidor. + </string> + <string name="CompileQueueProblemDownloading"> + Problema no download + </string> + <string name="CompileQueueInsufficientPermDownload"> + Permissões insuficientes para fazer o download do script. + </string> + <string name="CompileQueueInsufficientPermFor"> + Permissões insuficientes para + </string> + <string name="CompileQueueUnknownFailure"> + Falha desconhecida para download + </string> + <string name="CompileNoExperiencePerm"> + Pulando script [SCRIPT] com experiência [EXPERIENCE] + </string> + <string name="CompileQueueTitle"> + Progresso do recompilamento + </string> + <string name="CompileQueueStart"> + recompilar + </string> + <string name="ResetQueueTitle"> + Reset Progresso + </string> + <string name="ResetQueueStart"> + Zerar + </string> + <string name="RunQueueTitle"> + Definir funcionamento do progresso + </string> + <string name="RunQueueStart"> + deixar funcionando + </string> + <string name="NotRunQueueTitle"> + Definir progresso não funcionando + </string> + <string name="NotRunQueueStart"> + não deixar funcionando + </string> + <string name="CompileSuccessful"> + Compilação bem sucedida + </string> + <string name="CompileSuccessfulSaving"> + Compilação bem sucedida, salvando... + </string> + <string name="SaveComplete"> + Salvo. + </string> + <string name="UploadFailed"> + Falha ao carregar arquivo: + </string> + <string name="ObjectOutOfRange"> + Script (objeto fora de alcance) + </string> + <string name="ScriptWasDeleted"> + Script (excluído do inventário) + </string> + <string name="GodToolsObjectOwnedBy"> + Objeto [OBJECT] de propriedade de [OWNER] + </string> + <string name="GroupsNone"> + nenhum + </string> <string name="Group" value="(grupo)"/> - <string name="Unknown">(Desconhecido)</string> + <string name="Unknown"> + (Desconhecido) + </string> <string name="SummaryForTheWeek" value="Resumo para esta semana, com início em "/> <string name="NextStipendDay" value=". Próximo dia de salário é "/> - <string name="GroupPlanningDate">[mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc]</string> + <string name="GroupPlanningDate"> + [mthnum,datetime,utc]/[day,datetime,utc]/[year,datetime,utc] + </string> <string name="GroupIndividualShare" value="Grupo Divisão individualI"/> <string name="GroupColumn" value="Grupo"/> - <string name="Balance">Balanço</string> - <string name="Credits">Créditos</string> - <string name="Debits">Débitos</string> - <string name="Total">Total</string> - <string name="NoGroupDataFound">Não há dados de grupo</string> - <string name="IMParentEstate">Propriedade-pai</string> - <string name="IMMainland">continente</string> - <string name="IMTeen">adolescente</string> - <string name="Anyone">qualquer um</string> - <string name="RegionInfoError">erro</string> - <string name="RegionInfoAllEstatesOwnedBy">todas as propriedades pertencem a [OWNER]</string> - <string name="RegionInfoAllEstatesYouOwn">todas as propriedades que você possui</string> - <string name="RegionInfoAllEstatesYouManage">todas as propriedades que você gerencia para [OWNER]</string> - <string name="RegionInfoAllowedResidents">Sempre permitido: ([ALLOWEDAGENTS], máx [MAXACCESS])</string> - <string name="RegionInfoAllowedGroups">Grupos sempre permitidos: ([ALLOWEDGROUPS], máx [MAXACCESS])</string> - <string name="RegionInfoBannedResidents">Grupos banidos: ([BANNEDAGENTS], máx [MAXBANNED])</string> - <string name="RegionInfoListTypeAllowedAgents">Sempre permitido</string> - <string name="RegionInfoListTypeBannedAgents">Sempre banido</string> - <string name="RegionInfoAllEstates">todos os terrenos</string> - <string name="RegionInfoManagedEstates">administre terrenos</string> - <string name="RegionInfoThisEstate">este terreno</string> - <string name="AndNMore">e [EXTRA_COUNT] mais</string> - <string name="ScriptLimitsParcelScriptMemory">Memória de scripts no lote</string> - <string name="ScriptLimitsParcelsOwned">Lotes listados: [PARCELS]</string> - <string name="ScriptLimitsMemoryUsed">Memória usada: [COUNT] kb de [MAX] kb; [AVAILABLE] kb disponíveis</string> - <string name="ScriptLimitsMemoryUsedSimple">Memória usada: [COUNT] kb</string> - <string name="ScriptLimitsParcelScriptURLs">URL dos scripts do lote</string> - <string name="ScriptLimitsURLsUsed">URLs usados: [COUNT] de [MAX]; [AVAILABLE] disponíveis</string> - <string name="ScriptLimitsURLsUsedSimple">URLs usados: [COUNT]</string> - <string name="ScriptLimitsRequestError">Erro ao solicitar dados</string> - <string name="ScriptLimitsRequestNoParcelSelected">Nenhum lote foi selecionado</string> - <string name="ScriptLimitsRequestWrongRegion">Erro: dados de script só disponíveis na região da posição atual</string> - <string name="ScriptLimitsRequestWaiting">Obtendo dados...</string> - <string name="ScriptLimitsRequestDontOwnParcel">Você não está autorizado a examinar este lote.</string> - <string name="SITTING_ON">Sentado em</string> - <string name="ATTACH_CHEST">Peito</string> - <string name="ATTACH_HEAD">Crânio</string> - <string name="ATTACH_LSHOULDER">Ombro esquerdo</string> - <string name="ATTACH_RSHOULDER">Ombro direito</string> - <string name="ATTACH_LHAND">Mão esquerda</string> - <string name="ATTACH_RHAND">Mão direita</string> - <string name="ATTACH_LFOOT">Pé esquerdo</string> - <string name="ATTACH_RFOOT">Pé direito</string> - <string name="ATTACH_BACK">Coluna</string> - <string name="ATTACH_PELVIS">Pélvis</string> - <string name="ATTACH_MOUTH">Boca</string> - <string name="ATTACH_CHIN">Queixo</string> - <string name="ATTACH_LEAR">Orelha esquerda</string> - <string name="ATTACH_REAR">Orelha direita</string> - <string name="ATTACH_LEYE">Olho esquerdo</string> - <string name="ATTACH_REYE">Olho direito</string> - <string name="ATTACH_NOSE">Nariz</string> - <string name="ATTACH_RUARM">Braço direito</string> - <string name="ATTACH_RLARM">Antebraço direito</string> - <string name="ATTACH_LUARM">Braço esquerdo</string> - <string name="ATTACH_LLARM">Antebraço esquerdo</string> - <string name="ATTACH_RHIP">Quadril direito</string> - <string name="ATTACH_RULEG">Coxa direita</string> - <string name="ATTACH_RLLEG">Perna direita</string> - <string name="ATTACH_LHIP">Quadril esquerdo</string> - <string name="ATTACH_LULEG">Coxa esquerda</string> - <string name="ATTACH_LLLEG">Perna esquerda</string> - <string name="ATTACH_BELLY">Estômago</string> - <string name="ATTACH_LEFT_PEC">Peitorais E</string> - <string name="ATTACH_RIGHT_PEC">Peitorais D</string> - <string name="ATTACH_HUD_CENTER_2">HUD Central 2</string> - <string name="ATTACH_HUD_TOP_RIGHT">HUD superior direito</string> - <string name="ATTACH_HUD_TOP_CENTER">HUD centro superior</string> - <string name="ATTACH_HUD_TOP_LEFT">HUD superior esquerdo</string> - <string name="ATTACH_HUD_CENTER_1">HUD Central 1</string> - <string name="ATTACH_HUD_BOTTOM_LEFT">HUD esquerda inferior</string> - <string name="ATTACH_HUD_BOTTOM">HUD inferior</string> - <string name="ATTACH_HUD_BOTTOM_RIGHT">HUD direito inferior</string> - <string name="ATTACH_NECK">Pescoço</string> - <string name="ATTACH_AVATAR_CENTER">Centro do avatar</string> - <string name="ATTACH_LHAND_RING1">Anelar esquerdo</string> - <string name="ATTACH_RHAND_RING1">Anelar direito</string> - <string name="ATTACH_TAIL_BASE">Base do rabo</string> - <string name="ATTACH_TAIL_TIP">Ponta do rabo</string> - <string name="ATTACH_LWING">Asa esquerda</string> - <string name="ATTACH_RWING">Asa direita</string> - <string name="ATTACH_FACE_JAW">Maxilar</string> - <string name="ATTACH_FACE_LEAR">Orelha esquerda alt.</string> - <string name="ATTACH_FACE_REAR">Orelha direita alt.</string> - <string name="ATTACH_FACE_LEYE">Olho esquerdo alt.</string> - <string name="ATTACH_FACE_REYE">Olho direito alt.</string> - <string name="ATTACH_FACE_TONGUE">Língua</string> - <string name="ATTACH_GROIN">Virilha</string> - <string name="ATTACH_HIND_LFOOT">Pata esq. traseira</string> - <string name="ATTACH_HIND_RFOOT">Pata dir. traseira</string> - <string name="CursorPos">Linha [LINE], Coluna [COLUMN]</string> - <string name="PanelDirCountFound">[COUNT] encontrado</string> - <string name="PanelContentsTooltip">Conteúdo do objeto</string> - <string name="PanelContentsNewScript">Novo Script</string> - <string name="DoNotDisturbModeResponseDefault">Este residente ativou o "Não perturbe" e verá sua mensagem mais tarde.</string> - <string name="MuteByName">(por nome)</string> - <string name="MuteAgent">(residente)</string> - <string name="MuteObject">(objeto)</string> - <string name="MuteGroup">(grupo)</string> - <string name="MuteExternal">(Externo)</string> - <string name="RegionNoCovenant">Não foi definido um contrato para essa região.</string> - <string name="RegionNoCovenantOtherOwner">Não foi definido um contrato para essa Região. O terreno nesta região está sendo vendido pelo Proprietário, não pela Linden Lab. Favor contatar o Proprietário da região para detalhes de venda.</string> + <string name="Balance"> + Balanço + </string> + <string name="Credits"> + Créditos + </string> + <string name="Debits"> + Débitos + </string> + <string name="Total"> + Total + </string> + <string name="NoGroupDataFound"> + Não há dados de grupo + </string> + <string name="IMParentEstate"> + Propriedade-pai + </string> + <string name="IMMainland"> + continente + </string> + <string name="IMTeen"> + adolescente + </string> + <string name="Anyone"> + qualquer um + </string> + <string name="RegionInfoError"> + erro + </string> + <string name="RegionInfoAllEstatesOwnedBy"> + todas as propriedades pertencem a [OWNER] + </string> + <string name="RegionInfoAllEstatesYouOwn"> + todas as propriedades que você possui + </string> + <string name="RegionInfoAllEstatesYouManage"> + todas as propriedades que você gerencia para [OWNER] + </string> + <string name="RegionInfoAllowedResidents"> + Sempre permitido: ([ALLOWEDAGENTS], máx [MAXACCESS]) + </string> + <string name="RegionInfoAllowedGroups"> + Grupos sempre permitidos: ([ALLOWEDGROUPS], máx [MAXACCESS]) + </string> + <string name="RegionInfoBannedResidents"> + Grupos banidos: ([BANNEDAGENTS], máx [MAXBANNED]) + </string> + <string name="RegionInfoListTypeAllowedAgents"> + Sempre permitido + </string> + <string name="RegionInfoListTypeBannedAgents"> + Sempre banido + </string> + <string name="RegionInfoAllEstates"> + todos os terrenos + </string> + <string name="RegionInfoManagedEstates"> + administre terrenos + </string> + <string name="RegionInfoThisEstate"> + este terreno + </string> + <string name="AndNMore"> + e [EXTRA_COUNT] mais + </string> + <string name="ScriptLimitsParcelScriptMemory"> + Memória de scripts no lote + </string> + <string name="ScriptLimitsParcelsOwned"> + Lotes listados: [PARCELS] + </string> + <string name="ScriptLimitsMemoryUsed"> + Memória usada: [COUNT] kb de [MAX] kb; [AVAILABLE] kb disponíveis + </string> + <string name="ScriptLimitsMemoryUsedSimple"> + Memória usada: [COUNT] kb + </string> + <string name="ScriptLimitsParcelScriptURLs"> + URL dos scripts do lote + </string> + <string name="ScriptLimitsURLsUsed"> + URLs usados: [COUNT] de [MAX]; [AVAILABLE] disponíveis + </string> + <string name="ScriptLimitsURLsUsedSimple"> + URLs usados: [COUNT] + </string> + <string name="ScriptLimitsRequestError"> + Erro ao solicitar dados + </string> + <string name="ScriptLimitsRequestNoParcelSelected"> + Nenhum lote foi selecionado + </string> + <string name="ScriptLimitsRequestWrongRegion"> + Erro: dados de script só disponíveis na região da posição atual + </string> + <string name="ScriptLimitsRequestWaiting"> + Obtendo dados... + </string> + <string name="ScriptLimitsRequestDontOwnParcel"> + Você não está autorizado a examinar este lote. + </string> + <string name="SITTING_ON"> + Sentado em + </string> + <string name="ATTACH_CHEST"> + Peito + </string> + <string name="ATTACH_HEAD"> + Crânio + </string> + <string name="ATTACH_LSHOULDER"> + Ombro esquerdo + </string> + <string name="ATTACH_RSHOULDER"> + Ombro direito + </string> + <string name="ATTACH_LHAND"> + Mão esquerda + </string> + <string name="ATTACH_RHAND"> + Mão direita + </string> + <string name="ATTACH_LFOOT"> + Pé esquerdo + </string> + <string name="ATTACH_RFOOT"> + Pé direito + </string> + <string name="ATTACH_BACK"> + Coluna + </string> + <string name="ATTACH_PELVIS"> + Pélvis + </string> + <string name="ATTACH_MOUTH"> + Boca + </string> + <string name="ATTACH_CHIN"> + Queixo + </string> + <string name="ATTACH_LEAR"> + Orelha esquerda + </string> + <string name="ATTACH_REAR"> + Orelha direita + </string> + <string name="ATTACH_LEYE"> + Olho esquerdo + </string> + <string name="ATTACH_REYE"> + Olho direito + </string> + <string name="ATTACH_NOSE"> + Nariz + </string> + <string name="ATTACH_RUARM"> + Braço direito + </string> + <string name="ATTACH_RLARM"> + Antebraço direito + </string> + <string name="ATTACH_LUARM"> + Braço esquerdo + </string> + <string name="ATTACH_LLARM"> + Antebraço esquerdo + </string> + <string name="ATTACH_RHIP"> + Quadril direito + </string> + <string name="ATTACH_RULEG"> + Coxa direita + </string> + <string name="ATTACH_RLLEG"> + Perna direita + </string> + <string name="ATTACH_LHIP"> + Quadril esquerdo + </string> + <string name="ATTACH_LULEG"> + Coxa esquerda + </string> + <string name="ATTACH_LLLEG"> + Perna esquerda + </string> + <string name="ATTACH_BELLY"> + Estômago + </string> + <string name="ATTACH_LEFT_PEC"> + Peitorais E + </string> + <string name="ATTACH_RIGHT_PEC"> + Peitorais D + </string> + <string name="ATTACH_HUD_CENTER_2"> + HUD Central 2 + </string> + <string name="ATTACH_HUD_TOP_RIGHT"> + HUD superior direito + </string> + <string name="ATTACH_HUD_TOP_CENTER"> + HUD centro superior + </string> + <string name="ATTACH_HUD_TOP_LEFT"> + HUD superior esquerdo + </string> + <string name="ATTACH_HUD_CENTER_1"> + HUD Central 1 + </string> + <string name="ATTACH_HUD_BOTTOM_LEFT"> + HUD esquerda inferior + </string> + <string name="ATTACH_HUD_BOTTOM"> + HUD inferior + </string> + <string name="ATTACH_HUD_BOTTOM_RIGHT"> + HUD direito inferior + </string> + <string name="ATTACH_NECK"> + Pescoço + </string> + <string name="ATTACH_AVATAR_CENTER"> + Centro do avatar + </string> + <string name="ATTACH_LHAND_RING1"> + Anelar esquerdo + </string> + <string name="ATTACH_RHAND_RING1"> + Anelar direito + </string> + <string name="ATTACH_TAIL_BASE"> + Base do rabo + </string> + <string name="ATTACH_TAIL_TIP"> + Ponta do rabo + </string> + <string name="ATTACH_LWING"> + Asa esquerda + </string> + <string name="ATTACH_RWING"> + Asa direita + </string> + <string name="ATTACH_FACE_JAW"> + Maxilar + </string> + <string name="ATTACH_FACE_LEAR"> + Orelha esquerda alt. + </string> + <string name="ATTACH_FACE_REAR"> + Orelha direita alt. + </string> + <string name="ATTACH_FACE_LEYE"> + Olho esquerdo alt. + </string> + <string name="ATTACH_FACE_REYE"> + Olho direito alt. + </string> + <string name="ATTACH_FACE_TONGUE"> + Língua + </string> + <string name="ATTACH_GROIN"> + Virilha + </string> + <string name="ATTACH_HIND_LFOOT"> + Pata esq. traseira + </string> + <string name="ATTACH_HIND_RFOOT"> + Pata dir. traseira + </string> + <string name="CursorPos"> + Linha [LINE], Coluna [COLUMN] + </string> + <string name="PanelDirCountFound"> + [COUNT] encontrado + </string> + <string name="PanelContentsTooltip"> + Conteúdo do objeto + </string> + <string name="PanelContentsNewScript"> + Novo Script + </string> + <string name="DoNotDisturbModeResponseDefault"> + Este residente ativou o "Não perturbe" e verá sua mensagem mais tarde. + </string> + <string name="MuteByName"> + (por nome) + </string> + <string name="MuteAgent"> + (residente) + </string> + <string name="MuteObject"> + (objeto) + </string> + <string name="MuteGroup"> + (grupo) + </string> + <string name="MuteExternal"> + (Externo) + </string> + <string name="RegionNoCovenant"> + Não foi definido um contrato para essa região. + </string> + <string name="RegionNoCovenantOtherOwner"> + Não foi definido um contrato para essa Região. O terreno nesta região está sendo vendido pelo Proprietário, não pela Linden Lab. Favor contatar o Proprietário da região para detalhes de venda. + </string> <string name="covenant_last_modified" value="Última modificação: "/> <string name="none_text" value="(nenhum)"/> <string name="never_text" value="(nunca)"/> - <string name="GroupOwned">Propriedade do Grupo</string> - <string name="Public">Público</string> - <string name="LocalSettings">Configurações locais</string> - <string name="RegionSettings">Configurações da região</string> - <string name="NoEnvironmentSettings">Esta Região não suporta as configurações do ambiente.</string> - <string name="EnvironmentSun">Dom</string> - <string name="EnvironmentMoon">Lua</string> - <string name="EnvironmentBloom">Florescer</string> - <string name="EnvironmentCloudNoise">Ruído na nuvem</string> - <string name="EnvironmentNormalMap">Mapa normal</string> - <string name="EnvironmentTransparent">Transparente</string> - <string name="ClassifiedClicksTxt">Cliques: [TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil</string> - <string name="ClassifiedUpdateAfterPublish">(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.</string> - <string name="NoPicksText">Você não criou nenhuma Escolha. Clique em Novo Botão para criar um Escolher</string> - <string name="NoClassifiedsText">Você criou nenhum Anúncio. Clique em Novo Botão para criar um Classificado</string> - <string name="NoAvatarPicksClassifiedsText">O usuário não tem nenhum destaque ou anúncio</string> - <string name="NoAvatarPicksText">Usuário não tem escolha</string> - <string name="NoAvatarClassifiedsText">Usuário não tem anúncio</string> - <string name="PicksClassifiedsLoadingText">Carregando...</string> - <string name="MultiPreviewTitle">Preview</string> - <string name="MultiPropertiesTitle">Propriedades</string> - <string name="InvOfferAnObjectNamed">um objeto chamado</string> - <string name="InvOfferOwnedByGroup">possuído pelo grupo</string> - <string name="InvOfferOwnedByUnknownGroup">de um grupo desconhecido</string> - <string name="InvOfferOwnedBy">de</string> - <string name="InvOfferOwnedByUnknownUser">de usuário desconhecido</string> - <string name="InvOfferGaveYou">deu a você</string> - <string name="InvOfferDecline">Você recusou um(a) [DESC] de <nolink>[NAME]</nolink>.</string> - <string name="GroupMoneyTotal">Total</string> - <string name="GroupMoneyBought">comprou</string> - <string name="GroupMoneyPaidYou">pagou a você</string> - <string name="GroupMoneyPaidInto">depositado</string> - <string name="GroupMoneyBoughtPassTo">comprou passe para</string> - <string name="GroupMoneyPaidFeeForEvent">pagou taxa para o evento</string> - <string name="GroupMoneyPaidPrizeForEvent">pagou prêmio para o evento</string> - <string name="GroupMoneyBalance">Saldo</string> - <string name="GroupMoneyCredits">Créditos</string> - <string name="GroupMoneyDebits">Débitos</string> - <string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string> - <string name="AcquiredItems">Itens adquiridos</string> - <string name="Cancel">Cancelar</string> - <string name="UploadingCosts">Carregar [NAME] custa L$ [AMOUNT]</string> - <string name="BuyingCosts">Isso custa L$ [AMOUNT]</string> - <string name="UnknownFileExtension">Extensão de arquivo desconhecida [.%s] -Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh</string> - <string name="MuteObject2">Bloquear</string> - <string name="AddLandmarkNavBarMenu">Adicionar marco...</string> - <string name="EditLandmarkNavBarMenu">Editar marco...</string> - <string name="accel-mac-control">⌃</string> - <string name="accel-mac-command">⌘</string> - <string name="accel-mac-option">⌥</string> - <string name="accel-mac-shift">⇧</string> - <string name="accel-win-control">Ctrl+</string> - <string name="accel-win-alt">Alt+</string> - <string name="accel-win-shift">Shift+</string> - <string name="FileSaved">Arquivo salvo</string> - <string name="Receiving">Recebendo</string> - <string name="AM">AM</string> - <string name="PM">PM</string> - <string name="PST">PST</string> - <string name="PDT">PDT</string> - <string name="Direction_Forward">Frente</string> - <string name="Direction_Left">Esquerda</string> - <string name="Direction_Right">Direita</string> - <string name="Direction_Back">Atrás</string> - <string name="Direction_North">Norte</string> - <string name="Direction_South">Sul</string> - <string name="Direction_West">Oeste</string> - <string name="Direction_East">Leste</string> - <string name="Direction_Up">P/ cima</string> - <string name="Direction_Down">P/ baixo</string> - <string name="Any Category">Qualquer categoria</string> - <string name="Shopping">Compras</string> - <string name="Land Rental">Aluguel de terrenos</string> - <string name="Property Rental">Aluguel de propriedade</string> - <string name="Special Attraction">Atração especial</string> - <string name="New Products">Novos Produtos</string> - <string name="Employment">Emprego</string> - <string name="Wanted">Desejado</string> - <string name="Service">Serviço</string> - <string name="Personal">Pessoal</string> - <string name="None">Nenhum</string> - <string name="Linden Location">Locação Linden</string> - <string name="Adult">Adulto</string> - <string name="Arts&Culture">Artes e Cultura</string> - <string name="Business">Negócios</string> - <string name="Educational">Educacional</string> - <string name="Gaming">Games</string> - <string name="Hangout">Moradia</string> - <string name="Newcomer Friendly">Para recém-chegados</string> - <string name="Parks&Nature">Parques & Natureza</string> - <string name="Residential">Residencial</string> - <string name="Stage">Estágio</string> - <string name="Other">Outros</string> - <string name="Rental">Aluguel</string> - <string name="Any">Qualquer</string> - <string name="You">Você</string> - <string name="Multiple Media">Mídia múltipla</string> - <string name="Play Media">Tocar/Pausar mídia</string> - <string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string> - <string name="NvidiaDriverPage">http://www.nvidia.com.br/Download/index.aspx?lang=br</string> - <string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string> - <string name="MBCmdLineError">Um erro foi encontrado analisando a linha de comando. + <string name="GroupOwned"> + Propriedade do Grupo + </string> + <string name="Public"> + Público + </string> + <string name="LocalSettings"> + Configurações locais + </string> + <string name="RegionSettings"> + Configurações da região + </string> + <string name="NoEnvironmentSettings"> + Esta Região não suporta as configurações do ambiente. + </string> + <string name="EnvironmentSun"> + Dom + </string> + <string name="EnvironmentMoon"> + Lua + </string> + <string name="EnvironmentBloom"> + Florescer + </string> + <string name="EnvironmentCloudNoise"> + Ruído na nuvem + </string> + <string name="EnvironmentNormalMap"> + Mapa normal + </string> + <string name="EnvironmentTransparent"> + Transparente + </string> + <string name="ClassifiedClicksTxt"> + Cliques: [TELEPORT] teletransporte, [MAP] mapa, [PROFILE] perfil + </string> + <string name="ClassifiedUpdateAfterPublish"> + (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. + </string> + <string name="NoPicksText"> + Você não criou nenhuma Escolha. Clique em Novo Botão para criar um Escolher + </string> + <string name="NoClassifiedsText"> + Você criou nenhum Anúncio. Clique em Novo Botão para criar um Classificado + </string> + <string name="NoAvatarPicksClassifiedsText"> + O usuário não tem nenhum destaque ou anúncio + </string> + <string name="NoAvatarPicksText"> + Usuário não tem escolha + </string> + <string name="NoAvatarClassifiedsText"> + Usuário não tem anúncio + </string> + <string name="PicksClassifiedsLoadingText"> + Carregando... + </string> + <string name="MultiPreviewTitle"> + Preview + </string> + <string name="MultiPropertiesTitle"> + Propriedades + </string> + <string name="InvOfferAnObjectNamed"> + um objeto chamado + </string> + <string name="InvOfferOwnedByGroup"> + possuído pelo grupo + </string> + <string name="InvOfferOwnedByUnknownGroup"> + de um grupo desconhecido + </string> + <string name="InvOfferOwnedBy"> + de + </string> + <string name="InvOfferOwnedByUnknownUser"> + de usuário desconhecido + </string> + <string name="InvOfferGaveYou"> + deu a você + </string> + <string name="InvOfferDecline"> + Você recusou um(a) [DESC] de <nolink>[NAME]</nolink>. + </string> + <string name="GroupMoneyTotal"> + Total + </string> + <string name="GroupMoneyBought"> + comprou + </string> + <string name="GroupMoneyPaidYou"> + pagou a você + </string> + <string name="GroupMoneyPaidInto"> + depositado + </string> + <string name="GroupMoneyBoughtPassTo"> + comprou passe para + </string> + <string name="GroupMoneyPaidFeeForEvent"> + pagou taxa para o evento + </string> + <string name="GroupMoneyPaidPrizeForEvent"> + pagou prêmio para o evento + </string> + <string name="GroupMoneyBalance"> + Saldo + </string> + <string name="GroupMoneyCredits"> + Créditos + </string> + <string name="GroupMoneyDebits"> + Débitos + </string> + <string name="GroupMoneyDate"> + [weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc] + </string> + <string name="AcquiredItems"> + Itens adquiridos + </string> + <string name="Cancel"> + Cancelar + </string> + <string name="UploadingCosts"> + Carregar [NAME] custa L$ [AMOUNT] + </string> + <string name="BuyingCosts"> + Isso custa L$ [AMOUNT] + </string> + <string name="UnknownFileExtension"> + Extensão de arquivo desconhecida [.%s] +Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh + </string> + <string name="MuteObject2"> + Bloquear + </string> + <string name="AddLandmarkNavBarMenu"> + Adicionar marco... + </string> + <string name="EditLandmarkNavBarMenu"> + Editar marco... + </string> + <string name="accel-mac-control"> + ⌃ + </string> + <string name="accel-mac-command"> + ⌘ + </string> + <string name="accel-mac-option"> + ⌥ + </string> + <string name="accel-mac-shift"> + ⇧ + </string> + <string name="accel-win-control"> + Ctrl+ + </string> + <string name="accel-win-alt"> + Alt+ + </string> + <string name="accel-win-shift"> + Shift+ + </string> + <string name="FileSaved"> + Arquivo salvo + </string> + <string name="Receiving"> + Recebendo + </string> + <string name="AM"> + AM + </string> + <string name="PM"> + PM + </string> + <string name="PST"> + PST + </string> + <string name="PDT"> + PDT + </string> + <string name="Direction_Forward"> + Frente + </string> + <string name="Direction_Left"> + Esquerda + </string> + <string name="Direction_Right"> + Direita + </string> + <string name="Direction_Back"> + Atrás + </string> + <string name="Direction_North"> + Norte + </string> + <string name="Direction_South"> + Sul + </string> + <string name="Direction_West"> + Oeste + </string> + <string name="Direction_East"> + Leste + </string> + <string name="Direction_Up"> + P/ cima + </string> + <string name="Direction_Down"> + P/ baixo + </string> + <string name="Any Category"> + Qualquer categoria + </string> + <string name="Shopping"> + Compras + </string> + <string name="Land Rental"> + Aluguel de terrenos + </string> + <string name="Property Rental"> + Aluguel de propriedade + </string> + <string name="Special Attraction"> + Atração especial + </string> + <string name="New Products"> + Novos Produtos + </string> + <string name="Employment"> + Emprego + </string> + <string name="Wanted"> + Desejado + </string> + <string name="Service"> + Serviço + </string> + <string name="Personal"> + Pessoal + </string> + <string name="None"> + Nenhum + </string> + <string name="Linden Location"> + Locação Linden + </string> + <string name="Adult"> + Adulto + </string> + <string name="Arts&Culture"> + Artes e Cultura + </string> + <string name="Business"> + Negócios + </string> + <string name="Educational"> + Educacional + </string> + <string name="Gaming"> + Games + </string> + <string name="Hangout"> + Moradia + </string> + <string name="Newcomer Friendly"> + Para recém-chegados + </string> + <string name="Parks&Nature"> + Parques & Natureza + </string> + <string name="Residential"> + Residencial + </string> + <string name="Stage"> + Estágio + </string> + <string name="Other"> + Outros + </string> + <string name="Rental"> + Aluguel + </string> + <string name="Any"> + Qualquer + </string> + <string name="You"> + Você + </string> + <string name="Multiple Media"> + Mídia múltipla + </string> + <string name="Play Media"> + Tocar/Pausar mídia + </string> + <string name="IntelDriverPage"> + http://www.intel.com/p/en_US/support/detect/graphics + </string> + <string name="NvidiaDriverPage"> + http://www.nvidia.com.br/Download/index.aspx?lang=br + </string> + <string name="AMDDriverPage"> + http://support.amd.com/us/Pages/AMDSupportHub.aspx + </string> + <string name="MBCmdLineError"> + Um erro foi encontrado analisando a linha de comando. Consulte: http://wiki.secondlife.com/wiki/Client_parameters -Erro:</string> - <string name="MBCmdLineUsg">[APP_NAME] Uso de linha de comando:</string> - <string name="MBUnableToAccessFile">[APP_NAME] não é capaz de acessar um arquivo que ele precisa. +Erro: + </string> + <string name="MBCmdLineUsg"> + [APP_NAME] Uso de linha de comando: + </string> + <string name="MBUnableToAccessFile"> + [APP_NAME] não é capaz de acessar um arquivo que ele precisa. Isto pode ocorrer porque você de alguma maneira tem várias cópias em execução, ou o seu sistema acredita de maneira incorreta que um arquivo está aberto. Se a mensagem persistir, reinicie o computador e tente novamente. -Se o error persistir, pode ser necessário desinstalar completamente [APP_NAME] e reinstalá-lo.</string> - <string name="MBFatalError">Erro fatal</string> - <string name="MBRequiresAltiVec">[APP_NAME] exige processador com AltiVec (G4 ou superior).</string> - <string name="MBAlreadyRunning">[APP_NAME] já está em execução. +Se o error persistir, pode ser necessário desinstalar completamente [APP_NAME] e reinstalá-lo. + </string> + <string name="MBFatalError"> + Erro fatal + </string> + <string name="MBRequiresAltiVec"> + [APP_NAME] exige processador com AltiVec (G4 ou superior). + </string> + <string name="MBAlreadyRunning"> + [APP_NAME] já está em execução. Verifique a sua barra de tarefas para obter uma cópia do programa minimizado. -Se a mensagem persistir, reinicie o computador.</string> - <string name="MBFrozenCrashed">[APP_NAME] parece ter congelado ou falhado na execução anterior. Enviar relatório de falha?</string> - <string name="MBAlert">Alerta</string> - <string name="MBNoDirectX">[APP_NAME] é incapaz de detectar o DirectX 9.0b ou superior. +Se a mensagem persistir, reinicie o computador. + </string> + <string name="MBFrozenCrashed"> + [APP_NAME] parece ter congelado ou falhado na execução anterior. Enviar relatório de falha? + </string> + <string name="MBAlert"> + Alerta + </string> + <string name="MBNoDirectX"> + [APP_NAME] é incapaz de detectar o DirectX 9.0b ou superior. [APP_NAME] usa o DirectX para a detecção de hardware e / ou controladores desatualizados que podem causar problemas de estabilidade, desempenho ruim e falhas. Embora você possa executar [APP_NAME] sem ele, nós recomendamos fortemente que utilize o DirectX 9.0b. -Deseja continuar?</string> - <string name="MBWarning">Aviso</string> - <string name="MBNoAutoUpdate">Atualização automática ainda não está implementada para o Linux. -Faça o download da versão mais recente do www.secondlife.com.</string> - <string name="MBRegClassFailed">RegisterClass falhou</string> - <string name="MBError">Erro</string> - <string name="MBFullScreenErr">Incapaz de funcionar com tela cheia de [WIDTH] x [HEIGHT]. -Executando em janela.</string> - <string name="MBDestroyWinFailed">Erro de desligamento ao destruir janela (DestroyWindow() failed)</string> - <string name="MBShutdownErr">Erro de desligamento</string> - <string name="MBDevContextErr">Não é possível fazer contexto do dispositivo GL</string> - <string name="MBPixelFmtErr">Não é possível encontrar um formato de pixel adequado</string> - <string name="MBPixelFmtDescErr">Não é possível encontrar descrição de formato de pixel</string> - <string name="MBTrueColorWindow">[APP_NAME] requer True Color (32-bit) para ser executado. -Por favor, vá para as configurações de vídeo do computador e defina o modo de cores para 32-bit.</string> - <string name="MBAlpha">[APP_NAME] é incapaz de executar porque ele não consegue obter um canal alpha de 8 bits. Geralmente isso ocorre devido a problemas de drivers da placa de vídeo. +Deseja continuar? + </string> + <string name="MBWarning"> + Aviso + </string> + <string name="MBNoAutoUpdate"> + Atualização automática ainda não está implementada para o Linux. +Faça o download da versão mais recente do www.secondlife.com. + </string> + <string name="MBRegClassFailed"> + RegisterClass falhou + </string> + <string name="MBError"> + Erro + </string> + <string name="MBFullScreenErr"> + Incapaz de funcionar com tela cheia de [WIDTH] x [HEIGHT]. +Executando em janela. + </string> + <string name="MBDestroyWinFailed"> + Erro de desligamento ao destruir janela (DestroyWindow() failed) + </string> + <string name="MBShutdownErr"> + Erro de desligamento + </string> + <string name="MBDevContextErr"> + Não é possível fazer contexto do dispositivo GL + </string> + <string name="MBPixelFmtErr"> + Não é possível encontrar um formato de pixel adequado + </string> + <string name="MBPixelFmtDescErr"> + Não é possível encontrar descrição de formato de pixel + </string> + <string name="MBTrueColorWindow"> + [APP_NAME] requer True Color (32-bit) para ser executado. +Por favor, vá para as configurações de vídeo do computador e defina o modo de cores para 32-bit. + </string> + <string name="MBAlpha"> + [APP_NAME] é incapaz de executar porque ele não consegue obter um canal alpha de 8 bits. Geralmente isso ocorre devido a problemas de drivers da placa de vídeo. Por favor, certifique-se que os últimos drivers da placa de vídeo estão instalados. Também não se esqueça de definir seu monitor para True Color (32-bit), em painéis de controle Configurações> Display>. -Se você continuar a receber esta mensagem, contate o [SUPPORT_SITE].</string> - <string name="MBPixelFmtSetErr">Não é possível definir o formato de pixel</string> - <string name="MBGLContextErr">Não é possível criar o contexto de renderização GL</string> - <string name="MBGLContextActErr">Não é possível ativar o contexto de renderização GL</string> - <string name="MBVideoDrvErr">[APP_NAME] é incapaz de funcionar por causa do seu driver de video não ter sido instalado corretamente, estão desatualizados, ou não são suportados pelo hardware. Por favor certifique-se que você possui os drivers de placa de vídeo mais recente e mesmo assim, tente reinstalá-los. +Se você continuar a receber esta mensagem, contate o [SUPPORT_SITE]. + </string> + <string name="MBPixelFmtSetErr"> + Não é possível definir o formato de pixel + </string> + <string name="MBGLContextErr"> + Não é possível criar o contexto de renderização GL + </string> + <string name="MBGLContextActErr"> + Não é possível ativar o contexto de renderização GL + </string> + <string name="MBVideoDrvErr"> + [APP_NAME] é incapaz de funcionar por causa do seu driver de video não ter sido instalado corretamente, estão desatualizados, ou não são suportados pelo hardware. Por favor certifique-se que você possui os drivers de placa de vídeo mais recente e mesmo assim, tente reinstalá-los. -If you continue to receive this message, contact the [SUPPORT_SITE].</string> - <string name="5 O'Clock Shadow">Barba por fazer</string> - <string name="All White">Todo branco</string> - <string name="Anime Eyes">Olhos de Anime</string> - <string name="Arced">Arqueados</string> - <string name="Arm Length">Comprimento do braço</string> - <string name="Attached">Anexado</string> - <string name="Attached Earlobes">Lóbulos da orelha anexados</string> - <string name="Back Fringe">corte traseiro</string> - <string name="Baggy">folgado</string> - <string name="Bangs">Franja</string> - <string name="Beady Eyes">Olhos pequenos</string> - <string name="Belly Size">Tamanho da barriga</string> - <string name="Big">Grande</string> - <string name="Big Butt">Bunda grande</string> - <string name="Big Hair Back">Cabelo volumoso: Trás</string> - <string name="Big Hair Front">Cabelo volumoso: Frente</string> - <string name="Big Hair Top">Cabelo volumoso: Topo</string> - <string name="Big Head">cabeça grande</string> - <string name="Big Pectorals">Peitorais grandes</string> - <string name="Big Spikes">Pontas grandes</string> - <string name="Black">Negro</string> - <string name="Blonde">Loiro</string> - <string name="Blonde Hair">Cabelo loiro</string> - <string name="Blush">Blush</string> - <string name="Blush Color">Cor do blush</string> - <string name="Blush Opacity">Opacidade do blush</string> - <string name="Body Definition">Definição do corpo</string> - <string name="Body Fat">Gordura</string> - <string name="Body Freckles">Sardas</string> - <string name="Body Thick">Corpo cheio</string> - <string name="Body Thickness">Ossatura</string> - <string name="Body Thin">Corpo magro</string> - <string name="Bow Legged">Pernas arqueadas</string> - <string name="Breast Buoyancy">Caimento dos seios</string> - <string name="Breast Cleavage">Separação dos seios</string> - <string name="Breast Size">Tamanho dos seios</string> - <string name="Bridge Width">Largura do nariz</string> - <string name="Broad">Largo</string> - <string name="Brow Size">Tamanho da sobrancelha</string> - <string name="Bug Eyes">Olhos saltados</string> - <string name="Bugged Eyes">Olhos esbugalhados</string> - <string name="Bulbous">Bulbos</string> - <string name="Bulbous Nose">Nariz em bulbo</string> - <string name="Breast Physics Mass">Seios - massa</string> - <string name="Breast Physics Smoothing">Seios - suavização</string> - <string name="Breast Physics Gravity">Seios - gravidade</string> - <string name="Breast Physics Drag">Seios - resistência do ar</string> - <string name="Breast Physics InOut Max Effect">Efeito máximo</string> - <string name="Breast Physics InOut Spring">Vibração</string> - <string name="Breast Physics InOut Gain">Ganho</string> - <string name="Breast Physics InOut Damping">Duração</string> - <string name="Breast Physics UpDown Max Effect">Efeito máximo</string> - <string name="Breast Physics UpDown Spring">Vibração</string> - <string name="Breast Physics UpDown Gain">Ganho</string> - <string name="Breast Physics UpDown Damping">Duração</string> - <string name="Breast Physics LeftRight Max Effect">Efeito máximo</string> - <string name="Breast Physics LeftRight Spring">Vibração</string> - <string name="Breast Physics LeftRight Gain">Ganho</string> - <string name="Breast Physics LeftRight Damping">Duração</string> - <string name="Belly Physics Mass">Barriga - massa</string> - <string name="Belly Physics Smoothing">Barriga - suavização</string> - <string name="Belly Physics Gravity">Barriga - gravidade</string> - <string name="Belly Physics Drag">Barriga - resistência do ar</string> - <string name="Belly Physics UpDown Max Effect">Efeito máximo</string> - <string name="Belly Physics UpDown Spring">Vibração</string> - <string name="Belly Physics UpDown Gain">Ganho</string> - <string name="Belly Physics UpDown Damping">Duração</string> - <string name="Butt Physics Mass">Nádegas - massa</string> - <string name="Butt Physics Smoothing">Nádegas - suavização</string> - <string name="Butt Physics Gravity">Nádegas - gravidade</string> - <string name="Butt Physics Drag">Nádegas - resistência do ar</string> - <string name="Butt Physics UpDown Max Effect">Efeito máximo</string> - <string name="Butt Physics UpDown Spring">Vibração</string> - <string name="Butt Physics UpDown Gain">Ganho</string> - <string name="Butt Physics UpDown Damping">Duração</string> - <string name="Butt Physics LeftRight Max Effect">Efeito máximo</string> - <string name="Butt Physics LeftRight Spring">Vibração</string> - <string name="Butt Physics LeftRight Gain">Ganho</string> - <string name="Butt Physics LeftRight Damping">Duração</string> - <string name="Bushy Eyebrows">Sobrancelhas grossas</string> - <string name="Bushy Hair">Cabelo grosso</string> - <string name="Butt Size">Tamanho do traseiro</string> - <string name="Butt Gravity">Nádegas - gravidade</string> - <string name="bustle skirt">Saia armada</string> - <string name="no bustle">Saia reta</string> - <string name="more bustle">Mais</string> - <string name="Chaplin">Chaplin</string> - <string name="Cheek Bones">Maçãs do rosto</string> - <string name="Chest Size">Tamanho do peito</string> - <string name="Chin Angle">Ângulo do queixo</string> - <string name="Chin Cleft">Fissura do queixo</string> - <string name="Chin Curtains">Barba de contorno</string> - <string name="Chin Depth">Profundidade do queixo</string> - <string name="Chin Heavy">Queixo pronunciado</string> - <string name="Chin In">Queixo para dentro</string> - <string name="Chin Out">Queixo para fora</string> - <string name="Chin-Neck">Queixo-pescoço</string> - <string name="Clear">Limpar</string> - <string name="Cleft">Fenda</string> - <string name="Close Set Eyes">Fechar conjunto de olhos</string> - <string name="Closed">Fechado</string> - <string name="Closed Back">Trás fechada</string> - <string name="Closed Front">Frente fechada</string> - <string name="Closed Left">Esquerda fechada</string> - <string name="Closed Right">Direita fechada</string> - <string name="Coin Purse">Pouco volume</string> - <string name="Collar Back">Colarinho posterior</string> - <string name="Collar Front">Colarinho anterior</string> - <string name="Corner Down">Canto para baixo</string> - <string name="Corner Up">Canto para cima</string> - <string name="Creased">Vincado</string> - <string name="Crooked Nose">Nariz torto</string> - <string name="Cuff Flare">Bainha larga</string> - <string name="Dark">Escuro</string> - <string name="Dark Green">Verde escuro</string> - <string name="Darker">Mais escuro</string> - <string name="Deep">Profundidade</string> - <string name="Default Heels">Salto padrão</string> - <string name="Dense">Densidade</string> - <string name="Double Chin">Queixo duplo</string> - <string name="Downturned">Curvado para baixo</string> - <string name="Duffle Bag">Mais volume</string> - <string name="Ear Angle">Ângulo da orelha</string> - <string name="Ear Size">Tamanho da orelha</string> - <string name="Ear Tips">Pontas das orelhas</string> - <string name="Egg Head">Cabeça oval</string> - <string name="Eye Bags">Olheiras</string> - <string name="Eye Color">Cor dos olhos</string> - <string name="Eye Depth">Profundidade dos olhos</string> - <string name="Eye Lightness">Luminosidade dos olhos</string> - <string name="Eye Opening">Abertura dos olhos</string> - <string name="Eye Pop">Olho saltado</string> - <string name="Eye Size">Tamanho dos olhos</string> - <string name="Eye Spacing">Espaçamento dos olhos</string> - <string name="Eyebrow Arc">Arco da sobrancelha</string> - <string name="Eyebrow Density">Densidade da sobrancelha</string> - <string name="Eyebrow Height">Altura da sobrancelha</string> - <string name="Eyebrow Points">Pontas da sobrancelha</string> - <string name="Eyebrow Size">Tamanho da sobrancelha</string> - <string name="Eyelash Length">Comprimento das pestanas</string> - <string name="Eyeliner">Delineador</string> - <string name="Eyeliner Color">Cor do delineador</string> - <string name="Eyes Bugged">Olhos esbugalhados</string> - <string name="Face Shear">Face raspada</string> - <string name="Facial Definition">Definição facial</string> - <string name="Far Set Eyes">Distância entre os olhos</string> - <string name="Fat Lips">Lábios carnudos</string> - <string name="Female">Feminino</string> - <string name="Fingerless">Dedos</string> - <string name="Fingers">Dedos</string> - <string name="Flared Cuffs">Punhos largos</string> - <string name="Flat">Chato</string> - <string name="Flat Butt">Traseiro chato</string> - <string name="Flat Head">Cabeça chata</string> - <string name="Flat Toe">Dedos dos pés chatos</string> - <string name="Foot Size">Tamanho dos pés</string> - <string name="Forehead Angle">Ângulo da testa</string> - <string name="Forehead Heavy">Testa pronunciada</string> - <string name="Freckles">Sardas</string> - <string name="Front Fringe">Franja</string> - <string name="Full Back">Trás cheia</string> - <string name="Full Eyeliner">Delienador cheio</string> - <string name="Full Front">Frente cheia</string> - <string name="Full Hair Sides">Cabelos laterais cheios</string> - <string name="Full Sides">Lados cheios</string> - <string name="Glossy">Brilhante</string> - <string name="Glove Fingers">Dedos da luva</string> - <string name="Glove Length">Comprimento das luvas</string> - <string name="Hair">Cabelo</string> - <string name="Hair Back">Cabelo: Trás</string> - <string name="Hair Front">Cabelo: Frente</string> - <string name="Hair Sides">Cabelos: Lateral</string> - <string name="Hair Sweep">Cabelo penteado</string> - <string name="Hair Thickess">Espessura do cabelo</string> - <string name="Hair Thickness">Espessura do cabelo</string> - <string name="Hair Tilt">Divisão do cabelo</string> - <string name="Hair Tilted Left">Divistão do cabelo esquerda</string> - <string name="Hair Tilted Right">Divisão do cabelo direita</string> - <string name="Hair Volume">Cabelo: Volume</string> - <string name="Hand Size">Tamanho das mãos</string> - <string name="Handlebars">Bigode</string> - <string name="Head Length">Comprimento da cabeça</string> - <string name="Head Shape">Formato da cabeça</string> - <string name="Head Size">Tamanho da cabeça</string> - <string name="Head Stretch">Extensão da cabeça</string> - <string name="Heel Height">Altura do salto</string> - <string name="Heel Shape">Formato do salto</string> - <string name="Height">Altura</string> - <string name="High">Alto</string> - <string name="High Heels">Salto alto</string> - <string name="High Jaw">Maxilar alto</string> - <string name="High Platforms">Plataformas altas</string> - <string name="High and Tight">Alto e justo</string> - <string name="Higher">Mais alto</string> - <string name="Hip Length">Comprimento do quadril</string> - <string name="Hip Width">Largura do quadril</string> - <string name="Hover">Pairar</string> - <string name="In">Dentro</string> - <string name="In Shdw Color">Cor da sombra interna</string> - <string name="In Shdw Opacity">Opacidade da sombra interna</string> - <string name="Inner Eye Corner">Canto interno dos olhos</string> - <string name="Inner Eye Shadow">Sombra interna dos olhos</string> - <string name="Inner Shadow">Sombra interna</string> - <string name="Jacket Length">Comprimento da blusa</string> - <string name="Jacket Wrinkles">Dobras da jaqueta</string> - <string name="Jaw Angle">Ângulo da mandíbula</string> - <string name="Jaw Jut">Posição do maxilar</string> - <string name="Jaw Shape">Formato do maxilar</string> - <string name="Join">Juntar</string> - <string name="Jowls">Papo</string> - <string name="Knee Angle">Ângulo do joelho</string> - <string name="Knock Kneed">Joelhos para dentro</string> - <string name="Large">Grande</string> - <string name="Large Hands">Mãos grandes</string> - <string name="Left Part">Parte esquerda</string> - <string name="Leg Length">Comprimento da perna</string> - <string name="Leg Muscles">Musculatura da perna</string> - <string name="Less">Menos</string> - <string name="Less Body Fat">Menos gordura</string> - <string name="Less Curtains">Menos barba</string> - <string name="Less Freckles">Menos sardas</string> - <string name="Less Full">Menos</string> - <string name="Less Gravity">Menos gravidade</string> - <string name="Less Love">Menos excesso</string> - <string name="Less Muscles">Menos músculos</string> - <string name="Less Muscular">Menos musculoso</string> - <string name="Less Rosy">Menos rosado</string> - <string name="Less Round">Menos arredondado</string> - <string name="Less Saddle">Menos ancas</string> - <string name="Less Square">Menos quadrado</string> - <string name="Less Volume">Menos volume</string> - <string name="Less soul">Menos alma</string> - <string name="Lighter">Lighter</string> - <string name="Lip Cleft">Fenda dos lábios</string> - <string name="Lip Cleft Depth">Profundidade da fenda dos lábios</string> - <string name="Lip Fullness">Volume dos lábios</string> - <string name="Lip Pinkness">Rosado dos lábios</string> - <string name="Lip Ratio">Proporção dos lábios</string> - <string name="Lip Thickness">Espessura dos lábios</string> - <string name="Lip Width">Largura dos lábios</string> - <string name="Lipgloss">Brilho dos lábios</string> - <string name="Lipstick">Batom</string> - <string name="Lipstick Color">Cor do batom</string> - <string name="Long">Longo</string> - <string name="Long Head">Cabeça alongada</string> - <string name="Long Hips">Lábios longos</string> - <string name="Long Legs">Pernas longas</string> - <string name="Long Neck">Pescoço longo</string> - <string name="Long Pigtails">Chiquinhas longas</string> - <string name="Long Ponytail">Rabo de cavalo longo</string> - <string name="Long Torso">Torso longo</string> - <string name="Long arms">Braços longos</string> - <string name="Loose Pants">Pantalonas</string> - <string name="Loose Shirt">Camisa folgada</string> - <string name="Loose Sleeves">Mangas folgadas</string> - <string name="Love Handles">Pneu</string> - <string name="Low">Baixo</string> - <string name="Low Heels">Salto baixo</string> - <string name="Low Jaw">Maxilar baixo</string> - <string name="Low Platforms">Plataformas baixas</string> - <string name="Low and Loose">Baixo e solto</string> - <string name="Lower">Mais baixo</string> - <string name="Lower Bridge">Mais baixa</string> - <string name="Lower Cheeks">Bochechas abaixadas</string> - <string name="Male">Masculino</string> - <string name="Middle Part">Parte do meio</string> - <string name="More">Mais</string> - <string name="More Blush">Mais blush</string> - <string name="More Body Fat">Mais gordura</string> - <string name="More Curtains">Mais barba</string> - <string name="More Eyeshadow">Mais sombra dos olhos</string> - <string name="More Freckles">Mais sardas</string> - <string name="More Full">Mais volume</string> - <string name="More Gravity">Mais gravidade</string> - <string name="More Lipstick">Mais batom</string> - <string name="More Love">Mais cintura</string> - <string name="More Lower Lip">Mais lábio inferior</string> - <string name="More Muscles">Mais músculos</string> - <string name="More Muscular">Mais musculoso</string> - <string name="More Rosy">Mais rosado</string> - <string name="More Round">Mais arredondado</string> - <string name="More Saddle">Mais ancas</string> - <string name="More Sloped">Mais inclinado</string> - <string name="More Square">Mais quadrado</string> - <string name="More Upper Lip">Mais lábios superiores</string> - <string name="More Vertical">Mais vertical</string> - <string name="More Volume">Mais volume</string> - <string name="More soul">Mais alma</string> - <string name="Moustache">Bigode</string> - <string name="Mouth Corner">Canto da boca</string> - <string name="Mouth Position">Posição da boca</string> - <string name="Mowhawk">Moicano</string> - <string name="Muscular">Muscular</string> - <string name="Mutton Chops">Costeletas</string> - <string name="Nail Polish">Esmate das unhas</string> - <string name="Nail Polish Color">Cor do esmalte das unhas</string> - <string name="Narrow">Estreito</string> - <string name="Narrow Back">Costas estreitas</string> - <string name="Narrow Front">Frente estreita</string> - <string name="Narrow Lips">Lábios estreitos</string> - <string name="Natural">Natural</string> - <string name="Neck Length">Comprimento do pescoço</string> - <string name="Neck Thickness">Espessura do pescoço</string> - <string name="No Blush">Sem blush</string> - <string name="No Eyeliner">Sem delineador</string> - <string name="No Eyeshadow">Sem sombra</string> - <string name="No Lipgloss">Sem brilho</string> - <string name="No Lipstick">Sem batom</string> - <string name="No Part">Sem parte</string> - <string name="No Polish">Sem esmalte</string> - <string name="No Red">Sem vermelho</string> - <string name="No Spikes">Sem pontas</string> - <string name="No White">Sem branco</string> - <string name="No Wrinkles">Sem dobras</string> - <string name="Normal Lower">Normal inferior</string> - <string name="Normal Upper">Normal superior</string> - <string name="Nose Left">Nariz para esquerda</string> - <string name="Nose Right">Nariz para direita</string> - <string name="Nose Size">Tamanho do nariz</string> - <string name="Nose Thickness">Espessura do nariz</string> - <string name="Nose Tip Angle">Ângulo da ponta do nariz</string> - <string name="Nose Tip Shape">Formato da ponta do nariz</string> - <string name="Nose Width">Largura do nariz</string> - <string name="Nostril Division">Divisão das narinas</string> - <string name="Nostril Width">Largura das narinas</string> - <string name="Opaque">Opaco</string> - <string name="Open">Abrir</string> - <string name="Open Back">Aberto atrás</string> - <string name="Open Front">Aberto na frente</string> - <string name="Open Left">Aberto esquerdo</string> - <string name="Open Right">Aberto direito</string> - <string name="Orange">Laranja</string> - <string name="Out">Fora</string> - <string name="Out Shdw Color">Cor da sombra externa</string> - <string name="Out Shdw Opacity">Opacidade da sombra externa</string> - <string name="Outer Eye Corner">Canto externo do olho</string> - <string name="Outer Eye Shadow">Sombra externa do olho</string> - <string name="Outer Shadow">Sombra externa</string> - <string name="Overbite">Má oclusão</string> - <string name="Package">Púbis</string> - <string name="Painted Nails">Unhas pintadas</string> - <string name="Pale">Pálido</string> - <string name="Pants Crotch">Cavalo da calça</string> - <string name="Pants Fit">Caimento das calças</string> - <string name="Pants Length">Comprimento das calças</string> - <string name="Pants Waist">Cintura da calça</string> - <string name="Pants Wrinkles">Dobras das calças</string> - <string name="Part">Parte</string> - <string name="Part Bangs">Divisão da franja</string> - <string name="Pectorals">Peitorais</string> - <string name="Pigment">Pigmento</string> - <string name="Pigtails">Chiquinhas</string> - <string name="Pink">Rosa</string> - <string name="Pinker">Mais rosado</string> - <string name="Platform Height">Altura da plataforma</string> - <string name="Platform Width">Largura da plataforma</string> - <string name="Pointy">Pontudo</string> - <string name="Pointy Heels">Salto agulha</string> - <string name="Ponytail">Rabo de cavalo</string> - <string name="Poofy Skirt">Saia bufante</string> - <string name="Pop Left Eye">Olho saltado esquerdo</string> - <string name="Pop Right Eye">Olho saltado direito</string> - <string name="Puffy">Inchado</string> - <string name="Puffy Eyelids">Pálpebras inchadas</string> - <string name="Rainbow Color">Cor do arco íris</string> - <string name="Red Hair">Cabelo ruivo</string> - <string name="Regular">Normal</string> - <string name="Right Part">Parte direita</string> - <string name="Rosy Complexion">Rosado da face</string> - <string name="Round">Arredondado</string> - <string name="Ruddiness">Rubor</string> - <string name="Ruddy">Corado</string> - <string name="Rumpled Hair">Cabelo desalinhado</string> - <string name="Saddle Bags">Culote</string> - <string name="Scrawny Leg">Pernas magricelas</string> - <string name="Separate">Separar</string> - <string name="Shallow">Raso</string> - <string name="Shear Back">Trás rente</string> - <string name="Shear Face">Face raspada</string> - <string name="Shear Front">Frente rente</string> - <string name="Shear Left Up">Esquerda rente para cima</string> - <string name="Shear Right Up">Trás rente para cima</string> - <string name="Sheared Back">Rente atrás</string> - <string name="Sheared Front">Rente frente</string> - <string name="Shift Left">Deslocar p/ esquerda</string> - <string name="Shift Mouth">Deslocar boca</string> - <string name="Shift Right">Deslocar p/ direita</string> - <string name="Shirt Bottom">Barra da camisa</string> - <string name="Shirt Fit">Ajuste da camisa</string> - <string name="Shirt Wrinkles">+/- amassada</string> - <string name="Shoe Height">Altura do sapato</string> - <string name="Short">Curto</string> - <string name="Short Arms">Braços curtos</string> - <string name="Short Legs">Pernas curtas</string> - <string name="Short Neck">Pescoço curto</string> - <string name="Short Pigtails">Chiquinhas curtas</string> - <string name="Short Ponytail">Rabo de cavalo curto</string> - <string name="Short Sideburns">Costeletas curtas</string> - <string name="Short Torso">Tronco curto</string> - <string name="Short hips">Quadril curto</string> - <string name="Shoulders">Ombros</string> - <string name="Side Fringe">pontas laterais</string> - <string name="Sideburns">Costeletas</string> - <string name="Sides Hair">Cabelo lateral</string> - <string name="Sides Hair Down">Cabelo lateral long</string> - <string name="Sides Hair Up">Cabelo lateral superior</string> - <string name="Skinny Neck">Pescoço fino</string> - <string name="Skirt Fit">Ajuste de saia</string> - <string name="Skirt Length">Comprimento da saia</string> - <string name="Slanted Forehead">Testa inclinada</string> - <string name="Sleeve Length">Comprimento da manga</string> - <string name="Sleeve Looseness">Folga da manga</string> - <string name="Slit Back">Abertura : Atrás</string> - <string name="Slit Front">Abertura: Frente</string> - <string name="Slit Left">Abertura: Esquerda</string> - <string name="Slit Right">Abertura: Direita</string> - <string name="Small">Pequeno</string> - <string name="Small Hands">Mãos pequenas</string> - <string name="Small Head">Cabeça pequena</string> - <string name="Smooth">Suavizar</string> - <string name="Smooth Hair">Suavizar cabelo</string> - <string name="Socks Length">Comprimento das meias</string> - <string name="Soulpatch">Cavanhaque</string> - <string name="Sparse">Disperso</string> - <string name="Spiked Hair">Cabelo espetado</string> - <string name="Square">Quadrado</string> - <string name="Square Toe">Dedo quadrado</string> - <string name="Squash Head">Cabeça de Pera</string> - <string name="Stretch Head">Cabeça esticada</string> - <string name="Sunken">Afundar</string> - <string name="Sunken Chest">Peito afundado</string> - <string name="Sunken Eyes">Olhos afundados</string> - <string name="Sweep Back">Pentear para trás</string> - <string name="Sweep Forward">Pentear para frente</string> - <string name="Tall">Alto</string> - <string name="Taper Back">Afinar atrás</string> - <string name="Taper Front">Afinar a frente</string> - <string name="Thick Heels">Salto grosso</string> - <string name="Thick Neck">Pescoço grosso</string> - <string name="Thick Toe">Dedo grosso</string> - <string name="Thin">Fino</string> - <string name="Thin Eyebrows">Sobrancelhas finas</string> - <string name="Thin Lips">Lábios finos</string> - <string name="Thin Nose">Nariz fino</string> - <string name="Tight Chin">Queixo apertado</string> - <string name="Tight Cuffs">Punho justo</string> - <string name="Tight Pants">Calça justa</string> - <string name="Tight Shirt">Camisa justa</string> - <string name="Tight Skirt">Saia justa</string> - <string name="Tight Sleeves">Tight Sleeves</string> - <string name="Toe Shape">Formato dos dedos</string> - <string name="Toe Thickness">Espessura dos dos dedos</string> - <string name="Torso Length">Comprimento do tronco</string> - <string name="Torso Muscles">Músculos do tronco</string> - <string name="Torso Scrawny">Tronco magricela</string> - <string name="Unattached">Desanexado</string> - <string name="Uncreased">Uncreased</string> - <string name="Underbite">Underbite</string> - <string name="Unnatural">Não natural</string> - <string name="Upper Bridge">Parte alta do nariz</string> - <string name="Upper Cheeks">Bochechas altas</string> - <string name="Upper Chin Cleft">fenda do queixo alta</string> - <string name="Upper Eyelid Fold">Curvatura dos cílios supériores</string> - <string name="Upturned">Voltado para cima</string> - <string name="Very Red">Bem vermelho</string> - <string name="Waist Height">Altura da cintura</string> - <string name="Well-Fed">Corpulento</string> - <string name="White Hair">Grisalho</string> - <string name="Wide">Amplo</string> - <string name="Wide Back">Costas largas</string> - <string name="Wide Front">Testa larga</string> - <string name="Wide Lips">Lábios amplos</string> - <string name="Wild">Selvagem</string> - <string name="Wrinkles">Rugas</string> - <string name="LocationCtrlAddLandmarkTooltip">Adicionar às minhas Landmarks</string> - <string name="LocationCtrlEditLandmarkTooltip">Editar minhas Landmarks</string> - <string name="LocationCtrlInfoBtnTooltip">Ver mais informações sobre a localização atual</string> - <string name="LocationCtrlComboBtnTooltip">Histórico de localizações</string> - <string name="LocationCtrlAdultIconTooltip">Região Adulta</string> - <string name="LocationCtrlModerateIconTooltip">Região Moderada</string> - <string name="LocationCtrlGeneralIconTooltip">Região em geral</string> - <string name="LocationCtrlSeeAVsTooltip">Os avatares neste lote não podem ser vistos ou ouvidos por avatares fora dele</string> - <string name="LocationCtrlPathfindingDirtyTooltip">Os objetos que se movem podem não se comportar corretamente nesta região até que ela seja recarregada.</string> - <string name="LocationCtrlPathfindingDisabledTooltip">O pathfinding dinâmico não está habilitado nesta região.</string> - <string name="UpdaterWindowTitle">[APP_NAME] Atualização</string> - <string name="UpdaterNowUpdating">Atualizando agora o [APP_NAME]...</string> - <string name="UpdaterNowInstalling">Instalando [APP_NAME]...</string> - <string name="UpdaterUpdatingDescriptive">Seu visualizador [APP_NAME] está sendo atualizado para a versão mais recente. Isso pode levar algum tempo, então por favor seja paciente.</string> - <string name="UpdaterProgressBarTextWithEllipses">Fazendo o download da atualização...</string> - <string name="UpdaterProgressBarText">Fazendo o download da atualização</string> - <string name="UpdaterFailDownloadTitle">Falha no download da atualização</string> - <string name="UpdaterFailUpdateDescriptive">Um erro ocorreu ao atualizar [APP_NAME]. Por favor, faça o download da versão mais recente em www.secondlife.com.</string> - <string name="UpdaterFailInstallTitle">Falha ao instalar a atualização</string> - <string name="UpdaterFailStartTitle">Falha ao iniciar o visualizador</string> - <string name="ItemsComingInTooFastFrom">[APP_NAME]: Entrada de itens rápida demais de [FROM_NAME], visualização automática suspensa por [TIME] segundos</string> - <string name="ItemsComingInTooFast">[APP_NAME]: Entrada de itens rápida demais, visualização automática suspensa por [TIME] segundos</string> - <string name="IM_logging_string">-- Log de mensagem instantânea habilitado --</string> - <string name="IM_typing_start_string">[NAME] está digitando...</string> - <string name="Unnamed">(Anônimo)</string> - <string name="IM_moderated_chat_label">(Moderado: Voz desativado por padrão)</string> - <string name="IM_unavailable_text_label">Bate-papo de texto não está disponível para esta chamada.</string> - <string name="IM_muted_text_label">Seu bate- papo de texto foi desabilitado por um Moderador do Grupo.</string> - <string name="IM_default_text_label">Clique aqui para menagem instantânea.</string> - <string name="IM_to_label">Para</string> - <string name="IM_moderator_label">(Moderador)</string> - <string name="Saved_message">(Salvo em [LONG_TIMESTAMP])</string> - <string name="IM_unblock_only_groups_friends">Para visualizar esta mensagem, você deve desmarcar "Apenas amigos e grupos podem me ligar ou enviar MIs" em Preferências/Privacidade.</string> - <string name="OnlineStatus">Conectado</string> - <string name="OfflineStatus">Desconectado</string> - <string name="not_online_msg">O usuário não está online. As mensagens serão armazenadas e enviadas mais tarde.</string> - <string name="not_online_inventory">O usuário não está online. O inventário foi salvo.</string> - <string name="answered_call">Ligação atendida</string> - <string name="you_started_call">Você iniciou uma ligação de voz</string> - <string name="you_joined_call">Você entrou na ligação</string> - <string name="you_auto_rejected_call-im">Você recusou automaticamente a chamada de voz enquanto "Não perturbe" estava ativado.</string> - <string name="name_started_call">[NAME] iniciou uma ligação de voz</string> - <string name="ringing-im">Entrando em ligação de voz...</string> - <string name="connected-im">Conectado. Para sair, clique em Desligar</string> - <string name="hang_up-im">Saiu da ligação de voz</string> - <string name="conference-title">Bate-papo com várias pessoas</string> - <string name="conference-title-incoming">Conversa com [AGENT_NAME]</string> - <string name="inventory_item_offered-im">Item do inventário '[ITEM_NAME]' oferecido</string> - <string name="inventory_folder_offered-im">Pasta do inventário '[ITEM_NAME]' oferecida</string> - <string name="facebook_post_success">Você publicou no Facebook.</string> - <string name="flickr_post_success">Você publicou no Flickr.</string> - <string name="twitter_post_success">Você publicou no Twitter.</string> - <string name="no_session_message">(Sessão de MI inexistente)</string> - <string name="only_user_message">Você é o único usuário desta sessão.</string> - <string name="offline_message">[NAME] 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">Erro de solicitação, tente novamente mais tarde.</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="no_ability">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">Bate-papo de texto desativado por um moderador.</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 usuários na sessão de bate-papo com [RECIPIENT].</string> - <string name="message">Não foi possível enviar sua mensagem para o 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="mute">Erro durante a moderação.</string> - <string name="removed">Você foi tirado do grupo.</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> - <string name="unread_chat_single">[SOURCES] disse alguma coisa</string> - <string name="unread_chat_multiple">[SOURCES] disseram alguma coisa</string> - <string name="session_initialization_timed_out_error">A inicialização da sessão expirou</string> - <string name="Home position set.">Posição inicial definida.</string> - <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string> - <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string> - <string name="paid_you_ldollars">[NAME] lhe pagou L$ [AMOUNT] [REASON].</string> - <string name="paid_you_ldollars_gift">[NAME] lhe pagou L$ [AMOUNT]: [REASON]</string> - <string name="paid_you_ldollars_no_reason">[NAME] lhe pagou L$ [AMOUNT]</string> - <string name="you_paid_ldollars">Você pagou L$[AMOUNT] por [REASON] a [NAME].</string> - <string name="you_paid_ldollars_gift">Você pagou L$[AMOUNT] a [NAME]: [REASON]</string> - <string name="you_paid_ldollars_no_info">Você acaba de pagar L$[AMOUNT].</string> - <string name="you_paid_ldollars_no_reason">Você pagou L$[AMOUNT] a [NAME].</string> - <string name="you_paid_ldollars_no_name">Você pagou L$[AMOUNT] por [REASON].</string> - <string name="you_paid_failure_ldollars">Você não pagou L$[AMOUNT] a [NAME] referentes a [REASON].</string> - <string name="you_paid_failure_ldollars_gift">Você não pagou L$[AMOUNT] a [NAME]: [REASON]</string> - <string name="you_paid_failure_ldollars_no_info">Você não pagou L$[AMOUNT].</string> - <string name="you_paid_failure_ldollars_no_reason">Você não pagou L$[AMOUNT] a [NAME].</string> - <string name="you_paid_failure_ldollars_no_name">Você não pagou L$[AMOUNT] referentes a [REASON].</string> - <string name="for item">por [ITEM]</string> - <string name="for a parcel of land">por uma parcela</string> - <string name="for a land access pass">por um passe de acesso</string> - <string name="for deeding land">para doar um terreno</string> - <string name="to create a group">para criar um grupo</string> - <string name="to join a group">para entrar em um grupo</string> - <string name="to upload">para carregar</string> - <string name="to publish a classified ad">para publicar um anúncio</string> - <string name="giving">Dando L$ [AMOUNT]</string> - <string name="uploading_costs">O upload custa L$ [AMOUNT]</string> - <string name="this_costs">Isso custa L$ [AMOUNT]</string> - <string name="buying_selected_land">Comprando terreno selecionado L$ [AMOUNT]</string> - <string name="this_object_costs">Esse objeto custa L$ [AMOUNT]</string> - <string name="group_role_everyone">Todos</string> - <string name="group_role_officers">Oficiais</string> - <string name="group_role_owners">Proprietários</string> - <string name="group_member_status_online">Conectado</string> - <string name="uploading_abuse_report">Carregando... +If you continue to receive this message, contact the [SUPPORT_SITE]. + </string> + <string name="5 O'Clock Shadow"> + Barba por fazer + </string> + <string name="All White"> + Todo branco + </string> + <string name="Anime Eyes"> + Olhos de Anime + </string> + <string name="Arced"> + Arqueados + </string> + <string name="Arm Length"> + Comprimento do braço + </string> + <string name="Attached"> + Anexado + </string> + <string name="Attached Earlobes"> + Lóbulos da orelha anexados + </string> + <string name="Back Fringe"> + corte traseiro + </string> + <string name="Baggy"> + folgado + </string> + <string name="Bangs"> + Franja + </string> + <string name="Beady Eyes"> + Olhos pequenos + </string> + <string name="Belly Size"> + Tamanho da barriga + </string> + <string name="Big"> + Grande + </string> + <string name="Big Butt"> + Bunda grande + </string> + <string name="Big Hair Back"> + Cabelo volumoso: Trás + </string> + <string name="Big Hair Front"> + Cabelo volumoso: Frente + </string> + <string name="Big Hair Top"> + Cabelo volumoso: Topo + </string> + <string name="Big Head"> + cabeça grande + </string> + <string name="Big Pectorals"> + Peitorais grandes + </string> + <string name="Big Spikes"> + Pontas grandes + </string> + <string name="Black"> + Negro + </string> + <string name="Blonde"> + Loiro + </string> + <string name="Blonde Hair"> + Cabelo loiro + </string> + <string name="Blush"> + Blush + </string> + <string name="Blush Color"> + Cor do blush + </string> + <string name="Blush Opacity"> + Opacidade do blush + </string> + <string name="Body Definition"> + Definição do corpo + </string> + <string name="Body Fat"> + Gordura + </string> + <string name="Body Freckles"> + Sardas + </string> + <string name="Body Thick"> + Corpo cheio + </string> + <string name="Body Thickness"> + Ossatura + </string> + <string name="Body Thin"> + Corpo magro + </string> + <string name="Bow Legged"> + Pernas arqueadas + </string> + <string name="Breast Buoyancy"> + Caimento dos seios + </string> + <string name="Breast Cleavage"> + Separação dos seios + </string> + <string name="Breast Size"> + Tamanho dos seios + </string> + <string name="Bridge Width"> + Largura do nariz + </string> + <string name="Broad"> + Largo + </string> + <string name="Brow Size"> + Tamanho da sobrancelha + </string> + <string name="Bug Eyes"> + Olhos saltados + </string> + <string name="Bugged Eyes"> + Olhos esbugalhados + </string> + <string name="Bulbous"> + Bulbos + </string> + <string name="Bulbous Nose"> + Nariz em bulbo + </string> + <string name="Breast Physics Mass"> + Seios - massa + </string> + <string name="Breast Physics Smoothing"> + Seios - suavização + </string> + <string name="Breast Physics Gravity"> + Seios - gravidade + </string> + <string name="Breast Physics Drag"> + Seios - resistência do ar + </string> + <string name="Breast Physics InOut Max Effect"> + Efeito máximo + </string> + <string name="Breast Physics InOut Spring"> + Vibração + </string> + <string name="Breast Physics InOut Gain"> + Ganho + </string> + <string name="Breast Physics InOut Damping"> + Duração + </string> + <string name="Breast Physics UpDown Max Effect"> + Efeito máximo + </string> + <string name="Breast Physics UpDown Spring"> + Vibração + </string> + <string name="Breast Physics UpDown Gain"> + Ganho + </string> + <string name="Breast Physics UpDown Damping"> + Duração + </string> + <string name="Breast Physics LeftRight Max Effect"> + Efeito máximo + </string> + <string name="Breast Physics LeftRight Spring"> + Vibração + </string> + <string name="Breast Physics LeftRight Gain"> + Ganho + </string> + <string name="Breast Physics LeftRight Damping"> + Duração + </string> + <string name="Belly Physics Mass"> + Barriga - massa + </string> + <string name="Belly Physics Smoothing"> + Barriga - suavização + </string> + <string name="Belly Physics Gravity"> + Barriga - gravidade + </string> + <string name="Belly Physics Drag"> + Barriga - resistência do ar + </string> + <string name="Belly Physics UpDown Max Effect"> + Efeito máximo + </string> + <string name="Belly Physics UpDown Spring"> + Vibração + </string> + <string name="Belly Physics UpDown Gain"> + Ganho + </string> + <string name="Belly Physics UpDown Damping"> + Duração + </string> + <string name="Butt Physics Mass"> + Nádegas - massa + </string> + <string name="Butt Physics Smoothing"> + Nádegas - suavização + </string> + <string name="Butt Physics Gravity"> + Nádegas - gravidade + </string> + <string name="Butt Physics Drag"> + Nádegas - resistência do ar + </string> + <string name="Butt Physics UpDown Max Effect"> + Efeito máximo + </string> + <string name="Butt Physics UpDown Spring"> + Vibração + </string> + <string name="Butt Physics UpDown Gain"> + Ganho + </string> + <string name="Butt Physics UpDown Damping"> + Duração + </string> + <string name="Butt Physics LeftRight Max Effect"> + Efeito máximo + </string> + <string name="Butt Physics LeftRight Spring"> + Vibração + </string> + <string name="Butt Physics LeftRight Gain"> + Ganho + </string> + <string name="Butt Physics LeftRight Damping"> + Duração + </string> + <string name="Bushy Eyebrows"> + Sobrancelhas grossas + </string> + <string name="Bushy Hair"> + Cabelo grosso + </string> + <string name="Butt Size"> + Tamanho do traseiro + </string> + <string name="Butt Gravity"> + Nádegas - gravidade + </string> + <string name="bustle skirt"> + Saia armada + </string> + <string name="no bustle"> + Saia reta + </string> + <string name="more bustle"> + Mais + </string> + <string name="Chaplin"> + Chaplin + </string> + <string name="Cheek Bones"> + Maçãs do rosto + </string> + <string name="Chest Size"> + Tamanho do peito + </string> + <string name="Chin Angle"> + Ângulo do queixo + </string> + <string name="Chin Cleft"> + Fissura do queixo + </string> + <string name="Chin Curtains"> + Barba de contorno + </string> + <string name="Chin Depth"> + Profundidade do queixo + </string> + <string name="Chin Heavy"> + Queixo pronunciado + </string> + <string name="Chin In"> + Queixo para dentro + </string> + <string name="Chin Out"> + Queixo para fora + </string> + <string name="Chin-Neck"> + Queixo-pescoço + </string> + <string name="Clear"> + Limpar + </string> + <string name="Cleft"> + Fenda + </string> + <string name="Close Set Eyes"> + Fechar conjunto de olhos + </string> + <string name="Closed"> + Fechado + </string> + <string name="Closed Back"> + Trás fechada + </string> + <string name="Closed Front"> + Frente fechada + </string> + <string name="Closed Left"> + Esquerda fechada + </string> + <string name="Closed Right"> + Direita fechada + </string> + <string name="Coin Purse"> + Pouco volume + </string> + <string name="Collar Back"> + Colarinho posterior + </string> + <string name="Collar Front"> + Colarinho anterior + </string> + <string name="Corner Down"> + Canto para baixo + </string> + <string name="Corner Up"> + Canto para cima + </string> + <string name="Creased"> + Vincado + </string> + <string name="Crooked Nose"> + Nariz torto + </string> + <string name="Cuff Flare"> + Bainha larga + </string> + <string name="Dark"> + Escuro + </string> + <string name="Dark Green"> + Verde escuro + </string> + <string name="Darker"> + Mais escuro + </string> + <string name="Deep"> + Profundidade + </string> + <string name="Default Heels"> + Salto padrão + </string> + <string name="Dense"> + Densidade + </string> + <string name="Double Chin"> + Queixo duplo + </string> + <string name="Downturned"> + Curvado para baixo + </string> + <string name="Duffle Bag"> + Mais volume + </string> + <string name="Ear Angle"> + Ângulo da orelha + </string> + <string name="Ear Size"> + Tamanho da orelha + </string> + <string name="Ear Tips"> + Pontas das orelhas + </string> + <string name="Egg Head"> + Cabeça oval + </string> + <string name="Eye Bags"> + Olheiras + </string> + <string name="Eye Color"> + Cor dos olhos + </string> + <string name="Eye Depth"> + Profundidade dos olhos + </string> + <string name="Eye Lightness"> + Luminosidade dos olhos + </string> + <string name="Eye Opening"> + Abertura dos olhos + </string> + <string name="Eye Pop"> + Olho saltado + </string> + <string name="Eye Size"> + Tamanho dos olhos + </string> + <string name="Eye Spacing"> + Espaçamento dos olhos + </string> + <string name="Eyebrow Arc"> + Arco da sobrancelha + </string> + <string name="Eyebrow Density"> + Densidade da sobrancelha + </string> + <string name="Eyebrow Height"> + Altura da sobrancelha + </string> + <string name="Eyebrow Points"> + Pontas da sobrancelha + </string> + <string name="Eyebrow Size"> + Tamanho da sobrancelha + </string> + <string name="Eyelash Length"> + Comprimento das pestanas + </string> + <string name="Eyeliner"> + Delineador + </string> + <string name="Eyeliner Color"> + Cor do delineador + </string> + <string name="Eyes Bugged"> + Olhos esbugalhados + </string> + <string name="Face Shear"> + Face raspada + </string> + <string name="Facial Definition"> + Definição facial + </string> + <string name="Far Set Eyes"> + Distância entre os olhos + </string> + <string name="Fat Lips"> + Lábios carnudos + </string> + <string name="Female"> + Feminino + </string> + <string name="Fingerless"> + Dedos + </string> + <string name="Fingers"> + Dedos + </string> + <string name="Flared Cuffs"> + Punhos largos + </string> + <string name="Flat"> + Chato + </string> + <string name="Flat Butt"> + Traseiro chato + </string> + <string name="Flat Head"> + Cabeça chata + </string> + <string name="Flat Toe"> + Dedos dos pés chatos + </string> + <string name="Foot Size"> + Tamanho dos pés + </string> + <string name="Forehead Angle"> + Ângulo da testa + </string> + <string name="Forehead Heavy"> + Testa pronunciada + </string> + <string name="Freckles"> + Sardas + </string> + <string name="Front Fringe"> + Franja + </string> + <string name="Full Back"> + Trás cheia + </string> + <string name="Full Eyeliner"> + Delienador cheio + </string> + <string name="Full Front"> + Frente cheia + </string> + <string name="Full Hair Sides"> + Cabelos laterais cheios + </string> + <string name="Full Sides"> + Lados cheios + </string> + <string name="Glossy"> + Brilhante + </string> + <string name="Glove Fingers"> + Dedos da luva + </string> + <string name="Glove Length"> + Comprimento das luvas + </string> + <string name="Hair"> + Cabelo + </string> + <string name="Hair Back"> + Cabelo: Trás + </string> + <string name="Hair Front"> + Cabelo: Frente + </string> + <string name="Hair Sides"> + Cabelos: Lateral + </string> + <string name="Hair Sweep"> + Cabelo penteado + </string> + <string name="Hair Thickess"> + Espessura do cabelo + </string> + <string name="Hair Thickness"> + Espessura do cabelo + </string> + <string name="Hair Tilt"> + Divisão do cabelo + </string> + <string name="Hair Tilted Left"> + Divistão do cabelo esquerda + </string> + <string name="Hair Tilted Right"> + Divisão do cabelo direita + </string> + <string name="Hair Volume"> + Cabelo: Volume + </string> + <string name="Hand Size"> + Tamanho das mãos + </string> + <string name="Handlebars"> + Bigode + </string> + <string name="Head Length"> + Comprimento da cabeça + </string> + <string name="Head Shape"> + Formato da cabeça + </string> + <string name="Head Size"> + Tamanho da cabeça + </string> + <string name="Head Stretch"> + Extensão da cabeça + </string> + <string name="Heel Height"> + Altura do salto + </string> + <string name="Heel Shape"> + Formato do salto + </string> + <string name="Height"> + Altura + </string> + <string name="High"> + Alto + </string> + <string name="High Heels"> + Salto alto + </string> + <string name="High Jaw"> + Maxilar alto + </string> + <string name="High Platforms"> + Plataformas altas + </string> + <string name="High and Tight"> + Alto e justo + </string> + <string name="Higher"> + Mais alto + </string> + <string name="Hip Length"> + Comprimento do quadril + </string> + <string name="Hip Width"> + Largura do quadril + </string> + <string name="Hover"> + Pairar + </string> + <string name="In"> + Dentro + </string> + <string name="In Shdw Color"> + Cor da sombra interna + </string> + <string name="In Shdw Opacity"> + Opacidade da sombra interna + </string> + <string name="Inner Eye Corner"> + Canto interno dos olhos + </string> + <string name="Inner Eye Shadow"> + Sombra interna dos olhos + </string> + <string name="Inner Shadow"> + Sombra interna + </string> + <string name="Jacket Length"> + Comprimento da blusa + </string> + <string name="Jacket Wrinkles"> + Dobras da jaqueta + </string> + <string name="Jaw Angle"> + Ângulo da mandíbula + </string> + <string name="Jaw Jut"> + Posição do maxilar + </string> + <string name="Jaw Shape"> + Formato do maxilar + </string> + <string name="Join"> + Juntar + </string> + <string name="Jowls"> + Papo + </string> + <string name="Knee Angle"> + Ângulo do joelho + </string> + <string name="Knock Kneed"> + Joelhos para dentro + </string> + <string name="Large"> + Grande + </string> + <string name="Large Hands"> + Mãos grandes + </string> + <string name="Left Part"> + Parte esquerda + </string> + <string name="Leg Length"> + Comprimento da perna + </string> + <string name="Leg Muscles"> + Musculatura da perna + </string> + <string name="Less"> + Menos + </string> + <string name="Less Body Fat"> + Menos gordura + </string> + <string name="Less Curtains"> + Menos barba + </string> + <string name="Less Freckles"> + Menos sardas + </string> + <string name="Less Full"> + Menos + </string> + <string name="Less Gravity"> + Menos gravidade + </string> + <string name="Less Love"> + Menos excesso + </string> + <string name="Less Muscles"> + Menos músculos + </string> + <string name="Less Muscular"> + Menos musculoso + </string> + <string name="Less Rosy"> + Menos rosado + </string> + <string name="Less Round"> + Menos arredondado + </string> + <string name="Less Saddle"> + Menos ancas + </string> + <string name="Less Square"> + Menos quadrado + </string> + <string name="Less Volume"> + Menos volume + </string> + <string name="Less soul"> + Menos alma + </string> + <string name="Lighter"> + Lighter + </string> + <string name="Lip Cleft"> + Fenda dos lábios + </string> + <string name="Lip Cleft Depth"> + Profundidade da fenda dos lábios + </string> + <string name="Lip Fullness"> + Volume dos lábios + </string> + <string name="Lip Pinkness"> + Rosado dos lábios + </string> + <string name="Lip Ratio"> + Proporção dos lábios + </string> + <string name="Lip Thickness"> + Espessura dos lábios + </string> + <string name="Lip Width"> + Largura dos lábios + </string> + <string name="Lipgloss"> + Brilho dos lábios + </string> + <string name="Lipstick"> + Batom + </string> + <string name="Lipstick Color"> + Cor do batom + </string> + <string name="Long"> + Longo + </string> + <string name="Long Head"> + Cabeça alongada + </string> + <string name="Long Hips"> + Lábios longos + </string> + <string name="Long Legs"> + Pernas longas + </string> + <string name="Long Neck"> + Pescoço longo + </string> + <string name="Long Pigtails"> + Chiquinhas longas + </string> + <string name="Long Ponytail"> + Rabo de cavalo longo + </string> + <string name="Long Torso"> + Torso longo + </string> + <string name="Long arms"> + Braços longos + </string> + <string name="Loose Pants"> + Pantalonas + </string> + <string name="Loose Shirt"> + Camisa folgada + </string> + <string name="Loose Sleeves"> + Mangas folgadas + </string> + <string name="Love Handles"> + Pneu + </string> + <string name="Low"> + Baixo + </string> + <string name="Low Heels"> + Salto baixo + </string> + <string name="Low Jaw"> + Maxilar baixo + </string> + <string name="Low Platforms"> + Plataformas baixas + </string> + <string name="Low and Loose"> + Baixo e solto + </string> + <string name="Lower"> + Mais baixo + </string> + <string name="Lower Bridge"> + Mais baixa + </string> + <string name="Lower Cheeks"> + Bochechas abaixadas + </string> + <string name="Male"> + Masculino + </string> + <string name="Middle Part"> + Parte do meio + </string> + <string name="More"> + Mais + </string> + <string name="More Blush"> + Mais blush + </string> + <string name="More Body Fat"> + Mais gordura + </string> + <string name="More Curtains"> + Mais barba + </string> + <string name="More Eyeshadow"> + Mais sombra dos olhos + </string> + <string name="More Freckles"> + Mais sardas + </string> + <string name="More Full"> + Mais volume + </string> + <string name="More Gravity"> + Mais gravidade + </string> + <string name="More Lipstick"> + Mais batom + </string> + <string name="More Love"> + Mais cintura + </string> + <string name="More Lower Lip"> + Mais lábio inferior + </string> + <string name="More Muscles"> + Mais músculos + </string> + <string name="More Muscular"> + Mais musculoso + </string> + <string name="More Rosy"> + Mais rosado + </string> + <string name="More Round"> + Mais arredondado + </string> + <string name="More Saddle"> + Mais ancas + </string> + <string name="More Sloped"> + Mais inclinado + </string> + <string name="More Square"> + Mais quadrado + </string> + <string name="More Upper Lip"> + Mais lábios superiores + </string> + <string name="More Vertical"> + Mais vertical + </string> + <string name="More Volume"> + Mais volume + </string> + <string name="More soul"> + Mais alma + </string> + <string name="Moustache"> + Bigode + </string> + <string name="Mouth Corner"> + Canto da boca + </string> + <string name="Mouth Position"> + Posição da boca + </string> + <string name="Mowhawk"> + Moicano + </string> + <string name="Muscular"> + Muscular + </string> + <string name="Mutton Chops"> + Costeletas + </string> + <string name="Nail Polish"> + Esmate das unhas + </string> + <string name="Nail Polish Color"> + Cor do esmalte das unhas + </string> + <string name="Narrow"> + Estreito + </string> + <string name="Narrow Back"> + Costas estreitas + </string> + <string name="Narrow Front"> + Frente estreita + </string> + <string name="Narrow Lips"> + Lábios estreitos + </string> + <string name="Natural"> + Natural + </string> + <string name="Neck Length"> + Comprimento do pescoço + </string> + <string name="Neck Thickness"> + Espessura do pescoço + </string> + <string name="No Blush"> + Sem blush + </string> + <string name="No Eyeliner"> + Sem delineador + </string> + <string name="No Eyeshadow"> + Sem sombra + </string> + <string name="No Lipgloss"> + Sem brilho + </string> + <string name="No Lipstick"> + Sem batom + </string> + <string name="No Part"> + Sem parte + </string> + <string name="No Polish"> + Sem esmalte + </string> + <string name="No Red"> + Sem vermelho + </string> + <string name="No Spikes"> + Sem pontas + </string> + <string name="No White"> + Sem branco + </string> + <string name="No Wrinkles"> + Sem dobras + </string> + <string name="Normal Lower"> + Normal inferior + </string> + <string name="Normal Upper"> + Normal superior + </string> + <string name="Nose Left"> + Nariz para esquerda + </string> + <string name="Nose Right"> + Nariz para direita + </string> + <string name="Nose Size"> + Tamanho do nariz + </string> + <string name="Nose Thickness"> + Espessura do nariz + </string> + <string name="Nose Tip Angle"> + Ângulo da ponta do nariz + </string> + <string name="Nose Tip Shape"> + Formato da ponta do nariz + </string> + <string name="Nose Width"> + Largura do nariz + </string> + <string name="Nostril Division"> + Divisão das narinas + </string> + <string name="Nostril Width"> + Largura das narinas + </string> + <string name="Opaque"> + Opaco + </string> + <string name="Open"> + Abrir + </string> + <string name="Open Back"> + Aberto atrás + </string> + <string name="Open Front"> + Aberto na frente + </string> + <string name="Open Left"> + Aberto esquerdo + </string> + <string name="Open Right"> + Aberto direito + </string> + <string name="Orange"> + Laranja + </string> + <string name="Out"> + Fora + </string> + <string name="Out Shdw Color"> + Cor da sombra externa + </string> + <string name="Out Shdw Opacity"> + Opacidade da sombra externa + </string> + <string name="Outer Eye Corner"> + Canto externo do olho + </string> + <string name="Outer Eye Shadow"> + Sombra externa do olho + </string> + <string name="Outer Shadow"> + Sombra externa + </string> + <string name="Overbite"> + Má oclusão + </string> + <string name="Package"> + Púbis + </string> + <string name="Painted Nails"> + Unhas pintadas + </string> + <string name="Pale"> + Pálido + </string> + <string name="Pants Crotch"> + Cavalo da calça + </string> + <string name="Pants Fit"> + Caimento das calças + </string> + <string name="Pants Length"> + Comprimento das calças + </string> + <string name="Pants Waist"> + Cintura da calça + </string> + <string name="Pants Wrinkles"> + Dobras das calças + </string> + <string name="Part"> + Parte + </string> + <string name="Part Bangs"> + Divisão da franja + </string> + <string name="Pectorals"> + Peitorais + </string> + <string name="Pigment"> + Pigmento + </string> + <string name="Pigtails"> + Chiquinhas + </string> + <string name="Pink"> + Rosa + </string> + <string name="Pinker"> + Mais rosado + </string> + <string name="Platform Height"> + Altura da plataforma + </string> + <string name="Platform Width"> + Largura da plataforma + </string> + <string name="Pointy"> + Pontudo + </string> + <string name="Pointy Heels"> + Salto agulha + </string> + <string name="Ponytail"> + Rabo de cavalo + </string> + <string name="Poofy Skirt"> + Saia bufante + </string> + <string name="Pop Left Eye"> + Olho saltado esquerdo + </string> + <string name="Pop Right Eye"> + Olho saltado direito + </string> + <string name="Puffy"> + Inchado + </string> + <string name="Puffy Eyelids"> + Pálpebras inchadas + </string> + <string name="Rainbow Color"> + Cor do arco íris + </string> + <string name="Red Hair"> + Cabelo ruivo + </string> + <string name="Regular"> + Normal + </string> + <string name="Right Part"> + Parte direita + </string> + <string name="Rosy Complexion"> + Rosado da face + </string> + <string name="Round"> + Arredondado + </string> + <string name="Ruddiness"> + Rubor + </string> + <string name="Ruddy"> + Corado + </string> + <string name="Rumpled Hair"> + Cabelo desalinhado + </string> + <string name="Saddle Bags"> + Culote + </string> + <string name="Scrawny Leg"> + Pernas magricelas + </string> + <string name="Separate"> + Separar + </string> + <string name="Shallow"> + Raso + </string> + <string name="Shear Back"> + Trás rente + </string> + <string name="Shear Face"> + Face raspada + </string> + <string name="Shear Front"> + Frente rente + </string> + <string name="Shear Left Up"> + Esquerda rente para cima + </string> + <string name="Shear Right Up"> + Trás rente para cima + </string> + <string name="Sheared Back"> + Rente atrás + </string> + <string name="Sheared Front"> + Rente frente + </string> + <string name="Shift Left"> + Deslocar p/ esquerda + </string> + <string name="Shift Mouth"> + Deslocar boca + </string> + <string name="Shift Right"> + Deslocar p/ direita + </string> + <string name="Shirt Bottom"> + Barra da camisa + </string> + <string name="Shirt Fit"> + Ajuste da camisa + </string> + <string name="Shirt Wrinkles"> + +/- amassada + </string> + <string name="Shoe Height"> + Altura do sapato + </string> + <string name="Short"> + Curto + </string> + <string name="Short Arms"> + Braços curtos + </string> + <string name="Short Legs"> + Pernas curtas + </string> + <string name="Short Neck"> + Pescoço curto + </string> + <string name="Short Pigtails"> + Chiquinhas curtas + </string> + <string name="Short Ponytail"> + Rabo de cavalo curto + </string> + <string name="Short Sideburns"> + Costeletas curtas + </string> + <string name="Short Torso"> + Tronco curto + </string> + <string name="Short hips"> + Quadril curto + </string> + <string name="Shoulders"> + Ombros + </string> + <string name="Side Fringe"> + pontas laterais + </string> + <string name="Sideburns"> + Costeletas + </string> + <string name="Sides Hair"> + Cabelo lateral + </string> + <string name="Sides Hair Down"> + Cabelo lateral long + </string> + <string name="Sides Hair Up"> + Cabelo lateral superior + </string> + <string name="Skinny Neck"> + Pescoço fino + </string> + <string name="Skirt Fit"> + Ajuste de saia + </string> + <string name="Skirt Length"> + Comprimento da saia + </string> + <string name="Slanted Forehead"> + Testa inclinada + </string> + <string name="Sleeve Length"> + Comprimento da manga + </string> + <string name="Sleeve Looseness"> + Folga da manga + </string> + <string name="Slit Back"> + Abertura : Atrás + </string> + <string name="Slit Front"> + Abertura: Frente + </string> + <string name="Slit Left"> + Abertura: Esquerda + </string> + <string name="Slit Right"> + Abertura: Direita + </string> + <string name="Small"> + Pequeno + </string> + <string name="Small Hands"> + Mãos pequenas + </string> + <string name="Small Head"> + Cabeça pequena + </string> + <string name="Smooth"> + Suavizar + </string> + <string name="Smooth Hair"> + Suavizar cabelo + </string> + <string name="Socks Length"> + Comprimento das meias + </string> + <string name="Soulpatch"> + Cavanhaque + </string> + <string name="Sparse"> + Disperso + </string> + <string name="Spiked Hair"> + Cabelo espetado + </string> + <string name="Square"> + Quadrado + </string> + <string name="Square Toe"> + Dedo quadrado + </string> + <string name="Squash Head"> + Cabeça de Pera + </string> + <string name="Stretch Head"> + Cabeça esticada + </string> + <string name="Sunken"> + Afundar + </string> + <string name="Sunken Chest"> + Peito afundado + </string> + <string name="Sunken Eyes"> + Olhos afundados + </string> + <string name="Sweep Back"> + Pentear para trás + </string> + <string name="Sweep Forward"> + Pentear para frente + </string> + <string name="Tall"> + Alto + </string> + <string name="Taper Back"> + Afinar atrás + </string> + <string name="Taper Front"> + Afinar a frente + </string> + <string name="Thick Heels"> + Salto grosso + </string> + <string name="Thick Neck"> + Pescoço grosso + </string> + <string name="Thick Toe"> + Dedo grosso + </string> + <string name="Thin"> + Fino + </string> + <string name="Thin Eyebrows"> + Sobrancelhas finas + </string> + <string name="Thin Lips"> + Lábios finos + </string> + <string name="Thin Nose"> + Nariz fino + </string> + <string name="Tight Chin"> + Queixo apertado + </string> + <string name="Tight Cuffs"> + Punho justo + </string> + <string name="Tight Pants"> + Calça justa + </string> + <string name="Tight Shirt"> + Camisa justa + </string> + <string name="Tight Skirt"> + Saia justa + </string> + <string name="Tight Sleeves"> + Tight Sleeves + </string> + <string name="Toe Shape"> + Formato dos dedos + </string> + <string name="Toe Thickness"> + Espessura dos dos dedos + </string> + <string name="Torso Length"> + Comprimento do tronco + </string> + <string name="Torso Muscles"> + Músculos do tronco + </string> + <string name="Torso Scrawny"> + Tronco magricela + </string> + <string name="Unattached"> + Desanexado + </string> + <string name="Uncreased"> + Uncreased + </string> + <string name="Underbite"> + Underbite + </string> + <string name="Unnatural"> + Não natural + </string> + <string name="Upper Bridge"> + Parte alta do nariz + </string> + <string name="Upper Cheeks"> + Bochechas altas + </string> + <string name="Upper Chin Cleft"> + fenda do queixo alta + </string> + <string name="Upper Eyelid Fold"> + Curvatura dos cílios supériores + </string> + <string name="Upturned"> + Voltado para cima + </string> + <string name="Very Red"> + Bem vermelho + </string> + <string name="Waist Height"> + Altura da cintura + </string> + <string name="Well-Fed"> + Corpulento + </string> + <string name="White Hair"> + Grisalho + </string> + <string name="Wide"> + Amplo + </string> + <string name="Wide Back"> + Costas largas + </string> + <string name="Wide Front"> + Testa larga + </string> + <string name="Wide Lips"> + Lábios amplos + </string> + <string name="Wild"> + Selvagem + </string> + <string name="Wrinkles"> + Rugas + </string> + <string name="LocationCtrlAddLandmarkTooltip"> + Adicionar às minhas Landmarks + </string> + <string name="LocationCtrlEditLandmarkTooltip"> + Editar minhas Landmarks + </string> + <string name="LocationCtrlInfoBtnTooltip"> + Ver mais informações sobre a localização atual + </string> + <string name="LocationCtrlComboBtnTooltip"> + Histórico de localizações + </string> + <string name="LocationCtrlAdultIconTooltip"> + Região Adulta + </string> + <string name="LocationCtrlModerateIconTooltip"> + Região Moderada + </string> + <string name="LocationCtrlGeneralIconTooltip"> + Região em geral + </string> + <string name="LocationCtrlSeeAVsTooltip"> + Os avatares neste lote não podem ser vistos ou ouvidos por avatares fora dele + </string> + <string name="LocationCtrlPathfindingDirtyTooltip"> + Os objetos que se movem podem não se comportar corretamente nesta região até que ela seja recarregada. + </string> + <string name="LocationCtrlPathfindingDisabledTooltip"> + O pathfinding dinâmico não está habilitado nesta região. + </string> + <string name="UpdaterWindowTitle"> + [APP_NAME] Atualização + </string> + <string name="UpdaterNowUpdating"> + Atualizando agora o [APP_NAME]... + </string> + <string name="UpdaterNowInstalling"> + Instalando [APP_NAME]... + </string> + <string name="UpdaterUpdatingDescriptive"> + Seu visualizador [APP_NAME] está sendo atualizado para a versão mais recente. Isso pode levar algum tempo, então por favor seja paciente. + </string> + <string name="UpdaterProgressBarTextWithEllipses"> + Fazendo o download da atualização... + </string> + <string name="UpdaterProgressBarText"> + Fazendo o download da atualização + </string> + <string name="UpdaterFailDownloadTitle"> + Falha no download da atualização + </string> + <string name="UpdaterFailUpdateDescriptive"> + Um erro ocorreu ao atualizar [APP_NAME]. Por favor, faça o download da versão mais recente em www.secondlife.com. + </string> + <string name="UpdaterFailInstallTitle"> + Falha ao instalar a atualização + </string> + <string name="UpdaterFailStartTitle"> + Falha ao iniciar o visualizador + </string> + <string name="ItemsComingInTooFastFrom"> + [APP_NAME]: Entrada de itens rápida demais de [FROM_NAME], visualização automática suspensa por [TIME] segundos + </string> + <string name="ItemsComingInTooFast"> + [APP_NAME]: Entrada de itens rápida demais, visualização automática suspensa por [TIME] segundos + </string> + <string name="IM_logging_string"> + -- Log de mensagem instantânea habilitado -- + </string> + <string name="IM_typing_start_string"> + [NAME] está digitando... + </string> + <string name="Unnamed"> + (Anônimo) + </string> + <string name="IM_moderated_chat_label"> + (Moderado: Voz desativado por padrão) + </string> + <string name="IM_unavailable_text_label"> + Bate-papo de texto não está disponível para esta chamada. + </string> + <string name="IM_muted_text_label"> + Seu bate- papo de texto foi desabilitado por um Moderador do Grupo. + </string> + <string name="IM_default_text_label"> + Clique aqui para menagem instantânea. + </string> + <string name="IM_to_label"> + Para + </string> + <string name="IM_moderator_label"> + (Moderador) + </string> + <string name="Saved_message"> + (Salvo em [LONG_TIMESTAMP]) + </string> + <string name="IM_unblock_only_groups_friends"> + Para visualizar esta mensagem, você deve desmarcar "Apenas amigos e grupos podem me ligar ou enviar MIs" em Preferências/Privacidade. + </string> + <string name="OnlineStatus"> + Conectado + </string> + <string name="OfflineStatus"> + Desconectado + </string> + <string name="not_online_msg"> + O usuário não está online. As mensagens serão armazenadas e enviadas mais tarde. + </string> + <string name="not_online_inventory"> + O usuário não está online. O inventário foi salvo. + </string> + <string name="answered_call"> + Ligação atendida + </string> + <string name="you_started_call"> + Você iniciou uma ligação de voz + </string> + <string name="you_joined_call"> + Você entrou na ligação + </string> + <string name="you_auto_rejected_call-im"> + Você recusou automaticamente a chamada de voz enquanto "Não perturbe" estava ativado. + </string> + <string name="name_started_call"> + [NAME] iniciou uma ligação de voz + </string> + <string name="ringing-im"> + Entrando em ligação de voz... + </string> + <string name="connected-im"> + Conectado. Para sair, clique em Desligar + </string> + <string name="hang_up-im"> + Saiu da ligação de voz + </string> + <string name="conference-title"> + Bate-papo com várias pessoas + </string> + <string name="conference-title-incoming"> + Conversa com [AGENT_NAME] + </string> + <string name="inventory_item_offered-im"> + Item do inventário '[ITEM_NAME]' oferecido + </string> + <string name="inventory_folder_offered-im"> + Pasta do inventário '[ITEM_NAME]' oferecida + </string> + <string name="bot_warning"> + Você está conversando com um bot, [NAME]. Não compartilhe informações pessoais. +Saiba mais em https://second.life/scripted-agents. + </string> + <string name="facebook_post_success"> + Você publicou no Facebook. + </string> + <string name="flickr_post_success"> + Você publicou no Flickr. + </string> + <string name="twitter_post_success"> + Você publicou no Twitter. + </string> + <string name="no_session_message"> + (Sessão de MI inexistente) + </string> + <string name="only_user_message"> + Você é o único usuário desta sessão. + </string> + <string name="offline_message"> + [NAME] 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"> + Erro de solicitação, tente novamente mais tarde. + </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="no_ability"> + 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"> + Bate-papo de texto desativado por um moderador. + </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 usuários na sessão de bate-papo com [RECIPIENT]. + </string> + <string name="message"> + Não foi possível enviar sua mensagem para o 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="mute"> + Erro durante a moderação. + </string> + <string name="removed"> + Você foi tirado do grupo. + </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> + <string name="unread_chat_single"> + [SOURCES] disse alguma coisa + </string> + <string name="unread_chat_multiple"> + [SOURCES] disseram alguma coisa + </string> + <string name="session_initialization_timed_out_error"> + A inicialização da sessão expirou + </string> + <string name="Home position set."> + Posição inicial definida. + </string> + <string name="voice_morphing_url"> + https://secondlife.com/destination/voice-island + </string> + <string name="premium_voice_morphing_url"> + https://secondlife.com/destination/voice-morphing-premium + </string> + <string name="paid_you_ldollars"> + [NAME] lhe pagou L$ [AMOUNT] [REASON]. + </string> + <string name="paid_you_ldollars_gift"> + [NAME] lhe pagou L$ [AMOUNT]: [REASON] + </string> + <string name="paid_you_ldollars_no_reason"> + [NAME] lhe pagou L$ [AMOUNT] + </string> + <string name="you_paid_ldollars"> + Você pagou L$[AMOUNT] por [REASON] a [NAME]. + </string> + <string name="you_paid_ldollars_gift"> + Você pagou L$[AMOUNT] a [NAME]: [REASON] + </string> + <string name="you_paid_ldollars_no_info"> + Você acaba de pagar L$[AMOUNT]. + </string> + <string name="you_paid_ldollars_no_reason"> + Você pagou L$[AMOUNT] a [NAME]. + </string> + <string name="you_paid_ldollars_no_name"> + Você pagou L$[AMOUNT] por [REASON]. + </string> + <string name="you_paid_failure_ldollars"> + Você não pagou L$[AMOUNT] a [NAME] referentes a [REASON]. + </string> + <string name="you_paid_failure_ldollars_gift"> + Você não pagou L$[AMOUNT] a [NAME]: [REASON] + </string> + <string name="you_paid_failure_ldollars_no_info"> + Você não pagou L$[AMOUNT]. + </string> + <string name="you_paid_failure_ldollars_no_reason"> + Você não pagou L$[AMOUNT] a [NAME]. + </string> + <string name="you_paid_failure_ldollars_no_name"> + Você não pagou L$[AMOUNT] referentes a [REASON]. + </string> + <string name="for item"> + por [ITEM] + </string> + <string name="for a parcel of land"> + por uma parcela + </string> + <string name="for a land access pass"> + por um passe de acesso + </string> + <string name="for deeding land"> + para doar um terreno + </string> + <string name="to create a group"> + para criar um grupo + </string> + <string name="to join a group"> + para entrar em um grupo + </string> + <string name="to upload"> + para carregar + </string> + <string name="to publish a classified ad"> + para publicar um anúncio + </string> + <string name="giving"> + Dando L$ [AMOUNT] + </string> + <string name="uploading_costs"> + O upload custa L$ [AMOUNT] + </string> + <string name="this_costs"> + Isso custa L$ [AMOUNT] + </string> + <string name="buying_selected_land"> + Comprando terreno selecionado L$ [AMOUNT] + </string> + <string name="this_object_costs"> + Esse objeto custa L$ [AMOUNT] + </string> + <string name="group_role_everyone"> + Todos + </string> + <string name="group_role_officers"> + Oficiais + </string> + <string name="group_role_owners"> + Proprietários + </string> + <string name="group_member_status_online"> + Conectado + </string> + <string name="uploading_abuse_report"> + Carregando... -Denunciar abuso</string> - <string name="New Shape">Nova forma</string> - <string name="New Skin">Nova pele</string> - <string name="New Hair">Novo cabelo</string> - <string name="New Eyes">Novos olhos</string> - <string name="New Shirt">Nova camisa</string> - <string name="New Pants">Novas calças</string> - <string name="New Shoes">Novos sapatos</string> - <string name="New Socks">Novas meias</string> - <string name="New Jacket">Nova blusa</string> - <string name="New Gloves">Novas luvas</string> - <string name="New Undershirt">Nova camiseta</string> - <string name="New Underpants">Novas roupa de baixo</string> - <string name="New Skirt">Nova saia</string> - <string name="New Alpha">Novo alpha</string> - <string name="New Tattoo">Nova tatuagem</string> - <string name="New Universal">Novo universal</string> - <string name="New Physics">Novo físico</string> - <string name="Invalid Wearable">Item inválido</string> - <string name="New Gesture">Novo gesto</string> - <string name="New Script">Novo script</string> - <string name="New Note">Nova nota</string> - <string name="New Folder">Nova pasta</string> - <string name="Contents">Conteúdo</string> - <string name="Gesture">Gesto</string> - <string name="Male Gestures">Gestos masculinos</string> - <string name="Female Gestures">Gestos femininos</string> - <string name="Other Gestures">Outros gestos</string> - <string name="Speech Gestures">Gestos da fala</string> - <string name="Common Gestures">Gestos comuns</string> - <string name="Male - Excuse me">Perdão - masculino</string> - <string name="Male - Get lost">Deixe-me em paz - masculino</string> - <string name="Male - Blow kiss">Mandar beijo - masculino</string> - <string name="Male - Boo">Vaia - masculino</string> - <string name="Male - Bored">Maçante - masculino</string> - <string name="Male - Hey">Ôpa! - masculino</string> - <string name="Male - Laugh">Risada - masculino</string> - <string name="Male - Repulsed">Quero distância! - masculino</string> - <string name="Male - Shrug">Encolher de ombros - masculino</string> - <string name="Male - Stick tougue out">Mostrar a língua - masculino</string> - <string name="Male - Wow">Wow - masculino</string> - <string name="Female - Chuckle">Engraçado - Feminino</string> - <string name="Female - Cry">Chorar - Feminino</string> - <string name="Female - Embarrassed">Com vergonha - Feminino</string> - <string name="Female - Excuse me">Perdão - fem</string> - <string name="Female - Get lost">Deixe-me em paz - feminino</string> - <string name="Female - Blow kiss">Mandar beijo - fem</string> - <string name="Female - Boo">Vaia - fem</string> - <string name="Female - Bored">Maçante - feminino</string> - <string name="Female - Hey">Ôpa - feminino</string> - <string name="Female - Hey baby">E aí, beliza? - Feminino</string> - <string name="Female - Laugh">Risada - feminina</string> - <string name="Female - Looking good">Que chique - Feminino</string> - <string name="Female - Over here">Acenar - Feminino</string> - <string name="Female - Please">Por favor - Feminino</string> - <string name="Female - Repulsed">Quero distância! - feminino</string> - <string name="Female - Shrug">Encolher ombros - feminino</string> - <string name="Female - Stick tougue out">Mostrar a língua - feminino</string> - <string name="Female - Wow">Wow - feminino</string> - <string name="New Daycycle">Novo ciclo de dias</string> - <string name="New Water">Nova água</string> - <string name="New Sky">Novo céu</string> - <string name="/bow">/reverência</string> - <string name="/clap">/palmas</string> - <string name="/count">/contar</string> - <string name="/extinguish">/apagar</string> - <string name="/kmb">/dane_se</string> - <string name="/muscle">/músculos</string> - <string name="/no">/não</string> - <string name="/no!">/não!</string> - <string name="/paper">/papel</string> - <string name="/pointme">/apontar_eu</string> - <string name="/pointyou">/apontar_você</string> - <string name="/rock">/pedra</string> - <string name="/scissor">/tesoura</string> - <string name="/smoke">/fumar</string> - <string name="/stretch">/alongar</string> - <string name="/whistle">/assobiar</string> - <string name="/yes">/sim</string> - <string name="/yes!">/sim!</string> - <string name="afk">ldt</string> - <string name="dance1">dança1</string> - <string name="dance2">dança2</string> - <string name="dance3">dança3</string> - <string name="dance4">dança4</string> - <string name="dance5">dança5</string> - <string name="dance6">dança6</string> - <string name="dance7">dança7</string> - <string name="dance8">dança8</string> - <string name="AvatarBirthDateFormat">[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]</string> - <string name="DefaultMimeType">nenhum/nehum</string> - <string name="texture_load_dimensions_error">A imagem excede o limite [WIDTH]*[HEIGHT]</string> - <string name="outfit_photo_load_dimensions_error">O tamanho máx. do look é [WIDTH]*[HEIGHT]. Redimensione ou use outra imagem</string> - <string name="outfit_photo_select_dimensions_error">O tamanho máx. do look é [WIDTH]*[HEIGHT]. Selecione outra textura</string> - <string name="outfit_photo_verify_dimensions_error">Não foi possível confirmar as dimensões da foto. Aguarde até que o tamanho da foto seja exibido no seletor</string> +Denunciar abuso + </string> + <string name="New Shape"> + Nova forma + </string> + <string name="New Skin"> + Nova pele + </string> + <string name="New Hair"> + Novo cabelo + </string> + <string name="New Eyes"> + Novos olhos + </string> + <string name="New Shirt"> + Nova camisa + </string> + <string name="New Pants"> + Novas calças + </string> + <string name="New Shoes"> + Novos sapatos + </string> + <string name="New Socks"> + Novas meias + </string> + <string name="New Jacket"> + Nova blusa + </string> + <string name="New Gloves"> + Novas luvas + </string> + <string name="New Undershirt"> + Nova camiseta + </string> + <string name="New Underpants"> + Novas roupa de baixo + </string> + <string name="New Skirt"> + Nova saia + </string> + <string name="New Alpha"> + Novo alpha + </string> + <string name="New Tattoo"> + Nova tatuagem + </string> + <string name="New Universal"> + Novo universal + </string> + <string name="New Physics"> + Novo físico + </string> + <string name="Invalid Wearable"> + Item inválido + </string> + <string name="New Gesture"> + Novo gesto + </string> + <string name="New Script"> + Novo script + </string> + <string name="New Note"> + Nova nota + </string> + <string name="New Folder"> + Nova pasta + </string> + <string name="Contents"> + Conteúdo + </string> + <string name="Gesture"> + Gesto + </string> + <string name="Male Gestures"> + Gestos masculinos + </string> + <string name="Female Gestures"> + Gestos femininos + </string> + <string name="Other Gestures"> + Outros gestos + </string> + <string name="Speech Gestures"> + Gestos da fala + </string> + <string name="Common Gestures"> + Gestos comuns + </string> + <string name="Male - Excuse me"> + Perdão - masculino + </string> + <string name="Male - Get lost"> + Deixe-me em paz - masculino + </string> + <string name="Male - Blow kiss"> + Mandar beijo - masculino + </string> + <string name="Male - Boo"> + Vaia - masculino + </string> + <string name="Male - Bored"> + Maçante - masculino + </string> + <string name="Male - Hey"> + Ôpa! - masculino + </string> + <string name="Male - Laugh"> + Risada - masculino + </string> + <string name="Male - Repulsed"> + Quero distância! - masculino + </string> + <string name="Male - Shrug"> + Encolher de ombros - masculino + </string> + <string name="Male - Stick tougue out"> + Mostrar a língua - masculino + </string> + <string name="Male - Wow"> + Wow - masculino + </string> + <string name="Female - Chuckle"> + Engraçado - Feminino + </string> + <string name="Female - Cry"> + Chorar - Feminino + </string> + <string name="Female - Embarrassed"> + Com vergonha - Feminino + </string> + <string name="Female - Excuse me"> + Perdão - fem + </string> + <string name="Female - Get lost"> + Deixe-me em paz - feminino + </string> + <string name="Female - Blow kiss"> + Mandar beijo - fem + </string> + <string name="Female - Boo"> + Vaia - fem + </string> + <string name="Female - Bored"> + Maçante - feminino + </string> + <string name="Female - Hey"> + Ôpa - feminino + </string> + <string name="Female - Hey baby"> + E aí, beliza? - Feminino + </string> + <string name="Female - Laugh"> + Risada - feminina + </string> + <string name="Female - Looking good"> + Que chique - Feminino + </string> + <string name="Female - Over here"> + Acenar - Feminino + </string> + <string name="Female - Please"> + Por favor - Feminino + </string> + <string name="Female - Repulsed"> + Quero distância! - feminino + </string> + <string name="Female - Shrug"> + Encolher ombros - feminino + </string> + <string name="Female - Stick tougue out"> + Mostrar a língua - feminino + </string> + <string name="Female - Wow"> + Wow - feminino + </string> + <string name="New Daycycle"> + Novo ciclo de dias + </string> + <string name="New Water"> + Nova água + </string> + <string name="New Sky"> + Novo céu + </string> + <string name="/bow"> + /reverência + </string> + <string name="/clap"> + /palmas + </string> + <string name="/count"> + /contar + </string> + <string name="/extinguish"> + /apagar + </string> + <string name="/kmb"> + /dane_se + </string> + <string name="/muscle"> + /músculos + </string> + <string name="/no"> + /não + </string> + <string name="/no!"> + /não! + </string> + <string name="/paper"> + /papel + </string> + <string name="/pointme"> + /apontar_eu + </string> + <string name="/pointyou"> + /apontar_você + </string> + <string name="/rock"> + /pedra + </string> + <string name="/scissor"> + /tesoura + </string> + <string name="/smoke"> + /fumar + </string> + <string name="/stretch"> + /alongar + </string> + <string name="/whistle"> + /assobiar + </string> + <string name="/yes"> + /sim + </string> + <string name="/yes!"> + /sim! + </string> + <string name="afk"> + ldt + </string> + <string name="dance1"> + dança1 + </string> + <string name="dance2"> + dança2 + </string> + <string name="dance3"> + dança3 + </string> + <string name="dance4"> + dança4 + </string> + <string name="dance5"> + dança5 + </string> + <string name="dance6"> + dança6 + </string> + <string name="dance7"> + dança7 + </string> + <string name="dance8"> + dança8 + </string> + <string name="AvatarBirthDateFormat"> + [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] + </string> + <string name="DefaultMimeType"> + nenhum/nehum + </string> + <string name="texture_load_dimensions_error"> + A imagem excede o limite [WIDTH]*[HEIGHT] + </string> + <string name="outfit_photo_load_dimensions_error"> + O tamanho máx. do look é [WIDTH]*[HEIGHT]. Redimensione ou use outra imagem + </string> + <string name="outfit_photo_select_dimensions_error"> + O tamanho máx. do look é [WIDTH]*[HEIGHT]. Selecione outra textura + </string> + <string name="outfit_photo_verify_dimensions_error"> + Não foi possível confirmar as dimensões da foto. Aguarde até que o tamanho da foto seja exibido no seletor + </string> <string name="words_separator" value=","/> - <string name="server_is_down">Aconteceu algo inesperado, apesar de termos tentado impedir isso. + <string name="server_is_down"> + Aconteceu algo inesperado, apesar de termos tentado impedir isso. Visite http://status.secondlifegrid.net para saber se foi detectado um problema com o serviço. - Se o problema persistir, cheque a configuração da sua rede e firewall.</string> - <string name="dateTimeWeekdaysNames">Domingo:Segunda:Terça:Quarta:Quinta:Sexta:Sábado</string> - <string name="dateTimeWeekdaysShortNames">Dom:Seg:Ter:Qua:Qui:Sex:Sab</string> - <string name="dateTimeMonthNames">Janeiro:Fevereiro:Março:Abril:Maio:Junho:Julho:Agosto:Setembro:Outubro:Novembro:Dezembro</string> - <string name="dateTimeMonthShortNames">Jan:Fev:Mar:Abr:Maio:Jun:Jul:Ago:Set:Out:Nov:Dez</string> - <string name="dateTimeDayFormat">[MDAY]</string> - <string name="dateTimeAM">AM</string> - <string name="dateTimePM">PM</string> - <string name="LocalEstimateUSD">US$ [AMOUNT]</string> - <string name="Group Ban">Banimento do grupo</string> - <string name="Membership">Plano</string> - <string name="Roles">Cargos</string> - <string name="Group Identity">Identidade do lote</string> - <string name="Parcel Management">Gestão do lote</string> - <string name="Parcel Identity">ID do lote</string> - <string name="Parcel Settings">Configurações do lote</string> - <string name="Parcel Powers">Poderes do lote</string> - <string name="Parcel Access">Acesso ao lote</string> - <string name="Parcel Content">Conteúdo do lote</string> - <string name="Object Management">Gestão de objetos</string> - <string name="Accounting">Contabilidade</string> - <string name="Notices">Avisos</string> - <string name="Chat" value="Bate papo">Bate-papo</string> - <string name="BaseMembership">Base</string> - <string name="DeleteItems">Excluir itens selecionados?</string> - <string name="DeleteItem">Excluir item selecionado?</string> - <string name="EmptyOutfitText">Este look não possui nenhuma peça</string> - <string name="ExternalEditorNotSet">Selecione um editor utilizando a configuração ExternalEditor.</string> - <string name="ExternalEditorNotFound">O editor externo especificado não foi localizado. + Se o problema persistir, cheque a configuração da sua rede e firewall. + </string> + <string name="dateTimeWeekdaysNames"> + Domingo:Segunda:Terça:Quarta:Quinta:Sexta:Sábado + </string> + <string name="dateTimeWeekdaysShortNames"> + Dom:Seg:Ter:Qua:Qui:Sex:Sab + </string> + <string name="dateTimeMonthNames"> + Janeiro:Fevereiro:Março:Abril:Maio:Junho:Julho:Agosto:Setembro:Outubro:Novembro:Dezembro + </string> + <string name="dateTimeMonthShortNames"> + Jan:Fev:Mar:Abr:Maio:Jun:Jul:Ago:Set:Out:Nov:Dez + </string> + <string name="dateTimeDayFormat"> + [MDAY] + </string> + <string name="dateTimeAM"> + AM + </string> + <string name="dateTimePM"> + PM + </string> + <string name="LocalEstimateUSD"> + US$ [AMOUNT] + </string> + <string name="Group Ban"> + Banimento do grupo + </string> + <string name="Membership"> + Plano + </string> + <string name="Roles"> + Cargos + </string> + <string name="Group Identity"> + Identidade do lote + </string> + <string name="Parcel Management"> + Gestão do lote + </string> + <string name="Parcel Identity"> + ID do lote + </string> + <string name="Parcel Settings"> + Configurações do lote + </string> + <string name="Parcel Powers"> + Poderes do lote + </string> + <string name="Parcel Access"> + Acesso ao lote + </string> + <string name="Parcel Content"> + Conteúdo do lote + </string> + <string name="Object Management"> + Gestão de objetos + </string> + <string name="Accounting"> + Contabilidade + </string> + <string name="Notices"> + Avisos + </string> + <string name="Chat" value="Bate papo"> + Bate-papo + </string> + <string name="BaseMembership"> + Base + </string> + <string name="DeleteItems"> + Excluir itens selecionados? + </string> + <string name="DeleteItem"> + Excluir item selecionado? + </string> + <string name="EmptyOutfitText"> + Este look não possui nenhuma peça + </string> + <string name="ExternalEditorNotSet"> + Selecione um editor utilizando a configuração ExternalEditor. + </string> + <string name="ExternalEditorNotFound"> + O editor externo especificado não foi localizado. Tente colocar o caminho do editor entre aspas. -(ex. "/caminho para/editor" "%s")</string> - <string name="ExternalEditorCommandParseError">Error ao analisar o comando do editor externo.</string> - <string name="ExternalEditorFailedToRun">Falha de execução do editor externo.</string> - <string name="TranslationFailed">Falha na tradução: [REASON]</string> - <string name="TranslationResponseParseError">Erro ao analisar resposta de tradução.</string> - <string name="Esc">Esc</string> - <string name="Space">Space</string> - <string name="Enter">Enter</string> - <string name="Tab">Tab</string> - <string name="Ins">Ins</string> - <string name="Del">Del</string> - <string name="Backsp">Backsp</string> - <string name="Shift">Shift</string> - <string name="Ctrl">Ctrl</string> - <string name="Alt">Alt</string> - <string name="CapsLock">CapsLock</string> - <string name="Home">Início</string> - <string name="End">End</string> - <string name="PgUp">PgUp</string> - <string name="PgDn">PgDn</string> - <string name="F1">F1</string> - <string name="F2">F2</string> - <string name="F3">F3</string> - <string name="F4">F4</string> - <string name="F5">F5</string> - <string name="F6">F6</string> - <string name="F7">F7</string> - <string name="F8">F8</string> - <string name="F9">F9</string> - <string name="F10">F10</string> - <string name="F11">F11</string> - <string name="F12">F12</string> - <string name="Add">Adicionar</string> - <string name="Subtract">Subtrair</string> - <string name="Multiply">Multiplicar</string> - <string name="Divide">Dividir</string> - <string name="PAD_DIVIDE">PAD_DIVIDE</string> - <string name="PAD_LEFT">PAD_LEFT</string> - <string name="PAD_RIGHT">PAD_RIGHT</string> - <string name="PAD_DOWN">PAD_DOWN</string> - <string name="PAD_UP">PAD_UP</string> - <string name="PAD_HOME">PAD_HOME</string> - <string name="PAD_END">PAD_END</string> - <string name="PAD_PGUP">PAD_PGUP</string> - <string name="PAD_PGDN">PAD_PGDN</string> - <string name="PAD_CENTER">PAD_CENTER</string> - <string name="PAD_INS">PAD_INS</string> - <string name="PAD_DEL">PAD_DEL</string> - <string name="PAD_Enter">PAD_Enter</string> - <string name="PAD_BUTTON0">PAD_BUTTON0</string> - <string name="PAD_BUTTON1">PAD_BUTTON1</string> - <string name="PAD_BUTTON2">PAD_BUTTON2</string> - <string name="PAD_BUTTON3">PAD_BUTTON3</string> - <string name="PAD_BUTTON4">PAD_BUTTON4</string> - <string name="PAD_BUTTON5">PAD_BUTTON5</string> - <string name="PAD_BUTTON6">PAD_BUTTON6</string> - <string name="PAD_BUTTON7">PAD_BUTTON7</string> - <string name="PAD_BUTTON8">PAD_BUTTON8</string> - <string name="PAD_BUTTON9">PAD_BUTTON9</string> - <string name="PAD_BUTTON10">PAD_BUTTON10</string> - <string name="PAD_BUTTON11">PAD_BUTTON11</string> - <string name="PAD_BUTTON12">PAD_BUTTON12</string> - <string name="PAD_BUTTON13">PAD_BUTTON13</string> - <string name="PAD_BUTTON14">PAD_BUTTON14</string> - <string name="PAD_BUTTON15">PAD_BUTTON15</string> - <string name="-">-</string> - <string name="=">=</string> - <string name="`">`</string> - <string name=";">;</string> - <string name="[">[</string> - <string name="]">]</string> - <string name="\">\</string> - <string name="0">0</string> - <string name="1">1</string> - <string name="2">2</string> - <string name="3">3</string> - <string name="4">4</string> - <string name="5">5</string> - <string name="6">6</string> - <string name="7">7</string> - <string name="8">8</string> - <string name="9">9</string> - <string name="A">A</string> - <string name="B">B</string> - <string name="C">C</string> - <string name="D">D</string> - <string name="E">E</string> - <string name="F">F</string> - <string name="G">G</string> - <string name="H">H</string> - <string name="I">I</string> - <string name="J">J</string> - <string name="K">K</string> - <string name="L">L</string> - <string name="M">M</string> - <string name="N">N</string> - <string name="O">O</string> - <string name="P">P</string> - <string name="Q">Q</string> - <string name="R">R</string> - <string name="S">S</string> - <string name="T">T</string> - <string name="U">U</string> - <string name="V">V</string> - <string name="W">W</string> - <string name="X">X</string> - <string name="Y">Y</string> - <string name="Z">Z</string> - <string name="BeaconParticle">Vendo balizas de partículas (azul)</string> - <string name="BeaconPhysical">Vendo balizas de objetos físicos (verde)</string> - <string name="BeaconScripted">Vendo balizas de objetos com script (vermelho)</string> - <string name="BeaconScriptedTouch">Vendo objeto com script com balizas com funcionalidade de toque (vermelho)</string> - <string name="BeaconSound">Vendo balizas de som (amarelo)</string> - <string name="BeaconMedia">Vendo balizas de mídia (branco)</string> - <string name="BeaconSun">Visualizando farol de direção do sol (alaranjado)</string> - <string name="BeaconMoon">Visualizando farol de direção da lua (roxo)</string> - <string name="ParticleHiding">Ocultar partículas</string> - <string name="Command_AboutLand_Label">Sobre terrenos</string> - <string name="Command_Appearance_Label">Aparência</string> - <string name="Command_Avatar_Label">Avatar</string> - <string name="Command_Build_Label">Construir</string> - <string name="Command_Chat_Label">Bate-papo</string> - <string name="Command_Conversations_Label">Conversas</string> - <string name="Command_Compass_Label">Bússola</string> - <string name="Command_Destinations_Label">Destinos</string> - <string name="Command_Environments_Label">Meus ambientes</string> - <string name="Command_Facebook_Label">Facebook</string> - <string name="Command_Flickr_Label">Flickr</string> - <string name="Command_Gestures_Label">Gestos</string> - <string name="Command_Grid_Status_Label">Status da grade</string> - <string name="Command_HowTo_Label">Como</string> - <string name="Command_Inventory_Label">Inventário</string> - <string name="Command_Map_Label">Mapa</string> - <string name="Command_Marketplace_Label">Mercado</string> - <string name="Command_MarketplaceListings_Label">Marketplace</string> - <string name="Command_MiniMap_Label">Mini Mapa</string> - <string name="Command_Move_Label">Andar/correr/voar</string> - <string name="Command_Outbox_Label">Caixa de saída do lojista</string> - <string name="Command_People_Label">Pessoas</string> - <string name="Command_Picks_Label">Destaques</string> - <string name="Command_Places_Label">Lugares</string> - <string name="Command_Preferences_Label">Preferências</string> - <string name="Command_Profile_Label">Perfil</string> - <string name="Command_Report_Abuse_Label">Relatar abuso</string> - <string name="Command_Search_Label">Buscar</string> - <string name="Command_Snapshot_Label">Foto</string> - <string name="Command_Speak_Label">Falar</string> - <string name="Command_Twitter_Label">Twitter</string> - <string name="Command_View_Label">Controles da câmera</string> - <string name="Command_Voice_Label">Configurações de voz</string> - <string name="Command_AboutLand_Tooltip">Informações sobre o terreno que você está visitando</string> - <string name="Command_Appearance_Tooltip">Mudar seu avatar</string> - <string name="Command_Avatar_Tooltip">Escolha um avatar completo</string> - <string name="Command_Build_Tooltip">Construindo objetos e redimensionando terreno</string> - <string name="Command_Chat_Tooltip">Bater papo com pessoas próximas usando texto</string> - <string name="Command_Conversations_Tooltip">Conversar com todos</string> - <string name="Command_Compass_Tooltip">Bússola</string> - <string name="Command_Destinations_Tooltip">Destinos de interesse</string> - <string name="Command_Environments_Tooltip">Meus ambientes</string> - <string name="Command_Facebook_Tooltip">Publicar no Facebook</string> - <string name="Command_Flickr_Tooltip">Carregar no Flickr</string> - <string name="Command_Gestures_Tooltip">Gestos para seu avatar</string> - <string name="Command_Grid_Status_Tooltip">Mostrar status da grade atual</string> - <string name="Command_HowTo_Tooltip">Como executar tarefas comuns</string> - <string name="Command_Inventory_Tooltip">Exibir e usar seus pertences</string> - <string name="Command_Map_Tooltip">Mapa-múndi</string> - <string name="Command_Marketplace_Tooltip">Faça compras</string> - <string name="Command_MarketplaceListings_Tooltip">Venda suas criações</string> - <string name="Command_MiniMap_Tooltip">Mostrar quem está aqui</string> - <string name="Command_Move_Tooltip">Movendo seu avatar</string> - <string name="Command_Outbox_Tooltip">Transferir itens para o seu mercado para venda</string> - <string name="Command_People_Tooltip">Amigos, grupos e pessoas próximas</string> - <string name="Command_Picks_Tooltip">Lugares mostrados como favoritos em seu perfil</string> - <string name="Command_Places_Tooltip">Lugares salvos</string> - <string name="Command_Preferences_Tooltip">Preferências</string> - <string name="Command_Profile_Tooltip">Edite ou visualize seu perfil</string> - <string name="Command_Report_Abuse_Tooltip">Relatar abuso</string> - <string name="Command_Search_Tooltip">Encontre lugares, eventos, pessoas</string> - <string name="Command_Snapshot_Tooltip">Tirar uma foto</string> - <string name="Command_Speak_Tooltip">Fale com pessoas próximas usando seu microfone</string> - <string name="Command_Twitter_Tooltip">Twitter</string> - <string name="Command_View_Tooltip">Alterar o ângulo da câmera</string> - <string name="Command_Voice_Tooltip">Controles de volume das chamadas e pessoas próximas a você no mundo virtual</string> - <string name="Toolbar_Bottom_Tooltip">atualmente na sua barra de ferramentas inferior</string> - <string name="Toolbar_Left_Tooltip">atualmente na sua barra de ferramentas esquerda</string> - <string name="Toolbar_Right_Tooltip">atualmente na sua barra de ferramentas direita</string> - <string name="Retain%">Reter%</string> - <string name="Detail">Detalhe</string> - <string name="Better Detail">Detalhamento maior</string> - <string name="Surface">Superfície</string> - <string name="Solid">Sólido</string> - <string name="Wrap">Conclusão</string> - <string name="Preview">Visualizar</string> - <string name="Normal">Normal</string> - <string name="Pathfinding_Wiki_URL">http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer</string> - <string name="Pathfinding_Object_Attr_None">Nenhum</string> - <string name="Pathfinding_Object_Attr_Permanent">Afeta o navmesh</string> - <string name="Pathfinding_Object_Attr_Character">Personagem</string> - <string name="Pathfinding_Object_Attr_MultiSelect">(Múltiplo)</string> - <string name="snapshot_quality_very_low">Muito baixo</string> - <string name="snapshot_quality_low">Baixo</string> - <string name="snapshot_quality_medium">Médio</string> - <string name="snapshot_quality_high">Alto</string> - <string name="snapshot_quality_very_high">Muito alto</string> - <string name="TeleportMaturityExceeded">O residente não pode visitar a região.</string> - <string name="UserDictionary">[Usuário]</string> - <string name="experience_tools_experience">Experiência</string> - <string name="ExperienceNameNull">(nenhuma experiência)</string> - <string name="ExperienceNameUntitled">(experiência sem título)</string> - <string name="Land-Scope">Dentro do terreno</string> - <string name="Grid-Scope">Dentro da grade</string> - <string name="Allowed_Experiences_Tab">PERMITIDO</string> - <string name="Blocked_Experiences_Tab">BLOQUEADO</string> - <string name="Contrib_Experiences_Tab">COLABORADOR</string> - <string name="Admin_Experiences_Tab">ADMINISTRADOR</string> - <string name="Recent_Experiences_Tab">RECENTE</string> - <string name="Owned_Experiences_Tab">PRÓPRIAS</string> - <string name="ExperiencesCounter">([EXPERIENCES], máx. [MAXEXPERIENCES])</string> - <string name="ExperiencePermission1">assumir seus controles</string> - <string name="ExperiencePermission3">acionar animações no seu avatar</string> - <string name="ExperiencePermission4">anexar ao avatar</string> - <string name="ExperiencePermission9">rastrear sua câmera</string> - <string name="ExperiencePermission10">controlar sua câmera</string> - <string name="ExperiencePermission11">teletransportar você</string> - <string name="ExperiencePermission12">aceitar automaticamente permissões de experiência</string> - <string name="ExperiencePermission16">forçar o avatar a sentar</string> - <string name="ExperiencePermission17">alterar sua configurações de ambiente</string> - <string name="ExperiencePermissionShortUnknown">realizar uma operação desconhecida: [Permission]</string> - <string name="ExperiencePermissionShort1">Assumir o controle</string> - <string name="ExperiencePermissionShort3">Acionar animações</string> - <string name="ExperiencePermissionShort4">Anexar</string> - <string name="ExperiencePermissionShort9">Rastrear câmera</string> - <string name="ExperiencePermissionShort10">Controlar câmera</string> - <string name="ExperiencePermissionShort11">Teletransportar</string> - <string name="ExperiencePermissionShort12">Autorização</string> - <string name="ExperiencePermissionShort16">Sentar</string> - <string name="ExperiencePermissionShort17">Ambiente</string> - <string name="logging_calls_disabled_log_empty">As conversas não estão sendo registradas. Para começar a manter um registro, selecione "Salvar: apenas registro" ou "Salvar: registro e transcrições" em Preferências> Bate-papo.</string> - <string name="logging_calls_disabled_log_not_empty">Nenhuma conversa será registrada. Para recomeçar a gravação de registros, selecione "Salvar: apenas registro" ou "Salvar: registro e transcrições" em Preferências> Bate-papo.</string> - <string name="logging_calls_enabled_log_empty">Não há conversas registradas. Depois que você entrar em contato com alguém, ou alguém entrar em contato com você, um registro será exibido aqui.</string> - <string name="loading_chat_logs">Carregando...</string> - <string name="na">n/d</string> - <string name="preset_combo_label">-Lista vazia-</string> - <string name="Default">Padrão</string> - <string name="none_paren_cap">(nenhum)</string> - <string name="no_limit">Sem limite</string> - <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">A forma física contém triângulos muito pequenos. Tente simplificar o modelo físico.</string> - <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH">A forma física contém dados de confirmação ruins. Tente consertar o modelo físico.</string> - <string name="Mav_Details_MAV_UNKNOWN_VERSION">A forma física não tem a versão correta. Defina a versão correta para o modelo físico.</string> - <string name="couldnt_resolve_host">O DNS não pode resolver o nome do host([HOSTNAME]). +(ex. "/caminho para/editor" "%s") + </string> + <string name="ExternalEditorCommandParseError"> + Error ao analisar o comando do editor externo. + </string> + <string name="ExternalEditorFailedToRun"> + Falha de execução do editor externo. + </string> + <string name="TranslationFailed"> + Falha na tradução: [REASON] + </string> + <string name="TranslationResponseParseError"> + Erro ao analisar resposta de tradução. + </string> + <string name="Esc"> + Esc + </string> + <string name="Space"> + Space + </string> + <string name="Enter"> + Enter + </string> + <string name="Tab"> + Tab + </string> + <string name="Ins"> + Ins + </string> + <string name="Del"> + Del + </string> + <string name="Backsp"> + Backsp + </string> + <string name="Shift"> + Shift + </string> + <string name="Ctrl"> + Ctrl + </string> + <string name="Alt"> + Alt + </string> + <string name="CapsLock"> + CapsLock + </string> + <string name="Home"> + Início + </string> + <string name="End"> + End + </string> + <string name="PgUp"> + PgUp + </string> + <string name="PgDn"> + PgDn + </string> + <string name="F1"> + F1 + </string> + <string name="F2"> + F2 + </string> + <string name="F3"> + F3 + </string> + <string name="F4"> + F4 + </string> + <string name="F5"> + F5 + </string> + <string name="F6"> + F6 + </string> + <string name="F7"> + F7 + </string> + <string name="F8"> + F8 + </string> + <string name="F9"> + F9 + </string> + <string name="F10"> + F10 + </string> + <string name="F11"> + F11 + </string> + <string name="F12"> + F12 + </string> + <string name="Add"> + Adicionar + </string> + <string name="Subtract"> + Subtrair + </string> + <string name="Multiply"> + Multiplicar + </string> + <string name="Divide"> + Dividir + </string> + <string name="PAD_DIVIDE"> + PAD_DIVIDE + </string> + <string name="PAD_LEFT"> + PAD_LEFT + </string> + <string name="PAD_RIGHT"> + PAD_RIGHT + </string> + <string name="PAD_DOWN"> + PAD_DOWN + </string> + <string name="PAD_UP"> + PAD_UP + </string> + <string name="PAD_HOME"> + PAD_HOME + </string> + <string name="PAD_END"> + PAD_END + </string> + <string name="PAD_PGUP"> + PAD_PGUP + </string> + <string name="PAD_PGDN"> + PAD_PGDN + </string> + <string name="PAD_CENTER"> + PAD_CENTER + </string> + <string name="PAD_INS"> + PAD_INS + </string> + <string name="PAD_DEL"> + PAD_DEL + </string> + <string name="PAD_Enter"> + PAD_Enter + </string> + <string name="PAD_BUTTON0"> + PAD_BUTTON0 + </string> + <string name="PAD_BUTTON1"> + PAD_BUTTON1 + </string> + <string name="PAD_BUTTON2"> + PAD_BUTTON2 + </string> + <string name="PAD_BUTTON3"> + PAD_BUTTON3 + </string> + <string name="PAD_BUTTON4"> + PAD_BUTTON4 + </string> + <string name="PAD_BUTTON5"> + PAD_BUTTON5 + </string> + <string name="PAD_BUTTON6"> + PAD_BUTTON6 + </string> + <string name="PAD_BUTTON7"> + PAD_BUTTON7 + </string> + <string name="PAD_BUTTON8"> + PAD_BUTTON8 + </string> + <string name="PAD_BUTTON9"> + PAD_BUTTON9 + </string> + <string name="PAD_BUTTON10"> + PAD_BUTTON10 + </string> + <string name="PAD_BUTTON11"> + PAD_BUTTON11 + </string> + <string name="PAD_BUTTON12"> + PAD_BUTTON12 + </string> + <string name="PAD_BUTTON13"> + PAD_BUTTON13 + </string> + <string name="PAD_BUTTON14"> + PAD_BUTTON14 + </string> + <string name="PAD_BUTTON15"> + PAD_BUTTON15 + </string> + <string name="-"> + - + </string> + <string name="="> + = + </string> + <string name="`"> + ` + </string> + <string name=";"> + ; + </string> + <string name="["> + [ + </string> + <string name="]"> + ] + </string> + <string name="\"> + \ + </string> + <string name="0"> + 0 + </string> + <string name="1"> + 1 + </string> + <string name="2"> + 2 + </string> + <string name="3"> + 3 + </string> + <string name="4"> + 4 + </string> + <string name="5"> + 5 + </string> + <string name="6"> + 6 + </string> + <string name="7"> + 7 + </string> + <string name="8"> + 8 + </string> + <string name="9"> + 9 + </string> + <string name="A"> + A + </string> + <string name="B"> + B + </string> + <string name="C"> + C + </string> + <string name="D"> + D + </string> + <string name="E"> + E + </string> + <string name="F"> + F + </string> + <string name="G"> + G + </string> + <string name="H"> + H + </string> + <string name="I"> + I + </string> + <string name="J"> + J + </string> + <string name="K"> + K + </string> + <string name="L"> + L + </string> + <string name="M"> + M + </string> + <string name="N"> + N + </string> + <string name="O"> + O + </string> + <string name="P"> + P + </string> + <string name="Q"> + Q + </string> + <string name="R"> + R + </string> + <string name="S"> + S + </string> + <string name="T"> + T + </string> + <string name="U"> + U + </string> + <string name="V"> + V + </string> + <string name="W"> + W + </string> + <string name="X"> + X + </string> + <string name="Y"> + Y + </string> + <string name="Z"> + Z + </string> + <string name="BeaconParticle"> + Vendo balizas de partículas (azul) + </string> + <string name="BeaconPhysical"> + Vendo balizas de objetos físicos (verde) + </string> + <string name="BeaconScripted"> + Vendo balizas de objetos com script (vermelho) + </string> + <string name="BeaconScriptedTouch"> + Vendo objeto com script com balizas com funcionalidade de toque (vermelho) + </string> + <string name="BeaconSound"> + Vendo balizas de som (amarelo) + </string> + <string name="BeaconMedia"> + Vendo balizas de mídia (branco) + </string> + <string name="BeaconSun"> + Visualizando farol de direção do sol (alaranjado) + </string> + <string name="BeaconMoon"> + Visualizando farol de direção da lua (roxo) + </string> + <string name="ParticleHiding"> + Ocultar partículas + </string> + <string name="Command_AboutLand_Label"> + Sobre terrenos + </string> + <string name="Command_Appearance_Label"> + Aparência + </string> + <string name="Command_Avatar_Label"> + Avatar + </string> + <string name="Command_Build_Label"> + Construir + </string> + <string name="Command_Chat_Label"> + Bate-papo + </string> + <string name="Command_Conversations_Label"> + Conversas + </string> + <string name="Command_Compass_Label"> + Bússola + </string> + <string name="Command_Destinations_Label"> + Destinos + </string> + <string name="Command_Environments_Label"> + Meus ambientes + </string> + <string name="Command_Facebook_Label"> + Facebook + </string> + <string name="Command_Flickr_Label"> + Flickr + </string> + <string name="Command_Gestures_Label"> + Gestos + </string> + <string name="Command_Grid_Status_Label"> + Status da grade + </string> + <string name="Command_HowTo_Label"> + Como + </string> + <string name="Command_Inventory_Label"> + Inventário + </string> + <string name="Command_Map_Label"> + Mapa + </string> + <string name="Command_Marketplace_Label"> + Mercado + </string> + <string name="Command_MarketplaceListings_Label"> + Marketplace + </string> + <string name="Command_MiniMap_Label"> + Mini Mapa + </string> + <string name="Command_Move_Label"> + Andar/correr/voar + </string> + <string name="Command_Outbox_Label"> + Caixa de saída do lojista + </string> + <string name="Command_People_Label"> + Pessoas + </string> + <string name="Command_Picks_Label"> + Destaques + </string> + <string name="Command_Places_Label"> + Lugares + </string> + <string name="Command_Preferences_Label"> + Preferências + </string> + <string name="Command_Profile_Label"> + Perfil + </string> + <string name="Command_Report_Abuse_Label"> + Relatar abuso + </string> + <string name="Command_Search_Label"> + Buscar + </string> + <string name="Command_Snapshot_Label"> + Foto + </string> + <string name="Command_Speak_Label"> + Falar + </string> + <string name="Command_Twitter_Label"> + Twitter + </string> + <string name="Command_View_Label"> + Controles da câmera + </string> + <string name="Command_Voice_Label"> + Configurações de voz + </string> + <string name="Command_AboutLand_Tooltip"> + Informações sobre o terreno que você está visitando + </string> + <string name="Command_Appearance_Tooltip"> + Mudar seu avatar + </string> + <string name="Command_Avatar_Tooltip"> + Escolha um avatar completo + </string> + <string name="Command_Build_Tooltip"> + Construindo objetos e redimensionando terreno + </string> + <string name="Command_Chat_Tooltip"> + Bater papo com pessoas próximas usando texto + </string> + <string name="Command_Conversations_Tooltip"> + Conversar com todos + </string> + <string name="Command_Compass_Tooltip"> + Bússola + </string> + <string name="Command_Destinations_Tooltip"> + Destinos de interesse + </string> + <string name="Command_Environments_Tooltip"> + Meus ambientes + </string> + <string name="Command_Facebook_Tooltip"> + Publicar no Facebook + </string> + <string name="Command_Flickr_Tooltip"> + Carregar no Flickr + </string> + <string name="Command_Gestures_Tooltip"> + Gestos para seu avatar + </string> + <string name="Command_Grid_Status_Tooltip"> + Mostrar status da grade atual + </string> + <string name="Command_HowTo_Tooltip"> + Como executar tarefas comuns + </string> + <string name="Command_Inventory_Tooltip"> + Exibir e usar seus pertences + </string> + <string name="Command_Map_Tooltip"> + Mapa-múndi + </string> + <string name="Command_Marketplace_Tooltip"> + Faça compras + </string> + <string name="Command_MarketplaceListings_Tooltip"> + Venda suas criações + </string> + <string name="Command_MiniMap_Tooltip"> + Mostrar quem está aqui + </string> + <string name="Command_Move_Tooltip"> + Movendo seu avatar + </string> + <string name="Command_Outbox_Tooltip"> + Transferir itens para o seu mercado para venda + </string> + <string name="Command_People_Tooltip"> + Amigos, grupos e pessoas próximas + </string> + <string name="Command_Picks_Tooltip"> + Lugares mostrados como favoritos em seu perfil + </string> + <string name="Command_Places_Tooltip"> + Lugares salvos + </string> + <string name="Command_Preferences_Tooltip"> + Preferências + </string> + <string name="Command_Profile_Tooltip"> + Edite ou visualize seu perfil + </string> + <string name="Command_Report_Abuse_Tooltip"> + Relatar abuso + </string> + <string name="Command_Search_Tooltip"> + Encontre lugares, eventos, pessoas + </string> + <string name="Command_Snapshot_Tooltip"> + Tirar uma foto + </string> + <string name="Command_Speak_Tooltip"> + Fale com pessoas próximas usando seu microfone + </string> + <string name="Command_Twitter_Tooltip"> + Twitter + </string> + <string name="Command_View_Tooltip"> + Alterar o ângulo da câmera + </string> + <string name="Command_Voice_Tooltip"> + Controles de volume das chamadas e pessoas próximas a você no mundo virtual + </string> + <string name="Toolbar_Bottom_Tooltip"> + atualmente na sua barra de ferramentas inferior + </string> + <string name="Toolbar_Left_Tooltip"> + atualmente na sua barra de ferramentas esquerda + </string> + <string name="Toolbar_Right_Tooltip"> + atualmente na sua barra de ferramentas direita + </string> + <string name="Retain%"> + Reter% + </string> + <string name="Detail"> + Detalhe + </string> + <string name="Better Detail"> + Detalhamento maior + </string> + <string name="Surface"> + Superfície + </string> + <string name="Solid"> + Sólido + </string> + <string name="Wrap"> + Conclusão + </string> + <string name="Preview"> + Visualizar + </string> + <string name="Normal"> + Normal + </string> + <string name="Pathfinding_Wiki_URL"> + http://wiki.secondlife.com/wiki/Pathfinding_Tools_in_the_Second_Life_Viewer + </string> + <string name="Pathfinding_Object_Attr_None"> + Nenhum + </string> + <string name="Pathfinding_Object_Attr_Permanent"> + Afeta o navmesh + </string> + <string name="Pathfinding_Object_Attr_Character"> + Personagem + </string> + <string name="Pathfinding_Object_Attr_MultiSelect"> + (Múltiplo) + </string> + <string name="snapshot_quality_very_low"> + Muito baixo + </string> + <string name="snapshot_quality_low"> + Baixo + </string> + <string name="snapshot_quality_medium"> + Médio + </string> + <string name="snapshot_quality_high"> + Alto + </string> + <string name="snapshot_quality_very_high"> + Muito alto + </string> + <string name="TeleportMaturityExceeded"> + O residente não pode visitar a região. + </string> + <string name="UserDictionary"> + [Usuário] + </string> + <string name="experience_tools_experience"> + Experiência + </string> + <string name="ExperienceNameNull"> + (nenhuma experiência) + </string> + <string name="ExperienceNameUntitled"> + (experiência sem título) + </string> + <string name="Land-Scope"> + Dentro do terreno + </string> + <string name="Grid-Scope"> + Dentro da grade + </string> + <string name="Allowed_Experiences_Tab"> + PERMITIDO + </string> + <string name="Blocked_Experiences_Tab"> + BLOQUEADO + </string> + <string name="Contrib_Experiences_Tab"> + COLABORADOR + </string> + <string name="Admin_Experiences_Tab"> + ADMINISTRADOR + </string> + <string name="Recent_Experiences_Tab"> + RECENTE + </string> + <string name="Owned_Experiences_Tab"> + PRÓPRIAS + </string> + <string name="ExperiencesCounter"> + ([EXPERIENCES], máx. [MAXEXPERIENCES]) + </string> + <string name="ExperiencePermission1"> + assumir seus controles + </string> + <string name="ExperiencePermission3"> + acionar animações no seu avatar + </string> + <string name="ExperiencePermission4"> + anexar ao avatar + </string> + <string name="ExperiencePermission9"> + rastrear sua câmera + </string> + <string name="ExperiencePermission10"> + controlar sua câmera + </string> + <string name="ExperiencePermission11"> + teletransportar você + </string> + <string name="ExperiencePermission12"> + aceitar automaticamente permissões de experiência + </string> + <string name="ExperiencePermission16"> + forçar o avatar a sentar + </string> + <string name="ExperiencePermission17"> + alterar sua configurações de ambiente + </string> + <string name="ExperiencePermissionShortUnknown"> + realizar uma operação desconhecida: [Permission] + </string> + <string name="ExperiencePermissionShort1"> + Assumir o controle + </string> + <string name="ExperiencePermissionShort3"> + Acionar animações + </string> + <string name="ExperiencePermissionShort4"> + Anexar + </string> + <string name="ExperiencePermissionShort9"> + Rastrear câmera + </string> + <string name="ExperiencePermissionShort10"> + Controlar câmera + </string> + <string name="ExperiencePermissionShort11"> + Teletransportar + </string> + <string name="ExperiencePermissionShort12"> + Autorização + </string> + <string name="ExperiencePermissionShort16"> + Sentar + </string> + <string name="ExperiencePermissionShort17"> + Ambiente + </string> + <string name="logging_calls_disabled_log_empty"> + As conversas não estão sendo registradas. Para começar a manter um registro, selecione "Salvar: apenas registro" ou "Salvar: registro e transcrições" em Preferências> Bate-papo. + </string> + <string name="logging_calls_disabled_log_not_empty"> + Nenhuma conversa será registrada. Para recomeçar a gravação de registros, selecione "Salvar: apenas registro" ou "Salvar: registro e transcrições" em Preferências> Bate-papo. + </string> + <string name="logging_calls_enabled_log_empty"> + Não há conversas registradas. Depois que você entrar em contato com alguém, ou alguém entrar em contato com você, um registro será exibido aqui. + </string> + <string name="loading_chat_logs"> + Carregando... + </string> + <string name="na"> + n/d + </string> + <string name="preset_combo_label"> + -Lista vazia- + </string> + <string name="Default"> + Padrão + </string> + <string name="none_paren_cap"> + (nenhum) + </string> + <string name="no_limit"> + Sem limite + </string> + <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES"> + A forma física contém triângulos muito pequenos. Tente simplificar o modelo físico. + </string> + <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH"> + A forma física contém dados de confirmação ruins. Tente consertar o modelo físico. + </string> + <string name="Mav_Details_MAV_UNKNOWN_VERSION"> + A forma física não tem a versão correta. Defina a versão correta para o modelo físico. + </string> + <string name="couldnt_resolve_host"> + O DNS não pode resolver o nome do host([HOSTNAME]). Verifique se você pode conectar ao site www.secondlife.com . Se você puder, mas se continuar recebendo esta mensagem de erro, vá à sessão -Suporte no site Secondlife.com e informe o problema.</string> - <string name="ssl_peer_certificate">O servidor de acesso não pôde verificá-lo pelo SSL. +Suporte no site Secondlife.com e informe o problema. + </string> + <string name="ssl_peer_certificate"> + O servidor de acesso não pôde verificá-lo pelo SSL. Se você continuar recebendo esta mensagem de erro, vá à sessão Suporte no site Secondlife.com -e informe o problema.</string> - <string name="ssl_connect_error">Geralmente, esse erro significa que o relógio do seu computador não está com o horário correto. +e informe o problema. + </string> + <string name="ssl_connect_error"> + Geralmente, esse erro significa que o relógio do seu computador não está com o horário correto. Vá em Painel de Controles e certifique-se de que a hora e data estejam corretos. Além disso, verifique se a sua rede e firewall estejam corretos. Se você continuar recebendo esta mensagem de erro, vá à sessão Suporte no site Secondlife.com e informe o problema. -[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de conhecimento]</string> +[https://community.secondlife.com/knowledgebase/english/error-messages-r520/#Section__3 Base de conhecimento] + </string> </strings> diff --git a/indra/newview/skins/default/xui/pt/teleport_strings.xml b/indra/newview/skins/default/xui/pt/teleport_strings.xml index 0cbf4dccd8..014e44a175 100644 --- a/indra/newview/skins/default/xui/pt/teleport_strings.xml +++ b/indra/newview/skins/default/xui/pt/teleport_strings.xml @@ -1,38 +1,94 @@ <?xml version="1.0" ?> <teleport_messages> <message_set name="errors"> - <message name="invalid_tport">Houve um problema ao processar o teletransporte. Talvez seja preciso sair e entrar do Second Life para fazer o teletransporte. -Se você continuar a receber esta mensagem, por favor consulte o [SUPPORT_SITE].</message> - <message name="invalid_region_handoff">Problema encontrado ao processar a passagem de regiões. Talvez seja preciso sair e entrar do Second Life atravessar regiões novamente. -Se você continuar a receber esta mensagem, por favor consulte o [SUPPORT_SITE].</message> - <message name="blocked_tport">Desculpe, teletransportes estão atualmente bloqueados. Tente novamente dentro de alguns instantes. Se você continuar com problemas de teletransporte, por favor tente deslogar e relogar para resolver o problema.</message> - <message name="nolandmark_tport">Desculpe, mas o sistema não conseguiu localizar a landmark de destino.</message> - <message name="timeout_tport">Desculpe, não foi possível para o sistema executar o teletransporte. Tente novamente dentro de alguns instantes.</message> - <message name="NoHelpIslandTP">Não é possível se teletransportar de volta à Ilha Welcome. -Vá para a 'Ilha Welcome Pública' para repetir o tutorial.</message> - <message name="noaccess_tport">Desculpe, você não tem acesso ao destino deste teletransporte.</message> - <message name="missing_attach_tport">Seu anexos ainda não chegaram. Tente esperar por alguns momentos ou deslogar e logar antes de tentar teleransportar-se novamente.</message> - <message name="too_many_uploads_tport">Afluxo nesta região é atualmente tão alto que seu pedido de teletransporte não será possível em tempo oportuno. Por favor, tente novamente em alguns minutos ou vá a uma área menos ocupada.</message> - <message name="expired_tport">Desculpe, mas o sistema não conseguiu concluir o seu pedido de teletransporte em tempo hábil. Por favor, tente novamente em alguns minutos.</message> - <message name="expired_region_handoff">Desculpe, mas o sistema não pôde concluir a sua travessia de região em tempo hábil. Por favor, tente novamente em alguns minutos.</message> - <message name="no_host">Não foi possível encontrar o destino do teletransporte. O destino pode estar temporariamente indisponível ou não existir mais. Por favor, tente novamente em poucos minutos.</message> - <message name="no_inventory_host">O sistema de inventário está indisponível no momento.</message> - <message name="MustGetAgeRegion">Você deve ter 18 anos ou mais para acessar esta região.</message> - <message name="RegionTPSpecialUsageBlocked">Não é possível inserir a região. '[REGION_NAME]' é uma Região de Skill Gaming, portanto você deve atender certos critérios para poder entrar. Para maiores detalhes, consulte as [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ].</message> - <message name="preexisting_tport">Desculpe, mas o sistema falhou ao iniciar o seu teletransporte. Por favor, tente novamente dentro de alguns minutos.</message> + <message name="invalid_tport"> + Houve um problema ao processar o teletransporte. Talvez seja preciso sair e entrar do Second Life para fazer o teletransporte. +Se você continuar a receber esta mensagem, por favor consulte o [SUPPORT_SITE]. + </message> + <message name="invalid_region_handoff"> + Problema encontrado ao processar a passagem de regiões. Talvez seja preciso sair e entrar do Second Life atravessar regiões novamente. +Se você continuar a receber esta mensagem, por favor consulte o [SUPPORT_SITE]. + </message> + <message name="blocked_tport"> + Desculpe, teletransportes estão atualmente bloqueados. Tente novamente dentro de alguns instantes. Se você continuar com problemas de teletransporte, por favor tente deslogar e relogar para resolver o problema. + </message> + <message name="nolandmark_tport"> + Desculpe, mas o sistema não conseguiu localizar a landmark de destino. + </message> + <message name="timeout_tport"> + Desculpe, não foi possível para o sistema executar o teletransporte. Tente novamente dentro de alguns instantes. + </message> + <message name="NoHelpIslandTP"> + Não é possível se teletransportar de volta à Ilha Welcome. +Vá para a 'Ilha Welcome Pública' para repetir o tutorial. + </message> + <message name="noaccess_tport"> + Desculpe, você não tem acesso ao destino deste teletransporte. + </message> + <message name="missing_attach_tport"> + Seu anexos ainda não chegaram. Tente esperar por alguns momentos ou deslogar e logar antes de tentar teleransportar-se novamente. + </message> + <message name="too_many_uploads_tport"> + Afluxo nesta região é atualmente tão alto que seu pedido de teletransporte não será possível em tempo oportuno. Por favor, tente novamente em alguns minutos ou vá a uma área menos ocupada. + </message> + <message name="expired_tport"> + Desculpe, mas o sistema não conseguiu concluir o seu pedido de teletransporte em tempo hábil. Por favor, tente novamente em alguns minutos. + </message> + <message name="expired_region_handoff"> + Desculpe, mas o sistema não pôde concluir a sua travessia de região em tempo hábil. Por favor, tente novamente em alguns minutos. + </message> + <message name="no_host"> + Não foi possível encontrar o destino do teletransporte. O destino pode estar temporariamente indisponível ou não existir mais. Por favor, tente novamente em poucos minutos. + </message> + <message name="no_inventory_host"> + O sistema de inventário está indisponível no momento. + </message> + <message name="MustGetAgeRegion"> + Você deve ter 18 anos ou mais para acessar esta região. + </message> + <message name="RegionTPSpecialUsageBlocked"> + Não é possível inserir a região. '[REGION_NAME]' é uma Região de Skill Gaming, portanto você deve atender certos critérios para poder entrar. Para maiores detalhes, consulte as [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ]. + </message> + <message name="preexisting_tport"> + Desculpe, mas o sistema falhou ao iniciar o seu teletransporte. Por favor, tente novamente dentro de alguns minutos. + </message> </message_set> <message_set name="progress"> - <message name="sending_dest">Enviando para o destino.</message> - <message name="redirecting">Redirecionando para uma localidade diferente.</message> - <message name="relaying">Transferindo para o destino.</message> - <message name="sending_home">Enviando solicitação de localização de início.</message> - <message name="sending_landmark">Enviando solicitação de localização de landmark.</message> - <message name="completing">Completando teletransporte.</message> - <message name="completed_from">Teletransporte de [T_SLURL] concluído</message> - <message name="resolving">Identificando destino.</message> - <message name="contacting">Contactando nova região.</message> - <message name="arriving">Chegando...</message> - <message name="requesting">Solicitando teletransporte...</message> - <message name="pending">Teletransporte pendente...</message> + <message name="sending_dest"> + Enviando para o destino. + </message> + <message name="redirecting"> + Redirecionando para uma localidade diferente. + </message> + <message name="relaying"> + Transferindo para o destino. + </message> + <message name="sending_home"> + Enviando solicitação de localização de início. + </message> + <message name="sending_landmark"> + Enviando solicitação de localização de landmark. + </message> + <message name="completing"> + Completando teletransporte. + </message> + <message name="completed_from"> + Teletransporte de [T_SLURL] concluído + </message> + <message name="resolving"> + Identificando destino. + </message> + <message name="contacting"> + Contactando nova região. + </message> + <message name="arriving"> + Chegando... + </message> + <message name="requesting"> + Solicitando teletransporte... + </message> + <message name="pending"> + Teletransporte pendente... + </message> </message_set> </teleport_messages> diff --git a/indra/newview/skins/default/xui/ru/panel_login_first.xml b/indra/newview/skins/default/xui/ru/panel_login_first.xml deleted file mode 100644 index 5db81ea7ca..0000000000 --- a/indra/newview/skins/default/xui/ru/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php - </panel.string> - <panel.string name="sign_up_url"> - https://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Имя пользователя" name="username_combo" tool_tip="Имя пользователя, которое вы выбрали при регистрации, например, «bobsmith12» или «Steller Sunshine»"/> - <line_editor label="Пароль" name="password_edit"/> - <button label="Войти" name="connect_btn"/> - <check_box label="Запомнить меня" name="remember_check"/> - <text name="forgot_password_text"> - Забытый пароль - </text> - <text name="sign_up_text"> - Регистрация - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Ваш первый шаг – Учебный остров. Найдите портал выхода! - </text> - <text name="image_caption_right"> - Затем исследуйте Социальный остров и познакомьтесь с другими новичками! - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml index 7ba03ee0c9..f7fda0b1dc 100644 --- a/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/ru/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="Сохранить на диске" name="save_to_computer_btn"/> - <button label="Сохранить в инвентаре (L$[AMOUNT])" name="save_to_inventory_btn"/> + <button label="Сохранить в инвентаре" name="save_to_inventory_btn"/> <button label="Поделиться в профиле" name="save_to_profile_btn"/> <button label="Поделиться в Facebook" name="send_to_facebook_btn"/> <button label="Поделиться в Twitter" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/ru/strings.xml b/indra/newview/skins/default/xui/ru/strings.xml index 48eb7118aa..8433f893b5 100644 --- a/indra/newview/skins/default/xui/ru/strings.xml +++ b/indra/newview/skins/default/xui/ru/strings.xml @@ -1,8 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- This file contains strings that used to be hardcoded in the source. - It is only for those strings which do not belong in a floater. - For example, the strings used in avatar chat bubbles, and strings - that are returned from one component and may appear in many places--> <strings> <string name="SECOND_LIFE"> Second Life @@ -1657,7 +1653,7 @@ support@secondlife.com. Тариф зависит от типа вашей подписки. Тарифы для владельцев расширенных пакетов меньше. [https://secondlife.com/my/account/membership.php? Узнать больше] </string> <string name="Open landmarks"> - Открыть сохраненные локации + Открыть сохраненные локации </string> <string name="Unconstrained"> Без ограничений @@ -2870,8 +2866,8 @@ support@secondlife.com. <string name="."> . </string> - <string name="'"> - ' + <string name="'"> + ' </string> <string name="---"> --- @@ -2983,7 +2979,7 @@ support@secondlife.com. Не удается запустить приложение [APP_NAME], поскольку драйверы видеокарты неправильно установлены, устарели или предназначены для оборудования, которое не поддерживается. Установите или переустановите последние драйверы видеокарты. Если это сообщение продолжает отображаться, обратитесь на сайт [SUPPORT_SITE]. </string> - <string name="5 O'Clock Shadow"> + <string name="5 O'Clock Shadow"> Жидкие </string> <string name="All White"> @@ -4576,6 +4572,10 @@ support@secondlife.com. <string name="inventory_folder_offered-im"> Предложена папка инвентаря «[ITEM_NAME]» </string> + <string name="bot_warning"> + Вы общаетесь с ботом [NAME]. Не передавайте личные данные. +Подробнее на https://second.life/scripted-agents. + </string> <string name="share_alert"> Перетаскивайте вещи из инвентаря сюда </string> @@ -5143,7 +5143,7 @@ support@secondlife.com. <string name="ExternalEditorNotFound"> Не удается найти указанный внешний редактор. Попробуйте взять путь к редактору в двойные кавычки -(например "/path to my/editor" "%s") +(например "/path to my/editor" "%s") </string> <string name="ExternalEditorCommandParseError"> Ошибка анализа командной строки для внешнего редактора. diff --git a/indra/newview/skins/default/xui/tr/panel_login_first.xml b/indra/newview/skins/default/xui/tr/panel_login_first.xml deleted file mode 100644 index 1fc80c2b97..0000000000 --- a/indra/newview/skins/default/xui/tr/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php - </panel.string> - <panel.string name="sign_up_url"> - https://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="Kullanıcı Adı" name="username_combo" tool_tip="Kaydolduğunuzda seçtiğiniz kullanıcı adı, örn. mustafayalcin12 veya Faruk Gungoren"/> - <line_editor label="Parola" name="password_edit"/> - <button label="Oturum Aç" name="connect_btn"/> - <check_box label="Beni hatırla" name="remember_check"/> - <text name="forgot_password_text"> - Parolamı unuttum - </text> - <text name="sign_up_text"> - Kaydol - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - Başlangıç yeriniz Eğitim Adası. Haydi çıkış portalını bulun! - </text> - <text name="image_caption_right"> - Sonra da Sosyal Ada'yı keşfe çıkın ve diğer LS sakinleriyle tanışın! - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml index 1b48bbeec2..a028710b98 100644 --- a/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/tr/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="Diske Kaydet" name="save_to_computer_btn"/> - <button label="Envantere Kaydet (L$[AMOUNT])" name="save_to_inventory_btn"/> + <button label="Envantere Kaydet" name="save_to_inventory_btn"/> <button label="Profil Akışında Paylaş" name="save_to_profile_btn"/> <button label="Facebook'ta Paylaş" name="send_to_facebook_btn"/> <button label="Twitter'da Paylaş" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/tr/strings.xml b/indra/newview/skins/default/xui/tr/strings.xml index 92e5160e97..e68d000179 100644 --- a/indra/newview/skins/default/xui/tr/strings.xml +++ b/indra/newview/skins/default/xui/tr/strings.xml @@ -1,8 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- This file contains strings that used to be hardcoded in the source. - It is only for those strings which do not belong in a floater. - For example, the strings used in avatar chat bubbles, and strings - that are returned from one component and may appear in many places--> <strings> <string name="SECOND_LIFE"> Second Life @@ -88,7 +84,7 @@ Ses Sunucusu Sürümü: [VOICE_VERSION] [month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt] </string> <string name="ErrorFetchingServerReleaseNotesURL"> - Sunucu sürümü notları URL'si alınırken hata oluştu. + Sunucu sürümü notları URL'si alınırken hata oluştu. </string> <string name="BuildConfiguration"> Yapı Konfigürasyonu @@ -205,7 +201,7 @@ Ses Sunucusu Sürümü: [VOICE_VERSION] http://secondlife.com/download </string> <string name="LoginFailedViewerNotPermitted"> - Kullandığınız görüntüleyici ile artık Second Life'a erişemezsiniz. Yeni bir görüntüleyiciyi karşıdan yüklemek için lütfen şu sayfayı ziyaret edin: + Kullandığınız görüntüleyici ile artık Second Life'a erişemezsiniz. Yeni bir görüntüleyiciyi karşıdan yüklemek için lütfen şu sayfayı ziyaret edin: http://secondlife.com/download Daha fazla bilgi edinmek için asağıdaki SSS sayfamızı ziyaret edin: @@ -247,10 +243,10 @@ Güncelleştirmeler için www.secondlife.com/status adresini kontrol edin. <string name="LoginFailedPremiumOnly"> Second Life üzerindeki aktif kullanıcıların olası en iyi deneyimi yaşamasını sağlamak için, oturum açılması geçici olarak kısıtlanmıştır. -Second Life için ödeme yapmış olan kişilere öncelik tanımak amacıyla, ücretsiz hesaplara sahip kişiler bu süre içerisinde Second Life'a erişemeyecekler. +Second Life için ödeme yapmış olan kişilere öncelik tanımak amacıyla, ücretsiz hesaplara sahip kişiler bu süre içerisinde Second Life'a erişemeyecekler. </string> <string name="LoginFailedComputerProhibited"> - Second Life'a bu bilgisayardan erişemezsiniz. + Second Life'a bu bilgisayardan erişemezsiniz. Bunun bir hata olduğunu düşünüyorsanız, lütfen şu adrese başvurun: support@secondlife.com. </string> @@ -286,7 +282,7 @@ Lütfen yeniden oturum açmayı denemeden önce bir dakika bekleyin. Bir simülatöre bağlanılamadı. </string> <string name="LoginFailedRestrictedHours"> - Hesabınız Second Life'a sadece + Hesabınız Second Life'a sadece Pasifik Saati ile [START] ve [END] arasında erişebilir. Lütfen bu saatler arasında tekrar uğrayın. Bunun bir hata olduğunu düşünüyorsanız, lütfen şu adrese başvurun: support@secondlife.com @@ -369,7 +365,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. Facebook ile bağlantı kurulurken sorun oluştu </string> <string name="SocialFacebookErrorPosting"> - Facebook'ta yayınlarken sorun oluştu + Facebook'ta yayınlarken sorun oluştu </string> <string name="SocialFacebookErrorDisconnecting"> Facebook bağlantısı kesilirken sorun oluştu @@ -387,7 +383,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. Flickr bağlantısı kurulurken sorun çıktı </string> <string name="SocialFlickrErrorPosting"> - Flickr'da yayınlarken sorun çıktı + Flickr'da yayınlarken sorun çıktı </string> <string name="SocialFlickrErrorDisconnecting"> Flickr bağlantısı kesilirken sorun çıktı @@ -405,7 +401,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. Twitter bağlantısı kurulurken sorun çıktı </string> <string name="SocialTwitterErrorPosting"> - Twitter'da yayınlarken sorun çıktı + Twitter'da yayınlarken sorun çıktı </string> <string name="SocialTwitterErrorDisconnecting"> Twitter bağlantısı kesilirken sorun çıktı @@ -414,7 +410,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. Siyah Beyaz </string> <string name="Colors1970"> - 70'lerin Renkleri + 70'lerin Renkleri </string> <string name="Intense"> Yoğun @@ -657,7 +653,7 @@ Lütfen bir dakika içerisinde tekrar oturum açmayı deneyin. not kartlarına eklenemez. </string> <string name="TooltipNotecardOwnerRestrictedDrop"> - Sadece kısıtlamasız 'sonraki sahip' + Sadece kısıtlamasız 'sonraki sahip' izinlerini içeren öğeler not kartlarına eklenebilir. </string> @@ -1107,10 +1103,10 @@ http://secondlife.com/support adresini ziyaret edin. Şimdi Yakındaki bir Sesli Sohbete yeniden bağlanılacaksınız. </string> <string name="ScriptQuestionCautionChatGranted"> - '[OWNERNAME]' adlı kişiye ait, [REGIONPOS] üzerinde [REGIONNAME] içerisinde bulunan '[OBJECTNAME]' nesnesine şunu yapma izni verildi: [PERMISSIONS]. + '[OWNERNAME]' adlı kişiye ait, [REGIONPOS] üzerinde [REGIONNAME] içerisinde bulunan '[OBJECTNAME]' nesnesine şunu yapma izni verildi: [PERMISSIONS]. </string> <string name="ScriptQuestionCautionChatDenied"> - '[OWNERNAME]' adlı kişiye ait, [REGIONPOS] üzerinde [REGIONNAME] içerisinde bulunan '[OBJECTNAME]' nesnesine şunu yapma izni verilmedi: [PERMISSIONS]. + '[OWNERNAME]' adlı kişiye ait, [REGIONPOS] üzerinde [REGIONNAME] içerisinde bulunan '[OBJECTNAME]' nesnesine şunu yapma izni verilmedi: [PERMISSIONS]. </string> <string name="AdditionalPermissionsRequestHeader"> Eğer hesabınıza erişime izin verirseniz, bu nesneye aynı zamanda şunun için izin vermiş olacaksınız: @@ -1486,7 +1482,7 @@ http://secondlife.com/support adresini ziyaret edin. Yüksek </string> <string name="LeaveMouselook"> - Dünya Görünümüne dönmek için ESC'e basın + Dünya Görünümüne dönmek için ESC'e basın </string> <string name="InventoryNoMatchingItems"> Aradığınızı bulamadınız mı? [secondlife:///app/search/all/[SEARCH_TERM] Arama] ile bulmayı deneyin. @@ -1545,7 +1541,7 @@ http://secondlife.com/support adresini ziyaret edin. </string> <string name="InventoryOutboxNoItemsTooltip"/> <string name="InventoryOutboxNoItems"> - Bu alana klasörleri sürükleyin ve bunları [[MARKETPLACE_DASHBOARD_URL] Pazaryerinde] satılık olarak duyurmak için "Pazaryerine Gönder" üzerine tıklayın. + Bu alana klasörleri sürükleyin ve bunları [[MARKETPLACE_DASHBOARD_URL] Pazaryerinde] satılık olarak duyurmak için "Pazaryerine Gönder" üzerine tıklayın. </string> <string name="InventoryOutboxInitializingTitle"> Pazaryeri Başlatılıyor. @@ -1815,7 +1811,7 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin Satın Al </string> <string name="BuyforL$"> - L$'a Satın Al + L$'a Satın Al </string> <string name="Stone"> Taş @@ -2001,19 +1997,19 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin Hata: Nesne mevcut dış görünüme dahil ama eklenmemiş </string> <string name="YearsMonthsOld"> - [AGEYEARS] [AGEMONTHS]'lık + [AGEYEARS] [AGEMONTHS]'lık </string> <string name="YearsOld"> [AGEYEARS] yaşında </string> <string name="MonthsOld"> - [AGEMONTHS]'lık + [AGEMONTHS]'lık </string> <string name="WeeksOld"> - [AGEWEEKS]'lık + [AGEWEEKS]'lık </string> <string name="DaysOld"> - [AGEDAYS]'lük + [AGEDAYS]'lük </string> <string name="TodayOld"> Bugün katıldı @@ -2034,7 +2030,7 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin Çevrenizdeki kimse sizi işleyemeyebilir. </string> <string name="hud_description_total"> - BÜG'niz + BÜG'niz </string> <string name="hud_name_with_joint"> [OBJ_NAME] ([JNT_NAME] üzerinde) @@ -2312,13 +2308,13 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin Kullanılan bellek: [COUNT] kb </string> <string name="ScriptLimitsParcelScriptURLs"> - Parsel Komut Dosyası URL'leri + Parsel Komut Dosyası URL'leri </string> <string name="ScriptLimitsURLsUsed"> - Kullanılan URL'ler: [COUNT] / [MAX] içerisinden; [AVAILABLE] serbest + Kullanılan URL'ler: [COUNT] / [MAX] içerisinden; [AVAILABLE] serbest </string> <string name="ScriptLimitsURLsUsedSimple"> - Kullanılan URL'ler: [COUNT] + Kullanılan URL'ler: [COUNT] </string> <string name="ScriptLimitsRequestError"> Bilgi talep edilirken hata oluştu @@ -2522,7 +2518,7 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin Yeni Komut Dosyası </string> <string name="DoNotDisturbModeResponseDefault"> - Bu sakin "Rahatsız Etme" seçeneğini devreye almış, mesajınızı sonra görecek. + Bu sakin "Rahatsız Etme" seçeneğini devreye almış, mesajınızı sonra görecek. </string> <string name="MuteByName"> (Adına göre) @@ -2633,7 +2629,7 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin size verdi: </string> <string name="InvOfferDecline"> - <nolink>[NAME]</nolink> tarafından gönderilen [DESC]'i reddettiniz. + <nolink>[NAME]</nolink> tarafından gönderilen [DESC]'i reddettiniz. </string> <string name="GroupMoneyTotal"> Toplam @@ -2870,8 +2866,8 @@ Bu mesaj size gelmeye devam ederse lütfen http://support.secondlife.com adresin <string name="."> . </string> - <string name="'"> - ' + <string name="'"> + ' </string> <string name="---"> --- @@ -2986,7 +2982,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. </string> - <string name="5 O'Clock Shadow"> + <string name="5 O'Clock Shadow"> Bir Günlük Sakal </string> <string name="All White"> @@ -4490,7 +4486,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. Görüntüleyici başlatılamadı </string> <string name="ItemsComingInTooFastFrom"> - [APP_NAME]: [FROM_NAME]'den öğeler çok hızlı geliyor, [TIME] saniye boyunca otomatik ön izleme devre dışı bırakıldı + [APP_NAME]: [FROM_NAME]'den öğeler çok hızlı geliyor, [TIME] saniye boyunca otomatik ön izleme devre dışı bırakıldı </string> <string name="ItemsComingInTooFast"> [APP_NAME]: Öğeler çok hızlı geliyor, [TIME] saniye boyunca otomatik ön izleme devre dışı bırakıldı @@ -4526,7 +4522,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. (Kaydedildi [LONG_TIMESTAMP]) </string> <string name="IM_unblock_only_groups_friends"> - Bu mesajı görmek için Tercihler/Gizlilik'de 'Sadece arkadaşlar ve gruplar beni arasın veya Aİ göndersin' seçeneğinin işaretini kaldırmalısınız. + Bu mesajı görmek için Tercihler/Gizlilik'de 'Sadece arkadaşlar ve gruplar beni arasın veya Aİ göndersin' seçeneğinin işaretini kaldırmalısınız. </string> <string name="OnlineStatus"> Çevrimiçi @@ -4550,7 +4546,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. Sesli aramaya katıldınız </string> <string name="you_auto_rejected_call-im"> - "Rahatsız Etme" seçeneğini devredeyken sesli aramayı otomatik olarak reddettiniz. + "Rahatsız Etme" seçeneğini devredeyken sesli aramayı otomatik olarak reddettiniz. </string> <string name="name_started_call"> [NAME] bir sesli arama başlattı @@ -4574,22 +4570,26 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. [AGENT_NAME] ile konferans </string> <string name="inventory_item_offered-im"> - "[ITEM_NAME]" envanter öğesi sunuldu + "[ITEM_NAME]" envanter öğesi sunuldu </string> <string name="inventory_folder_offered-im"> - "[ITEM_NAME]" envanter klasörü sunuldu + "[ITEM_NAME]" envanter klasörü sunuldu + </string> + <string name="bot_warning"> + Bir bot ile sohbet ediyorsunuz, [NAME]. Kişisel bilgilerinizi paylaşmayın. +Daha fazla bilgi için: https://second.life/scripted-agents. </string> <string name="share_alert"> Envanterinizden buraya öğeler sürükleyin </string> <string name="facebook_post_success"> - Facebook'ta yayınladınız. + Facebook'ta yayınladınız. </string> <string name="flickr_post_success"> - Flickr'da yayınladınız. + Flickr'da yayınladınız. </string> <string name="twitter_post_success"> - Twitter'da yayınladınız. + Twitter'da yayınladınız. </string> <string name="no_session_message"> (Aİ Oturumu Mevcut Değil) @@ -4682,7 +4682,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. [NAME] size L$[AMOUNT] ödedi. </string> <string name="you_paid_ldollars"> - [NAME]'e [REASON] L$[AMOUNT] ödediniz. + [NAME]'e [REASON] L$[AMOUNT] ödediniz. </string> <string name="you_paid_ldollars_gift"> [NAME] adlı kullanıcıya [AMOUNT] L$ ödediniz. [REASON] @@ -4691,13 +4691,13 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. L$[AMOUNT] ödediniz. </string> <string name="you_paid_ldollars_no_reason"> - [NAME]'e L$[AMOUNT] ödediniz. + [NAME]'e L$[AMOUNT] ödediniz. </string> <string name="you_paid_ldollars_no_name"> [REASON] L$[AMOUNT] ödediniz. </string> <string name="you_paid_failure_ldollars"> - [REASON] [NAME]'e L$[AMOUNT] ödeyemediniz. + [REASON] [NAME]'e L$[AMOUNT] ödeyemediniz. </string> <string name="you_paid_failure_ldollars_gift"> [NAME] adlı kullanıcıya [AMOUNT] L$ ödeyemediniz. [REASON] @@ -4706,7 +4706,7 @@ Bu iletiyi almaya devam ederseniz, lütfen [SUPPORT_SITE] bölümüne başvurun. L$[AMOUNT] ödeyemediniz. </string> <string name="you_paid_failure_ldollars_no_reason"> - [NAME]'e L$[AMOUNT] ödeyemediniz. + [NAME]'e L$[AMOUNT] ödeyemediniz. </string> <string name="you_paid_failure_ldollars_no_name"> [REASON] L$[AMOUNT] ödeyemediniz. @@ -5138,7 +5138,7 @@ Hizmetle ilişkili bilinen bir sorun olup olmadığını görmek için lütfen h <string name="ExternalEditorNotFound"> Belirttiğiniz harici düzenleyici bulunamadı. Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. -(örn. "/yolum/duzenleyici" "%s") +(örn. "/yolum/duzenleyici" "%s") </string> <string name="ExternalEditorCommandParseError"> Harici düzenleyici komutu ayrıştırılırken hata oluştu. @@ -5627,10 +5627,10 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. Ortamlarım </string> <string name="Command_Facebook_Tooltip"> - Facebook'ta Yayınla + Facebook'ta Yayınla </string> <string name="Command_Flickr_Tooltip"> - Flickr'a yükle + Flickr'a yükle </string> <string name="Command_Gestures_Tooltip"> Avatarınız için mimikler @@ -5861,10 +5861,10 @@ Düzenleyici yolunu çift tırnakla çevrelemeyi deneyin. Ortam </string> <string name="logging_calls_disabled_log_empty"> - Sohbetlerin günlüğü tutulmuyor. Bir günlük tutmaya başlamak için, Tercihler > Sohbet altında "Kaydet: Sadece günlük" veya "Kaydet: Günlük ve dökümler" seçimini yapın. + Sohbetlerin günlüğü tutulmuyor. Bir günlük tutmaya başlamak için, Tercihler > Sohbet altında "Kaydet: Sadece günlük" veya "Kaydet: Günlük ve dökümler" seçimini yapın. </string> <string name="logging_calls_disabled_log_not_empty"> - Bundan böyle sohbetlerin günlükleri tutulmayacak. Bir günlük tutmaya devam etmek için, Tercihler > Sohbet altında "Kaydet: Sadece günlük" veya "Kaydet: Günlük ve dökümler" seçimini yapın. + Bundan böyle sohbetlerin günlükleri tutulmayacak. Bir günlük tutmaya devam etmek için, Tercihler > Sohbet altında "Kaydet: Sadece günlük" veya "Kaydet: Günlük ve dökümler" seçimini yapın. </string> <string name="logging_calls_enabled_log_empty"> Günlüğü tutulmuş sohbet yok. Siz biriyle iletişime geçtikten sonra veya biri sizinle iletişime geçtikten sonra, burada bir günlük girişi gösterilir. @@ -5910,7 +5910,7 @@ bölümüne gidin ve sorunu bildirin. </string> <string name="ssl_connect_error"> Çoğunlukla, bu durum, bilgisayarınızın saatinin yanlış ayarlandığı anlamına gelir. -Lütfen Denetim Masası'na gidin ve tarih ve saat ayarlarının doğru yapıldığından emin olun. +Lütfen Denetim Masası'na gidin ve tarih ve saat ayarlarının doğru yapıldığından emin olun. Ayrıca, ağınızın ve güvenlik duvarınızın doğru şekilde ayarlanıp ayarlanmadığını kontrol edin. Bu hatayı almaya devam ederseniz, lütfen SecondLife.com web sitesinin Destek bölümüne gidin ve sorunu bildirin. diff --git a/indra/newview/skins/default/xui/tr/teleport_strings.xml b/indra/newview/skins/default/xui/tr/teleport_strings.xml index e3a08e04b2..b403786bd2 100644 --- a/indra/newview/skins/default/xui/tr/teleport_strings.xml +++ b/indra/newview/skins/default/xui/tr/teleport_strings.xml @@ -21,8 +21,8 @@ Hala ışınlanamıyorsanız, sorunu çözmek için lütfen çıkış yapıp otu Bir dakika sonra tekrar deneyin. </message> <message name="NoHelpIslandTP"> - Karşılama Ada'sına geri ışınlanamazsınız. -Öğreticiyi tekrarlamak için 'Karşılama Ada'sı Kamusal Alanı'na gidin. + Karşılama Ada'sına geri ışınlanamazsınız. +Öğreticiyi tekrarlamak için 'Karşılama Ada'sı Kamusal Alanı'na gidin. </message> <message name="noaccess_tport"> Üzgünüz, bu ışınlanma hedef konumuna erişim hakkına sahip değilsiniz. @@ -49,7 +49,7 @@ Bir dakika sonra tekrar deneyin. Bu bölgeye girebilmek için 18 veya üzeri bir yaşta olmanız gerekir. </message> <message name="RegionTPSpecialUsageBlocked"> - Bölgeye girilemiyor. "[REGION_NAME]" bir Yetenek Oyunu Bölgesi. Buraya girebilmek için bazı ölçütleri karşılamanız gerekiyor. Ayrıntılar için lütfen [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ] adresini ziyaret edin. + Bölgeye girilemiyor. "[REGION_NAME]" bir Yetenek Oyunu Bölgesi. Buraya girebilmek için bazı ölçütleri karşılamanız gerekiyor. Ayrıntılar için lütfen [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life Skill Gaming FAQ] adresini ziyaret edin. </message> </message_set> <message_set name="progress"> diff --git a/indra/newview/skins/default/xui/zh/panel_login_first.xml b/indra/newview/skins/default/xui/zh/panel_login_first.xml deleted file mode 100644 index 4d72fcdd03..0000000000 --- a/indra/newview/skins/default/xui/zh/panel_login_first.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<panel name="panel_login"> - <panel.string name="forgot_password_url"> - http://secondlife.com/account/request.php - </panel.string> - <panel.string name="sign_up_url"> - http://join.secondlife.com/ - </panel.string> - <layout_stack name="logo_stack"> - <layout_panel name="parent_panel2"> - <layout_stack name="widget_stack"> - <layout_panel name="widget_container"> - <combo_box label="使用者名稱" name="username_combo" tool_tip="使用者名稱是你註冊時所挑選的,例如 bobsmith12 或 Steller Sunshine"/> - <line_editor label="密碼" name="password_edit"/> - <button label="登入" name="connect_btn"/> - <check_box label="記得我" name="remember_check"/> - <text name="forgot_password_text"> - 忘記密碼 - </text> - <text name="sign_up_text"> - 註冊 - </text> - </layout_panel> - </layout_stack> - </layout_panel> - <layout_panel name="parent_panel3"> - <layout_stack name="images_stack"> - <layout_panel name="images_container"> - <text name="image_caption_left"> - 你在「學習島」的第一步。 找到離開的傳送門! - </text> - <text name="image_caption_right"> - 接著,到「社交島」探索,認識新的居民朋友! - </text> - </layout_panel> - </layout_stack> - </layout_panel> - </layout_stack> -</panel> diff --git a/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml index d7c65bb25e..d9536882ac 100644 --- a/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/zh/panel_snapshot_options.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel name="panel_snapshot_options"> <button label="儲存到硬碟" name="save_to_computer_btn"/> - <button label="儲存到收納區(L$[AMOUNT])" name="save_to_inventory_btn"/> + <button label="儲存到收納區" name="save_to_inventory_btn"/> <button label="分享至檔案訊息發佈" name="save_to_profile_btn"/> <button label="分享到臉書" name="send_to_facebook_btn"/> <button label="分享到推特" name="send_to_twitter_btn"/> diff --git a/indra/newview/skins/default/xui/zh/strings.xml b/indra/newview/skins/default/xui/zh/strings.xml index 8fae007429..cf6fa1d85f 100644 --- a/indra/newview/skins/default/xui/zh/strings.xml +++ b/indra/newview/skins/default/xui/zh/strings.xml @@ -1,8 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<!-- This file contains strings that used to be hardcoded in the source. - It is only for those strings which do not belong in a floater. - For example, the strings used in avatar chat bubbles, and strings - that are returned from one component and may appear in many places--> <strings> <string name="SECOND_LIFE"> 第二人生 @@ -1103,10 +1099,10 @@ http://secondlife.com/support 求助解決問題。 現在你將重新聯接到附近的語音聊天 </string> <string name="ScriptQuestionCautionChatGranted"> - 物件「[OBJECTNAME]'」(所有人「[OWNERNAME]」,位於「[REGIONNAME]」,方位「[REGIONPOS]」)已獲得下列權限:[PERMISSIONS]。 + 物件「[OBJECTNAME]'」(所有人「[OWNERNAME]」,位於「[REGIONNAME]」,方位「[REGIONPOS]」)已獲得下列權限:[PERMISSIONS]。 </string> <string name="ScriptQuestionCautionChatDenied"> - 物件「[OBJECTNAME]'」(所有人「[OWNERNAME]」,位於「[REGIONNAME]」,方位「[REGIONPOS]」)已被撤除下列權限:[PERMISSIONS]。 + 物件「[OBJECTNAME]'」(所有人「[OWNERNAME]」,位於「[REGIONNAME]」,方位「[REGIONPOS]」)已被撤除下列權限:[PERMISSIONS]。 </string> <string name="AdditionalPermissionsRequestHeader"> 你如果打開帳戶權限,也將一併允許該物件: @@ -2863,8 +2859,8 @@ http://secondlife.com/support 求助解決問題。 <string name="."> . </string> - <string name="'"> - ' + <string name="'"> + ' </string> <string name="---"> --- @@ -2979,7 +2975,7 @@ http://secondlife.com/support 求助解決問題。 如果你繼續看到此訊息,請聯絡 [SUPPORT_SITE]。 </string> - <string name="5 O'Clock Shadow"> + <string name="5 O'Clock Shadow"> 下午五點的新鬍渣 </string> <string name="All White"> @@ -4567,10 +4563,14 @@ http://secondlife.com/support 求助解決問題。 和 [AGENT_NAME] 多方通話 </string> <string name="inventory_item_offered-im"> - 收納區物品'[ITEM_NAME]'已向人提供 + 收納區物品'[ITEM_NAME]'已向人提供 </string> <string name="inventory_folder_offered-im"> - 收納區資料夾'[ITEM_NAME]'已向人提供 + 收納區資料夾'[ITEM_NAME]'已向人提供 + </string> + <string name="bot_warning"> + 您正在与人工智能机器人 [NAME] 聊天。请勿分享任何个人信息。 +了解更多:https://second.life/scripted-agents。 </string> <string name="share_alert"> 將收納區物品拖曳到這裡 @@ -5130,7 +5130,7 @@ http://secondlife.com/support 求助解決問題。 <string name="ExternalEditorNotFound"> 找不到你指定的外部編輯器。 請嘗試在編輯器路經前後加上英文雙括號。 -(例:"/path to my/editor" "%s") +(例:"/path to my/editor" "%s") </string> <string name="ExternalEditorCommandParseError"> 解析外部編輯器指令時出錯。 diff --git a/indra/newview/skins/default/xui/zh/teleport_strings.xml b/indra/newview/skins/default/xui/zh/teleport_strings.xml index 61db294272..5523c598b4 100644 --- a/indra/newview/skins/default/xui/zh/teleport_strings.xml +++ b/indra/newview/skins/default/xui/zh/teleport_strings.xml @@ -49,7 +49,7 @@ 你必須年滿 18 歲才可進入這地區。 </message> <message name="RegionTPSpecialUsageBlocked"> - 無法進入地區。 '[REGION_NAME]' 是個「技巧性博奕」(Skill Gaming)地區,你必須符合一定條件才可進入。 欲知詳情,請參閱 [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life 技巧性博奕常見問題集]。 + 無法進入地區。 '[REGION_NAME]' 是個「技巧性博奕」(Skill Gaming)地區,你必須符合一定條件才可進入。 欲知詳情,請參閱 [http://wiki.secondlife.com/wiki/Linden_Lab_Official:Skill_Gaming_in_Second_Life 技巧性博奕常見問題集]。 </message> </message_set> <message_set name="progress"> diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp index bff2289a7c..29ca903256 100644 --- a/indra/newview/tests/lllogininstance_test.cpp +++ b/indra/newview/tests/lllogininstance_test.cpp @@ -66,6 +66,7 @@ static LLEventStream gTestPump("test_pump"); #include "../llstartup.h" LLSLURL LLStartUp::sStartSLURL; LLSLURL& LLStartUp::getStartSLURL() { return sStartSLURL; } +std::string LLStartUp::getUserId() { return ""; }; #include "lllogin.h" diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp index d5e281bba8..10c68432a1 100644 --- a/indra/newview/tests/llviewerassetstats_test.cpp +++ b/indra/newview/tests/llviewerassetstats_test.cpp @@ -43,12 +43,15 @@ namespace LLStatViewer LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"); } -void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars) +void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts, F32& avg_cloud_time, S32& cloud_avatars, S32& pending_meshes, S32& control_avatars) { counts.resize(3); counts[0] = 0; counts[1] = 0; counts[2] = 1; + cloud_avatars = 0; + pending_meshes = 0; + control_avatars = 0; } // static diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index dfabb5c5c8..a0428ef95d 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -63,7 +63,6 @@ class ViewerManifest(LLManifest): def construct(self): super(ViewerManifest, self).construct() self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg") - self.path(src="../../etc/message.xml", dst="app_settings/message.xml") if self.is_packaging_viewer(): with self.prefix(src_dst="app_settings"): @@ -149,7 +148,6 @@ class ViewerManifest(LLManifest): with self.prefix(src_dst="skins"): # include the entire textures directory recursively with self.prefix(src_dst="*/textures"): - self.path("*/*.jpg") self.path("*/*.png") self.path("*.tga") self.path("*.j2c") @@ -275,13 +273,13 @@ class ViewerManifest(LLManifest): # All lines up to and including the first blank line are the file header; skip them lines.reverse() # so that pop will pull from first to last line - while not re.match("\s*$", lines.pop()) : + while not re.match(r"\s*$", lines.pop()) : pass # do nothing # A line that starts with a non-whitespace character is a name; all others describe contributions, so collect the names names = [] for line in lines : - if re.match("\S", line) : + if re.match(r"\S", line) : names.append(line.rstrip()) # It's not fair to always put the same people at the head of the list random.shuffle(names) @@ -557,6 +555,9 @@ class Windows_x86_64_Manifest(ViewerManifest): ): self.path(libfile) + if self.args['discord'] == 'ON': + self.path("discord_partner_sdk.dll") + if self.args['openal'] == 'ON': # Get openal dll self.path("OpenAL32.dll") @@ -1019,6 +1020,13 @@ class Darwin_x86_64_Manifest(ViewerManifest): ): self.path2basename(relpkgdir, libfile) + # Discord social SDK + if self.args['discord'] == 'ON': + for libfile in ( + "libdiscord_partner_sdk.dylib", + ): + self.path2basename(relpkgdir, libfile) + # OpenAL dylibs if self.args['openal'] == 'ON': for libfile in ( @@ -1385,6 +1393,7 @@ if __name__ == "__main__": extra_arguments = [ dict(name='bugsplat', description="""BugSplat database to which to post crashes, if BugSplat crash reporting is desired""", default=''), + dict(name='discord', description="""Indication discord social sdk libraries are needed""", default='OFF'), dict(name='openal', description="""Indication openal libraries are needed""", default='OFF'), dict(name='tracy', description="""Indication tracy profiler is enabled""", default='OFF'), ] diff --git a/indra/test/llhttpdate_tut.cpp b/indra/test/llhttpdate_tut.cpp index a47602dec5..b580b09a9f 100644 --- a/indra/test/llhttpdate_tut.cpp +++ b/indra/test/llhttpdate_tut.cpp @@ -112,13 +112,8 @@ namespace tut void httpdate_object::test<4>() { // test localization of http dates -#if LL_WINDOWS - const char *en_locale = "english"; - const char *fr_locale = "french"; -#else - const char *en_locale = "en_GB.UTF-8"; + const char *en_locale = "en_US.UTF-8"; const char *fr_locale = "fr_FR.UTF-8"; -#endif std::string prev_locale = LLStringUtil::getLocale(); std::string prev_clocale = std::string(setlocale(LC_TIME, NULL)); diff --git a/indra/tools/vstool/DispatchUtility.cs b/indra/tools/vstool/DispatchUtility.cs deleted file mode 100644 index 6056ac55a1..0000000000 --- a/indra/tools/vstool/DispatchUtility.cs +++ /dev/null @@ -1,271 +0,0 @@ -#region Using Directives
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
-using System.Reflection;
-using System.Security.Permissions;
-
-#endregion
-
-namespace TestDispatchUtility
-{
- /// <summary>
- /// Provides helper methods for working with COM IDispatch objects that have a registered type library.
- /// </summary>
- public static class DispatchUtility
- {
- #region Private Constants
-
- private const int S_OK = 0; //From WinError.h
- private const int LOCALE_SYSTEM_DEFAULT = 2 << 10; //From WinNT.h == 2048 == 0x800
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Gets whether the specified object implements IDispatch.
- /// </summary>
- /// <param name="obj">An object to check.</param>
- /// <returns>True if the object implements IDispatch. False otherwise.</returns>
- public static bool ImplementsIDispatch(object obj)
- {
- bool result = obj is IDispatchInfo;
- return result;
- }
-
- /// <summary>
- /// Gets a Type that can be used with reflection.
- /// </summary>
- /// <param name="obj">An object that implements IDispatch.</param>
- /// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
- /// <returns>A .NET Type that can be used with reflection.</returns>
- /// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public static Type GetType(object obj, bool throwIfNotFound)
- {
- RequireReference(obj, "obj");
- Type result = GetType((IDispatchInfo)obj, throwIfNotFound);
- return result;
- }
-
- /// <summary>
- /// Tries to get the DISPID for the requested member name.
- /// </summary>
- /// <param name="obj">An object that implements IDispatch.</param>
- /// <param name="name">The name of a member to lookup.</param>
- /// <param name="dispId">If the method returns true, this holds the DISPID on output.
- /// If the method returns false, this value should be ignored.</param>
- /// <returns>True if the member was found and resolved to a DISPID. False otherwise.</returns>
- /// <exception cref="InvalidCastException">If <paramref name="obj"/> doesn't implement IDispatch.</exception>
- [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public static bool TryGetDispId(object obj, string name, out int dispId)
- {
- RequireReference(obj, "obj");
- bool result = TryGetDispId((IDispatchInfo)obj, name, out dispId);
- return result;
- }
-
- /// <summary>
- /// Invokes a member by DISPID.
- /// </summary>
- /// <param name="obj">An object that implements IDispatch.</param>
- /// <param name="dispId">The DISPID of a member. This can be obtained using
- /// <see cref="TryGetDispId(object, string, out int)"/>.</param>
- /// <param name="args">The arguments to pass to the member.</param>
- /// <returns>The member's return value.</returns>
- /// <remarks>
- /// This can invoke a method or a property get accessor.
- /// </remarks>
- public static object Invoke(object obj, int dispId, object[] args)
- {
- string memberName = "[DispId=" + dispId + "]";
- object result = Invoke(obj, memberName, args);
- return result;
- }
-
- /// <summary>
- /// Invokes a member by name.
- /// </summary>
- /// <param name="obj">An object.</param>
- /// <param name="memberName">The name of the member to invoke.</param>
- /// <param name="args">The arguments to pass to the member.</param>
- /// <returns>The member's return value.</returns>
- /// <remarks>
- /// This can invoke a method or a property get accessor.
- /// </remarks>
- public static object Invoke(object obj, string memberName, object[] args)
- {
- RequireReference(obj, "obj");
- Type type = obj.GetType();
- object result = type.InvokeMember(memberName, BindingFlags.InvokeMethod | BindingFlags.GetProperty,
- null, obj, args, null);
- return result;
- }
-
- #endregion
-
- #region Private Methods
-
- /// <summary>
- /// Requires that the value is non-null.
- /// </summary>
- /// <typeparam name="T">The type of the value.</typeparam>
- /// <param name="value">The value to check.</param>
- /// <param name="name">The name of the value.</param>
- private static void RequireReference<T>(T value, string name) where T : class
- {
- if (value == null)
- {
- throw new ArgumentNullException(name);
- }
- }
-
- /// <summary>
- /// Gets a Type that can be used with reflection.
- /// </summary>
- /// <param name="dispatch">An object that implements IDispatch.</param>
- /// <param name="throwIfNotFound">Whether an exception should be thrown if a Type can't be obtained.</param>
- /// <returns>A .NET Type that can be used with reflection.</returns>
- private static Type GetType(IDispatchInfo dispatch, bool throwIfNotFound)
- {
- RequireReference(dispatch, "dispatch");
-
- Type result = null;
- int typeInfoCount;
- int hr = dispatch.GetTypeInfoCount(out typeInfoCount);
- if (hr == S_OK && typeInfoCount > 0)
- {
- // Type info isn't usually culture-aware for IDispatch, so we might as well pass
- // the default locale instead of looking up the current thread's LCID each time
- // (via CultureInfo.CurrentCulture.LCID).
- dispatch.GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, out result);
- }
-
- if (result == null && throwIfNotFound)
- {
- // If the GetTypeInfoCount called failed, throw an exception for that.
- Marshal.ThrowExceptionForHR(hr);
-
- // Otherwise, throw the same exception that Type.GetType would throw.
- throw new TypeLoadException();
- }
-
- return result;
- }
-
- /// <summary>
- /// Tries to get the DISPID for the requested member name.
- /// </summary>
- /// <param name="dispatch">An object that implements IDispatch.</param>
- /// <param name="name">The name of a member to lookup.</param>
- /// <param name="dispId">If the method returns true, this holds the DISPID on output.
- /// If the method returns false, this value should be ignored.</param>
- /// <returns>True if the member was found and resolved to a DISPID. False otherwise.</returns>
- private static bool TryGetDispId(IDispatchInfo dispatch, string name, out int dispId)
- {
- RequireReference(dispatch, "dispatch");
- RequireReference(name, "name");
-
- bool result = false;
-
- // Members names aren't usually culture-aware for IDispatch, so we might as well
- // pass the default locale instead of looking up the current thread's LCID each time
- // (via CultureInfo.CurrentCulture.LCID).
- Guid iidNull = Guid.Empty;
- int hr = dispatch.GetDispId(ref iidNull, ref name, 1, LOCALE_SYSTEM_DEFAULT, out dispId);
-
- const int DISP_E_UNKNOWNNAME = unchecked((int)0x80020006); //From WinError.h
- const int DISPID_UNKNOWN = -1; //From OAIdl.idl
- if (hr == S_OK)
- {
- result = true;
- }
- else if (hr == DISP_E_UNKNOWNNAME && dispId == DISPID_UNKNOWN)
- {
- // This is the only supported "error" case because it means IDispatch
- // is saying it doesn't know the member we asked about.
- result = false;
- }
- else
- {
- // The other documented result codes are all errors.
- Marshal.ThrowExceptionForHR(hr);
- }
-
- return result;
- }
-
- #endregion
-
- #region Private Interfaces
-
- /// <summary>
- /// A partial declaration of IDispatch used to lookup Type information and DISPIDs.
- /// </summary>
- /// <remarks>
- /// This interface only declares the first three methods of IDispatch. It omits the
- /// fourth method (Invoke) because there are already plenty of ways to do dynamic
- /// invocation in .NET. But the first three methods provide dynamic type metadata
- /// discovery, which .NET doesn't provide normally if you have a System.__ComObject
- /// RCW instead of a strongly-typed RCW.
- /// <para/>
- /// Note: The original declaration of IDispatch is in OAIdl.idl.
- /// </remarks>
- [ComImport]
- [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
- [Guid("00020400-0000-0000-C000-000000000046")]
- private interface IDispatchInfo
- {
- /// <summary>
- /// Gets the number of Types that the object provides (0 or 1).
- /// </summary>
- /// <param name="typeInfoCount">Returns 0 or 1 for the number of Types provided by <see cref="GetTypeInfo"/>.</param>
- /// <remarks>
- /// http://msdn.microsoft.com/en-us/library/da876d53-cb8a-465c-a43e-c0eb272e2a12(VS.85)
- /// </remarks>
- [PreserveSig]
- int GetTypeInfoCount(out int typeInfoCount);
-
- /// <summary>
- /// Gets the Type information for an object if <see cref="GetTypeInfoCount"/> returned 1.
- /// </summary>
- /// <param name="typeInfoIndex">Must be 0.</param>
- /// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
- /// <param name="typeInfo">Returns the object's Type information.</param>
- /// <remarks>
- /// http://msdn.microsoft.com/en-us/library/cc1ec9aa-6c40-4e70-819c-a7c6dd6b8c99(VS.85)
- /// </remarks>
- void GetTypeInfo(int typeInfoIndex, int lcid, [MarshalAs(UnmanagedType.CustomMarshaler,
- MarshalTypeRef = typeof(System.Runtime.InteropServices.CustomMarshalers.TypeToTypeInfoMarshaler))] out Type typeInfo);
-
- /// <summary>
- /// Gets the DISPID of the specified member name.
- /// </summary>
- /// <param name="riid">Must be IID_NULL. Pass a copy of Guid.Empty.</param>
- /// <param name="name">The name of the member to look up.</param>
- /// <param name="nameCount">Must be 1.</param>
- /// <param name="lcid">Typically, LOCALE_SYSTEM_DEFAULT (2048).</param>
- /// <param name="dispId">If a member with the requested <paramref name="name"/>
- /// is found, this returns its DISPID and the method's return value is 0.
- /// If the method returns a non-zero value, then this parameter's output value is
- /// undefined.</param>
- /// <returns>Zero for success. Non-zero for failure.</returns>
- /// <remarks>
- /// http://msdn.microsoft.com/en-us/library/6f6cf233-3481-436e-8d6a-51f93bf91619(VS.85)
- /// </remarks>
- [PreserveSig]
- int GetDispId(ref Guid riid, ref string name, int nameCount, int lcid, out int dispId);
-
- // NOTE: The real IDispatch also has an Invoke method next, but we don't need it.
- // We can invoke methods using .NET's Type.InvokeMember method with the special
- // [DISPID=n] syntax for member "names", or we can get a .NET Type using GetTypeInfo
- // and invoke methods on that through reflection.
- // Type.InvokeMember: http://msdn.microsoft.com/en-us/library/de3dhzwy.aspx
- }
-
- #endregion
- }
-}
diff --git a/indra/tools/vstool/README.txt b/indra/tools/vstool/README.txt deleted file mode 100644 index e419180031..0000000000 --- a/indra/tools/vstool/README.txt +++ /dev/null @@ -1,9 +0,0 @@ -VSTool is a command line utility to manipulate VisualStudio settings.
-
-The windows cmake project configuration uses VSTool.exe
-
-A handy upgrade:
- figure out how to make cmake build this csharp app
- - or write the app using script (jscript?!?) so it doesn't need to be built.
-
-
diff --git a/indra/tools/vstool/VSTool.csproj b/indra/tools/vstool/VSTool.csproj deleted file mode 100755 index 7f431e85c7..0000000000 --- a/indra/tools/vstool/VSTool.csproj +++ /dev/null @@ -1,98 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
- <PropertyGroup>
- <ProjectType>Local</ProjectType>
- <ProductVersion>8.0.50727</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{96943E2D-1373-4617-A117-D0F997A94919}</ProjectGuid>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ApplicationIcon>
- </ApplicationIcon>
- <AssemblyKeyContainerName>
- </AssemblyKeyContainerName>
- <AssemblyName>VSTool</AssemblyName>
- <AssemblyOriginatorKeyFile>
- </AssemblyOriginatorKeyFile>
- <DefaultClientScript>JScript</DefaultClientScript>
- <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout>
- <DefaultTargetSchema>IE50</DefaultTargetSchema>
- <DelaySign>false</DelaySign>
- <OutputType>Exe</OutputType>
- <RootNamespace>VSTool</RootNamespace>
- <RunPostBuildEvent>Always</RunPostBuildEvent>
- <StartupObject>VSTool.VSToolMain</StartupObject>
- <FileUpgradeFlags>
- </FileUpgradeFlags>
- <UpgradeBackupLocation>
- </UpgradeBackupLocation>
- <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
- <OldToolsVersion>2.0</OldToolsVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <OutputPath>.\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <ConfigurationOverrideFile>
- </ConfigurationOverrideFile>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <DocumentationFile>
- </DocumentationFile>
- <DebugSymbols>true</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <NoWarn>
- </NoWarn>
- <Optimize>false</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- <DebugType>full</DebugType>
- <ErrorReport>prompt</ErrorReport>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <OutputPath>.\</OutputPath>
- <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
- <BaseAddress>285212672</BaseAddress>
- <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
- <ConfigurationOverrideFile>
- </ConfigurationOverrideFile>
- <DefineConstants>TRACE</DefineConstants>
- <DocumentationFile>
- </DocumentationFile>
- <DebugSymbols>false</DebugSymbols>
- <FileAlignment>4096</FileAlignment>
- <NoStdLib>false</NoStdLib>
- <NoWarn>
- </NoWarn>
- <Optimize>true</Optimize>
- <RegisterForComInterop>false</RegisterForComInterop>
- <RemoveIntegerChecks>false</RemoveIntegerChecks>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
- <WarningLevel>4</WarningLevel>
- <DebugType>none</DebugType>
- <ErrorReport>prompt</ErrorReport>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System">
- <Name>System</Name>
- </Reference>
- <Reference Include="System.Data">
- <Name>System.Data</Name>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="main.cs">
- <SubType>Code</SubType>
- </Compile>
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <PropertyGroup>
- <PreBuildEvent>
- </PreBuildEvent>
- <PostBuildEvent>
- </PostBuildEvent>
- </PropertyGroup>
-</Project>
\ No newline at end of file diff --git a/indra/tools/vstool/VSTool.exe b/indra/tools/vstool/VSTool.exe Binary files differdeleted file mode 100755 index 751540413a..0000000000 --- a/indra/tools/vstool/VSTool.exe +++ /dev/null diff --git a/indra/tools/vstool/VSTool.sln b/indra/tools/vstool/VSTool.sln deleted file mode 100755 index 21e3d75971..0000000000 --- a/indra/tools/vstool/VSTool.sln +++ /dev/null @@ -1,19 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSTool", "VSTool.csproj", "{96943E2D-1373-4617-A117-D0F997A94919}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Release|Any CPU = Release|Any CPU
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {96943E2D-1373-4617-A117-D0F997A94919}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {96943E2D-1373-4617-A117-D0F997A94919}.Release|Any CPU.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/indra/tools/vstool/app.config b/indra/tools/vstool/app.config deleted file mode 100644 index 8494f728ff..0000000000 --- a/indra/tools/vstool/app.config +++ /dev/null @@ -1,3 +0,0 @@ -<?xml version="1.0"?>
-<configuration>
-<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
diff --git a/indra/tools/vstool/main.cs b/indra/tools/vstool/main.cs deleted file mode 100755 index 1d6b2f14d1..0000000000 --- a/indra/tools/vstool/main.cs +++ /dev/null @@ -1,733 +0,0 @@ -// Code about getting running instances visual studio
-// was borrowed from
-// http://www.codeproject.com/KB/cs/automatingvisualstudio.aspx
-
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Runtime.InteropServices.ComTypes;
-using Microsoft.CSharp;
-
-namespace VSTool
-{
- // The MessageFilter class comes from:
- // http://msdn.microsoft.com/en-us/library/ms228772(VS.80).aspx
- // It allows vstool to get timing error messages from
- // visualstudio and handle them.
- public class MessageFilter : IOleMessageFilter
- {
- //
- // Class containing the IOleMessageFilter
- // thread error-handling functions.
-
- // Start the filter.
- public static void Register()
- {
- IOleMessageFilter newFilter = new MessageFilter();
- IOleMessageFilter oldFilter = null;
- CoRegisterMessageFilter(newFilter, out oldFilter);
- }
-
- // Done with the filter, close it.
- public static void Revoke()
- {
- IOleMessageFilter oldFilter = null;
- CoRegisterMessageFilter(null, out oldFilter);
- }
-
- //
- // IOleMessageFilter functions.
- // Handle incoming thread requests.
- int IOleMessageFilter.HandleInComingCall(int dwCallType,
- System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr
- lpInterfaceInfo)
- {
- //Return the flag SERVERCALL_ISHANDLED.
- return 0;
- }
-
- // Thread call was rejected, so try again.
- int IOleMessageFilter.RetryRejectedCall(System.IntPtr
- hTaskCallee, int dwTickCount, int dwRejectType)
- {
- if (dwRejectType == 2)
- // flag = SERVERCALL_RETRYLATER.
- {
- // Retry the thread call immediately if return >=0 &
- // <100.
- return 99;
- }
- // Too busy; cancel call.
- return -1;
- }
-
- int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee,
- int dwTickCount, int dwPendingType)
- {
- //Return the flag PENDINGMSG_WAITDEFPROCESS.
- return 2;
- }
-
- // Implement the IOleMessageFilter interface.
- [DllImport("Ole32.dll")]
- private static extern int
- CoRegisterMessageFilter(IOleMessageFilter newFilter, out
- IOleMessageFilter oldFilter);
- }
-
- [ComImport(), Guid("00000016-0000-0000-C000-000000000046"),
- InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
- interface IOleMessageFilter
- {
- [PreserveSig]
- int HandleInComingCall(
- int dwCallType,
- IntPtr hTaskCaller,
- int dwTickCount,
- IntPtr lpInterfaceInfo);
-
- [PreserveSig]
- int RetryRejectedCall(
- IntPtr hTaskCallee,
- int dwTickCount,
- int dwRejectType);
-
- [PreserveSig]
- int MessagePending(
- IntPtr hTaskCallee,
- int dwTickCount,
- int dwPendingType);
- }
-
- class ViaCOM
- {
- public static object GetProperty(object from_obj, string prop_name)
- {
- try
- {
- Type objType = from_obj.GetType();
- return objType.InvokeMember(
- prop_name,
- BindingFlags.GetProperty, null,
- from_obj,
- null);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error getting property: \"{0}\"", prop_name);
- Console.WriteLine(e.Message);
- throw e;
- }
- }
-
- public static object SetProperty(object from_obj, string prop_name, object new_value)
- {
- try
- {
- object[] args = { new_value };
- Type objType = from_obj.GetType();
- return objType.InvokeMember(
- prop_name,
- BindingFlags.DeclaredOnly |
- BindingFlags.Public |
- BindingFlags.NonPublic |
- BindingFlags.Instance |
- BindingFlags.SetProperty,
- null,
- from_obj,
- args);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error setting property: \"{0}\"", prop_name);
- Console.WriteLine(e.Message);
- throw e;
- }
- }
-
- public static object CallMethod(object from_obj, string method_name, params object[] args)
- {
- try
- {
- Type objType = from_obj.GetType();
- return objType.InvokeMember(
- method_name,
- BindingFlags.DeclaredOnly |
- BindingFlags.Public |
- BindingFlags.NonPublic |
- BindingFlags.Instance |
- BindingFlags.InvokeMethod,
- null,
- from_obj,
- args);
- }
- catch (Exception e)
- {
- Console.WriteLine("Error calling method \"{0}\"", method_name);
- Console.WriteLine(e.Message);
- throw e;
- }
- }
- };
-
- /// <summary>
- /// The main entry point class for VSTool.
- /// </summary>
- class VSToolMain
- {
- #region Interop imports
- [DllImport("ole32.dll")]
- public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
-
- [DllImport("ole32.dll")]
- public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
- #endregion
-
- static System.Boolean ignore_case = true;
-
- static string solution_name = null;
- static bool use_new_vs = false;
- static Hashtable projectDict = new Hashtable();
- static string startup_project = null;
- static string config = null;
-
- static object dte = null;
- static object solution = null;
-
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- [STAThread]
- static int Main(string[] args)
- {
- int retVal = 0;
- bool need_save = false;
-
- try
- {
- parse_command_line(args);
-
- Console.WriteLine("Editing solution: {0}", solution_name);
-
- bool found_open_solution = GetDTEAndSolution();
-
- if (dte == null || solution == null)
- {
- retVal = 1;
- }
- else
- {
- MessageFilter.Register();
-
- // Walk through all of the projects in the solution
- // and list the type of each project.
- foreach (DictionaryEntry p in projectDict)
- {
- string project_name = (string)p.Key;
- string working_dir = (string)p.Value;
- if (SetProjectWorkingDir(solution, project_name, working_dir))
- {
- need_save = true;
- }
- }
-
- if (config != null)
- {
- need_save = SetActiveConfig(config);
- }
-
- if (startup_project != null)
- {
- need_save = SetStartupProject(startup_project);
- }
-
- if (need_save)
- {
- if (found_open_solution == false)
- {
- ViaCOM.CallMethod(solution, "Close", null);
- }
- }
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- retVal = 1;
- }
- finally
- {
- if (solution != null)
- {
- Marshal.ReleaseComObject(solution);
- solution = null;
- }
-
- if (dte != null)
- {
- Marshal.ReleaseComObject(dte);
- dte = null;
- }
-
- MessageFilter.Revoke();
- }
- return retVal;
- }
-
- public static bool parse_command_line(string[] args)
- {
- string options_desc =
- "--solution <solution_name> : MSVC solution name. (required)\n" +
- "--use_new_vs : Ignore running versions of visual studio.\n" +
- "--workingdir <project> <dir> : Set working dir of a VC project.\n" +
- "--config <config> : Set the active config for the solution.\n" +
- "--startup <project> : Set the startup project for the solution.\n";
-
- try
- {
- // Command line param parsing loop.
- int i = 0;
- for (; i < args.Length; ++i)
- {
- if ("--solution" == args[i])
- {
- if (solution_name != null)
- {
- throw new ApplicationException("Found second --solution option");
- }
- solution_name = args[++i];
- }
- else if ("--use_new_vs" == args[i])
- {
- use_new_vs = true;
- }
-
- else if ("--workingdir" == args[i])
- {
- string project_name = args[++i];
- string working_dir = args[++i];
- projectDict.Add(project_name, working_dir);
- }
- else if ("--config" == args[i])
- {
- if (config != null)
- {
- throw new ApplicationException("Found second --config option");
- }
- config = args[++i];
- }
- else if ("--startup" == args[i])
- {
- if (startup_project != null)
- {
- throw new ApplicationException("Found second --startup option");
- }
- startup_project = args[++i];
- }
- else
- {
- throw new ApplicationException("Found unrecognized token on command line: " + args[i]);
- }
- }
-
- if (solution_name == null)
- {
- throw new ApplicationException("The --solution option is required.");
- }
- }
- catch(ApplicationException e)
- {
-
- Console.WriteLine("Oops! " + e.Message);
- Console.Write("Command line:");
- foreach (string arg in args)
- {
- Console.Write(" " + arg);
- }
- Console.Write("\n\n");
- Console.WriteLine("VSTool command line usage");
- Console.Write(options_desc);
- throw e;
- }
- return true;
- }
-
- public static bool GetDTEAndSolution()
- {
- bool found_open_solution = true;
-
- Console.WriteLine("Looking for existing VisualStudio instance...");
-
- // Get an instance of the currently running Visual Studio .NET IDE.
- // dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.7.1");
- string full_solution_name = System.IO.Path.GetFullPath(solution_name);
- if (false == use_new_vs)
- {
- dte = GetIDEInstance(full_solution_name);
- }
-
- if (dte == null)
- {
- try
- {
- Console.WriteLine(" Didn't find open solution, starting new background VisualStudio instance...");
- Console.WriteLine(" Reading .sln file version...");
- string version = GetSolutionVersion(full_solution_name);
-
- Console.WriteLine(" Using version: {0}...", version);
- string progid = GetVSProgID(version);
-
- Type objType = Type.GetTypeFromProgID(progid);
- dte = System.Activator.CreateInstance(objType);
- Console.WriteLine(" Reading solution: \"{0}\"", full_solution_name);
-
- solution = ViaCOM.GetProperty(dte, "Solution");
- object[] openArgs = { full_solution_name };
- ViaCOM.CallMethod(solution, "Open", openArgs);
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- Console.WriteLine("Quitting do to error opening: {0}", full_solution_name);
- solution = null;
- dte = null;
- return found_open_solution;
- }
- found_open_solution = false;
- }
-
- if (solution == null)
- {
- solution = ViaCOM.GetProperty(dte, "Solution");
- }
-
- return found_open_solution;
- }
-
- /// <summary>
- /// Get the DTE object for the instance of Visual Studio IDE that has
- /// the specified solution open.
- /// </summary>
- /// <param name="solutionFile">The absolute filename of the solution</param>
- /// <returns>Corresponding DTE object or null if no such IDE is running</returns>
- public static object GetIDEInstance( string solutionFile )
- {
- Hashtable runningInstances = GetIDEInstances( true );
- IDictionaryEnumerator enumerator = runningInstances.GetEnumerator();
-
- while ( enumerator.MoveNext() )
- {
- try
- {
- object ide = enumerator.Value;
- if (ide != null)
- {
- object sol = ViaCOM.GetProperty(ide, "Solution");
- if (0 == string.Compare((string)ViaCOM.GetProperty(sol, "FullName"), solutionFile, ignore_case))
- {
- return ide;
- }
- }
- }
- catch{}
- }
-
- return null;
- }
-
- /// <summary>
- /// Get a table of the currently running instances of the Visual Studio .NET IDE.
- /// </summary>
- /// <param name="openSolutionsOnly">Only return instances that have opened a solution</param>
- /// <returns>A hashtable mapping the name of the IDE in the running object table to the corresponding DTE object</returns>
- public static Hashtable GetIDEInstances( bool openSolutionsOnly )
- {
- Hashtable runningIDEInstances = new Hashtable();
- Hashtable runningObjects = GetRunningObjectTable();
-
- IDictionaryEnumerator rotEnumerator = runningObjects.GetEnumerator();
- while ( rotEnumerator.MoveNext() )
- {
- string candidateName = (string) rotEnumerator.Key;
- if (!candidateName.StartsWith("!VisualStudio.DTE"))
- continue;
-
- object ide = rotEnumerator.Value;
- if (ide == null)
- continue;
-
- if (openSolutionsOnly)
- {
- try
- {
- object sol = ViaCOM.GetProperty(ide, "Solution");
- string solutionFile = (string)ViaCOM.GetProperty(sol, "FullName");
- if (solutionFile != String.Empty)
- {
- runningIDEInstances[ candidateName ] = ide;
- }
- }
- catch {}
- }
- else
- {
- runningIDEInstances[ candidateName ] = ide;
- }
- }
- return runningIDEInstances;
- }
-
- /// <summary>
- /// Get a snapshot of the running object table (ROT).
- /// </summary>
- /// <returns>A hashtable mapping the name of the object in the ROT to the corresponding object</returns>
- [STAThread]
- public static Hashtable GetRunningObjectTable()
- {
- Hashtable result = new Hashtable();
-
- int numFetched = 0;
- IRunningObjectTable runningObjectTable;
- IEnumMoniker monikerEnumerator;
- IMoniker[] monikers = new IMoniker[1];
-
- GetRunningObjectTable(0, out runningObjectTable);
- runningObjectTable.EnumRunning(out monikerEnumerator);
- monikerEnumerator.Reset();
-
- while (monikerEnumerator.Next(1, monikers, new IntPtr(numFetched)) == 0)
- {
- IBindCtx ctx;
- CreateBindCtx(0, out ctx);
-
- string runningObjectName;
- monikers[0].GetDisplayName(ctx, null, out runningObjectName);
-
- object runningObjectVal;
- runningObjectTable.GetObject( monikers[0], out runningObjectVal);
-
- result[ runningObjectName ] = runningObjectVal;
- }
-
- return result;
- }
-
- public static string GetSolutionVersion(string solutionFullFileName)
- {
- string version;
- System.IO.StreamReader solutionStreamReader = null;
- string firstLine;
- string format;
-
- try
- {
- solutionStreamReader = new System.IO.StreamReader(solutionFullFileName);
- do
- {
- firstLine = solutionStreamReader.ReadLine();
- }
- while (firstLine == "");
-
- format = firstLine.Substring(firstLine.LastIndexOf(" ")).Trim();
-
- switch(format)
- {
- case "7.00":
- version = "VC70";
- break;
-
- case "8.00":
- version = "VC71";
- break;
-
- case "9.00":
- version = "VC80";
- break;
-
- case "10.00":
- version = "VC90";
- break;
-
- case "11.00":
- version = "VC100";
- break;
-
- case "12.00":
- version = "VC150";
- break;
-
- default:
- throw new ApplicationException("Unknown .sln version: " + format);
- }
- }
- finally
- {
- if(solutionStreamReader != null)
- {
- solutionStreamReader.Close();
- }
- }
-
- return version;
- }
-
- public static string GetVSProgID(string version)
- {
- string progid = null;
- switch(version)
- {
- case "VC70":
- progid = "VisualStudio.DTE.7";
- break;
-
- case "VC71":
- progid = "VisualStudio.DTE.7.1";
- break;
-
- case "VC80":
- progid = "VisualStudio.DTE.8.0";
- break;
-
- case "VC90":
- progid = "VisualStudio.DTE.9.0";
- break;
-
- case "VC100":
- progid = "VisualStudio.DTE.10.0";
- break;
-
- case "VC120":
- progid = "VisualStudio.DTE.12.0";
- break;
-
- case "VC150":
- progid = "VisualStudio.DTE.15.0";
- break;
-
- default:
- throw new ApplicationException("Can't handle VS version: " + version);
- }
-
- return progid;
- }
-
- public static bool SetProjectWorkingDir(object sol, string project_name, string working_dir)
- {
- bool made_change = false;
- Console.WriteLine("Looking for project {0}...", project_name);
- try
- {
- object prjs = ViaCOM.GetProperty(sol, "Projects");
- object count = ViaCOM.GetProperty(prjs, "Count");
- for(int i = 1; i <= (int)count; ++i)
- {
- object[] prjItemArgs = { (object)i };
- object prj = ViaCOM.CallMethod(prjs, "Item", prjItemArgs);
- string name = (string)ViaCOM.GetProperty(prj, "Name");
- if (0 == string.Compare(name, project_name, ignore_case))
- {
- Console.WriteLine("Found project: {0}", project_name);
- Console.WriteLine("Setting working directory");
-
- string full_project_name = (string)ViaCOM.GetProperty(prj, "FullName");
- Console.WriteLine(full_project_name);
-
- // *NOTE:Mani Thanks to incompatibilities between different versions of the
- // VCProjectEngine.dll assembly, we can't cast the objects recevied from the DTE to
- // the VCProjectEngine types from a different version than the one built
- // with. ie, VisualStudio.DTE.7.1 objects can't be converted in a project built
- // in VS 8.0. To avoid this problem, we can use the com object interfaces directly,
- // without the type casting. Its tedious code, but it seems to work.
-
- // oCfgs should be assigned to a 'Project.Configurations' collection.
- object oCfgs = ViaCOM.GetProperty(ViaCOM.GetProperty(prj, "Object"), "Configurations");
-
- // oCount will be assigned to the number of configs present in oCfgs.
- object oCount = ViaCOM.GetProperty(oCfgs, "Count");
-
- for (int cfgIndex = 1; cfgIndex <= (int)oCount; ++cfgIndex)
- {
- object[] itemArgs = {(object)cfgIndex};
- object oCfg = ViaCOM.CallMethod(oCfgs, "Item", itemArgs);
- object oDebugSettings = ViaCOM.GetProperty(oCfg, "DebugSettings");
- ViaCOM.SetProperty(oDebugSettings, "WorkingDirectory", (object)working_dir);
- }
-
- break;
- }
- }
- made_change = true;
- }
- catch( Exception e )
- {
- Console.WriteLine(e.Message);
- Console.WriteLine("Failed to set working dir for project, {0}.", project_name);
- }
-
- return made_change;
- }
-
- public static bool SetStartupProject(string startup_project)
- {
- bool result = false;
- try
- {
- // You need the 'unique name of the project to set StartupProjects.
- // find the project by generic name.
- Console.WriteLine("Trying to set \"{0}\" to the startup project", startup_project);
- object prjs = ViaCOM.GetProperty(solution, "Projects");
- object count = ViaCOM.GetProperty(prjs, "Count");
- for (int i = 1; i <= (int)count; ++i)
- {
- object[] itemArgs = { (object)i };
- object prj = ViaCOM.CallMethod(prjs, "Item", itemArgs);
- object prjName = ViaCOM.GetProperty(prj, "Name");
- if (0 == string.Compare((string)prjName, startup_project, ignore_case))
- {
- object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
- ViaCOM.SetProperty(solBuild, "StartupProjects", ViaCOM.GetProperty(prj, "UniqueName"));
- Console.WriteLine(" Success!");
- result = true;
- break;
- }
- }
-
- if (result == false)
- {
- Console.WriteLine(" Could not find project \"{0}\" in the solution.", startup_project);
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(" Failed to set the startup project!");
- Console.WriteLine(e.Message);
- }
- return result;
- }
-
- public static bool SetActiveConfig(string config)
- {
- bool result = false;
- try
- {
- Console.WriteLine("Trying to set active config to \"{0}\"", config);
- object solBuild = ViaCOM.GetProperty(solution, "SolutionBuild");
- object solCfgs = ViaCOM.GetProperty(solBuild, "SolutionConfigurations");
- object[] itemArgs = { (object)config };
- object solCfg = ViaCOM.CallMethod(solCfgs, "Item", itemArgs);
- ViaCOM.CallMethod(solCfg, "Activate", null);
- Console.WriteLine(" Success!");
- result = true;
- }
- catch (Exception e)
- {
- Console.WriteLine(" Failed to set \"{0}\" as the active config.", config);
- Console.WriteLine(e.Message);
- }
- return result;
- }
- }
-}
diff --git a/indra/win_crash_logger/README.txt b/indra/win_crash_logger/README.txt deleted file mode 100644 index 6932a8d9c3..0000000000 --- a/indra/win_crash_logger/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This component is no longer used in Linden Lab builds. -Change requests to support continued use by open source -builds are welcome. |
