diff options
Diffstat (limited to 'indra')
192 files changed, 4941 insertions, 4451 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 6c20a813ba..62a8f3f003 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -3,8 +3,8 @@ # cmake_minimum_required should appear before any # other commands to guarantee full compatibility # with the version specified -## prior to 3.4, the Windows manifest handling was missing -cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR) +## 3.8 added VS_DEBUGGER_WORKING_DIRECTORY support +cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR) set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING "The root project/makefile/solution name. Defaults to SecondLife.") @@ -83,6 +83,12 @@ add_dependencies(viewer secondlife-bin) add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL) +# sets the 'startup project' for debugging from visual studio. +set_property( + DIRECTORY ${VIEWER_PREFIX} + PROPERTY VS_STARTUP_PROJECT secondlife-bin + ) + if (LL_TESTS) # Define after the custom targets are created so # individual apps can add themselves as dependencies diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 40fc706a99..03da30649a 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -151,6 +151,8 @@ endif (LINUX) if (DARWIN) + # Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default + set(CLANG_DISABLE_FATAL_WARNINGS OFF) set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}") set(DARWIN_extra_cstar_flags "-Wno-unused-local-typedef -Wno-deprecated-declarations") diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 38cda2e2f1..e60037b739 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -1482,6 +1482,21 @@ BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name ) param_name[0] = 1071; //"tattoo_red"; param_name[1] = 1072; //"tattoo_green"; param_name[2] = 1073; //"tattoo_blue"; + break; + case TEX_HEAD_UNIVERSAL_TATTOO: + case TEX_UPPER_UNIVERSAL_TATTOO: + case TEX_LOWER_UNIVERSAL_TATTOO: + case TEX_SKIRT_TATTOO: + case TEX_HAIR_TATTOO: + case TEX_EYES_TATTOO: + case TEX_LEFT_ARM_TATTOO: + case TEX_LEFT_LEG_TATTOO: + case TEX_AUX1_TATTOO: + case TEX_AUX2_TATTOO: + case TEX_AUX3_TATTOO: + param_name[0] = 1238; //"tattoo_universal_red"; + param_name[1] = 1239; //"tattoo_universal_green"; + param_name[2] = 1240; //"tattoo_universal_blue"; break; default: diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp index b5282d4f6f..c72943bb82 100644 --- a/indra/llappearance/llavatarappearancedefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -26,9 +26,10 @@ #include "linden_common.h" #include "llavatarappearancedefines.h" +#include "indra_constants.h" -const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512; -const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 1024; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 1024; const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2; using namespace LLAvatarAppearanceDefines; @@ -65,12 +66,30 @@ LLAvatarAppearanceDictionary::Textures::Textures() addEntry(TEX_UPPER_TATTOO, new TextureEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO)); addEntry(TEX_LOWER_TATTOO, new TextureEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_TATTOO)); + addEntry(TEX_HEAD_UNIVERSAL_TATTOO, new TextureEntry("head_universal_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_UPPER_UNIVERSAL_TATTOO, new TextureEntry("upper_universal_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_LOWER_UNIVERSAL_TATTOO, new TextureEntry("lower_universal_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_SKIRT_TATTOO, new TextureEntry("skirt_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_HAIR_TATTOO, new TextureEntry("hair_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_EYES_TATTOO, new TextureEntry("eyes_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_LEFT_ARM_TATTOO, new TextureEntry("leftarm_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_LEFT_LEG_TATTOO, new TextureEntry("leftleg_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_AUX1_TATTOO, new TextureEntry("aux1_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_AUX2_TATTOO, new TextureEntry("aux2_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + addEntry(TEX_AUX3_TATTOO, new TextureEntry("aux3_tattoo", TRUE, BAKED_NUM_INDICES, "", LLWearableType::WT_UNIVERSAL)); + + addEntry(TEX_HEAD_BAKED, new TextureEntry("head-baked", FALSE, BAKED_HEAD, "head")); addEntry(TEX_UPPER_BAKED, new TextureEntry("upper-baked", FALSE, BAKED_UPPER, "upper")); addEntry(TEX_LOWER_BAKED, new TextureEntry("lower-baked", FALSE, BAKED_LOWER, "lower")); addEntry(TEX_EYES_BAKED, new TextureEntry("eyes-baked", FALSE, BAKED_EYES, "eyes")); addEntry(TEX_HAIR_BAKED, new TextureEntry("hair-baked", FALSE, BAKED_HAIR, "hair")); addEntry(TEX_SKIRT_BAKED, new TextureEntry("skirt-baked", FALSE, BAKED_SKIRT, "skirt")); + addEntry(TEX_LEFT_ARM_BAKED, new TextureEntry("leftarm-baked", FALSE, BAKED_LEFT_ARM, "leftarm")); + addEntry(TEX_LEFT_LEG_BAKED, new TextureEntry("leftleg-baked", FALSE, BAKED_LEFT_LEG, "leftleg")); + addEntry(TEX_AUX1_BAKED, new TextureEntry("aux1-baked", FALSE, BAKED_AUX1, "aux1")); + addEntry(TEX_AUX2_BAKED, new TextureEntry("aux2-baked", FALSE, BAKED_AUX2, "aux2")); + addEntry(TEX_AUX3_BAKED, new TextureEntry("aux3-baked", FALSE, BAKED_AUX3, "aux3")); } LLAvatarAppearanceDictionary::BakedTextures::BakedTextures() @@ -78,35 +97,60 @@ LLAvatarAppearanceDictionary::BakedTextures::BakedTextures() // Baked textures addEntry(BAKED_HEAD, new BakedEntry(TEX_HEAD_BAKED, "head", "a4b9dc38-e13b-4df9-b284-751efb0566ff", - 3, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA, - 5, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_HAIR, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA)); + 4, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA, TEX_HEAD_UNIVERSAL_TATTOO, + 6, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_HAIR, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA, LLWearableType::WT_UNIVERSAL)); addEntry(BAKED_UPPER, new BakedEntry(TEX_UPPER_BAKED, "upper_body", "5943ff64-d26c-4a90-a8c0-d61f56bd98d4", - 7, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET, - TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA, - 8, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_SHIRT, LLWearableType::WT_JACKET, LLWearableType::WT_GLOVES, LLWearableType::WT_UNDERSHIRT, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA)); + 8, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET, + TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA, TEX_UPPER_UNIVERSAL_TATTOO, + 9, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_SHIRT, LLWearableType::WT_JACKET, LLWearableType::WT_GLOVES, LLWearableType::WT_UNDERSHIRT, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA, LLWearableType::WT_UNIVERSAL)); addEntry(BAKED_LOWER, new BakedEntry(TEX_LOWER_BAKED, "lower_body", "2944ee70-90a7-425d-a5fb-d749c782ed7d", - 8, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES, TEX_LOWER_SOCKS, - TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA, - 9, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_PANTS, LLWearableType::WT_SHOES, LLWearableType::WT_SOCKS, LLWearableType::WT_JACKET, LLWearableType::WT_UNDERPANTS, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA)); + 9, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES, TEX_LOWER_SOCKS, + TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA, TEX_LOWER_UNIVERSAL_TATTOO, + 10, LLWearableType::WT_SHAPE, LLWearableType::WT_SKIN, LLWearableType::WT_PANTS, LLWearableType::WT_SHOES, LLWearableType::WT_SOCKS, LLWearableType::WT_JACKET, LLWearableType::WT_UNDERPANTS, LLWearableType::WT_TATTOO, LLWearableType::WT_ALPHA, LLWearableType::WT_UNIVERSAL)); addEntry(BAKED_EYES, new BakedEntry(TEX_EYES_BAKED, "eyes", "27b1bc0f-979f-4b13-95fe-b981c2ba9788", - 2, TEX_EYES_IRIS, TEX_EYES_ALPHA, - 2, LLWearableType::WT_EYES, LLWearableType::WT_ALPHA)); + 3, TEX_EYES_IRIS, TEX_EYES_TATTOO, TEX_EYES_ALPHA, + 3, LLWearableType::WT_EYES, LLWearableType::WT_UNIVERSAL, LLWearableType::WT_ALPHA)); addEntry(BAKED_SKIRT, new BakedEntry(TEX_SKIRT_BAKED, "skirt", "03e7e8cb-1368-483b-b6f3-74850838ba63", - 1, TEX_SKIRT, - 1, LLWearableType::WT_SKIRT)); + 2, TEX_SKIRT, TEX_SKIRT_TATTOO, + 2, LLWearableType::WT_SKIRT, LLWearableType::WT_UNIVERSAL )); addEntry(BAKED_HAIR, new BakedEntry(TEX_HAIR_BAKED, "hair", "a60e85a9-74e8-48d8-8a2d-8129f28d9b61", - 2, TEX_HAIR, TEX_HAIR_ALPHA, - 2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA)); + 3, TEX_HAIR, TEX_HAIR_TATTOO, TEX_HAIR_ALPHA, + 3, LLWearableType::WT_HAIR, LLWearableType::WT_UNIVERSAL, LLWearableType::WT_ALPHA)); + + addEntry(BAKED_LEFT_ARM, new BakedEntry(TEX_LEFT_ARM_BAKED, + "leftarm", "9f39febf-22d7-0087-79d1-e9e8c6c9ed19", + 1, TEX_LEFT_ARM_TATTOO, + 1, LLWearableType::WT_UNIVERSAL)); + + addEntry(BAKED_LEFT_LEG, new BakedEntry(TEX_LEFT_LEG_BAKED, + "leftleg", "054a7a58-8ed5-6386-0add-3b636fb28b78", + 1, TEX_LEFT_LEG_TATTOO, + 1, LLWearableType::WT_UNIVERSAL)); + + addEntry(BAKED_AUX1, new BakedEntry(TEX_AUX1_BAKED, + "aux1", "790c11be-b25c-c17e-b4d2-6a4ad786b752", + 1, TEX_AUX1_TATTOO, + 1, LLWearableType::WT_UNIVERSAL)); + + addEntry(BAKED_AUX2, new BakedEntry(TEX_AUX2_BAKED, + "aux2", "d78c478f-48c7-5928-5864-8d99fb1f521e", + 1, TEX_AUX2_TATTOO, + 1, LLWearableType::WT_UNIVERSAL)); + + addEntry(BAKED_AUX3, new BakedEntry(TEX_AUX3_BAKED, + "aux3", "6a95dd53-edd9-aac8-f6d3-27ed99f3c3eb", + 1, TEX_AUX3_TATTOO, + 1, LLWearableType::WT_UNIVERSAL)); } LLAvatarAppearanceDictionary::MeshEntries::MeshEntries() @@ -265,3 +309,113 @@ LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIn { return getInstance()->getTexture(index)->mWearableType; } + +// static +BOOL LLAvatarAppearanceDictionary::isBakedImageId(const LLUUID& id) +{ + if ((id == IMG_USE_BAKED_EYES) || (id == IMG_USE_BAKED_HAIR) || (id == IMG_USE_BAKED_HEAD) || (id == IMG_USE_BAKED_LOWER) || (id == IMG_USE_BAKED_SKIRT) || (id == IMG_USE_BAKED_UPPER) + || (id == IMG_USE_BAKED_LEFTARM) || (id == IMG_USE_BAKED_LEFTLEG) || (id == IMG_USE_BAKED_AUX1) || (id == IMG_USE_BAKED_AUX2) || (id == IMG_USE_BAKED_AUX3) ) + { + return TRUE; + } + + return FALSE; +} + +// static +EBakedTextureIndex LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(const LLUUID& id) +{ + if (id == IMG_USE_BAKED_EYES) + { + return BAKED_EYES; + } + else if (id == IMG_USE_BAKED_HAIR) + { + return BAKED_HAIR; + } + else if (id == IMG_USE_BAKED_HEAD) + { + return BAKED_HEAD; + } + else if (id == IMG_USE_BAKED_LOWER) + { + return BAKED_LOWER; + } + else if (id == IMG_USE_BAKED_SKIRT) + { + return BAKED_SKIRT; + } + else if (id == IMG_USE_BAKED_UPPER) + { + return BAKED_UPPER; + } + else if (id == IMG_USE_BAKED_LEFTARM) + { + return BAKED_LEFT_ARM; + } + else if (id == IMG_USE_BAKED_LEFTLEG) + { + return BAKED_LEFT_LEG; + } + else if (id == IMG_USE_BAKED_AUX1) + { + return BAKED_AUX1; + } + else if (id == IMG_USE_BAKED_AUX2) + { + return BAKED_AUX2; + } + else if (id == IMG_USE_BAKED_AUX3) + { + return BAKED_AUX3; + } + + return BAKED_NUM_INDICES; +} + +//static +LLUUID LLAvatarAppearanceDictionary::localTextureIndexToMagicId(ETextureIndex t) +{ + LLUUID id = LLUUID::null; + + switch (t) + { + case LLAvatarAppearanceDefines::TEX_HEAD_BAKED: + id = IMG_USE_BAKED_HEAD; + break; + case LLAvatarAppearanceDefines::TEX_UPPER_BAKED: + id = IMG_USE_BAKED_UPPER; + break; + case LLAvatarAppearanceDefines::TEX_LOWER_BAKED: + id = IMG_USE_BAKED_LOWER; + break; + case LLAvatarAppearanceDefines::TEX_EYES_BAKED: + id = IMG_USE_BAKED_EYES; + break; + case LLAvatarAppearanceDefines::TEX_SKIRT_BAKED: + id = IMG_USE_BAKED_SKIRT; + break; + case LLAvatarAppearanceDefines::TEX_HAIR_BAKED: + id = IMG_USE_BAKED_HAIR; + break; + case LLAvatarAppearanceDefines::TEX_LEFT_ARM_BAKED: + id = IMG_USE_BAKED_LEFTARM; + break; + case LLAvatarAppearanceDefines::TEX_LEFT_LEG_BAKED: + id = IMG_USE_BAKED_LEFTLEG; + break; + case LLAvatarAppearanceDefines::TEX_AUX1_BAKED: + id = IMG_USE_BAKED_AUX1; + break; + case LLAvatarAppearanceDefines::TEX_AUX2_BAKED: + id = IMG_USE_BAKED_AUX2; + break; + case LLAvatarAppearanceDefines::TEX_AUX3_BAKED: + id = IMG_USE_BAKED_AUX3; + break; + default: + break; + } + + return id; +} diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h index d6223bb4d2..5663d24293 100644 --- a/indra/llappearance/llavatarappearancedefines.h +++ b/indra/llappearance/llavatarappearancedefines.h @@ -78,6 +78,22 @@ enum ETextureIndex TEX_HEAD_TATTOO, TEX_UPPER_TATTOO, TEX_LOWER_TATTOO, + TEX_HEAD_UNIVERSAL_TATTOO, + TEX_UPPER_UNIVERSAL_TATTOO, + TEX_LOWER_UNIVERSAL_TATTOO, + TEX_SKIRT_TATTOO, + TEX_HAIR_TATTOO, + TEX_EYES_TATTOO, + TEX_LEFT_ARM_TATTOO, + TEX_LEFT_LEG_TATTOO, + TEX_AUX1_TATTOO, + TEX_AUX2_TATTOO, + TEX_AUX3_TATTOO, + TEX_LEFT_ARM_BAKED, // Pre-composited + TEX_LEFT_LEG_BAKED, // Pre-composited + TEX_AUX1_BAKED, // Pre-composited + TEX_AUX2_BAKED, // Pre-composited + TEX_AUX3_BAKED, // Pre-composited TEX_NUM_INDICES }; @@ -89,6 +105,11 @@ enum EBakedTextureIndex BAKED_EYES, BAKED_SKIRT, BAKED_HAIR, + BAKED_LEFT_ARM, + BAKED_LEFT_LEG, + BAKED_AUX1, + BAKED_AUX2, + BAKED_AUX3, BAKED_NUM_INDICES }; @@ -223,6 +244,10 @@ public: // Given a texture entry, determine which wearable type owns it. static LLWearableType::EType getTEWearableType(ETextureIndex index); + static BOOL isBakedImageId(const LLUUID& id); + static EBakedTextureIndex assetIdToBakedTextureIndex(const LLUUID& id); + static LLUUID localTextureIndexToMagicId(ETextureIndex t); + }; // End LLAvatarAppearanceDictionary } // End namespace LLAvatarAppearanceDefines diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index 3f2fcce429..186986bf9c 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -1581,8 +1581,8 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC // nSight doesn't support use of glReadPixels if (!LLRender::sNsightDebugSupport) { - glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); - } + glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data); + } } getTexLayerSet()->getAvatarAppearance()->dirtyMesh(); diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index cd602b43b4..0e29bbe783 100644 --- a/indra/llappearance/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -91,6 +91,7 @@ LLWearableDictionary::LLWearableDictionary() addEntry(LLWearableType::WT_SKIRT, new WearableEntry("skirt", "New Skirt", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE)); addEntry(LLWearableType::WT_ALPHA, new WearableEntry("alpha", "New Alpha", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE)); addEntry(LLWearableType::WT_TATTOO, new WearableEntry("tattoo", "New Tattoo", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE)); + addEntry(LLWearableType::WT_UNIVERSAL, new WearableEntry("universal", "New Universal", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_UNIVERSAL, FALSE, TRUE)); addEntry(LLWearableType::WT_PHYSICS, new WearableEntry("physics", "New Physics", LLAssetType::AT_CLOTHING, LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE)); diff --git a/indra/llappearance/llwearabletype.h b/indra/llappearance/llwearabletype.h index 519d5b92a2..ac81376538 100644 --- a/indra/llappearance/llwearabletype.h +++ b/indra/llappearance/llwearabletype.h @@ -63,7 +63,8 @@ public: WT_ALPHA = 13, WT_TATTOO = 14, WT_PHYSICS = 15, - WT_COUNT = 16, + WT_UNIVERSAL = 16, + WT_COUNT = 17, WT_INVALID = 255, WT_NONE = -1, diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h index 6b22a2cb59..7372765075 100644 --- a/indra/llaudio/llvorbisencode.h +++ b/indra/llaudio/llvorbisencode.h @@ -40,7 +40,7 @@ const S32 LLVORBISENC_UNSUPPORTED_WORD_SIZE = 9; // unsupported word size const S32 LLVORBISENC_CLIP_TOO_LONG = 10; // source file is too long const S32 LLVORBISENC_CHUNK_SIZE_ERR = 11; // chunk size is wrong -const F32 LLVORBIS_CLIP_MAX_TIME = 10.0f; +const F32 LLVORBIS_CLIP_MAX_TIME = 30.0f; const U8 LLVORBIS_CLIP_MAX_CHANNELS = 2; const U32 LLVORBIS_CLIP_SAMPLE_RATE = 44100; const U32 LLVORBIS_CLIP_MAX_SAMPLES_PER_CHANNEL = (U32)(LLVORBIS_CLIP_MAX_TIME * LLVORBIS_CLIP_SAMPLE_RATE); diff --git a/indra/llcommon/indra_constants.cpp b/indra/llcommon/indra_constants.cpp index 7ea42a3fc0..e13176e8fa 100644 --- a/indra/llcommon/indra_constants.cpp +++ b/indra/llcommon/indra_constants.cpp @@ -72,3 +72,15 @@ const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // V const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER +const LLUUID IMG_USE_BAKED_HEAD ("5a9f4a74-30f2-821c-b88d-70499d3e7183"); +const LLUUID IMG_USE_BAKED_UPPER ("ae2de45c-d252-50b8-5c6e-19f39ce79317"); +const LLUUID IMG_USE_BAKED_LOWER ("24daea5f-0539-cfcf-047f-fbc40b2786ba"); +const LLUUID IMG_USE_BAKED_EYES ("52cc6bb6-2ee5-e632-d3ad-50197b1dcb8a"); +const LLUUID IMG_USE_BAKED_SKIRT ("43529ce8-7faa-ad92-165a-bc4078371687"); +const LLUUID IMG_USE_BAKED_HAIR ("09aac1fb-6bce-0bee-7d44-caac6dbb6c63"); +const LLUUID IMG_USE_BAKED_LEFTARM ("ff62763f-d60a-9855-890b-0c96f8f8cd98"); +const LLUUID IMG_USE_BAKED_LEFTLEG ("8e915e25-31d1-cc95-ae08-d58a47488251"); +const LLUUID IMG_USE_BAKED_AUX1 ("9742065b-19b5-297c-858a-29711d539043"); +const LLUUID IMG_USE_BAKED_AUX2 ("03642e83-2bd1-4eb9-34b4-4c47ed586d2d"); +const LLUUID IMG_USE_BAKED_AUX3 ("edd51b77-fc10-ce7a-4b3d-011dfc349e4f"); + diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index c0213d7c16..0fbf4b966b 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -206,6 +206,18 @@ LL_COMMON_API extern const LLUUID TERRAIN_GRASS_DETAIL; LL_COMMON_API extern const LLUUID TERRAIN_MOUNTAIN_DETAIL; LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_HEAD; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_UPPER; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_LOWER; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_EYES; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_SKIRT; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_HAIR; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_LEFTARM; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_LEFTLEG; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX1; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX2; +LL_COMMON_API extern const LLUUID IMG_USE_BAKED_AUX3; + LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 30bec3a6f8..b619a9e48c 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -1735,7 +1735,8 @@ bool LLStringUtilBase<T>::startsWith( const string_type& substr) { if(string.empty() || (substr.empty())) return false; - if(0 == string.find(substr)) return true; + if (substr.length() > string.length()) return false; + if (0 == string.compare(0, substr.length(), substr)) return true; return false; } @@ -1746,9 +1747,11 @@ bool LLStringUtilBase<T>::endsWith( const string_type& substr) { if(string.empty() || (substr.empty())) return false; - std::string::size_type idx = string.rfind(substr); - if(std::string::npos == idx) return false; - return (idx == (string.size() - substr.size())); + size_t sub_len = substr.length(); + size_t str_len = string.length(); + if (sub_len > str_len) return false; + if (0 == string.compare(str_len - sub_len, sub_len, substr)) return true; + return false; } // static diff --git a/indra/llcommon/lluri.cpp b/indra/llcommon/lluri.cpp index 758b98e143..9942bc0cf8 100644 --- a/indra/llcommon/lluri.cpp +++ b/indra/llcommon/lluri.cpp @@ -173,6 +173,19 @@ namespace "-._~"; return s; } + const std::string path() + { + static const std::string s = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "$-_.+" + "!*'()," + "{}|\\^~[]`" + "<>#%" + ";/?:@&="; + return s; + } const std::string sub_delims() { static const std::string s = "!$&'()*+,;="; @@ -187,6 +200,12 @@ namespace { return LLURI::escape(s, unreserved() + ":@!$'()*+,"); } // sub_delims - "&;=" + ":@" std::string escapeQueryValue(const std::string& s) { return LLURI::escape(s, unreserved() + ":@!$'()*+,="); } // sub_delims - "&;" + ":@" + std::string escapeUriQuery(const std::string& s) + { return LLURI::escape(s, unreserved() + ":@?&$;*+=%/"); } + std::string escapeUriData(const std::string& s) + { return LLURI::escape(s, unreserved() + "%"); } + std::string escapeUriPath(const std::string& s) + { return LLURI::escape(s, path()); } } //static @@ -202,6 +221,85 @@ std::string LLURI::escape(const std::string& str) return escape(str, default_allowed, true); } +//static +std::string LLURI::escapePathAndData(const std::string &str) +{ + std::string result; + + const std::string data_marker = "data:"; + if (str.compare(0, data_marker.length(), data_marker) == 0) + { + // This is not url, but data, data part needs to be properly escaped + // data part is separated by ',' from header. Minimal data uri is "data:," + // See "data URI scheme" + size_t separator = str.find(','); + if (separator != std::string::npos) + { + size_t header_size = separator + 1; + std::string header = str.substr(0, header_size); + // base64 is url-safe + if (header.find("base64") != std::string::npos) + { + // assume url-safe data + result = str; + } + else + { + std::string data = str.substr(header_size, str.length() - header_size); + + // Notes: File can be partially pre-escaped, that's why escaping ignores '%' + // It somewhat limits user from displaying strings like "%20" in text + // but that's how viewer worked for a while and user can double-escape it + + + // Header doesn't need escaping + result = header + escapeUriData(data); + } + } + } + else + { + // try processing it as path with query separator + // The query component is indicated by the first question + // mark("?") character and terminated by a number sign("#") + size_t delim_pos = str.find('?'); + if (delim_pos == std::string::npos) + { + // alternate separator + delim_pos = str.find(';'); + } + + if (delim_pos != std::string::npos) + { + size_t path_size = delim_pos + 1; + std::string query; + std::string fragment; + + size_t fragment_pos = str.find('#'); + if (fragment_pos != std::string::npos) + { + query = str.substr(path_size, fragment_pos - path_size); + fragment = str.substr(fragment_pos); + } + else + { + query = str.substr(path_size); + } + + std::string path = str.substr(0, path_size); + + result = escapeUriPath(path) + escapeUriQuery(query) + escapeUriPath(fragment); + } + } + + if (result.empty()) + { + // Not a known scheme or no data part, try just escaping as Uri path + result = escapeUriPath(str); + } + return result; +} + LLURI::LLURI() { } diff --git a/indra/llcommon/lluri.h b/indra/llcommon/lluri.h index 9e44cc7da2..b8fca0ca51 100644 --- a/indra/llcommon/lluri.h +++ b/indra/llcommon/lluri.h @@ -158,6 +158,14 @@ public: bool is_allowed_sorted = false); /** + * @brief Break string into data part and path or sheme + * and escape path (if present) and data. + * Data part is not allowed to have path related symbols + * @param str The raw URI to escape. + */ + static std::string escapePathAndData(const std::string &str); + + /** * @brief unescape an escaped URI string. * * @param str The escped URI to unescape. diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp index 4c64f15ca7..1a4c6641b9 100644 --- a/indra/llcommon/tests/lluri_test.cpp +++ b/indra/llcommon/tests/lluri_test.cpp @@ -383,6 +383,41 @@ namespace tut ensure_equals("query", u.query(), "redirect-http-hack=secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak®ion=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78"); ensure_equals("query map element", u.queryMap()["redirect-http-hack"].asString(), "secondlife:///app/login?first_name=Callum&last_name=Linden&location=specify&grid=vaak®ion=/Morris/128/128&web_login_key=efaa4795-c2aa-4c58-8966-763c27931e78"); } + + template<> template<> + void URITestObject::test<20>() + { + set_test_name("escapePathAndData uri test"); + + // Basics scheme:[//authority]path[?query][#fragment] + ensure_equals(LLURI::escapePathAndData("dirname?query"), + "dirname?query"); + ensure_equals(LLURI::escapePathAndData("dirname?query=data"), + "dirname?query=data"); + ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query#fragment"), + "host://dirname/subdir%20name?query#fragment"); + ensure_equals(LLURI::escapePathAndData("host://dirname/subdir name?query=some@>data#fragment"), + "host://dirname/subdir%20name?query=some@%3Edata#fragment"); + ensure_equals(LLURI::escapePathAndData("host://dir[name/subdir name?query=some[data#fra[gment"), + "host://dir[name/subdir%20name?query=some%5Bdata#fra[gment"); + ensure_equals(LLURI::escapePathAndData("mailto:zero@ll.com"), + "mailto:zero@ll.com"); + // pre-escaped + ensure_equals(LLURI::escapePathAndData("host://dirname/subdir%20name"), + "host://dirname/subdir%20name"); + + // data:[<mediatype>][;base64],<data> + ensure_equals(LLURI::escapePathAndData("data:,Hello, World!"), + "data:,Hello%2C%20World%21"); + ensure_equals(LLURI::escapePathAndData("data:text/html,<h1>Hello, World!</h1>"), + "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E"); + // pre-escaped + ensure_equals(LLURI::escapePathAndData("data:text/html,%3Ch1%3EHello%2C%20World!</h1>"), + "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E"); + // assume that base64 does not need escaping + ensure_equals(LLURI::escapePathAndData("data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?="), + "data:image;base64,SGVs/bG8sIFd/vcmxkIQ%3D%3D!-&*?="); + } } diff --git a/indra/llcorehttp/_httplibcurl.cpp b/indra/llcorehttp/_httplibcurl.cpp index abd304f6a5..975ce8a4d5 100644 --- a/indra/llcorehttp/_httplibcurl.cpp +++ b/indra/llcorehttp/_httplibcurl.cpp @@ -355,7 +355,8 @@ bool HttpLibcurl::completeRequest(CURLM * multi_handle, CURL * handle, CURLcode } if (op->mStatus) { - int http_status(HTTP_OK); + // note: CURLINFO_RESPONSE_CODE requires a long - https://curl.haxx.se/libcurl/c/CURLINFO_RESPONSE_CODE.html + long http_status(HTTP_OK); if (handle) { diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index 867b2bb47b..90b7272efa 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -181,7 +181,7 @@ bool LLImageBMP::updateData() } } else - if( 12 <= header.mSize && 64 <= header.mSize ) + if( 12 <= header.mSize && header.mSize <= 64 ) { setLastError("OS/2 2.x BMP files are not supported"); return false; diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index 891ab217fd..034cee5f45 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -101,6 +101,7 @@ public: ICONNAME_CLOTHING_SKIRT, ICONNAME_CLOTHING_ALPHA, ICONNAME_CLOTHING_TATTOO, + ICONNAME_CLOTHING_UNIVERSAL, ICONNAME_ANIMATION, ICONNAME_GESTURE, diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 280d2653d3..0e2f62f9db 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -401,7 +401,7 @@ public: child->insert(data); } } - else + else if (parent) { //it's not in here, give it to the root OCT_ERRS << "Octree insertion failed, starting over from root!" << LL_ENDL; @@ -416,6 +416,13 @@ public: node->insert(data); } + else + { + // It's not in here, and we are root. + // LLOctreeRoot::insert() should have expanded + // root by now, something is wrong + OCT_ERRS << "Octree insertion failed! Root expansion failed." << LL_ENDL; + } return false; } @@ -763,10 +770,15 @@ public: { LLOctreeNode<T>::insert(data); } - else + else if (node->isInside(data->getPositionGroup())) { node->insert(data); } + else + { + // calling node->insert(data) will return us to root + OCT_ERRS << "Failed to insert data at child node" << LL_ENDL; + } } else if (this->getChildCount() == 0) { diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index b15b98db80..7caf0766b7 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -265,7 +265,7 @@ LLSocket::~LLSocket() void LLSocket::setBlocking(S32 timeout) { // set up the socket options - ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout)); + ll_apr_warn_status(apr_socket_timeout_set(mSocket, timeout)); // Sets both receive and send timeout SO_RCVTIMEO, SO_SNDTIMEO ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_NONBLOCK, 0)); ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_SNDBUF, LL_SEND_BUFFER_SIZE)); ll_apr_warn_status(apr_socket_opt_set(mSocket, APR_SO_RCVBUF, LL_RECV_BUFFER_SIZE)); diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index 5730a36267..dea03aab85 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -473,7 +473,8 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou rv = apr_socket_send(apr_socket, dataout, &outlen); if (APR_SUCCESS != rv) { - LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << LL_ENDL; + char buf[MAX_STRING]; + LL_WARNS("Proxy") << "Error sending data to proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL; ll_apr_warn_status(rv); } else if (expected_len != outlen) @@ -483,13 +484,16 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou rv = -1; } + ms_sleep(1); + if (APR_SUCCESS == rv) { expected_len = maxinlen; rv = apr_socket_recv(apr_socket, datain, &maxinlen); if (rv != APR_SUCCESS) { - LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << LL_ENDL; + 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); } else if (expected_len < maxinlen) diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 9d447b0f37..78b1483810 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -33,7 +33,10 @@ #include "llpluginmessageclasses.h" #include "llcontrol.h" -extern LLControlGroup gSavedSettings; +extern LLControlGroup gSavedSettings; +#if LL_DARWIN +extern BOOL gHiDPISupport; +#endif static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256; @@ -365,11 +368,16 @@ void LLPluginClassMedia::setSizeInternal(void) mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight); } - if(mRequestedMediaWidth > 2048) - mRequestedMediaWidth = 2048; +#if LL_DARWIN + if (!gHiDPISupport) +#endif + { + if (mRequestedMediaWidth > 2048) + mRequestedMediaWidth = 2048; - if(mRequestedMediaHeight > 2048) - mRequestedMediaHeight = 2048; + if (mRequestedMediaHeight > 2048) + mRequestedMediaHeight = 2048; + } } void LLPluginClassMedia::setAutoScale(bool auto_scale) diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 27d1bee9bd..a0987b35d8 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1040,14 +1040,26 @@ S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_fa } //assign exception faces to cur_ptr - if (exception_faces >= (0x1 << 7)) + if (exception_faces >= ((U64)0x1 << 7)) { - if (exception_faces >= (0x1 << 14)) + if (exception_faces >= ((U64)0x1 << 14)) { - if (exception_faces >= (0x1 << 21)) + if (exception_faces >= ((U64)0x1 << 21)) { - if (exception_faces >= (0x1 << 28)) + if (exception_faces >= ((U64)0x1 << 28)) { + if (exception_faces >= ((U64)0x1 << 35)) + { + if (exception_faces >= ((U64)0x1 << 42)) + { + if (exception_faces >= ((U64)0x1 << 49)) + { + *cur_ptr++ = (U8)(((exception_faces >> 49) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 42) & 0x7F) | 0x80); + } + *cur_ptr++ = (U8)(((exception_faces >> 35) & 0x7F) | 0x80); + } *cur_ptr++ = (U8)(((exception_faces >> 28) & 0x7F) | 0x80); } *cur_ptr++ = (U8)(((exception_faces >> 21) & 0x7F) | 0x80); @@ -1056,6 +1068,7 @@ S32 LLPrimitive::packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_fa } *cur_ptr++ = (U8)(((exception_faces >> 7) & 0x7F) | 0x80); } + *cur_ptr++ = (U8)(exception_faces & 0x7F); @@ -1115,7 +1128,7 @@ S32 LLPrimitive::unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 dat // Includes information about image ID, color, scale S,T, offset S,T and rotation BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const { - const U32 MAX_TES = 32; + const U32 MAX_TES = 45; U8 image_ids[MAX_TES*16]; U8 colors[MAX_TES*4]; @@ -1200,7 +1213,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const { - const U32 MAX_TES = 32; + const U32 MAX_TES = 45; U8 image_ids[MAX_TES*16]; U8 colors[MAX_TES*4]; @@ -1313,6 +1326,8 @@ S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER); } + + tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES); U8 *cur_ptr = tec.packed_buffer; @@ -1385,6 +1400,8 @@ S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec) retval |= setTEColor(i, color); + + } return retval; @@ -1403,7 +1420,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) { // use a negative block_num to indicate a single-block read (a non-variable block) S32 retval = 0; - const U32 MAX_TES = 32; + const U32 MAX_TES = 45; // Avoid construction of 32 UUIDs per call static LLUUID image_ids[MAX_TES]; diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index c138c2ac2b..6fd433c337 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -319,7 +319,7 @@ public: // - Vir struct LLTEContents { - static const U32 MAX_TES = 32; + static const U32 MAX_TES = 45; U8 image_data[MAX_TES*16]; U8 colors[MAX_TES*4]; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index ab668dc192..c41730ebaa 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -157,7 +157,7 @@ void ft_close_cb(FT_Stream stream) { } #endif -BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n) { // Don't leak face objects. This is also needed to deal with // changed font file names. @@ -168,40 +168,8 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v } int error; - #ifdef LL_WINDOWS - pFileStream = new llifstream(filename, std::ios::binary); - if (pFileStream->is_open()) - { - std::streampos beg = pFileStream->tellg(); - pFileStream->seekg(0, std::ios::end); - std::streampos end = pFileStream->tellg(); - std::size_t file_size = end - beg; - pFileStream->seekg(0, std::ios::beg); - - pFtStream = new LLFT_Stream(); - pFtStream->base = 0; - pFtStream->pos = 0; - pFtStream->size = file_size; - pFtStream->descriptor.pointer = pFileStream; - pFtStream->read = ft_read_cb; - pFtStream->close = ft_close_cb; - - FT_Open_Args args; - args.flags = FT_OPEN_STREAM; - args.stream = (FT_StreamRec*)pFtStream; - - error = FT_Open_Face(gFTLibrary, - &args, - 0, - &mFTFace); - } - else - { - delete pFileStream; - pFileStream = NULL; - return FALSE; - } + error = ftOpenFace(filename, face_n); #else error = FT_New_Face( gFTLibrary, filename.c_str(), @@ -212,11 +180,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if (error) { #ifdef LL_WINDOWS - pFileStream->close(); - delete pFileStream; - delete pFtStream; - pFileStream = NULL; - pFtStream = NULL; + clearFontStreams(); #endif return FALSE; } @@ -235,11 +199,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v // Clean up freetype libs. FT_Done_Face(mFTFace); #ifdef LL_WINDOWS - pFileStream->close(); - delete pFileStream; - delete pFtStream; - pFileStream = NULL; - pFtStream = NULL; + clearFontStreams(); #endif mFTFace = NULL; return FALSE; @@ -285,18 +245,88 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if(mFTFace->style_flags & FT_STYLE_FLAG_BOLD) { mStyle |= LLFontGL::BOLD; - mStyle &= ~LLFontGL::NORMAL; } if(mFTFace->style_flags & FT_STYLE_FLAG_ITALIC) { mStyle |= LLFontGL::ITALIC; - mStyle &= ~LLFontGL::NORMAL; } return TRUE; } +S32 LLFontFreetype::getNumFaces(const std::string& filename) +{ + if (mFTFace) + { + FT_Done_Face(mFTFace); + mFTFace = NULL; + } + + S32 num_faces = 1; + +#ifdef LL_WINDOWS + int error = ftOpenFace(filename, 0); + + if (error) + { + return 0; + } + else + { + num_faces = mFTFace->num_faces; + } + + FT_Done_Face(mFTFace); + clearFontStreams(); + mFTFace = NULL; +#endif + + return num_faces; +} + +#ifdef LL_WINDOWS +S32 LLFontFreetype::ftOpenFace(const std::string& filename, S32 face_n) +{ + S32 error = -1; + pFileStream = new llifstream(filename, std::ios::binary); + if (pFileStream->is_open()) + { + std::streampos beg = pFileStream->tellg(); + pFileStream->seekg(0, std::ios::end); + std::streampos end = pFileStream->tellg(); + std::size_t file_size = end - beg; + pFileStream->seekg(0, std::ios::beg); + + pFtStream = new LLFT_Stream(); + pFtStream->base = 0; + pFtStream->pos = 0; + pFtStream->size = file_size; + pFtStream->descriptor.pointer = pFileStream; + pFtStream->read = ft_read_cb; + pFtStream->close = ft_close_cb; + + FT_Open_Args args; + args.flags = FT_OPEN_STREAM; + args.stream = (FT_StreamRec*)pFtStream; + error = FT_Open_Face(gFTLibrary, &args, face_n, &mFTFace); + } + return error; +} + +void LLFontFreetype::clearFontStreams() +{ + if (pFileStream) + { + pFileStream->close(); + } + delete pFileStream; + delete pFtStream; + pFileStream = NULL; + pFtStream = NULL; +} +#endif + void LLFontFreetype::setFallbackFonts(const font_vector_t &font) { mFallbackFonts = font; diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index aadebf5e70..1afe84e770 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -84,7 +84,14 @@ public: // is_fallback should be true for fallback fonts that aren't used // to render directly (Unicode backup, primarily) - BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback); + BOOL loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n = 0); + + S32 getNumFaces(const std::string& filename); + +#ifdef LL_WINDOWS + S32 ftOpenFace(const std::string& filename, S32 face_n); + void clearFontStreams(); +#endif typedef std::vector<LLPointer<LLFontFreetype> > font_vector_t; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 8cd18c5fa1..86a4c35e6d 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -89,14 +89,24 @@ void LLFontGL::destroyGL() mFontFreetype->destroyGL(); } -BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback) +BOOL LLFontGL::loadFace(const std::string& filename, F32 point_size, F32 vert_dpi, F32 horz_dpi, S32 components, BOOL is_fallback, S32 face_n) { if(mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL)) { mFontFreetype = new LLFontFreetype; } - return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback); + return mFontFreetype->loadFace(filename, point_size, vert_dpi, horz_dpi, components, is_fallback, face_n); +} + +S32 LLFontGL::getNumFaces(const std::string& filename) +{ + if (mFontFreetype == reinterpret_cast<LLFontFreetype*>(NULL)) + { + mFontFreetype = new LLFontFreetype; + } + + return mFontFreetype->getNumFaces(filename); } static LLTrace::BlockTimerStatHandle FTM_RENDER_FONTS("Fonts"); @@ -860,10 +870,6 @@ void LLFontGL::destroyAllGL() U8 LLFontGL::getStyleFromString(const std::string &style) { S32 ret = 0; - if (style.find("NORMAL") != style.npos) - { - ret |= NORMAL; - } if (style.find("BOLD") != style.npos) { ret |= BOLD; @@ -883,7 +889,7 @@ U8 LLFontGL::getStyleFromString(const std::string &style) std::string LLFontGL::getStringFromStyle(U8 style) { std::string style_string; - if (style & NORMAL) + if (style == NORMAL) { style_string += "|NORMAL"; } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index 7d0e53f60f..10891faed9 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -87,7 +87,9 @@ public: void destroyGL(); - BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback); + BOOL loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, const S32 components, BOOL is_fallback, S32 face_n = 0); + + S32 getNumFaces(const std::string& filename); S32 render(const LLWString &text, S32 begin_offset, const LLRect& rect, diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp index 3c829596ce..dbe71e2882 100644 --- a/indra/llrender/llfontregistry.cpp +++ b/indra/llrender/llfontregistry.cpp @@ -44,6 +44,8 @@ using std::map; bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc); bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node); +const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/"; + LLFontDescriptor::LLFontDescriptor(): mStyle(0) { @@ -61,6 +63,16 @@ LLFontDescriptor::LLFontDescriptor(const std::string& name, } LLFontDescriptor::LLFontDescriptor(const std::string& name, + const std::string& size, + const U8 style, + const string_vec_t& file_names, + const string_vec_t& ft_collection_listections) : + LLFontDescriptor(name, size, style, file_names) +{ + mFontCollectionsList = ft_collection_listections; +} + +LLFontDescriptor::LLFontDescriptor(const std::string& name, const std::string& size, const U8 style): mName(name), @@ -162,7 +174,7 @@ LLFontDescriptor LLFontDescriptor::normalize() const if (removeSubString(new_name,"Italic")) new_style |= LLFontGL::ITALIC; - return LLFontDescriptor(new_name,new_size,new_style,getFileNames()); + return LLFontDescriptor(new_name,new_size,new_style,getFileNames(),getFontCollectionsList()); } LLFontRegistry::LLFontRegistry(bool create_gl_textures) @@ -213,6 +225,7 @@ bool LLFontRegistry::parseFontInfo(const std::string& xml_filename) success = success || init_succ; } } + //if (success) // dump(); @@ -260,6 +273,16 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc) { std::string font_file_name = child->getTextContents(); desc.getFileNames().push_back(font_file_name); + + if (child->hasAttribute("load_collection")) + { + BOOL col = FALSE; + child->getAttributeBOOL("load_collection", col); + if (col) + { + desc.getFontCollectionsList().push_back(font_file_name); + } + } } else if (child->hasName("os")) { @@ -306,8 +329,15 @@ bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node) match_file_names.insert(match_file_names.begin(), desc.getFileNames().begin(), desc.getFileNames().end()); + + string_vec_t collections_list = match_desc->getFontCollectionsList(); + collections_list.insert(collections_list.begin(), + desc.getFontCollectionsList().begin(), + desc.getFontCollectionsList().end()); + LLFontDescriptor new_desc = *match_desc; new_desc.getFileNames() = match_file_names; + new_desc.getFontCollectionsList() = collections_list; registry->mFontMap.erase(*match_desc); registry->mFontMap[new_desc] = NULL; } @@ -393,6 +423,7 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) // Build list of font names to look for. // Files specified for this font come first, followed by those from the default descriptor. string_vec_t file_names = match_desc->getFileNames(); + string_vec_t ft_collection_list = match_desc->getFontCollectionsList(); string_vec_t default_file_names; LLFontDescriptor default_desc("default",s_template_string,0); const LLFontDescriptor *match_default_desc = getMatchingFontDesc(default_desc); @@ -401,6 +432,9 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) file_names.insert(file_names.end(), match_default_desc->getFileNames().begin(), match_default_desc->getFileNames().end()); + ft_collection_list.insert(ft_collection_list.end(), + match_default_desc->getFontCollectionsList().begin(), + match_default_desc->getFontCollectionsList().end()); } // Add ultimate fallback list - generated dynamically on linux, @@ -433,39 +467,62 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc) file_name_it != file_names.end(); ++file_name_it) { - LLFontGL *fontp = new LLFontGL; - std::string font_path = local_path + *file_name_it; + LLFontGL *fontp = NULL; + string_vec_t font_paths; + font_paths.push_back(local_path + *file_name_it); + font_paths.push_back(sys_path + *file_name_it); +#if LL_DARWIN + font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it); +#endif + + bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end()); // *HACK: Fallback fonts don't render, so we can use that to suppress // creation of OpenGL textures for test apps. JC BOOL is_fallback = !is_first_found || !mCreateGLTextures; F32 extra_scale = (is_fallback)?fallback_scale:1.0; - if (!fontp->loadFace(font_path, extra_scale * point_size, - LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback)) + F32 point_size_scale = extra_scale * point_size; + bool is_font_loaded = false; + for(string_vec_t::iterator font_paths_it = font_paths.begin(); + font_paths_it != font_paths.end(); + ++font_paths_it) { - font_path = sys_path + *file_name_it; - - if (!fontp->loadFace(font_path, extra_scale * point_size, - LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback)) + fontp = new LLFontGL; + S32 num_faces = is_ft_collection ? fontp->getNumFaces(*font_paths_it) : 1; + for (S32 i = 0; i < num_faces; i++) { - LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << " from path " << local_path << LL_ENDL; - delete fontp; - fontp = NULL; + if (fontp == NULL) + { + fontp = new LLFontGL; + } + if (fontp->loadFace(*font_paths_it, point_size_scale, + LLFontGL::sVertDPI, LLFontGL::sHorizDPI, 2, is_fallback, i)) + { + is_font_loaded = true; + if (is_first_found) + { + result = fontp; + is_first_found = false; + } + else + { + fontlist.push_back(fontp->mFontFreetype); + delete fontp; + fontp = NULL; + } + } + else + { + delete fontp; + fontp = NULL; + } } + if (is_font_loaded) break; } - - if(fontp) + if(!is_font_loaded) { - if (is_first_found) - { - result = fontp; - is_first_found = false; - } - else - { - fontlist.push_back(fontp->mFontFreetype); - delete fontp; - fontp = NULL; - } + LL_INFOS_ONCE("LLFontRegistry") << "Couldn't load font " << *file_name_it << LL_ENDL; + delete fontp; + fontp = NULL; } } diff --git a/indra/llrender/llfontregistry.h b/indra/llrender/llfontregistry.h index 177eb6c8a5..e30c81c630 100644 --- a/indra/llrender/llfontregistry.h +++ b/indra/llrender/llfontregistry.h @@ -40,6 +40,7 @@ public: LLFontDescriptor(); LLFontDescriptor(const std::string& name, const std::string& size, const U8 style); LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names); + LLFontDescriptor(const std::string& name, const std::string& size, const U8 style, const string_vec_t& file_names, const string_vec_t& font_collections); LLFontDescriptor normalize() const; bool operator<(const LLFontDescriptor& b) const; @@ -52,6 +53,8 @@ public: void setSize(const std::string& size) { mSize = size; } const std::vector<std::string>& getFileNames() const { return mFileNames; } std::vector<std::string>& getFileNames() { return mFileNames; } + const std::vector<std::string>& getFontCollectionsList() const { return mFontCollectionsList; } + std::vector<std::string>& getFontCollectionsList() { return mFontCollectionsList; } const U8 getStyle() const { return mStyle; } void setStyle(U8 style) { mStyle = style; } @@ -59,6 +62,7 @@ private: std::string mName; std::string mSize; string_vec_t mFileNames; + string_vec_t mFontCollectionsList; U8 mStyle; }; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 01fe82e45d..9faff1278d 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -122,6 +122,7 @@ void LLTextBox::setEnabled(BOOL enabled) LLTextBase::setReadOnly(read_only); updateSegments(); } + LLTextBase::setEnabled(enabled); } void LLTextBox::setText(const LLStringExplicit& text , const LLStyle::Params& input_params ) diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 220cee4c90..b1534bb5e4 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -44,7 +44,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS); if (!success) { - LL_ERRS() << "Couldn't load string table " << xml_filename << LL_ENDL; + LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; return false; } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index e9f8ba020e..52190a1473 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -236,14 +236,14 @@ void LLUI::dirtyRect(LLRect rect) //static void LLUI::setMousePositionScreen(S32 x, S32 y) { - S32 screen_x, screen_y; #if defined(LL_DARWIN) - screen_x = ll_round((F32)x); - screen_y = ll_round((F32)y); + S32 screen_x = ll_round(((F32)x * getScaleFactor().mV[VX]) / LLView::getWindow()->getSystemUISize()); + S32 screen_y = ll_round(((F32)y * getScaleFactor().mV[VY]) / LLView::getWindow()->getSystemUISize()); #else - screen_x = ll_round((F32)x * getScaleFactor().mV[VX]); - screen_y = ll_round((F32)y * getScaleFactor().mV[VY]); + S32 screen_x = ll_round((F32)x * getScaleFactor().mV[VX]); + S32 screen_y = ll_round((F32)y * getScaleFactor().mV[VY]); #endif + LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert()); } diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 10bd3cbb91..99af161102 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -110,9 +110,9 @@ void glSwapBuffers(void* context); CGLContextObj getCGLContextObj(GLViewRef view); unsigned long getVramSize(GLViewRef view); float getDeviceUnitSize(GLViewRef view); -const CGPoint getContentViewBoundsPosition(NSWindowRef window); -const CGSize getContentViewBoundsSize(NSWindowRef window); -const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view); +CGPoint getContentViewBoundsPosition(NSWindowRef window); +CGSize getContentViewBoundsSize(NSWindowRef window); +CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view); void getWindowSize(NSWindowRef window, float* size); void setWindowSize(NSWindowRef window, int width, int height); void getCursorPos(NSWindowRef window, float* pos); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 8fece7c5c7..f895c17643 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -258,17 +258,17 @@ float getDeviceUnitSize(GLViewRef view) return [(LLOpenGLView*)view convertSizeToBacking:NSMakeSize(1, 1)].width; } -const CGPoint getContentViewBoundsPosition(NSWindowRef window) +CGPoint getContentViewBoundsPosition(NSWindowRef window) { return [[(LLNSWindow*)window contentView] bounds].origin; } -const CGSize getContentViewBoundsSize(NSWindowRef window) +CGSize getContentViewBoundsSize(NSWindowRef window) { return [[(LLNSWindow*)window contentView] bounds].size; } -const CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view) +CGSize getDeviceContentViewSize(NSWindowRef window, GLViewRef view) { return [(NSOpenGLView*)view convertRectToBacking:[[(LLNSWindow*)window contentView] bounds]].size; } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 6dec131a34..3554f90be8 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -382,7 +382,10 @@ void callWindowFocus() void callWindowUnfocus() { - gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + } } void callWindowHide() diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 97cd31de81..e05f507506 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -741,6 +741,17 @@ void LLWindowWin32::restore() SetFocus(mWindowHandle); } +bool destroy_window_handler(HWND &hWnd) +{ + __try + { + return DestroyWindow(hWnd); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } +} // close() destroys all OS-specific code associated with a window. // Usually called from LLWindowManager::destroyWindow() @@ -814,7 +825,7 @@ void LLWindowWin32::close() ShowWindow(mWindowHandle, SW_HIDE); // This causes WM_DESTROY to be sent *immediately* - if (!DestroyWindow(mWindowHandle)) + if (!destroy_window_handler(mWindowHandle)) { OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"), mCallbacks->translateString("MBShutdownErr"), @@ -4036,7 +4047,7 @@ void LLWindowWin32::setDPIAwareness() F32 LLWindowWin32::getSystemUISize() { - float scale_value = 0; + F32 scale_value = 1.f; HWND hWnd = (HWND)getPlatformWindow(); HDC hdc = GetDC(hWnd); HMONITOR hMonitor; diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp index 66b316df90..eead92fd8e 100644 --- a/indra/media_plugins/cef/media_plugin_cef.cpp +++ b/indra/media_plugins/cef/media_plugin_cef.cpp @@ -498,7 +498,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string) dullahan::dullahan_settings settings; settings.accept_language_list = mHostLanguage; - settings.background_color = 0xff282828; + settings.background_color = 0xffffffff; settings.cache_enabled = true; settings.cache_path = mCachePath; settings.cookie_store_path = mCookiePath; @@ -531,7 +531,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string) } // now we can set page zoom factor - mCEFLib->setPageZoom(message_in.getValueReal("factor")); + F32 factor = (F32)message_in.getValueReal("factor"); +#if LL_DARWIN + //temporary fix for SL-10473: issue with displaying checkboxes on Mojave + factor*=1.001; +#endif + mCEFLib->setPageZoom(factor); // Plugin gets to decide the texture parameters to use. mDepth = 4; @@ -736,6 +741,10 @@ void MediaPluginCEF::receiveMessage(const char* message_string) if (message_name == "set_page_zoom_factor") { F32 factor = (F32)message_in.getValueReal("factor"); +#if LL_DARWIN + //temporary fix for SL-10473: issue with displaying checkboxes on Mojave + factor*=1.001; +#endif mCEFLib->setPageZoom(factor); } if (message_name == "browse_stop") @@ -813,7 +822,8 @@ void MediaPluginCEF::keyEvent(dullahan::EKeyEvent key_event, LLSD native_key_dat // adding new code below in unicodeInput means we don't send ascii chars // here too or we get double key presses on a mac. bool esc_key = (event_umodchars == 27); - if (esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) + bool tab_key_up = (event_umodchars == 9) && (key_event == dullahan::EKeyEvent::KE_KEY_UP); + if ((esc_key || ((unsigned char)event_chars < 0x10 || (unsigned char)event_chars >= 0x7f )) && !tab_key_up) { mCEFLib->nativeKeyboardEventOSX(key_event, event_modifiers, event_keycode, event_chars, diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 766dc5226c..46fd0f3fd1 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -201,7 +201,6 @@ set(viewer_SOURCE_FILES llexperiencelog.cpp llexternaleditor.cpp llface.cpp - llfacebookconnect.cpp llfasttimerview.cpp llfavoritesbar.cpp llfeaturemanager.cpp @@ -245,7 +244,6 @@ set(viewer_SOURCE_FILES llfloaterexperiencepicker.cpp llfloaterexperienceprofile.cpp llfloaterexperiences.cpp - llfloaterfacebook.cpp llfloaterflickr.cpp llfloaterfonttest.cpp llfloatergesture.cpp @@ -828,7 +826,6 @@ set(viewer_HEADER_FILES llexperiencelog.h llexternaleditor.h llface.h - llfacebookconnect.h llfasttimerview.h llfavoritesbar.h llfeaturemanager.h @@ -872,7 +869,6 @@ set(viewer_HEADER_FILES llfloaterexperiencepicker.h llfloaterexperienceprofile.h llfloaterexperiences.h - llfloaterfacebook.h llfloaterflickr.h llfloaterfonttest.h llfloatergesture.h @@ -1881,12 +1877,12 @@ if (WINDOWS) # sets the 'working directory' for debugging from visual studio. # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865) - if ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2")) + if (NOT UNATTENDED) set_property( TARGET ${VIEWER_BINARY_NAME} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) - endif ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2")) + endif (NOT UNATTENDED) if (PACKAGE) add_custom_command( diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 42cc526d6c..91e4a9f262 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.2.4 +6.3.2 diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 412d3a53b3..cab0c523b2 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -228,16 +228,6 @@ is_running_function="Floater.IsOpen" is_running_parameters="snapshot" /> - <command name="facebook" - available_in_toybox="true" - icon="Command_Facebook_Icon" - label_ref="Command_Facebook_Label" - tooltip_ref="Command_Facebook_Tooltip" - execute_function="Floater.ToggleOrBringToFront" - execute_parameters="facebook" - is_running_function="Floater.IsOpen" - is_running_parameters="facebook" - /> <command name="flickr" available_in_toybox="true" icon="Command_Flickr_Icon" diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 3d4bd659f1..8f4ca6c633 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -414,5 +414,16 @@ <key>Value</key> <string>Snapshot</string> </map> + <key>ExperienceSearchMaturity</key> + <map> + <key>Comment</key> + <string>Setting for the user's preferred Max Content rating for Experiences search (Default rating is General)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>U32</string> + <key>Value</key> + <integer>2</integer> + </map> </map> </llsd> diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml index 36e4eb91fd..eec0d81e8b 100644 --- a/indra/newview/app_settings/toolbars.xml +++ b/indra/newview/app_settings/toolbars.xml @@ -21,7 +21,6 @@ <command name="voice"/> <command name="minimap"/> <command name="snapshot"/> - <command name="facebook"/> </left_toolbar> <right_toolbar button_display_mode="icons_only"> diff --git a/indra/newview/character/aux_base.tga b/indra/newview/character/aux_base.tga Binary files differnew file mode 100644 index 0000000000..dbcaaaf2b1 --- /dev/null +++ b/indra/newview/character/aux_base.tga diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index df30f46002..2cdd86267e 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -8947,6 +8947,66 @@ <texture local_texture="hair_alpha" /> </layer> + <layer + name="hair_tattoo"> + <texture + local_texture="hair_tattoo" /> + <param + id="1211" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_hair_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1212" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_hair_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1213" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_hair_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + </layer_set> <!-- =========================================================== --> @@ -10024,7 +10084,65 @@ render_pass="bump"> </param> </layer> + <layer + name="head_universal_tattoo"> + <texture + local_texture="head_universal_tattoo" /> + <param + id="1229" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_head_universal_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1230" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_head_universal_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + <param + id="1231" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_head_universal_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> </layer_set> @@ -10201,7 +10319,65 @@ render_pass="bump"> </param> </layer> + <layer + name="upper_universal_tattoo"> + <texture + local_texture="upper_universal_tattoo" /> + <param + id="1232" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_upper_universal_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1233" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_upper_universal_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1234" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_upper_universal_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> <layer name="upper_undershirt bump" @@ -11453,7 +11629,65 @@ render_pass="bump"> </param> </layer> + <layer + name="lower_universal_tattoo"> + <texture + local_texture="lower_universal_tattoo" /> + <param + id="1235" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_lower_universal_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1236" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_lower_universal_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1237" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_lower_universal_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> <layer name="lower_underpants bump" render_pass="bump" @@ -12235,6 +12469,66 @@ render_pass="bump"> <texture local_texture="eyes_alpha" /> </layer> + <layer + name="eyes_tattoo"> + <texture + local_texture="eyes_tattoo" /> + <param + id="924" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_eyes_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="925" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_eyes_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="926" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_eyes_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + </layer_set> @@ -12415,6 +12709,447 @@ render_pass="bump"> domain="0" /> </param> </layer> + <layer + name="skirt_tattoo"> + <texture + local_texture="skirt_tattoo" /> + <param + id="1208" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_skirt_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1209" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_skirt_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1210" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_skirt_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="leftarm" + width="512" + height="512" + clear_alpha="false"> + <layer + name="base" + write_all_channels="true" + fixed_color = "128,128,128,255"> + <texture + tga_file="aux_base.tga" /> + </layer> + + <layer + name="leftarm_tattoo"> + <texture + local_texture="leftarm_tattoo" /> + <param + id="1214" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_leftarm_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1215" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_leftarm_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1216" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_leftarm_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="leftleg" + width="512" + height="512" + clear_alpha="false"> + <layer + name="base" + write_all_channels="true" + fixed_color = "128,128,128,255"> + <texture + tga_file="aux_base.tga" /> + </layer> + <layer + name="leftleg_tattoo"> + <texture + local_texture="leftleg_tattoo" /> + <param + id="1217" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_leftleg_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1218" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_leftleg_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1219" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_leftleg_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="aux1" + width="512" + height="512" + clear_alpha="false"> + + <layer + name="base" + write_all_channels="true" + fixed_color = "128,128,128,255"> + <texture + tga_file="aux_base.tga" /> + </layer> + + <layer + name="aux1_tattoo"> + <texture + local_texture="aux1_tattoo" /> + <param + id="1220" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux1_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1221" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux1_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1222" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux1_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="aux2" + width="512" + height="512" + clear_alpha="false"> + + <layer + name="base" + write_all_channels="true" + fixed_color = "128,128,128,255"> + <texture + tga_file="aux_base.tga" /> + </layer> + + <layer + name="aux2_tattoo"> + <texture + local_texture="aux2_tattoo" /> + <param + id="1223" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux2_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1224" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux2_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1225" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux2_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> + + </layer_set> + + <!-- =========================================================== --> + <layer_set + body_region="aux3" + width="512" + height="512" + clear_alpha="false"> + + <layer + name="base" + write_all_channels="true" + fixed_color = "128,128,128,255"> + <texture + tga_file="aux_base.tga" /> + </layer> + + <layer + name="aux3_tattoo"> + <texture + local_texture="aux3_tattoo" /> + <param + id="1226" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux3_red" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="255, 0, 0, 255" /> + </param_color> + </param> + + <param + id="1227" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux3_green" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 255, 0, 255" /> + </param_color> + </param> + + <param + id="1228" + group="1" + edit_group="colorpicker_driven" + wearable="universal" + name="tattoo_aux3_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_color> + <value + color="0, 0, 0, 255" /> + + <value + color="0, 0, 255, 255" /> + </param_color> + </param> + + </layer> </layer_set> @@ -15934,7 +16669,277 @@ render_pass="bump"> </param_driver> </param> + <param + id="1238" + group="2" + wearable="universal" + edit_group="colorpicker" + name="tattoo_universal_red" + value_min="0" + value_max="1" + value_default="1"> + <param_driver> + <driven + id="1229" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1232" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1235" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1208" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1211" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="924" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1214" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1217" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1220" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1223" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1226" + min1="0" + max1="1" + max2="1" + min2="1" /> + + </param_driver> + </param> + + <param + id="1239" + group="2" + wearable="universal" + edit_group="colorpicker" + name="tattoo_universal_green" + value_min="0" + value_max="1" + value_default="1"> + <param_driver> + <driven + id="1230" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1233" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1236" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1209" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1212" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="925" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1215" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1218" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1221" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1224" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1227" + min1="0" + max1="1" + max2="1" + min2="1" /> + + </param_driver> + </param> + + <param + id="1240" + group="2" + wearable="universal" + edit_group="colorpicker" + name="tattoo_universal_blue" + value_min="0" + value_max="1" + value_default="1"> + <param_driver> + <driven + id="1231" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1234" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1237" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1210" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1213" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="926" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1216" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1219" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1222" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1225" + min1="0" + max1="1" + max2="1" + min2="1" /> + + <driven + id="1228" + min1="0" + max1="1" + max2="1" + min2="1" /> + + </param_driver> + </param> <!-- ==PHYSICS PARAMETERS======================================= --> + <param id="1100" diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index d1d5301efe..8838b6d0be 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -346,6 +346,11 @@ Call CheckWillUninstallV2 # Check if Second Life is already installed StrCmp $DO_UNINSTALL_V2 "" PRESERVE_DONE
PRESERVE_DONE:
+# Viewer had "SLLauncher" for some time and we was seting "IsHostApp" for viewer, make sure to clean it up
+DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp"
+DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage"
+ClearErrors
+
Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer
# This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py
@@ -417,7 +422,7 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$ # URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
-WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" ""
+WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
# Write out uninstaller
@@ -464,7 +469,7 @@ DeleteRegKey SHELL_CONTEXT "${INSTNAME_KEY}" DeleteRegKey SHELL_CONTEXT "${MSCURRVER_KEY}\Uninstall\$INSTNAME"
# BUG-2707 Remove entry that disabled SEHOP
DeleteRegKey SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE"
-##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
+DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
# Clean up shortcuts
diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi Binary files differindex 8bb20476b3..eebcf027a8 100755 --- a/indra/newview/installers/windows/lang_de.nsi +++ b/indra/newview/installers/windows/lang_de.nsi diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index ba250fa471..8b2d591da5 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -24,6 +24,7 @@ * $/LicenseInfo$ */ + #include "llviewerprecompiledheaders.h" #include "llagent.h" @@ -742,7 +743,7 @@ BOOL LLAgent::getFlying() const //----------------------------------------------------------------------------- // setFlying() //----------------------------------------------------------------------------- -void LLAgent::setFlying(BOOL fly) +void LLAgent::setFlying(BOOL fly, BOOL fail_sound) { if (isAgentAvatarValid()) { @@ -771,7 +772,10 @@ void LLAgent::setFlying(BOOL fly) // parcel doesn't let you start fly // gods can always fly // and it's OK if you're already flying - make_ui_sound("UISndBadKeystroke"); + if (fail_sound) + { + make_ui_sound("UISndBadKeystroke"); + } return; } if( !was_flying ) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index b1b39b637e..ea6f68c482 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -337,7 +337,7 @@ private: //-------------------------------------------------------------------- public: BOOL getFlying() const; - void setFlying(BOOL fly); + void setFlying(BOOL fly, BOOL fail_sound = FALSE); static void toggleFlying(); static bool enableFlying(); BOOL canFly(); // Does this parcel allow you to fly? diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 170e4063a1..15e4de8f69 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1538,6 +1538,12 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con { if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; + if (type == LLWearableType::WT_UNIVERSAL && !gAgent.getRegion()->bakesOnMeshEnabled()) + { + LL_WARNS("Inventory") << "Can't create WT_UNIVERSAL type " << LL_ENDL; + return; + } + LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp); LLAssetType::EType asset_type = wearable->getAssetType(); LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 56e8cc8ff4..be5611899a 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2439,9 +2439,9 @@ bool LLAppViewer::initConfiguration() bool set_defaults = true; if(!loadSettingsFromDirectory("Default", set_defaults)) { - std::ostringstream msg; - msg << "Unable to load default settings file. The installation may be corrupted."; - OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK); + OSMessageBox( + "Unable to load default settings file. The installation may be corrupted.", + LLStringUtil::null,OSMB_OK); return false; } @@ -2562,7 +2562,7 @@ bool LLAppViewer::initConfiguration() if(gSavedSettings.getBOOL("DisableCrashLogger")) { LL_WARNS() << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << LL_ENDL; - LLAppViewer::instance()->disableCrashlogger(); + disableCrashlogger(); } // Handle initialization from settings. @@ -2579,7 +2579,7 @@ bool LLAppViewer::initConfiguration() LL_INFOS() << msg.str() << LL_ENDL; OSMessageBox( - msg.str().c_str(), + msg.str(), LLStringUtil::null, OSMB_OK); @@ -2689,7 +2689,34 @@ bool LLAppViewer::initConfiguration() ll_init_fail_log(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "test_failures.log")); } + const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); + if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) + { + // Examining "Language" may not suffice -- see LLUI::getLanguage() + // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much + // good because we haven't yet called LLUI::initClass(). + gDirUtilp->setSkinFolder(skinfolder->getValue().asString(), + gSavedSettings.getString("Language")); + } + + if (gSavedSettings.getBOOL("SpellCheck")) + { + std::list<std::string> dict_list; + std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); + boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); + if (!dict_list.empty()) + { + LLSpellChecker::setUseSpellCheck(dict_list.front()); + dict_list.pop_front(); + LLSpellChecker::instance().setSecondaryDictionaries(dict_list); + } + } + // Handle slurl use. NOTE: Don't let SL-55321 reappear. + // This initial-SLURL logic, up through the call to + // sendURLToOtherInstance(), must precede LLSplashScreen::show() -- + // because if sendURLToOtherInstance() succeeds, we take a fast exit, + // SKIPPING the splash screen and everything else. // *FIX: This init code should be made more robust to prevent // the issue SL-55321 from returning. One thought is to allow @@ -2734,6 +2761,27 @@ bool LLAppViewer::initConfiguration() } } + // NextLoginLocation is set as a side effect of LLStartUp::setStartSLURL() + std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); + if ( !nextLoginLocation.empty() ) + { + LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL; + LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation)); + } + else if ( ( clp.hasOption("login") || clp.hasOption("autologin")) + && gSavedSettings.getString("CmdLineLoginLocation").empty()) + { + // If automatic login from command line with --login switch + // init StartSLURL location. + std::string start_slurl_setting = gSavedSettings.getString("LoginLocation"); + LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL; + LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting)); + } + else + { + // the login location will be set by the login panel (see LLPanelLogin) + } + //RN: if we received a URL, hand it off to the existing instance. // don't call anotherInstanceRunning() when doing URL handoff, as // it relies on checking a marker file which will not work when running @@ -2749,30 +2797,6 @@ bool LLAppViewer::initConfiguration() } } - const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); - if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) - { - // Examining "Language" may not suffice -- see LLUI::getLanguage() - // logic. Unfortunately LLUI::getLanguage() doesn't yet do us much - // good because we haven't yet called LLUI::initClass(). - gDirUtilp->setSkinFolder(skinfolder->getValue().asString(), - gSavedSettings.getString("Language")); - } - - if (gSavedSettings.getBOOL("SpellCheck")) - { - std::list<std::string> dict_list; - std::string dict_setting = gSavedSettings.getString("SpellCheckDictionary"); - boost::split(dict_list, dict_setting, boost::is_any_of(std::string(","))); - if (!dict_list.empty()) - { - LLSpellChecker::setUseSpellCheck(dict_list.front()); - dict_list.pop_front(); - LLSpellChecker::instance().setSecondaryDictionaries(dict_list); - } - } - - // Display splash screen. Must be after above check for previous // crash as this dialog is always frontmost. std::string splash_msg; @@ -2804,30 +2828,15 @@ bool LLAppViewer::initConfiguration() } LLStringUtil::truncate(gWindowTitle, 255); - //RN: if we received a URL, hand it off to the existing instance. - // don't call anotherInstanceRunning() when doing URL handoff, as - // it relies on checking a marker file which will not work when running - // out of different directories - - if (LLStartUp::getStartSLURL().isValid() && - (gSavedSettings.getBOOL("SLURLPassToOtherInstance"))) - { - if (sendURLToOtherInstance(LLStartUp::getStartSLURL().getSLURLString())) - { - // successfully handed off URL to existing instance, exit - return false; - } - } - // // Check for another instance of the app running + // This happens AFTER LLSplashScreen::show(). That may or may not be + // important. // if (mSecondInstance && !gSavedSettings.getBOOL("AllowMultipleViewers")) { - std::ostringstream msg; - msg << LLTrans::getString("MBAlreadyRunning"); OSMessageBox( - msg.str(), + LLTrans::getString("MBAlreadyRunning"), LLStringUtil::null, OSMB_OK); return false; @@ -2845,27 +2854,6 @@ bool LLAppViewer::initConfiguration() } } - // NextLoginLocation is set from the command line option - std::string nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); - if ( !nextLoginLocation.empty() ) - { - LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL; - LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation)); - } - else if ( ( clp.hasOption("login") || clp.hasOption("autologin")) - && gSavedSettings.getString("CmdLineLoginLocation").empty()) - { - // If automatic login from command line with --login switch - // init StartSLURL location. - std::string start_slurl_setting = gSavedSettings.getString("LoginLocation"); - LL_DEBUGS("AppInit") << "start slurl setting '" << start_slurl_setting << "'" << LL_ENDL; - LLStartUp::setStartSLURL(LLSLURL(start_slurl_setting)); - } - else - { - // the login location will be set by the login panel (see LLPanelLogin) - } - gLastRunVersion = gSavedSettings.getString("LastRunVersion"); loadColorSettings(); @@ -2889,7 +2877,14 @@ bool LLAppViewer::initConfiguration() // keeps growing, necessitating a method all its own. void LLAppViewer::initStrings() { - LLTransUtil::parseStrings("strings.xml", default_trans_args); + std::string strings_file = "strings.xml"; + std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file); + if (strings_path_full.empty() || !LLFile::isfile(strings_path_full)) + { + // initial check to make sure files are there failed + LL_ERRS() << "Viewer failed to find localization and UI files. Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL; + } + LLTransUtil::parseStrings(strings_file, default_trans_args); LLTransUtil::parseLanguageStrings("language_settings.xml"); // parseStrings() sets up the LLTrans substitution table. Add this one item. @@ -3174,6 +3169,10 @@ LLSD LLAppViewer::getViewerInfo() const substitution["datetime"] = (S32)(gVFS ? gVFS->creationTime() : 0); info["VFS_TIME"] = LLTrans::getString("AboutTime", substitution); +#if LL_DARWIN + info["HIDPI"] = gHiDPISupport; +#endif + // Libraries info["J2C_VERSION"] = LLImageJ2C::getEngineInfo(); @@ -3316,6 +3315,9 @@ std::string LLAppViewer::getViewerInfoString(bool default_string) const } support << "\n" << LLTrans::getString("AboutOGL", args, default_string); support << "\n\n" << LLTrans::getString("AboutSettings", args, default_string); +#if LL_DARWIN + support << "\n" << LLTrans::getString("AboutOSXHiDPI", args, default_string); +#endif support << "\n\n" << LLTrans::getString("AboutLibs", args, default_string); if (info.has("COMPILER")) { diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 90a5483dc9..fe14bc081f 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -374,12 +374,40 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv) bool LLCommandLineParser::parseCommandLineString(const std::string& str) { + std::string cmd_line_string(""); + if (!str.empty()) + { + bool add_last_c = true; + S32 last_c_pos = str.size() - 1; //don't get out of bounds on pos+1, last char will be processed separately + for (S32 pos = 0; pos < last_c_pos; ++pos) + { + cmd_line_string.append(&str[pos], 1); + if (str[pos] == '\\') + { + cmd_line_string.append("\\", 1); + if (str[pos + 1] == '\\') + { + ++pos; + add_last_c = (pos != last_c_pos); + } + } + } + if (add_last_c) + { + cmd_line_string.append(&str[last_c_pos], 1); + if (str[last_c_pos] == '\\') + { + cmd_line_string.append("\\", 1); + } + } + } + // Split the string content into tokens - const char* escape_chars = "\\"; - const char* separator_chars = "\r\n "; - const char* quote_chars = "\"'"; + const char* escape_chars = "\\"; + const char* separator_chars = "\r\n "; + const char* quote_chars = "\"'"; boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars); - boost::tokenizer< boost::escaped_list_separator<char> > tok(str, sep); + boost::tokenizer< boost::escaped_list_separator<char> > tok(cmd_line_string, sep); std::vector<std::string> tokens; // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens)); for(boost::tokenizer< boost::escaped_list_separator<char> >::iterator i = tok.begin(); diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp index 0f02c23cb0..d24dac385f 100644 --- a/indra/newview/llcontrolavatar.cpp +++ b/indra/newview/llcontrolavatar.cpp @@ -566,27 +566,49 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV LLVector4a* normal, LLVector4a* tangent) { - LLViewerObject* hit = NULL; + if (!mRootVolp) + { + return NULL; + } - if (lineSegmentBoundingBox(start, end)) - { - LLVector4a local_end = end; - LLVector4a local_intersection; + LLViewerObject* hit = NULL; - if (mRootVolp && - mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent)) + if (lineSegmentBoundingBox(start, end)) + { + LLVector4a local_end = end; + LLVector4a local_intersection; + if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent)) { local_end = local_intersection; if (intersection) { *intersection = local_intersection; } - hit = mRootVolp; } - } - - return hit; + else + { + std::vector<LLVOVolume*> volumes; + getAnimatedVolumes(volumes); + + for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it) + { + LLVOVolume *volp = *vol_it; + if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent)) + { + local_end = local_intersection; + if (intersection) + { + *intersection = local_intersection; + } + hit = volp; + break; + } + } + } + } + + return hit; } // virtual diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b2da5bb9f8..912bde9986 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -608,15 +608,10 @@ void renderFace(LLDrawable* drawable, LLFace *face) LLVOVolume* vobj = drawable->getVOVolume(); if (vobj) { - LLVertexBuffer::unbind(); - gGL.pushMatrix(); - gGL.multMatrix((F32*)vobj->getRelativeXform().mMatrix); - LLVolume* volume = NULL; if (drawable->isState(LLDrawable::RIGGED)) { - vobj->updateRiggedVolume(); volume = vobj->getRiggedVolume(); } else @@ -629,44 +624,11 @@ void renderFace(LLDrawable* drawable, LLFace *face) const LLVolumeFace& vol_face = volume->getVolumeFace(face->getTEOffset()); LLVertexBuffer::drawElements(LLRender::TRIANGLES, vol_face.mPositions, NULL, vol_face.mNumIndices, vol_face.mIndices); } - - gGL.popMatrix(); } } -void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wireframe_selection, bool bRenderHiddenSelections) +void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wireframe_selection, bool bRenderHiddenSelections, bool shader) { - //Need to because crash on ATI 3800 (and similar cards) MAINT-5018 - LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (shader) - { - gDebugProgram.bind(); - } - - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - - BOOL is_hud_object = mVObjp->isHUDAttachment(); - - if (mDrawablep->isActive()) - { - gGL.loadMatrix(gGLModelView); - gGL.multMatrix((F32*)mVObjp->getRenderMatrix().mMatrix); - } - else if (!is_hud_object) - { - gGL.loadIdentity(); - gGL.multMatrix(gGLModelView); - LLVector3 trans = mVObjp->getRegion()->getOriginAgent(); - gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); - } - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - if (bRenderHiddenSelections) { gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE); @@ -715,15 +677,6 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); renderFace(mDrawablep, this); } - - glLineWidth(1.f); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - gGL.popMatrix(); - - if (shader) - { - shader->bind(); - } } /* removed in lieu of raycast uv detection @@ -1106,7 +1059,7 @@ void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_po // Returns the necessary texture transform to align this face's TE to align_to's TE bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offset, - LLVector2* res_st_scale, F32* res_st_rot) const + LLVector2* res_st_scale, F32* res_st_rot, LLRender::eTexIndex map) const { if (!align_to) { @@ -1119,6 +1072,43 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs return false; } + F32 map_rot = 0.f, map_scaleS = 0.f, map_scaleT = 0.f, map_offsS = 0.f, map_offsT = 0.f; + + switch (map) + { + case LLRender::DIFFUSE_MAP: + map_rot = orig_tep->getRotation(); + map_scaleS = orig_tep->mScaleS; + map_scaleT = orig_tep->mScaleT; + map_offsS = orig_tep->mOffsetS; + map_offsT = orig_tep->mOffsetT; + break; + case LLRender::NORMAL_MAP: + if (orig_tep->getMaterialParams()->getNormalID().isNull()) + { + return false; + } + map_rot = orig_tep->getMaterialParams()->getNormalRotation(); + map_scaleS = orig_tep->getMaterialParams()->getNormalRepeatX(); + map_scaleT = orig_tep->getMaterialParams()->getNormalRepeatY(); + map_offsS = orig_tep->getMaterialParams()->getNormalOffsetX(); + map_offsT = orig_tep->getMaterialParams()->getNormalOffsetY(); + break; + case LLRender::SPECULAR_MAP: + if (orig_tep->getMaterialParams()->getSpecularID().isNull()) + { + return false; + } + map_rot = orig_tep->getMaterialParams()->getSpecularRotation(); + map_scaleS = orig_tep->getMaterialParams()->getSpecularRepeatX(); + map_scaleT = orig_tep->getMaterialParams()->getSpecularRepeatY(); + map_offsS = orig_tep->getMaterialParams()->getSpecularOffsetX(); + map_offsT = orig_tep->getMaterialParams()->getSpecularOffsetY(); + break; + default: /*make compiler happy*/ + break; + } + LLVector3 orig_pos, this_pos; LLQuaternion orig_face_rot, this_face_rot; F32 orig_proj_scale, this_proj_scale; @@ -1126,7 +1116,7 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs getPlanarProjectedParams(&this_face_rot, &this_pos, &this_proj_scale); // The rotation of "this face's" texture: - LLQuaternion orig_st_rot = LLQuaternion(orig_tep->getRotation(), LLVector3::z_axis) * orig_face_rot; + LLQuaternion orig_st_rot = LLQuaternion(map_rot, LLVector3::z_axis) * orig_face_rot; LLQuaternion this_st_rot = orig_st_rot * ~this_face_rot; F32 x_ang, y_ang, z_ang; this_st_rot.getEulerAngles(&x_ang, &y_ang, &z_ang); @@ -1134,10 +1124,10 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs // Offset and scale of "this face's" texture: LLVector3 centers_dist = (this_pos - orig_pos) * ~orig_st_rot; - LLVector3 st_scale(orig_tep->mScaleS, orig_tep->mScaleT, 1.f); + LLVector3 st_scale(map_scaleS, map_scaleT, 1.f); st_scale *= orig_proj_scale; centers_dist.scaleVec(st_scale); - LLVector2 orig_st_offset(orig_tep->mOffsetS, orig_tep->mOffsetT); + LLVector2 orig_st_offset(map_offsS, map_offsT); *res_st_offset = orig_st_offset + (LLVector2)centers_dist; res_st_offset->mV[VX] -= (S32)res_st_offset->mV[VX]; diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 736d45b7ad..a08e730e54 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -114,7 +114,7 @@ public: LLVector2 surfaceToTexture(LLVector2 surface_coord, const LLVector4a& position, const LLVector4a& normal); void getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const; bool calcAlignedPlanarTE(const LLFace* align_to, LLVector2* st_offset, - LLVector2* st_scale, F32* st_rot) const; + LLVector2* st_scale, F32* st_rot, LLRender::eTexIndex map = LLRender::DIFFUSE_MAP) const; U32 getState() const { return mState; } void setState(U32 state) { mState |= state; } @@ -198,7 +198,7 @@ public: void renderSelectedUV(); void renderSelected(LLViewerTexture *image, const LLColor4 &color); - void renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wireframe_selection, bool bRenderHiddenSelections); + void renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wireframe_selection, bool bRenderHiddenSelections, bool shader); F32 getKey() const { return mDistance; } diff --git a/indra/newview/llfacebookconnect.cpp b/indra/newview/llfacebookconnect.cpp deleted file mode 100644 index 43b01fa2f1..0000000000 --- a/indra/newview/llfacebookconnect.cpp +++ /dev/null @@ -1,714 +0,0 @@ -/** - * @file llfacebookconnect.h - * @author Merov, Cho, Gil - * @brief Connection to Facebook Service - * - * $LicenseInfo:firstyear=2013&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2013, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfacebookconnect.h" -#include "llflickrconnect.h" -#include "lltwitterconnect.h" - -#include "llagent.h" -#include "llcallingcard.h" // for LLAvatarTracker -#include "llcommandhandler.h" -#include "llnotificationsutil.h" -#include "llurlaction.h" -#include "llimagepng.h" -#include "llimagejpeg.h" -#include "lltrans.h" -#include "llevents.h" -#include "llviewerregion.h" -#include "llviewercontrol.h" - -#include "llfloaterwebcontent.h" -#include "llfloaterreg.h" -#include "llcorehttputil.h" - -boost::scoped_ptr<LLEventPump> LLFacebookConnect::sStateWatcher(new LLEventStream("FacebookConnectState")); -boost::scoped_ptr<LLEventPump> LLFacebookConnect::sInfoWatcher(new LLEventStream("FacebookConnectInfo")); -boost::scoped_ptr<LLEventPump> LLFacebookConnect::sContentWatcher(new LLEventStream("FacebookConnectContent")); - -// Local functions -void log_facebook_connect_error(const std::string& request, U32 status, const std::string& reason, const std::string& code, const std::string& description) -{ - // Note: 302 (redirect) is *not* an error that warrants logging - if (status != 302) - { - LL_WARNS("FacebookConnect") << request << " request failed with a " << status << " " << reason << ". Reason: " << code << " (" << description << ")" << LL_ENDL; - } -} - -void toast_user_for_facebook_success() -{ - LLSD args; - args["MESSAGE"] = LLTrans::getString("facebook_post_success"); - LLNotificationsUtil::add("FacebookConnect", args); -} - -LLCore::HttpHeaders::ptr_t get_headers() -{ - LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders); - // The DebugSlshareLogTag mechanism is intended to trigger slshare-service - // debug logging. slshare-service is coded to respond to an X-debug-tag - // header by engaging debug logging for that request only. This way a - // developer need not muck with the slshare-service image to engage debug - // logging. Moreover, the value of X-debug-tag is embedded in each such - // log line so the developer can quickly find the log lines pertinent to - // THIS session. - std::string logtag(gSavedSettings.getString("DebugSlshareLogTag")); - if (! logtag.empty()) - { - httpHeaders->append("X-debug-tag", logtag); - } - return httpHeaders; -} - -/////////////////////////////////////////////////////////////////////////////// -// -class LLFacebookConnectHandler : public LLCommandHandler -{ -public: - LLFacebookConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) { } - - bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) - { - if (tokens.size() >= 1) - { - if (tokens[0].asString() == "connect") - { - if (tokens.size() >= 2 && tokens[1].asString() == "flickr") - { - // this command probably came from the flickr_web browser, so close it - LLFloaterReg::hideInstance("flickr_web"); - - // connect to flickr - if (query_map.has("oauth_token")) - { - LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier")); - } - return true; - } - else if (tokens.size() >= 2 && tokens[1].asString() == "twitter") - { - // this command probably came from the twitter_web browser, so close it - LLFloaterReg::hideInstance("twitter_web"); - - // connect to twitter - if (query_map.has("oauth_token")) - { - LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier")); - } - return true; - } - else //if (tokens.size() >= 2 && tokens[1].asString() == "facebook") - { - // this command probably came from the fbc_web browser, so close it - LLFloaterReg::hideInstance("fbc_web"); - - // connect to facebook - if (query_map.has("code")) - { - LLFacebookConnect::instance().connectToFacebook(query_map["code"], query_map.get("state")); - } - return true; - } - } - } - return false; - } -}; -LLFacebookConnectHandler gFacebookConnectHandler; - -/////////////////////////////////////////////////////////////////////////////// -// -void LLFacebookConnect::facebookConnectCoro(std::string authCode, std::string authState) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - - LLSD putData; - if (!authCode.empty()) - { - putData["code"] = authCode; - } - if (!authState.empty()) - { - putData["state"] = authState; - } - - httpOpts->setWantHeaders(true); - httpOpts->setFollowRedirects(false); - - LLSD result = httpAdapter->putAndSuspend(httpRequest, getFacebookConnectURL("/connection"), putData, httpOpts, get_headers()); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - if (!status) - { - if (status == LLCore::HttpStatus(HTTP_FOUND)) - { - std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; - if (location.empty()) - { - LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; - } - else - { - openFacebookWeb(location); - } - } - } - else - { - LL_INFOS("FacebookConnect") << "Connect successful. " << LL_ENDL; - setConnectionState(LLFacebookConnect::FB_CONNECTED); - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// -bool LLFacebookConnect::testShareStatus(LLSD &result) -{ - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (status) - return true; - - if (status == LLCore::HttpStatus(HTTP_FOUND)) - { - std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; - if (location.empty()) - { - LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; - } - else - { - openFacebookWeb(location); - } - } - if (status == LLCore::HttpStatus(HTTP_NOT_FOUND)) - { - LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL; - connectToFacebook(); - } - else - { - LL_WARNS("FacebookConnect") << "HTTP Status error " << status.toString() << LL_ENDL; - setConnectionState(LLFacebookConnect::FB_POST_FAILED); - log_facebook_connect_error("Share", status.getStatus(), status.toString(), - result.get("error_code"), result.get("error_description")); - } - return false; -} - -void LLFacebookConnect::facebookShareCoro(std::string route, LLSD share) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - - httpOpts->setWantHeaders(true); - httpOpts->setFollowRedirects(false); - - LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), share, httpOpts, get_headers()); - - if (testShareStatus(result)) - { - toast_user_for_facebook_success(); - LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL; - setConnectionState(LLFacebookConnect::FB_POSTED); - } -} - -void LLFacebookConnect::facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpHeaders::ptr_t httpHeaders(get_headers()); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - - httpOpts->setWantHeaders(true); - httpOpts->setFollowRedirects(false); - - std::string imageFormat; - if (dynamic_cast<LLImagePNG*>(image.get())) - { - imageFormat = "png"; - } - else if (dynamic_cast<LLImageJPEG*>(image.get())) - { - imageFormat = "jpg"; - } - else - { - LL_WARNS() << "Image to upload is not a PNG or JPEG" << LL_ENDL; - return; - } - - // All this code is mostly copied from LLWebProfile::post() - static const std::string boundary = "----------------------------0123abcdefab"; - - std::string contentType = "multipart/form-data; boundary=" + boundary; - httpHeaders->append("Content-Type", contentType.c_str()); - - LLCore::BufferArray::ptr_t raw = LLCore::BufferArray::ptr_t(new LLCore::BufferArray()); // - LLCore::BufferArrayStream body(raw.get()); - - // *NOTE: The order seems to matter. - body << "--" << boundary << "\r\n" - << "Content-Disposition: form-data; name=\"caption\"\r\n\r\n" - << caption << "\r\n"; - - body << "--" << boundary << "\r\n" - << "Content-Disposition: form-data; name=\"image\"; filename=\"Untitled." << imageFormat << "\"\r\n" - << "Content-Type: image/" << imageFormat << "\r\n\r\n"; - - // Insert the image data. - // *FIX: Treating this as a string will probably screw it up ... - U8* image_data = image->getData(); - for (S32 i = 0; i < image->getDataSize(); ++i) - { - body << image_data[i]; - } - - body << "\r\n--" << boundary << "--\r\n"; - - setConnectionState(LLFacebookConnect::FB_POSTING); - - LLSD result = httpAdapter->postAndSuspend(httpRequest, getFacebookConnectURL(route, true), raw, httpOpts, httpHeaders); - - if (testShareStatus(result)) - { - toast_user_for_facebook_success(); - LL_DEBUGS("FacebookConnect") << "Post successful. " << LL_ENDL; - setConnectionState(LLFacebookConnect::FB_POSTED); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// -void LLFacebookConnect::facebookDisconnectCoro() -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - - httpOpts->setFollowRedirects(false); - - LLSD result = httpAdapter->deleteAndSuspend(httpRequest, getFacebookConnectURL("/connection"), httpOpts, get_headers()); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - if (!status && (status != LLCore::HttpStatus(HTTP_FOUND))) - { - LL_WARNS("FacebookConnect") << "Failed to disconnect:" << status.toTerseString() << LL_ENDL; - setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED); - log_facebook_connect_error("Disconnect", status.getStatus(), status.toString(), - result.get("error_code"), result.get("error_description")); - } - else - { - LL_DEBUGS("FacebookConnect") << "Facebook Disconnect successful. " << LL_ENDL; - clearInfo(); - clearContent(); - //Notify state change - setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED); - } - -} - -/////////////////////////////////////////////////////////////////////////////// -// -void LLFacebookConnect::facebookConnectedCheckCoro(bool autoConnect) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - - setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS); - - httpOpts->setFollowRedirects(false); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/connection", true), httpOpts, get_headers()); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - if ( status == LLCore::HttpStatus(HTTP_NOT_FOUND) ) - { - LL_DEBUGS("FacebookConnect") << "Not connected. " << LL_ENDL; - if (autoConnect) - { - connectToFacebook(); - } - else - { - setConnectionState(LLFacebookConnect::FB_NOT_CONNECTED); - } - } - else - { - LL_WARNS("FacebookConnect") << "Failed to test connection:" << status.toTerseString() << LL_ENDL; - - setConnectionState(LLFacebookConnect::FB_DISCONNECT_FAILED); - log_facebook_connect_error("Connected", status.getStatus(), status.toString(), - result.get("error_code"), result.get("error_description")); - } - } - else - { - LL_DEBUGS("FacebookConnect") << "Connect successful. " << LL_ENDL; - setConnectionState(LLFacebookConnect::FB_CONNECTED); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// -void LLFacebookConnect::facebookConnectInfoCoro() -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - - httpOpts->setWantHeaders(true); - httpOpts->setFollowRedirects(false); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/info", true), httpOpts, get_headers()); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (status == LLCore::HttpStatus(HTTP_FOUND)) - { - std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; - if (location.empty()) - { - LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; - } - else - { - openFacebookWeb(location); - } - } - else if (!status) - { - LL_WARNS("FacebookConnect") << "Facebook Info failed: " << status.toString() << LL_ENDL; - log_facebook_connect_error("Info", status.getStatus(), status.toString(), - result.get("error_code"), result.get("error_description")); - } - else - { - LL_INFOS("FacebookConnect") << "Facebook: Info received" << LL_ENDL; - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - storeInfo(result); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// -void LLFacebookConnect::facebookConnectFriendsCoro() -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("FacebookConnect", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - - httpOpts->setFollowRedirects(false); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, getFacebookConnectURL("/friends", true), httpOpts, get_headers()); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (status == LLCore::HttpStatus(HTTP_FOUND)) - { - std::string location = httpResults[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS][HTTP_IN_HEADER_LOCATION]; - if (location.empty()) - { - LL_WARNS("FacebookConnect") << "Missing Location header " << LL_ENDL; - } - else - { - openFacebookWeb(location); - } - } - else if (!status) - { - LL_WARNS("FacebookConnect") << "Facebook Friends failed: " << status.toString() << LL_ENDL; - log_facebook_connect_error("Info", status.getStatus(), status.toString(), - result.get("error_code"), result.get("error_description")); - } - else - { - LL_INFOS("FacebookConnect") << "Facebook: Friends received" << LL_ENDL; - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - LLSD content = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT]; - storeContent(content); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// -LLFacebookConnect::LLFacebookConnect() -: mConnectionState(FB_NOT_CONNECTED), - mConnected(false), - mInfo(), - mContent(), - mRefreshInfo(false), - mRefreshContent(false), - mReadFromMaster(false) -{ -} - -void LLFacebookConnect::openFacebookWeb(std::string url) -{ - LLFloaterWebContent::Params p; - p.url(url); - p.show_chrome(true); - p.allow_back_forward_navigation(false); - p.clean_browser(true); - LLFloater *floater = LLFloaterReg::showInstance("fbc_web", p); - //the internal web browser has a bug that prevents it from gaining focus unless a mouse event occurs first (it seems). - //So when showing the internal web browser, set focus to it's containing floater "fbc_web". When a mouse event - //occurs on the "webbrowser" panel part of the floater, a mouse cursor will properly show and the "webbrowser" will gain focus. - //fbc_web floater contains the "webbrowser" panel. JIRA: ACME-744 - gFocusMgr.setKeyboardFocus( floater ); - - //LLUrlAction::openURLExternal(url); -} - -std::string LLFacebookConnect::getFacebookConnectURL(const std::string& route, bool include_read_from_master) -{ - std::string url(""); - LLViewerRegion *regionp = gAgent.getRegion(); - if (regionp) - { - //url = "http://pdp15.lindenlab.com/fbc/agent/" + gAgentID.asString(); // TEMPORARY FOR TESTING - CHO - url = regionp->getCapability("FacebookConnect"); - url += route; - - if (include_read_from_master && mReadFromMaster) - { - url += "?read_from_master=true"; - } - } - return url; -} - -void LLFacebookConnect::connectToFacebook(const std::string& auth_code, const std::string& auth_state) -{ - setConnectionState(LLFacebookConnect::FB_CONNECTION_IN_PROGRESS); - - LLCoros::instance().launch("LLFacebookConnect::facebookConnectCoro", - boost::bind(&LLFacebookConnect::facebookConnectCoro, this, auth_code, auth_state)); -} - -void LLFacebookConnect::disconnectFromFacebook() -{ - LLCoros::instance().launch("LLFacebookConnect::facebookDisconnectCoro", - boost::bind(&LLFacebookConnect::facebookDisconnectCoro, this)); -} - -void LLFacebookConnect::checkConnectionToFacebook(bool auto_connect) -{ - setConnectionState(LLFacebookConnect::FB_DISCONNECTING); - - LLCoros::instance().launch("LLFacebookConnect::facebookConnectedCheckCoro", - boost::bind(&LLFacebookConnect::facebookConnectedCheckCoro, this, auto_connect)); -} - -void LLFacebookConnect::loadFacebookInfo() -{ - if(mRefreshInfo) - { - LLCoros::instance().launch("LLFacebookConnect::facebookConnectInfoCoro", - boost::bind(&LLFacebookConnect::facebookConnectInfoCoro, this)); - } -} - -void LLFacebookConnect::loadFacebookFriends() -{ - if(mRefreshContent) - { - LLCoros::instance().launch("LLFacebookConnect::facebookConnectFriendsCoro", - boost::bind(&LLFacebookConnect::facebookConnectFriendsCoro, this)); - } -} - -void LLFacebookConnect::postCheckin(const std::string& location, const std::string& name, - const std::string& description, const std::string& image, const std::string& message) -{ - setConnectionState(LLFacebookConnect::FB_POSTING); - - LLSD body; - if (!location.empty()) - { - body["location"] = location; - } - if (!name.empty()) - { - body["name"] = name; - } - if (!description.empty()) - { - body["description"] = description; - } - if (!image.empty()) - { - body["image"] = image; - } - if (!message.empty()) - { - body["message"] = message; - } - - LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro", - boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/checkin", body)); -} - -void LLFacebookConnect::sharePhoto(const std::string& image_url, const std::string& caption) -{ - setConnectionState(LLFacebookConnect::FB_POSTING); - - LLSD body; - body["image"] = image_url; - body["caption"] = caption; - - LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro", - boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/photo", body)); -} - -void LLFacebookConnect::sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption) -{ - setConnectionState(LLFacebookConnect::FB_POSTING); - - LLCoros::instance().launch("LLFacebookConnect::facebookShareImageCoro", - boost::bind(&LLFacebookConnect::facebookShareImageCoro, this, "/share/photo", image, caption)); -} - -void LLFacebookConnect::updateStatus(const std::string& message) -{ - LLSD body; - body["message"] = message; - - setConnectionState(LLFacebookConnect::FB_POSTING); - - LLCoros::instance().launch("LLFacebookConnect::facebookShareCoro", - boost::bind(&LLFacebookConnect::facebookShareCoro, this, "/share/wall", body)); -} - -void LLFacebookConnect::storeInfo(const LLSD& info) -{ - mInfo = info; - mRefreshInfo = false; - - sInfoWatcher->post(info); -} - -const LLSD& LLFacebookConnect::getInfo() const -{ - return mInfo; -} - -void LLFacebookConnect::clearInfo() -{ - mInfo = LLSD(); -} - -void LLFacebookConnect::storeContent(const LLSD& content) -{ - mContent = content; - mRefreshContent = false; - - sContentWatcher->post(content); -} - -const LLSD& LLFacebookConnect::getContent() const -{ - return mContent; -} - -void LLFacebookConnect::clearContent() -{ - mContent = LLSD(); -} - -void LLFacebookConnect::setDataDirty() -{ - mRefreshInfo = true; - mRefreshContent = true; -} - -void LLFacebookConnect::setConnectionState(LLFacebookConnect::EConnectionState connection_state) -{ - if(connection_state == FB_CONNECTED) - { - mReadFromMaster = true; - setConnected(true); - setDataDirty(); - } - else if(connection_state == FB_NOT_CONNECTED) - { - setConnected(false); - } - else if(connection_state == FB_POSTED) - { - mReadFromMaster = false; - } - - if (mConnectionState != connection_state) - { - // set the connection state before notifying watchers - mConnectionState = connection_state; - - LLSD state_info; - state_info["enum"] = connection_state; - sStateWatcher->post(state_info); - } -} - -void LLFacebookConnect::setConnected(bool connected) -{ - mConnected = connected; -} diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h deleted file mode 100644 index 7fd4070f54..0000000000 --- a/indra/newview/llfacebookconnect.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file llfacebookconnect.h - * @author Merov, Cho, Gil - * @brief Connection to Facebook Service - * - * $LicenseInfo:firstyear=2013&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2013, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFACEBOOKCONNECT_H -#define LL_LLFACEBOOKCONNECT_H - -#include "llsingleton.h" -#include "llimage.h" -#include "llcoros.h" -#include "lleventcoro.h" - -class LLEventPump; - -/** - * @class LLFacebookConnect - * - * Manages authentication to, and interaction with, a web service allowing the - * the viewer to get Facebook OpenGraph data. - */ -class LLFacebookConnect : public LLSingleton<LLFacebookConnect> -{ - LLSINGLETON(LLFacebookConnect); - ~LLFacebookConnect() {}; - LOG_CLASS(LLFacebookConnect); -public: - enum EConnectionState - { - FB_NOT_CONNECTED = 0, - FB_CONNECTION_IN_PROGRESS = 1, - FB_CONNECTED = 2, - FB_CONNECTION_FAILED = 3, - FB_POSTING = 4, - FB_POSTED = 5, - FB_POST_FAILED = 6, - FB_DISCONNECTING = 7, - FB_DISCONNECT_FAILED = 8 - }; - - void connectToFacebook(const std::string& auth_code = "", const std::string& auth_state = ""); // Initiate the complete FB connection. Please use checkConnectionToFacebook() in normal use. - void disconnectFromFacebook(); // Disconnect from the FBC service. - void checkConnectionToFacebook(bool auto_connect = false); // Check if an access token is available on the FBC service. If not, call connectToFacebook(). - - void loadFacebookInfo(); - void loadFacebookFriends(); - void postCheckin(const std::string& location, const std::string& name, const std::string& description, const std::string& picture, const std::string& message); - void sharePhoto(const std::string& image_url, const std::string& caption); - void sharePhoto(LLPointer<LLImageFormatted> image, const std::string& caption); - void updateStatus(const std::string& message); - - void storeInfo(const LLSD& info); - const LLSD& getInfo() const; - void clearInfo(); - void storeContent(const LLSD& content); - const LLSD& getContent() const; - void clearContent(); - void setDataDirty(); - - void setConnectionState(EConnectionState connection_state); - void setConnected(bool connected); - bool isConnected() { return mConnected; } - bool isTransactionOngoing() { return ((mConnectionState == FB_CONNECTION_IN_PROGRESS) || (mConnectionState == FB_POSTING) || (mConnectionState == FB_DISCONNECTING)); } - EConnectionState getConnectionState() { return mConnectionState; } - - void openFacebookWeb(std::string url); - -private: - - std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false); - - EConnectionState mConnectionState; - BOOL mConnected; - LLSD mInfo; - LLSD mContent; - bool mRefreshInfo; - bool mRefreshContent; - bool mReadFromMaster; - - static boost::scoped_ptr<LLEventPump> sStateWatcher; - static boost::scoped_ptr<LLEventPump> sInfoWatcher; - static boost::scoped_ptr<LLEventPump> sContentWatcher; - - bool testShareStatus(LLSD &results); - void facebookConnectCoro(std::string authCode, std::string authState); - void facebookConnectedCheckCoro(bool autoConnect); - void facebookDisconnectCoro(); - void facebookShareCoro(std::string route, LLSD share); - void facebookShareImageCoro(std::string route, LLPointer<LLImageFormatted> image, std::string caption); - void facebookConnectInfoCoro(); - void facebookConnectFriendsCoro(); -}; - -#endif // LL_LLFACEBOOKCONNECT_H diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index f68e63cb96..d90f03b403 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -43,6 +43,7 @@ #include "llsdserialize.h" #include "lltooltip.h" #include "llbutton.h" +#include "llscrollbar.h" #include "llappviewer.h" #include "llviewertexturelist.h" @@ -128,7 +129,8 @@ void LLFastTimerView::setPauseState(bool pause_state) BOOL LLFastTimerView::postBuild() { LLButton& pause_btn = getChildRef<LLButton>("pause_btn"); - + mScrollBar = getChild<LLScrollbar>("scroll_vert"); + pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this)); return TRUE; } @@ -183,7 +185,7 @@ BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) { - if (x < mBarRect.mLeft) + if (x < mScrollBar->getRect().mLeft) { BlockTimerStatHandle* idp = getLegendID(y); if (idp) @@ -284,7 +286,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } } } - else if (x < mBarRect.mLeft) + else if (x < mScrollBar->getRect().mLeft) { BlockTimerStatHandle* timer_id = getLegendID(y); if (timer_id) @@ -335,7 +337,7 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) else { // tooltips for timer legend - if (x < mBarRect.mLeft) + if (x < mScrollBar->getRect().mLeft) { BlockTimerStatHandle* idp = getLegendID(y); if (idp) @@ -352,11 +354,19 @@ BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks) { - setPauseState(true); - mScrollIndex = llclamp( mScrollIndex + clicks, - 0, - llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY)); - return TRUE; + if (x < mBarRect.mLeft) + { + // Inside mScrollBar and list of timers + mScrollBar->handleScrollWheel(x,y,clicks); + } + else + { + setPauseState(true); + mScrollIndex = llclamp(mScrollIndex + clicks, + 0, + llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY)); + } + return TRUE; } static BlockTimerStatHandle FTM_RENDER_TIMER("Timers"); @@ -1197,6 +1207,7 @@ void LLFastTimerView::drawLegend() { LLLocalClipRect clip(mLegendRect); S32 cur_line = 0; + S32 scroll_offset = 0; // element's y offset from top of the inner scroll's rect ft_display_idx.clear(); std::map<BlockTimerStatHandle*, S32> display_line; for (block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); @@ -1204,10 +1215,24 @@ void LLFastTimerView::drawLegend() ++it) { BlockTimerStatHandle* idp = (*it); + // Needed to figure out offsets and parenting display_line[idp] = cur_line; - ft_display_idx.push_back(idp); cur_line++; + if (scroll_offset < mScrollBar->getDocPos()) + { + // only offset for visible items + scroll_offset += TEXT_HEIGHT + 2; + if (idp->getTreeNode().mCollapsed) + { + it.skipDescendants(); + } + continue; + } + + // used for mouse clicks + ft_display_idx.push_back(idp); + // Actual draw, first bar (square), then text x = MARGIN; LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT); @@ -1281,11 +1306,14 @@ void LLFastTimerView::drawLegend() y -= (TEXT_HEIGHT + 2); + scroll_offset += TEXT_HEIGHT + 2; if (idp->getTreeNode().mCollapsed) { it.skipDescendants(); } } + // Recalculate scroll size + mScrollBar->setDocSize(scroll_offset - mLegendRect.getHeight()); } } diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index 3e30bd86ba..ff65f8da07 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -33,6 +33,8 @@ #include "lltracerecording.h" #include <deque> +class LLScrollbar; + class LLFastTimerView : public LLFloater { public: @@ -142,6 +144,8 @@ private: mLegendRect; LLFrameTimer mHighlightTimer; LLTrace::PeriodicRecording mRecording; + + LLScrollbar* mScrollBar; }; #endif diff --git a/indra/newview/llfloaterfacebook.cpp b/indra/newview/llfloaterfacebook.cpp deleted file mode 100644 index e84cbc289f..0000000000 --- a/indra/newview/llfloaterfacebook.cpp +++ /dev/null @@ -1,1132 +0,0 @@ -/** -* @file llfloaterfacebook.cpp -* @brief Implementation of llfloaterfacebook -* @author Gilbert@lindenlab.com -* -* $LicenseInfo:firstyear=2013&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2013, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ - -#include "llviewerprecompiledheaders.h" - -#include "llfloaterfacebook.h" - -#include "llagent.h" -#include "llagentui.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llfacebookconnect.h" -#include "llfloaterbigpreview.h" -#include "llfloaterreg.h" -#include "lliconctrl.h" -#include "llimagefiltersmanager.h" -#include "llresmgr.h" // LLLocale -#include "llsdserialize.h" -#include "llloadingindicator.h" -#include "llslurl.h" -#include "lltrans.h" -#include "llsnapshotlivepreview.h" -#include "llviewerregion.h" -#include "llviewercontrol.h" -#include "llviewermedia.h" -#include "lltabcontainer.h" -#include "llavatarlist.h" -#include "llpanelpeoplemenus.h" -#include "llaccordionctrl.h" -#include "llaccordionctrltab.h" - -static LLPanelInjector<LLFacebookStatusPanel> t_panel_status("llfacebookstatuspanel"); -static LLPanelInjector<LLFacebookPhotoPanel> t_panel_photo("llfacebookphotopanel"); -static LLPanelInjector<LLFacebookCheckinPanel> t_panel_checkin("llfacebookcheckinpanel"); -static LLPanelInjector<LLFacebookFriendsPanel> t_panel_friends("llfacebookfriendspanel"); - -const std::string DEFAULT_CHECKIN_LOCATION_URL = "http://maps.secondlife.com/"; -const std::string DEFAULT_CHECKIN_ICON_URL = "http://map.secondlife.com.s3.amazonaws.com/map_placeholder.png"; -const std::string DEFAULT_CHECKIN_QUERY_PARAMETERS = "?sourceid=slshare_checkin&utm_source=facebook&utm_medium=checkin&utm_campaign=slshare"; -const std::string DEFAULT_PHOTO_QUERY_PARAMETERS = "?sourceid=slshare_photo&utm_source=facebook&utm_medium=photo&utm_campaign=slshare"; - -const S32 MAX_QUALITY = 100; // Max quality value for jpeg images -const S32 MIN_QUALITY = 0; // Min quality value for jpeg images -const S32 TARGET_DATA_SIZE = 950000; // Size of the image (compressed) we're trying to send to Facebook - -std::string get_map_url() -{ - LLVector3d center_agent; - LLViewerRegion *regionp = gAgent.getRegion(); - if (regionp) - { - center_agent = regionp->getCenterGlobal(); - } - int x_pos = center_agent[0] / 256.0; - int y_pos = center_agent[1] / 256.0; - std::string map_url = gSavedSettings.getString("CurrentMapServerURL") + llformat("map-1-%d-%d-objects.jpg", x_pos, y_pos); - return map_url; -} - -// Compute target jpeg quality : see https://wiki.lindenlab.com/wiki/Facebook_Image_Quality for details -S32 compute_jpeg_quality(S32 width, S32 height) -{ - F32 target_compression_ratio = (F32)(width * height * 3) / (F32)(TARGET_DATA_SIZE); - S32 quality = (S32)(110.0f - (2.0f * target_compression_ratio)); - return llclamp(quality, MIN_QUALITY, MAX_QUALITY); -} - -/////////////////////////// -//LLFacebookStatusPanel////// -/////////////////////////// - -LLFacebookStatusPanel::LLFacebookStatusPanel() : - mMessageTextEditor(NULL), - mPostButton(NULL), - mCancelButton(NULL), - mAccountCaptionLabel(NULL), - mAccountNameLabel(NULL), - mPanelButtons(NULL), - mConnectButton(NULL), - mDisconnectButton(NULL) -{ - mCommitCallbackRegistrar.add("SocialSharing.Connect", boost::bind(&LLFacebookStatusPanel::onConnect, this)); - mCommitCallbackRegistrar.add("SocialSharing.Disconnect", boost::bind(&LLFacebookStatusPanel::onDisconnect, this)); - - setVisibleCallback(boost::bind(&LLFacebookStatusPanel::onVisibilityChange, this, _2)); - - mCommitCallbackRegistrar.add("SocialSharing.SendStatus", boost::bind(&LLFacebookStatusPanel::onSend, this)); -} - -BOOL LLFacebookStatusPanel::postBuild() -{ - mAccountCaptionLabel = getChild<LLTextBox>("account_caption_label"); - mAccountNameLabel = getChild<LLTextBox>("account_name_label"); - mPanelButtons = getChild<LLUICtrl>("panel_buttons"); - mConnectButton = getChild<LLUICtrl>("connect_btn"); - mDisconnectButton = getChild<LLUICtrl>("disconnect_btn"); - - mMessageTextEditor = getChild<LLUICtrl>("status_message"); - mPostButton = getChild<LLUICtrl>("post_status_btn"); - mCancelButton = getChild<LLUICtrl>("cancel_status_btn"); - - return LLPanel::postBuild(); -} - -void LLFacebookStatusPanel::draw() -{ - LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState(); - - //Disable the 'disconnect' button and the 'use another account' button when disconnecting in progress - bool disconnecting = connection_state == LLFacebookConnect::FB_DISCONNECTING; - mDisconnectButton->setEnabled(!disconnecting); - - //Disable the 'connect' button when a connection is in progress - bool connecting = connection_state == LLFacebookConnect::FB_CONNECTION_IN_PROGRESS; - mConnectButton->setEnabled(!connecting); - - if (mMessageTextEditor && mPostButton && mCancelButton) - { - bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing()); - std::string message = mMessageTextEditor->getValue().asString(); - mMessageTextEditor->setEnabled(no_ongoing_connection); - mCancelButton->setEnabled(no_ongoing_connection); - mPostButton->setEnabled(no_ongoing_connection && !message.empty()); - } - - LLPanel::draw(); -} - -void LLFacebookStatusPanel::onSend() -{ - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookStatusPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectStateChange, this, _1)); - - // Connect to Facebook if necessary and then post - if (LLFacebookConnect::instance().isConnected()) - { - sendStatus(); - } - else - { - LLFacebookConnect::instance().checkConnectionToFacebook(true); - } -} - -bool LLFacebookStatusPanel::onFacebookConnectStateChange(const LLSD& data) -{ - switch (data.get("enum").asInteger()) - { - case LLFacebookConnect::FB_CONNECTED: - sendStatus(); - break; - - case LLFacebookConnect::FB_POSTED: - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookStatusPanel"); - clearAndClose(); - break; - } - - return false; -} - -bool LLFacebookStatusPanel::onFacebookConnectAccountStateChange(const LLSD& data) -{ - if (LLFacebookConnect::instance().isConnected()) - { - //In process of disconnecting so leave the layout as is - if (data.get("enum").asInteger() != LLFacebookConnect::FB_DISCONNECTING) - { - showConnectedLayout(); - } - } - else - { - showDisconnectedLayout(); - } - - return false; -} - -void LLFacebookStatusPanel::sendStatus() -{ - std::string message = mMessageTextEditor->getValue().asString(); - if (!message.empty()) - { - LLFacebookConnect::instance().updateStatus(message); - } -} - -void LLFacebookStatusPanel::onVisibilityChange(BOOL visible) -{ - if (visible) - { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel"); - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectAccountStateChange, this, _1)); - - LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel"); - LLEventPumps::instance().obtain("FacebookConnectInfo").listen("LLFacebookAccountPanel", boost::bind(&LLFacebookStatusPanel::onFacebookConnectInfoChange, this)); - - //Connected - if (LLFacebookConnect::instance().isConnected()) - { - showConnectedLayout(); - } - //Check if connected (show disconnected layout in meantime) - else - { - showDisconnectedLayout(); - } - if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) || - (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED)) - { - LLFacebookConnect::instance().checkConnectionToFacebook(); - } - } - else - { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookAccountPanel"); - LLEventPumps::instance().obtain("FacebookConnectInfo").stopListening("LLFacebookAccountPanel"); - } -} - -bool LLFacebookStatusPanel::onFacebookConnectInfoChange() -{ - LLSD info = LLFacebookConnect::instance().getInfo(); - std::string clickable_name; - - //Strings of format [http://www.somewebsite.com Click Me] become clickable text - if (info.has("link") && info.has("name")) - { - clickable_name = "[" + info["link"].asString() + " " + info["name"].asString() + "]"; - } - - mAccountNameLabel->setText(clickable_name); - - return false; -} - -void LLFacebookStatusPanel::showConnectButton() -{ - if (!mConnectButton->getVisible()) - { - mConnectButton->setVisible(TRUE); - mDisconnectButton->setVisible(FALSE); - } -} - -void LLFacebookStatusPanel::hideConnectButton() -{ - if (mConnectButton->getVisible()) - { - mConnectButton->setVisible(FALSE); - mDisconnectButton->setVisible(TRUE); - } -} - -void LLFacebookStatusPanel::showDisconnectedLayout() -{ - mAccountCaptionLabel->setText(getString("facebook_disconnected")); - mAccountNameLabel->setText(std::string("")); - showConnectButton(); -} - -void LLFacebookStatusPanel::showConnectedLayout() -{ - LLFacebookConnect::instance().loadFacebookInfo(); - - mAccountCaptionLabel->setText(getString("facebook_connected")); - hideConnectButton(); -} - -void LLFacebookStatusPanel::onConnect() -{ - LLFacebookConnect::instance().checkConnectionToFacebook(true); -} - -void LLFacebookStatusPanel::onDisconnect() -{ - LLFacebookConnect::instance().disconnectFromFacebook(); -} - -void LLFacebookStatusPanel::clearAndClose() -{ - mMessageTextEditor->setValue(""); - - LLFloater* floater = getParentByType<LLFloater>(); - if (floater) - { - floater->closeFloater(); - } -} - -/////////////////////////// -//LLFacebookPhotoPanel/////// -/////////////////////////// - -LLFacebookPhotoPanel::LLFacebookPhotoPanel() : - mResolutionComboBox(NULL), - mRefreshBtn(NULL), - mBtnPreview(NULL), - mWorkingLabel(NULL), - mThumbnailPlaceholder(NULL), - mCaptionTextBox(NULL), - mPostButton(NULL), - mBigPreviewFloater(NULL), - mQuality(MAX_QUALITY) -{ - mCommitCallbackRegistrar.add("SocialSharing.SendPhoto", boost::bind(&LLFacebookPhotoPanel::onSend, this)); - mCommitCallbackRegistrar.add("SocialSharing.RefreshPhoto", boost::bind(&LLFacebookPhotoPanel::onClickNewSnapshot, this)); - mCommitCallbackRegistrar.add("SocialSharing.BigPreview", boost::bind(&LLFacebookPhotoPanel::onClickBigPreview, this)); -} - -LLFacebookPhotoPanel::~LLFacebookPhotoPanel() -{ - if (mPreviewHandle.get()) - { - mPreviewHandle.get()->die(); - } -} - -BOOL LLFacebookPhotoPanel::postBuild() -{ - setVisibleCallback(boost::bind(&LLFacebookPhotoPanel::onVisibilityChange, this, _2)); - - mResolutionComboBox = getChild<LLUICtrl>("resolution_combobox"); - mResolutionComboBox->setValue("[i1200,i630]"); // hardcoded defaults ftw! - mResolutionComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE)); - mFilterComboBox = getChild<LLUICtrl>("filters_combobox"); - mFilterComboBox->setCommitCallback(boost::bind(&LLFacebookPhotoPanel::updateResolution, this, TRUE)); - mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); - mBtnPreview = getChild<LLButton>("big_preview_btn"); - mWorkingLabel = getChild<LLUICtrl>("working_lbl"); - mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); - mCaptionTextBox = getChild<LLUICtrl>("photo_caption"); - mPostButton = getChild<LLUICtrl>("post_photo_btn"); - mCancelButton = getChild<LLUICtrl>("cancel_photo_btn"); - mBigPreviewFloater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview")); - - // Update filter list - std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); - LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox); - for (U32 i = 0; i < filter_list.size(); i++) - { - filterbox->add(filter_list[i]); - } - - return LLPanel::postBuild(); -} - -// virtual -S32 LLFacebookPhotoPanel::notify(const LLSD& info) -{ - if (info.has("snapshot-updating")) - { - // Disable the Post button and whatever else while the snapshot is not updated - // updateControls(); - return 1; - } - - if (info.has("snapshot-updated")) - { - // Enable the send/post/save buttons. - updateControls(); - - // The refresh button is initially hidden. We show it after the first update, - // i.e. after snapshot is taken - LLUICtrl * refresh_button = getRefreshBtn(); - if (!refresh_button->getVisible()) - { - refresh_button->setVisible(true); - } - return 1; - } - - return 0; -} - -void LLFacebookPhotoPanel::draw() -{ - LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get()); - - // Enable interaction only if no transaction with the service is on-going (prevent duplicated posts) - bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing()); - mCancelButton->setEnabled(no_ongoing_connection); - mCaptionTextBox->setEnabled(no_ongoing_connection); - mResolutionComboBox->setEnabled(no_ongoing_connection); - mFilterComboBox->setEnabled(no_ongoing_connection); - mRefreshBtn->setEnabled(no_ongoing_connection); - mBtnPreview->setEnabled(no_ongoing_connection); - - // Reassign the preview floater if we have the focus and the preview exists - if (hasFocus() && isPreviewVisible()) - { - attachPreview(); - } - - // Toggle the button state as appropriate - bool preview_active = (isPreviewVisible() && mBigPreviewFloater->isFloaterOwner(getParentByType<LLFloater>())); - mBtnPreview->setToggleState(preview_active); - - // Display the thumbnail if one is available - if (previewp && previewp->getThumbnailImage()) - { - const LLRect& thumbnail_rect = mThumbnailPlaceholder->getRect(); - const S32 thumbnail_w = previewp->getThumbnailWidth(); - const S32 thumbnail_h = previewp->getThumbnailHeight(); - - // calc preview offset within the preview rect - const S32 local_offset_x = (thumbnail_rect.getWidth() - thumbnail_w) / 2; - const S32 local_offset_y = (thumbnail_rect.getHeight() - thumbnail_h) / 2; - S32 offset_x = thumbnail_rect.mLeft + local_offset_x; - S32 offset_y = thumbnail_rect.mBottom + local_offset_y; - - gGL.matrixMode(LLRender::MM_MODELVIEW); - // Apply floater transparency to the texture unless the floater is focused. - F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); - LLColor4 color = LLColor4::white; - gl_draw_scaled_image(offset_x, offset_y, - thumbnail_w, thumbnail_h, - previewp->getThumbnailImage(), color % alpha); - } - - // Update the visibility of the working (computing preview) label - mWorkingLabel->setVisible(!(previewp && previewp->getSnapshotUpToDate())); - - // Enable Post if we have a preview to send and no on going connection being processed - mPostButton->setEnabled(no_ongoing_connection && (previewp && previewp->getSnapshotUpToDate())); - - // Draw the rest of the panel on top of it - LLPanel::draw(); -} - -LLSnapshotLivePreview* LLFacebookPhotoPanel::getPreviewView() -{ - LLSnapshotLivePreview* previewp = (LLSnapshotLivePreview*)mPreviewHandle.get(); - return previewp; -} - -void LLFacebookPhotoPanel::onVisibilityChange(BOOL visible) -{ - if (visible) - { - if (mPreviewHandle.get()) - { - LLSnapshotLivePreview* preview = getPreviewView(); - if (preview) - { - LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; - preview->updateSnapshot(TRUE); - } - } - else - { - LLRect full_screen_rect = getRootView()->getRect(); - LLSnapshotLivePreview::Params p; - p.rect(full_screen_rect); - LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); - mPreviewHandle = previewp->getHandle(); - mQuality = MAX_QUALITY; - - previewp->setContainer(this); - previewp->setSnapshotType(LLSnapshotModel::SNAPSHOT_WEB); - previewp->setSnapshotFormat(LLSnapshotModel::SNAPSHOT_FORMAT_JPEG); - previewp->setSnapshotQuality(mQuality, false); - previewp->setThumbnailSubsampled(TRUE); // We want the preview to reflect the *saved* image - previewp->setAllowRenderUI(FALSE); // We do not want the rendered UI in our snapshots - previewp->setAllowFullScreenPreview(FALSE); // No full screen preview in SL Share mode - previewp->setThumbnailPlaceholderRect(mThumbnailPlaceholder->getRect()); - - updateControls(); - } - } -} - -void LLFacebookPhotoPanel::onClickNewSnapshot() -{ - LLSnapshotLivePreview* previewp = getPreviewView(); - if (previewp) - { - previewp->updateSnapshot(TRUE); - } -} - -void LLFacebookPhotoPanel::onClickBigPreview() -{ - // Toggle the preview - if (isPreviewVisible()) - { - LLFloaterReg::hideInstance("big_preview"); - } - else - { - attachPreview(); - LLFloaterReg::showInstance("big_preview"); - } -} - -bool LLFacebookPhotoPanel::isPreviewVisible() -{ - return (mBigPreviewFloater && mBigPreviewFloater->getVisible()); -} - -void LLFacebookPhotoPanel::attachPreview() -{ - if (mBigPreviewFloater) - { - LLSnapshotLivePreview* previewp = getPreviewView(); - mBigPreviewFloater->setPreview(previewp); - mBigPreviewFloater->setFloaterOwner(getParentByType<LLFloater>()); - } -} - -void LLFacebookPhotoPanel::onSend() -{ - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookPhotoPanel", boost::bind(&LLFacebookPhotoPanel::onFacebookConnectStateChange, this, _1)); - - // Connect to Facebook if necessary and then post - if (LLFacebookConnect::instance().isConnected()) - { - sendPhoto(); - } - else - { - LLFacebookConnect::instance().checkConnectionToFacebook(true); - } -} - -bool LLFacebookPhotoPanel::onFacebookConnectStateChange(const LLSD& data) -{ - switch (data.get("enum").asInteger()) - { - case LLFacebookConnect::FB_CONNECTED: - sendPhoto(); - break; - - case LLFacebookConnect::FB_POSTED: - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookPhotoPanel"); - clearAndClose(); - break; - } - - return false; -} - -void LLFacebookPhotoPanel::sendPhoto() -{ - // Get the caption - std::string caption = mCaptionTextBox->getValue().asString(); - - // Get the image - LLSnapshotLivePreview* previewp = getPreviewView(); - - // Post to Facebook - LLFacebookConnect::instance().sharePhoto(previewp->getFormattedImage(), caption); - - updateControls(); -} - -void LLFacebookPhotoPanel::clearAndClose() -{ - mCaptionTextBox->setValue(""); - - LLFloater* floater = getParentByType<LLFloater>(); - if (floater) - { - floater->closeFloater(); - if (mBigPreviewFloater) - { - mBigPreviewFloater->closeOnFloaterOwnerClosing(floater); - } - } -} - -void LLFacebookPhotoPanel::updateControls() -{ - LLSnapshotLivePreview* previewp = getPreviewView(); - BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); - - // *TODO: Separate maximum size for Web images from postcards - LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL; - - updateResolution(FALSE); -} - -void LLFacebookPhotoPanel::updateResolution(BOOL do_update) -{ - LLComboBox* combobox = static_cast<LLComboBox *>(mResolutionComboBox); - LLComboBox* filterbox = static_cast<LLComboBox *>(mFilterComboBox); - - std::string sdstring = combobox->getSelectedValue(); - LLSD sdres; - std::stringstream sstream(sdstring); - LLSDSerialize::fromNotation(sdres, sstream, sdstring.size()); - - S32 width = sdres[0]; - S32 height = sdres[1]; - - // Note : index 0 of the filter drop down is assumed to be "No filter" in whichever locale - std::string filter_name = (filterbox->getCurrentIndex() ? filterbox->getSimple() : ""); - - LLSnapshotLivePreview * previewp = static_cast<LLSnapshotLivePreview *>(mPreviewHandle.get()); - if (previewp && combobox->getCurrentIndex() >= 0) - { - S32 original_width = 0, original_height = 0; - previewp->getSize(original_width, original_height); - - if (width == 0 || height == 0) - { - // take resolution from current window size - LL_DEBUGS() << "Setting preview res from window: " << gViewerWindow->getWindowWidthRaw() << "x" << gViewerWindow->getWindowHeightRaw() << LL_ENDL; - previewp->setSize(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); - } - else - { - // use the resolution from the selected pre-canned drop-down choice - LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL; - previewp->setSize(width, height); - } - - checkAspectRatio(width); - - previewp->getSize(width, height); - - // Recompute quality setting - mQuality = compute_jpeg_quality(width, height); - previewp->setSnapshotQuality(mQuality, false); - - if (original_width != width || original_height != height) - { - previewp->setSize(width, height); - if (do_update) - { - previewp->updateSnapshot(TRUE); - updateControls(); - } - } - // Get the old filter, compare to the current one "filter_name" and set if changed - std::string original_filter = previewp->getFilter(); - if (original_filter != filter_name) - { - previewp->setFilter(filter_name); - if (do_update) - { - previewp->updateSnapshot(FALSE, TRUE); - updateControls(); - } - } - } -} - -void LLFacebookPhotoPanel::checkAspectRatio(S32 index) -{ - LLSnapshotLivePreview *previewp = getPreviewView(); - - BOOL keep_aspect = FALSE; - - if (0 == index) // current window size - { - keep_aspect = TRUE; - } - else // predefined resolution - { - keep_aspect = FALSE; - } - - if (previewp) - { - previewp->mKeepAspectRatio = keep_aspect; - } -} - -LLUICtrl* LLFacebookPhotoPanel::getRefreshBtn() -{ - return mRefreshBtn; -} - -//////////////////////// -//LLFacebookCheckinPanel// -//////////////////////// - -LLFacebookCheckinPanel::LLFacebookCheckinPanel() : - mMapUrl(""), - mReloadingMapTexture(false) -{ - mCommitCallbackRegistrar.add("SocialSharing.SendCheckin", boost::bind(&LLFacebookCheckinPanel::onSend, this)); -} - -BOOL LLFacebookCheckinPanel::postBuild() -{ - // Keep pointers to widgets so we don't traverse the UI hierarchy too often - mPostButton = getChild<LLUICtrl>("post_place_btn"); - mCancelButton = getChild<LLUICtrl>("cancel_place_btn"); - mMessageTextEditor = getChild<LLUICtrl>("place_caption"); - mMapLoadingIndicator = getChild<LLUICtrl>("map_loading_indicator"); - mMapPlaceholder = getChild<LLIconCtrl>("map_placeholder"); - mMapDefault = getChild<LLIconCtrl>("map_default"); - mMapCheckBox = getChild<LLCheckBoxCtrl>("add_place_view_cb"); - - return LLPanel::postBuild(); -} - -void LLFacebookCheckinPanel::draw() -{ - bool no_ongoing_connection = !(LLFacebookConnect::instance().isTransactionOngoing()); - mPostButton->setEnabled(no_ongoing_connection); - mCancelButton->setEnabled(no_ongoing_connection); - mMessageTextEditor->setEnabled(no_ongoing_connection); - mMapCheckBox->setEnabled(no_ongoing_connection); - - std::string map_url = get_map_url(); - // Did we change location? - if (map_url != mMapUrl) - { - mMapUrl = map_url; - // Load the map tile - mMapTexture = LLViewerTextureManager::getFetchedTextureFromUrl(mMapUrl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - mMapTexture->setBoostLevel(LLGLTexture::BOOST_MAP); - mReloadingMapTexture = true; - // In the meantime, put the "loading" indicator on, hide the tile map and disable the checkbox - mMapLoadingIndicator->setVisible(true); - mMapPlaceholder->setVisible(false); - } - // Are we done loading the map tile? - if (mReloadingMapTexture && mMapTexture->isFullyLoaded()) - { - // Don't do it again next time around - mReloadingMapTexture = false; - // Convert the map texture to the appropriate image object - LLPointer<LLUIImage> ui_image = new LLUIImage(mMapUrl, mMapTexture); - // Load the map widget with the correct map tile image - mMapPlaceholder->setImage(ui_image); - // Now hide the loading indicator, bring the tile in view and reenable the checkbox with its previous value - mMapLoadingIndicator->setVisible(false); - mMapPlaceholder->setVisible(true); - } - // Show the default icon if that's the checkbox value (the real one...) - // This will hide/show the loading indicator and/or tile underneath - mMapDefault->setVisible(!(mMapCheckBox->get())); - - LLPanel::draw(); -} - -void LLFacebookCheckinPanel::onSend() -{ - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookCheckinPanel", boost::bind(&LLFacebookCheckinPanel::onFacebookConnectStateChange, this, _1)); - - // Connect to Facebook if necessary and then post - if (LLFacebookConnect::instance().isConnected()) - { - sendCheckin(); - } - else - { - LLFacebookConnect::instance().checkConnectionToFacebook(true); - } -} - -bool LLFacebookCheckinPanel::onFacebookConnectStateChange(const LLSD& data) -{ - switch (data.get("enum").asInteger()) - { - case LLFacebookConnect::FB_CONNECTED: - sendCheckin(); - break; - - case LLFacebookConnect::FB_POSTED: - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookCheckinPanel"); - clearAndClose(); - break; - } - - return false; -} - -void LLFacebookCheckinPanel::sendCheckin() -{ - // Get the location SLURL - LLSLURL slurl; - LLAgentUI::buildSLURL(slurl); - std::string slurl_string = slurl.getSLURLString(); - - // Use a valid http:// URL if the scheme is secondlife:// - LLURI slurl_uri(slurl_string); - if (slurl_uri.scheme() == LLSLURL::SLURL_SECONDLIFE_SCHEME) - { - slurl_string = DEFAULT_CHECKIN_LOCATION_URL; - } - - // Add query parameters so Google Analytics can track incoming clicks! - slurl_string += DEFAULT_CHECKIN_QUERY_PARAMETERS; - - // Get the region name - std::string region_name(""); - LLViewerRegion *regionp = gAgent.getRegion(); - if (regionp) - { - region_name = regionp->getName(); - } - - // Get the region description - std::string description; - LLAgentUI::buildLocationString(description, LLAgentUI::LOCATION_FORMAT_NORMAL_COORDS, gAgent.getPositionAgent()); - - // Optionally add the region map view - bool add_map_view = mMapCheckBox->getValue().asBoolean(); - std::string map_url = (add_map_view ? get_map_url() : DEFAULT_CHECKIN_ICON_URL); - - // Get the caption - std::string caption = mMessageTextEditor->getValue().asString(); - - // Post to Facebook - LLFacebookConnect::instance().postCheckin(slurl_string, region_name, description, map_url, caption); -} - -void LLFacebookCheckinPanel::clearAndClose() -{ - mMessageTextEditor->setValue(""); - - LLFloater* floater = getParentByType<LLFloater>(); - if (floater) - { - floater->closeFloater(); - } -} - -/////////////////////////// -//LLFacebookFriendsPanel////// -/////////////////////////// - -LLFacebookFriendsPanel::LLFacebookFriendsPanel() : - mFriendsStatusCaption(NULL), - mSecondLifeFriends(NULL), - mSuggestedFriends(NULL) -{ -} - -LLFacebookFriendsPanel::~LLFacebookFriendsPanel() -{ - LLAvatarTracker::instance().removeObserver(this); -} - -BOOL LLFacebookFriendsPanel::postBuild() -{ - mFriendsStatusCaption = getChild<LLTextBox>("facebook_friends_status"); - - mSecondLifeFriends = getChild<LLAvatarList>("second_life_friends"); - mSecondLifeFriends->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); - - mSuggestedFriends = getChild<LLAvatarList>("suggested_friends"); - mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu); - - setVisibleCallback(boost::bind(&LLFacebookFriendsPanel::updateFacebookList, this, _2)); - - LLAvatarTracker::instance().addObserver(this); - - return LLPanel::postBuild(); -} - -bool LLFacebookFriendsPanel::updateSuggestedFriendList() -{ - const LLAvatarTracker& av_tracker = LLAvatarTracker::instance(); - uuid_vec_t& second_life_friends = mSecondLifeFriends->getIDs(); - second_life_friends.clear(); - uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs(); - suggested_friends.clear(); - - //Add suggested friends - LLSD friends = LLFacebookConnect::instance().getContent(); - for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i) - { - LLUUID agent_id = (*i).asUUID(); - if (agent_id.notNull()) - { - bool second_life_buddy = av_tracker.isBuddy(agent_id); - if (second_life_buddy) - { - second_life_friends.push_back(agent_id); - } - else - { - //FB+SL but not SL friend - suggested_friends.push_back(agent_id); - } - } - } - - //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display) - mSecondLifeFriends->setDirty(true, !mSecondLifeFriends->filterHasMatches()); - mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches()); - showFriendsAccordionsIfNeeded(); - - return false; -} - -void LLFacebookFriendsPanel::showFriendsAccordionsIfNeeded() -{ - // Show / hide the status text : needs to be done *before* showing / hidding the accordions - if (!mSecondLifeFriends->filterHasMatches() && !mSuggestedFriends->filterHasMatches()) - { - // Show some explanation text if the lists are empty... - mFriendsStatusCaption->setVisible(true); - if (LLFacebookConnect::instance().isConnected()) - { - //...you're connected to FB but have no friends :( - mFriendsStatusCaption->setText(getString("facebook_friends_empty")); - } - else - { - //...you're not connected to FB - mFriendsStatusCaption->setText(getString("facebook_friends_no_connected")); - } - // Hide the lists - getChild<LLAccordionCtrl>("friends_accordion")->setVisible(false); - getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(false); - getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(false); - } - else - { - // We have something in the lists, hide the explanatory text - mFriendsStatusCaption->setVisible(false); - - // Show the lists - LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion"); - accordion->setVisible(true); - - // Expand and show accordions if needed, else - hide them - getChild<LLAccordionCtrlTab>("tab_second_life_friends")->setVisible(mSecondLifeFriends->filterHasMatches()); - getChild<LLAccordionCtrlTab>("tab_suggested_friends")->setVisible(mSuggestedFriends->filterHasMatches()); - - // Rearrange accordions - accordion->arrange(); - } -} - -void LLFacebookFriendsPanel::changed(U32 mask) -{ - if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE)) - { - LLFacebookConnect::instance().loadFacebookFriends(); - updateFacebookList(true); - } -} - - -void LLFacebookFriendsPanel::updateFacebookList(bool visible) -{ - if (visible) - { - // We want this to be called to fetch the friends list once a connection is established - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLFacebookFriendsPanel"); - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::onConnectedToFacebook, this, _1)); - - // We then want this to be called to update the displayed lists once the list of friends is received - LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLFacebookFriendsPanel"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLFacebookFriendsPanel", boost::bind(&LLFacebookFriendsPanel::updateSuggestedFriendList, this)); - - // Try to connect to Facebook - if ((LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_NOT_CONNECTED) || - (LLFacebookConnect::instance().getConnectionState() == LLFacebookConnect::FB_CONNECTION_FAILED)) - { - LLFacebookConnect::instance().checkConnectionToFacebook(); - } - // Loads FB friends - if (LLFacebookConnect::instance().isConnected()) - { - LLFacebookConnect::instance().loadFacebookFriends(); - } - // Sort the FB friends and update the lists - updateSuggestedFriendList(); - } -} - -bool LLFacebookFriendsPanel::onConnectedToFacebook(const LLSD& data) -{ - LLSD::Integer connection_state = data.get("enum").asInteger(); - - if (connection_state == LLFacebookConnect::FB_CONNECTED) - { - LLFacebookConnect::instance().loadFacebookFriends(); - } - else if (connection_state == LLFacebookConnect::FB_NOT_CONNECTED) - { - updateSuggestedFriendList(); - } - - return false; -} - -//////////////////////// -//LLFloaterFacebook/////// -//////////////////////// - -LLFloaterFacebook::LLFloaterFacebook(const LLSD& key) : LLFloater(key), - mFacebookPhotoPanel(NULL), - mStatusErrorText(NULL), - mStatusLoadingText(NULL), - mStatusLoadingIndicator(NULL) -{ - mCommitCallbackRegistrar.add("SocialSharing.Cancel", boost::bind(&LLFloaterFacebook::onCancel, this)); -} - -void LLFloaterFacebook::onClose(bool app_quitting) -{ - LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview")); - if (big_preview_floater) - { - big_preview_floater->closeOnFloaterOwnerClosing(this); - } - LLFloater::onClose(app_quitting); -} - -void LLFloaterFacebook::onCancel() -{ - LLFloaterBigPreview* big_preview_floater = dynamic_cast<LLFloaterBigPreview*>(LLFloaterReg::getInstance("big_preview")); - if (big_preview_floater) - { - big_preview_floater->closeOnFloaterOwnerClosing(this); - } - closeFloater(); -} - -BOOL LLFloaterFacebook::postBuild() -{ - // Keep tab of the Photo Panel - mFacebookPhotoPanel = static_cast<LLFacebookPhotoPanel*>(getChild<LLUICtrl>("panel_facebook_photo")); - // Connection status widgets - mStatusErrorText = getChild<LLTextBox>("connection_error_text"); - mStatusLoadingText = getChild<LLTextBox>("connection_loading_text"); - mStatusLoadingIndicator = getChild<LLUICtrl>("connection_loading_indicator"); - return LLFloater::postBuild(); -} - -void LLFloaterFacebook::showPhotoPanel() -{ - LLTabContainer* parent = dynamic_cast<LLTabContainer*>(mFacebookPhotoPanel->getParent()); - if (!parent) - { - LL_WARNS() << "Cannot find panel container" << LL_ENDL; - return; - } - - parent->selectTabPanel(mFacebookPhotoPanel); -} - -void LLFloaterFacebook::draw() -{ - if (mStatusErrorText && mStatusLoadingText && mStatusLoadingIndicator) - { - mStatusErrorText->setVisible(false); - mStatusLoadingText->setVisible(false); - mStatusLoadingIndicator->setVisible(false); - LLFacebookConnect::EConnectionState connection_state = LLFacebookConnect::instance().getConnectionState(); - std::string status_text; - - switch (connection_state) - { - case LLFacebookConnect::FB_NOT_CONNECTED: - // No status displayed when first opening the panel and no connection done - case LLFacebookConnect::FB_CONNECTED: - // When successfully connected, no message is displayed - case LLFacebookConnect::FB_POSTED: - // No success message to show since we actually close the floater after successful posting completion - break; - case LLFacebookConnect::FB_CONNECTION_IN_PROGRESS: - // Connection loading indicator - mStatusLoadingText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookConnecting"); - mStatusLoadingText->setValue(status_text); - mStatusLoadingIndicator->setVisible(true); - break; - case LLFacebookConnect::FB_POSTING: - // Posting indicator - mStatusLoadingText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookPosting"); - mStatusLoadingText->setValue(status_text); - mStatusLoadingIndicator->setVisible(true); - break; - case LLFacebookConnect::FB_CONNECTION_FAILED: - // Error connecting to the service - mStatusErrorText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookErrorConnecting"); - mStatusErrorText->setValue(status_text); - break; - case LLFacebookConnect::FB_POST_FAILED: - // Error posting to the service - mStatusErrorText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookErrorPosting"); - mStatusErrorText->setValue(status_text); - break; - case LLFacebookConnect::FB_DISCONNECTING: - // Disconnecting loading indicator - mStatusLoadingText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookDisconnecting"); - mStatusLoadingText->setValue(status_text); - mStatusLoadingIndicator->setVisible(true); - break; - case LLFacebookConnect::FB_DISCONNECT_FAILED: - // Error disconnecting from the service - mStatusErrorText->setVisible(true); - status_text = LLTrans::getString("SocialFacebookErrorDisconnecting"); - mStatusErrorText->setValue(status_text); - break; - } - } - LLFloater::draw(); -} - diff --git a/indra/newview/llfloaterfacebook.h b/indra/newview/llfloaterfacebook.h deleted file mode 100644 index a4ca666b20..0000000000 --- a/indra/newview/llfloaterfacebook.h +++ /dev/null @@ -1,185 +0,0 @@ -/** -* @file llfloaterfacebook.h -* @brief Header file for llfloaterfacebook -* @author Gilbert@lindenlab.com -* -* $LicenseInfo:firstyear=2013&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2013, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ -#ifndef LL_LLFLOATERFACEBOOK_H -#define LL_LLFLOATERFACEBOOK_H - -#include "llcallingcard.h" -#include "llfloater.h" -#include "lltextbox.h" -#include "llviewertexture.h" - -class LLIconCtrl; -class LLCheckBoxCtrl; -class LLSnapshotLivePreview; -class LLAvatarList; -class LLFloaterBigPreview; - -class LLFacebookStatusPanel : public LLPanel -{ -public: - LLFacebookStatusPanel(); - BOOL postBuild(); - void draw(); - void onSend(); - bool onFacebookConnectStateChange(const LLSD& data); - bool onFacebookConnectAccountStateChange(const LLSD& data); - - void sendStatus(); - void clearAndClose(); - -private: - void onVisibilityChange(BOOL new_visibility); - bool onFacebookConnectInfoChange(); - void onConnect(); - void onUseAnotherAccount(); - void onDisconnect(); - - void showConnectButton(); - void hideConnectButton(); - void showDisconnectedLayout(); - void showConnectedLayout(); - - LLTextBox * mAccountCaptionLabel; - LLTextBox * mAccountNameLabel; - LLUICtrl * mPanelButtons; - LLUICtrl * mConnectButton; - LLUICtrl * mDisconnectButton; - LLUICtrl* mMessageTextEditor; - LLUICtrl* mPostButton; - LLUICtrl* mCancelButton; -}; - -class LLFacebookPhotoPanel : public LLPanel -{ -public: - LLFacebookPhotoPanel(); - ~LLFacebookPhotoPanel(); - - BOOL postBuild(); - void draw(); - - LLSnapshotLivePreview* getPreviewView(); - void onVisibilityChange(BOOL new_visibility); - void onClickBigPreview(); - void onClickNewSnapshot(); - void onSend(); - S32 notify(const LLSD& info); - bool onFacebookConnectStateChange(const LLSD& data); - - void sendPhoto(); - void clearAndClose(); - - void updateControls(); - void updateResolution(BOOL do_update); - void checkAspectRatio(S32 index); - LLUICtrl* getRefreshBtn(); - -private: - bool isPreviewVisible(); - void attachPreview(); - - LLHandle<LLView> mPreviewHandle; - - LLUICtrl * mResolutionComboBox; - LLUICtrl * mFilterComboBox; - LLUICtrl * mRefreshBtn; - LLUICtrl * mWorkingLabel; - LLUICtrl * mThumbnailPlaceholder; - LLUICtrl * mCaptionTextBox; - LLUICtrl * mPostButton; - LLUICtrl * mCancelButton; - LLButton * mBtnPreview; - - LLFloaterBigPreview * mBigPreviewFloater; - - S32 mQuality; // Compression quality -}; - -class LLFacebookCheckinPanel : public LLPanel -{ -public: - LLFacebookCheckinPanel(); - BOOL postBuild(); - void draw(); - void onSend(); - bool onFacebookConnectStateChange(const LLSD& data); - - void sendCheckin(); - void clearAndClose(); - -private: - std::string mMapUrl; - LLPointer<LLViewerFetchedTexture> mMapTexture; - LLUICtrl* mPostButton; - LLUICtrl* mCancelButton; - LLUICtrl* mMessageTextEditor; - LLUICtrl* mMapLoadingIndicator; - LLIconCtrl* mMapPlaceholder; - LLIconCtrl* mMapDefault; - LLCheckBoxCtrl* mMapCheckBox; - bool mReloadingMapTexture; -}; - -class LLFacebookFriendsPanel : public LLPanel, public LLFriendObserver -{ -public: - LLFacebookFriendsPanel(); - ~LLFacebookFriendsPanel(); - BOOL postBuild(); - virtual void changed(U32 mask); - -private: - bool updateSuggestedFriendList(); - void showFriendsAccordionsIfNeeded(); - void updateFacebookList(bool visible); - bool onConnectedToFacebook(const LLSD& data); - - LLTextBox * mFriendsStatusCaption; - LLAvatarList* mSecondLifeFriends; - LLAvatarList* mSuggestedFriends; -}; - -class LLFloaterFacebook : public LLFloater -{ -public: - LLFloaterFacebook(const LLSD& key); - BOOL postBuild(); - void draw(); - void onClose(bool app_quitting); - void onCancel(); - - void showPhotoPanel(); - -private: - LLFacebookPhotoPanel* mFacebookPhotoPanel; - LLTextBox* mStatusErrorText; - LLTextBox* mStatusLoadingText; - LLUICtrl* mStatusLoadingIndicator; -}; - -#endif // LL_LLFLOATERFACEBOOK_H - diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 7f2e8fd82a..3098c6d118 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1877,6 +1877,7 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel) mLandingTypeCombo(NULL), mSnapshotCtrl(NULL), mLocationText(NULL), + mSeeAvatarsText(NULL), mSetBtn(NULL), mClearBtn(NULL), mMatureCtrl(NULL), @@ -1923,6 +1924,14 @@ BOOL LLPanelLandOptions::postBuild() mSeeAvatarsCtrl = getChild<LLCheckBoxCtrl>( "SeeAvatarsCheck"); childSetCommitCallback("SeeAvatarsCheck", onCommitAny, this); + mSeeAvatarsText = getChild<LLTextBox>("allow_see_label"); + if (mSeeAvatarsText) + { + mSeeAvatarsText->setShowCursorHand(false); + mSeeAvatarsText->setSoundFlags(LLView::MOUSE_UP); + mSeeAvatarsText->setClickedCallback(boost::bind(&toggleSeeAvatars, this)); + } + mCheckShowDirectory = getChild<LLCheckBoxCtrl>( "ShowDirectoryCheck"); childSetCommitCallback("ShowDirectoryCheck", onCommitAny, this); @@ -2016,6 +2025,7 @@ void LLPanelLandOptions::refresh() mSeeAvatarsCtrl->set(TRUE); mSeeAvatarsCtrl->setEnabled(FALSE); + mSeeAvatarsText->setEnabled(FALSE); mLandingTypeCombo->setCurrentByIndex(0); mLandingTypeCombo->setEnabled(FALSE); @@ -2074,6 +2084,7 @@ void LLPanelLandOptions::refresh() mSeeAvatarsCtrl->set(parcel->getSeeAVs()); mSeeAvatarsCtrl->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData()); + mSeeAvatarsText->setEnabled(can_change_options && parcel->getHaveNewParcelLimitData()); BOOL can_change_landing_point = LLViewerParcelMgr::isParcelModifiableByAgent(parcel, GP_LAND_SET_LANDING_POINT); @@ -2364,7 +2375,16 @@ void LLPanelLandOptions::onClickClear(void* userdata) self->refresh(); } - +void LLPanelLandOptions::toggleSeeAvatars(void* userdata) +{ + LLPanelLandOptions* self = (LLPanelLandOptions*)userdata; + if (self) + { + self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->toggle(); + self->getChild<LLCheckBoxCtrl>("SeeAvatarsCheck")->setBtnFocus(); + self->onCommitAny(NULL, userdata); + } +} //--------------------------------------------------------------------------- // LLPanelLandAccess //--------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index e846d42666..0c49d78a20 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -327,6 +327,7 @@ private: static void onCommitAny(LLUICtrl* ctrl, void *userdata); static void onClickSet(void* userdata); static void onClickClear(void* userdata); + static void toggleSeeAvatars(void* userdata); private: LLCheckBoxCtrl* mCheckEditObjects; @@ -345,6 +346,7 @@ private: LLTextureCtrl* mSnapshotCtrl; LLTextBox* mLocationText; + LLTextBox* mSeeAvatarsText; LLButton* mSetBtn; LLButton* mClearBtn; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index b648ff4a7e..9c2ddfb68d 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -331,6 +331,8 @@ BOOL LLFloaterModelPreview::postBuild() childSetCommitCallback("import_scale", onImportScaleCommit, this); childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this); + getChild<LLLineEditor>("description_form")->setKeystrokeCallback(boost::bind(&LLFloaterModelPreview::onDescriptionKeystroke, this, _1), NULL); + getChild<LLCheckBoxCtrl>("show_edges")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); getChild<LLCheckBoxCtrl>("show_physics")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); getChild<LLCheckBoxCtrl>("show_textures")->setCommitCallback(boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _1)); @@ -573,6 +575,16 @@ void LLFloaterModelPreview::onClickCalculateBtn() mUploadBtn->setEnabled(false); } +void LLFloaterModelPreview::onDescriptionKeystroke(LLUICtrl* ctrl) +{ + // Workaround for SL-4186, server doesn't allow name changes after 'calculate' stage + LLLineEditor* input = static_cast<LLLineEditor*>(ctrl); + if (input->isDirty()) // dirty will be reset after commit + { + toggleCalculateButton(true); + } +} + //static void LLFloaterModelPreview::onImportScaleCommit(LLUICtrl*,void* userdata) { diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index c459b9296b..a080965ffc 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -143,7 +143,9 @@ protected: friend class LLModelPreview; friend class LLMeshFilePicker; friend class LLPhysicsDecomp; - + + void onDescriptionKeystroke(LLUICtrl*); + static void onImportScaleCommit(LLUICtrl*, void*); static void onPelvisOffsetCommit(LLUICtrl*, void*); static void onUploadJointsCommit(LLUICtrl*,void*); diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp index d80793f9e4..bfcd1b8b47 100644 --- a/indra/newview/llfloateroutfitsnapshot.cpp +++ b/indra/newview/llfloateroutfitsnapshot.cpp @@ -30,9 +30,7 @@ #include "llfloateroutfitsnapshot.h" #include "llagent.h" -#include "llfacebookconnect.h" #include "llfloaterreg.h" -#include "llfloaterfacebook.h" #include "llfloaterflickr.h" #include "llfloatertwitter.h" #include "llimagefiltersmanager.h" diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index c08aaf3f50..2798e375c7 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -28,9 +28,7 @@ #include "llfloatersnapshot.h" -#include "llfacebookconnect.h" #include "llfloaterreg.h" -#include "llfloaterfacebook.h" #include "llfloaterflickr.h" #include "llfloatertwitter.h" #include "llimagefiltersmanager.h" @@ -784,6 +782,7 @@ void LLFloaterSnapshot::Impl::onCommitLayerTypes(LLUICtrl* ctrl, void*data) previewp->setSnapshotBufferType((LLSnapshotModel::ESnapshotLayerType)combobox->getCurrentIndex()); } view->impl->checkAutoSnapshot(previewp, TRUE); + previewp->updateSnapshot(TRUE, TRUE); } } @@ -1241,11 +1240,10 @@ BOOL LLFloaterSnapshot::isWaitingState() BOOL LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized) { - LLFloaterFacebook* floater_facebook = LLFloaterReg::findTypedInstance<LLFloaterFacebook>("facebook"); LLFloaterFlickr* floater_flickr = LLFloaterReg::findTypedInstance<LLFloaterFlickr>("flickr"); LLFloaterTwitter* floater_twitter = LLFloaterReg::findTypedInstance<LLFloaterTwitter>("twitter"); - if (!initialized && !floater_facebook && !floater_flickr && !floater_twitter) + if (!initialized && !floater_flickr && !floater_twitter) return FALSE; BOOL changed = FALSE; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index ee4fdbe9a5..c2c15ee12b 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -514,11 +514,6 @@ void LLFloaterTools::refresh() selection_info << getString("status_selectcount", selection_args); getChild<LLTextBox>("selection_count")->setText(selection_info.str()); - - bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); - childSetVisible("selection_count", have_selection); - childSetVisible("remaining_capacity", have_selection); - childSetVisible("selection_empty", !have_selection); } diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 3b17368445..13953d6be5 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -30,7 +30,6 @@ #include "lliconctrl.h" #include "llfloaterreg.h" #include "llhttpconstants.h" -#include "llfacebookconnect.h" #include "llflickrconnect.h" #include "lltwitterconnect.h" #include "lllayoutstack.h" @@ -289,17 +288,7 @@ void LLFloaterWebContent::onOpen(const LLSD& key) //virtual void LLFloaterWebContent::onClose(bool app_quitting) { - // If we close the web browsing window showing the facebook login, we need to signal to this object that the connection will not happen - // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad. - LLFloater* fbc_web = LLFloaterReg::findInstance("fbc_web"); - if (fbc_web == this) - { - if (!LLFacebookConnect::instance().isConnected()) - { - LLFacebookConnect::instance().setConnectionState(LLFacebookConnect::FB_CONNECTION_FAILED); - } - } - // Same with Flickr + // If we close the web browsing window showing the Flickr login, we need to signal to this object that the connection will not happen // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad. LLFloater* flickr_web = LLFloaterReg::findInstance("flickr_web"); if (flickr_web == this) @@ -309,7 +298,7 @@ void LLFloaterWebContent::onClose(bool app_quitting) LLFlickrConnect::instance().setConnectionState(LLFlickrConnect::FLICKR_CONNECTION_FAILED); } } - // And Twitter + // Same with Twitter // MAINT-3440 note change here to use findInstance and not getInstance - latter creates an instance if it's not there which is bad. LLFloater* twitter_web = LLFloaterReg::findInstance("twitter_web"); if (twitter_web == this) @@ -380,13 +369,6 @@ void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent // The browser instance wants its window closed. closeFloater(); } - else if(event == MEDIA_EVENT_GEOMETRY_CHANGE) - { - if (mCurrentURL.find("facebook.com/dialog/oauth") == std::string::npos) // HACK to fix ACME-1317 - Cho - { - geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight()); - } - } else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED ) { const std::string text = self->getStatusText(); diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index a9b15fc8b6..fea01786f3 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1005,7 +1005,10 @@ F32 gpu_benchmark() //number of samples to take const S32 samples = 64; - + + //time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark. + const F32 time_limit = 30; + ShaderProfileHelper initProfile; std::vector<LLRenderTarget> dest(count); @@ -1023,12 +1026,14 @@ F32 gpu_benchmark() gGL.setColorMask(true, true); LLGLDepthTest depth(GL_FALSE); + LLTimer alloc_timer; + alloc_timer.start(); for (U32 i = 0; i < count; ++i) { //allocate render targets and textures if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true)) { - LL_WARNS() << "Failed to allocate render target." << LL_ENDL; + LL_WARNS("Benchmark") << "Failed to allocate render target." << LL_ENDL; // abandon the benchmark test delete[] pixels; return -1.f; @@ -1040,12 +1045,20 @@ F32 gpu_benchmark() if (!texHolder.bind(i)) { // can use a dummy value mDummyTexUnit = new LLTexUnit(-1); - LL_WARNS() << "Failed to bind tex unit." << LL_ENDL; + LL_WARNS("Benchmark") << "Failed to bind tex unit." << LL_ENDL; // abandon the benchmark test delete[] pixels; return -1.f; } LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + if (alloc_timer.getElapsedTimeF32() > time_limit) + { + // abandon the benchmark test + LL_WARNS("Benchmark") << "Allocation operation took longer then 30 seconds, stopping." << LL_ENDL; + delete[] pixels; + return -1.f; + } } delete [] pixels; @@ -1055,7 +1068,7 @@ F32 gpu_benchmark() if (!buff->allocateBuffer(3, 0, true)) { - LL_WARNS() << "Failed to allocate buffer during benchmark." << LL_ENDL; + LL_WARNS("Benchmark") << "Failed to allocate buffer during benchmark." << LL_ENDL; // abandon the benchmark test return -1.f; } @@ -1065,7 +1078,7 @@ F32 gpu_benchmark() if (! buff->getVertexStrider(v)) { - LL_WARNS() << "GL LLVertexBuffer::getVertexStrider() returned false, " + LL_WARNS("Benchmark") << "GL LLVertexBuffer::getVertexStrider() returned false, " << "buff->getMappedData() is" << (buff->getMappedData()? " not" : "") << " NULL" << LL_ENDL; @@ -1086,7 +1099,8 @@ F32 gpu_benchmark() buff->setBuffer(LLVertexBuffer::MAP_VERTEX); glFinish(); - for (S32 c = -1; c < samples; ++c) + F32 time_passed = 0; // seconds + for (S32 c = -1; c < samples && time_passed < time_limit; ++c) { LLTimer timer; timer.start(); @@ -1103,6 +1117,7 @@ F32 gpu_benchmark() glFinish(); F32 time = timer.getElapsedTimeF32(); + time_passed += time; if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow { @@ -1117,12 +1132,12 @@ F32 gpu_benchmark() F32 gbps = results[results.size()/2]; - LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << LL_ENDL; - + LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL; + #if LL_DARWIN if (gbps > 512.f) { - LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL; + LL_WARNS("Benchmark") << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL; //OSX is probably lying, discard result return -1.f; } @@ -1131,11 +1146,11 @@ F32 gpu_benchmark() F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f; F32 seconds = ms/1000.f; - F64 samples_drawn = res*res*count*samples; + F64 samples_drawn = res*res*count*results.size(); F32 samples_sec = (samples_drawn/1000000000.0)/seconds; gbps = samples_sec*8; - LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL; + LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL; return gbps; } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 152d0eddcd..088d052533 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -2137,6 +2137,7 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) static U32 lastGroupMemberRequestFrame = 0; // Have we requested the information already this frame? + // Todo: make this per group, we can invite to one group and simultaneously be checking another one if ((lastGroupMemberRequestFrame == gFrameCount) || (mMemberRequestInFlight)) return; @@ -2166,6 +2167,9 @@ void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) return; } + LLGroupMgrGroupData* group_datap = createGroupData(group_id); //make sure group exists + group_datap->mMemberRequestID.generate(); // mark as pending + lastGroupMemberRequestFrame = gFrameCount; LLCoros::instance().launch("LLGroupMgr::groupMembersRequestCoro", diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 940ef6eea1..cf9735e38a 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -258,6 +258,11 @@ public: bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; } bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + bool isMemberDataPending() { return mMemberRequestID.notNull(); } + bool isRoleDataPending() { return mRoleDataRequestID.notNull(); } + bool isRoleMemberDataPending() { return (mRoleMembersRequestID.notNull() || mPendingRoleMemberRequest); } + bool isGroupTitlePending() { return mTitlesRequestID.notNull(); } + bool isSingleMemberNotOwner(); F32 getAccessTime() const { return mAccessTime; } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 074b0c9c14..a50a66a8ce 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1399,13 +1399,6 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, // Only should happen for broken links. new_listener = new LLLinkItemBridge(inventory, root, uuid); break; - case LLAssetType::AT_MESH: - if(!(inv_type == LLInventoryType::IT_MESH)) - { - LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL; - } - new_listener = new LLMeshBridge(inventory, root, uuid); - break; case LLAssetType::AT_UNKNOWN: new_listener = new LLUnknownItemBridge(inventory, root, uuid); break; @@ -2101,7 +2094,9 @@ BOOL LLItemBridge::isItemCopyable() const LLViewerInventoryItem* item = getItem(); if (item) { - // Can't copy worn objects. DEV-15183 + // Can't copy worn objects. + // Worn objects are tied to their inworld conterparts + // Copy of modified worn object will return object with obsolete asset and inventory if(get_is_item_worn(mUUID)) { return FALSE; @@ -6830,58 +6825,6 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } -// +=================================================+ -// | LLMeshBridge | -// +=================================================+ - -LLUIImagePtr LLMeshBridge::getIcon() const -{ - return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE); -} - -void LLMeshBridge::openItem() -{ - LLViewerInventoryItem* item = getItem(); - - if (item) - { - // open mesh - } -} - -void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ - LL_DEBUGS() << "LLMeshBridge::buildContextMenu()" << LL_ENDL; - std::vector<std::string> items; - std::vector<std::string> disabled_items; - - if(isItemInTrash()) - { - items.push_back(std::string("Purge Item")); - if (!isItemRemovable()) - { - disabled_items.push_back(std::string("Purge Item")); - } - - items.push_back(std::string("Restore Item")); - } - else if (isMarketplaceListingsFolder()) - { - addMarketplaceContextMenuOptions(flags, items, disabled_items); - items.push_back(std::string("Properties")); - getClipboardEntries(false, items, disabled_items, flags); - } - else - { - items.push_back(std::string("Properties")); - - getClipboardEntries(true, items, disabled_items, flags); - } - - addLinkReplaceMenuOption(items, disabled_items); - hide_context_entries(menu, items, disabled_items); -} - // +=================================================+ // | LLLinkBridge | @@ -7358,8 +7301,7 @@ bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids) for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it) { LLViewerInventoryItem* item = gInventory.getItem(*it); - LLAssetType::EType asset_type = item->getType(); - if (!item || (asset_type >= LLAssetType::AT_COUNT) || (asset_type <= LLAssetType::AT_NONE)) + if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE)) { return false; } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index ce06e8fffc..f4df566fa6 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -603,23 +603,6 @@ protected: static std::string sPrefix; }; - -class LLMeshBridge : public LLItemBridge -{ - friend class LLInvFVBridge; -public: - virtual LLUIImagePtr getIcon() const; - virtual void openItem(); - virtual void buildContextMenu(LLMenuGL& menu, U32 flags); - -protected: - LLMeshBridge(LLInventoryPanel* inventory, - LLFolderView* root, - const LLUUID& uuid) : - LLItemBridge(inventory, root, uuid) {} -}; - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInvFVBridgeAction // @@ -650,17 +633,6 @@ protected: LLInventoryModel* mModel; }; -class LLMeshBridgeAction: public LLInvFVBridgeAction -{ - friend class LLInvFVBridgeAction; -public: - virtual void doIt() ; - virtual ~LLMeshBridgeAction(){} -protected: - LLMeshBridgeAction(const LLUUID& id,LLInventoryModel* model):LLInvFVBridgeAction(id,model){} - -}; - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Recent Inventory Panel related classes diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 9193613e9f..16385928b4 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -58,6 +58,7 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p) mHoursAgo(p.hours_ago), mDateSearchDirection(p.date_search_direction), mShowFolderState(p.show_folder_state), + mFilterCreatorType(p.creator_type), mPermissions(p.permissions), mFilterTypes(p.types), mFilterUUID(p.uuid), @@ -78,8 +79,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p) mCurrentGeneration(0), mFirstRequiredGeneration(0), mFirstSuccessGeneration(0), - mSearchType(SEARCHTYPE_NAME), - mFilterCreatorType(FILTERCREATOR_ALL) + mSearchType(SEARCHTYPE_NAME) { // copy mFilterOps into mDefaultFilterOps markDefault(); @@ -489,7 +489,7 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory { if (!listener) return TRUE; const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY; - switch(mFilterCreatorType) + switch (mFilterOps.mFilterCreatorType) { case FILTERCREATOR_SELF: if(is_folder) return FALSE; @@ -601,9 +601,9 @@ void LLInventoryFilter::setSearchType(ESearchType type) void LLInventoryFilter::setFilterCreator(EFilterCreatorType type) { - if(mFilterCreatorType != type) + if (mFilterOps.mFilterCreatorType != type) { - mFilterCreatorType = type; + mFilterOps.mFilterCreatorType = type; setModified(); } } @@ -1194,6 +1194,7 @@ void LLInventoryFilter::toParams(Params& params) const params.filter_ops.hours_ago = getHoursAgo(); params.filter_ops.date_search_direction = getDateSearchDirection(); params.filter_ops.show_folder_state = getShowFolderState(); + params.filter_ops.creator_type = getFilterCreatorType(); params.filter_ops.permissions = getFilterPermissions(); params.substring = getFilterSubString(); params.since_logoff = isSinceLogoff(); @@ -1216,6 +1217,7 @@ void LLInventoryFilter::fromParams(const Params& params) setHoursAgo(params.filter_ops.hours_ago); setDateSearchDirection(params.filter_ops.date_search_direction); setShowFolderState(params.filter_ops.show_folder_state); + setFilterCreator(params.filter_ops.creator_type); setFilterPermissions(params.filter_ops.permissions); setFilterSubString(params.substring); setDateRangeLastLogoff(params.since_logoff); @@ -1278,6 +1280,11 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const return mFilterOps.mShowFolderState; } +LLInventoryFilter::EFilterCreatorType LLInventoryFilter::getFilterCreatorType() const +{ + return mFilterOps.mFilterCreatorType; +} + bool LLInventoryFilter::isTimedOut() { return mFilterTime.hasExpired(); diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 01754ed023..4a1fec8454 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -126,6 +126,7 @@ public: Optional<U32> date_search_direction; Optional<EFolderShow> show_folder_state; Optional<PermissionMask> permissions; + Optional<EFilterCreatorType> creator_type; Params() : types("filter_types", FILTERTYPE_OBJECT), @@ -138,6 +139,7 @@ public: hours_ago("hours_ago", 0), date_search_direction("date_search_direction", FILTERDATEDIRECTION_NEWER), show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS), + creator_type("creator_type", FILTERCREATOR_ALL), permissions("permissions", PERM_NONE) {} }; @@ -156,8 +158,9 @@ public: U32 mHoursAgo; U32 mDateSearchDirection; - EFolderShow mShowFolderState; - PermissionMask mPermissions; + EFolderShow mShowFolderState; + PermissionMask mPermissions; + EFilterCreatorType mFilterCreatorType; }; struct Params : public LLInitParam::Block<Params> @@ -202,7 +205,6 @@ public: void setSearchType(ESearchType type); ESearchType getSearchType() { return mSearchType; } void setFilterCreator(EFilterCreatorType type); - EFilterCreatorType getFilterCreator() { return mFilterCreatorType; } void setFilterSubString(const std::string& string); const std::string& getFilterSubString(BOOL trim = FALSE) const; @@ -243,8 +245,9 @@ public: // +-------------------------------------------------------------------+ // + Presentation // +-------------------------------------------------------------------+ - void setShowFolderState( EFolderShow state); - EFolderShow getShowFolderState() const; + void setShowFolderState( EFolderShow state); + EFolderShow getShowFolderState() const; + EFilterCreatorType getFilterCreatorType() const; void setEmptyLookupMessage(const std::string& message); std::string getEmptyLookupMessage() const; @@ -324,7 +327,6 @@ private: std::string mEmptyLookupMessage; ESearchType mSearchType; - EFilterCreatorType mFilterCreatorType; }; #endif diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index d0df1c94d5..ee6e3dd384 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -83,6 +83,7 @@ LLIconDictionary::LLIconDictionary() addEntry(LLInventoryType::ICONNAME_CLOTHING_SKIRT, new IconEntry("Inv_Skirt")); addEntry(LLInventoryType::ICONNAME_CLOTHING_ALPHA, new IconEntry("Inv_Alpha")); addEntry(LLInventoryType::ICONNAME_CLOTHING_TATTOO, new IconEntry("Inv_Tattoo")); + addEntry(LLInventoryType::ICONNAME_CLOTHING_UNIVERSAL, new IconEntry("Inv_Universal")); addEntry(LLInventoryType::ICONNAME_ANIMATION, new IconEntry("Inv_Animation")); addEntry(LLInventoryType::ICONNAME_GESTURE, new IconEntry("Inv_Gesture")); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index b140c7c38e..c49d61df31 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -888,14 +888,6 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask) return mask; } - // We're hiding mesh types -#if 0 - if (item->getType() == LLAssetType::AT_MESH) - { - return mask; - } -#endif - LLPointer<LLViewerInventoryItem> old_item = getItem(item->getUUID()); LLPointer<LLViewerInventoryItem> new_item; if(old_item) diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 760325b652..0243e2183e 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -381,6 +381,7 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) updateUserLayers(old_id, new_id, LLWearableType::WT_SKIRT); updateUserLayers(old_id, new_id, LLWearableType::WT_SOCKS); updateUserLayers(old_id, new_id, LLWearableType::WT_TATTOO); + updateUserLayers(old_id, new_id, LLWearableType::WT_UNIVERSAL); updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS); updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT); } @@ -512,7 +513,7 @@ void LLLocalBitmap::updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel) { LLVOVolume* volobjp = (*old_texture->getVolumeList(channel))[volume_iter]; switch (channel) - { + { case LLRender::LIGHT_TEX: { if (volobjp->getLightTextureID() == old_id) @@ -526,19 +527,19 @@ void LLLocalBitmap::updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel) LLViewerObject* object = (LLViewerObject*)volobjp; if (object) - { - if (object->isSculpted() && object->getVolume() && - object->getVolume()->getParams().getSculptID() == old_id) - { - LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLSculptParams new_params(*old_params); - new_params.setSculptTexture(new_id, (*old_params).getSculptType()); - object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, TRUE); - } - } + { + if (object->isSculpted() && object->getVolume() && + object->getVolume()->getParams().getSculptID() == old_id) + { + LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + LLSculptParams new_params(*old_params); + new_params.setSculptTexture(new_id, (*old_params).getSculptType()); + object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, TRUE); } } } + } + } } void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type) @@ -746,7 +747,7 @@ LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex( case LLWearableType::WT_TATTOO: { - switch(baked_texind) + switch (baked_texind) { case LLAvatarAppearanceDefines::BAKED_HEAD: { @@ -764,6 +765,75 @@ LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex( result = LLAvatarAppearanceDefines::TEX_UPPER_TATTOO; break; } + default: + { + break; + } + } + break; + + } + case LLWearableType::WT_UNIVERSAL: + { + switch (baked_texind) + { + + case LLAvatarAppearanceDefines::BAKED_SKIRT: + { + result = LLAvatarAppearanceDefines::TEX_SKIRT_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_EYES: + { + result = LLAvatarAppearanceDefines::TEX_EYES_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_HAIR: + { + result = LLAvatarAppearanceDefines::TEX_HAIR_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_LEFT_ARM: + { + result = LLAvatarAppearanceDefines::TEX_LEFT_ARM_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_LEFT_LEG: + { + result = LLAvatarAppearanceDefines::TEX_LEFT_LEG_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_AUX1: + { + result = LLAvatarAppearanceDefines::TEX_AUX1_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_AUX2: + { + result = LLAvatarAppearanceDefines::TEX_AUX2_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_AUX3: + { + result = LLAvatarAppearanceDefines::TEX_AUX3_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_UPPER: + { + result = LLAvatarAppearanceDefines::TEX_UPPER_UNIVERSAL_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_LOWER: + { + result = LLAvatarAppearanceDefines::TEX_LOWER_UNIVERSAL_TATTOO; + break; + } + case LLAvatarAppearanceDefines::BAKED_HEAD: + { + result = LLAvatarAppearanceDefines::TEX_HEAD_UNIVERSAL_TATTOO; + break; + } + default: { diff --git a/indra/newview/llmachineid.cpp b/indra/newview/llmachineid.cpp index b0ee8e7fcb..51127928d1 100644 --- a/indra/newview/llmachineid.cpp +++ b/indra/newview/llmachineid.cpp @@ -65,11 +65,11 @@ public: S32 LLMachineID::init() { - memset(static_unique_id,0,sizeof(static_unique_id)); + size_t len = sizeof(static_unique_id); + memset(static_unique_id, 0, len); S32 ret_code = 0; #if LL_WINDOWS # pragma comment(lib, "wbemuuid.lib") - size_t len = sizeof(static_unique_id); // algorithm to detect BIOS serial number found at: // http://msdn.microsoft.com/en-us/library/aa394077%28VS.85%29.aspx @@ -217,17 +217,27 @@ S32 LLMachineID::init() // Get the value of the Name property hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); + if (FAILED(hr)) + { + LL_WARNS() << "Failed to get SerialNumber. Error code = 0x" << hex << hres << LL_ENDL; + pclsObj->Release(); + pclsObj = NULL; + continue; + } LL_INFOS("AppInit") << " Serial Number : " << vtProp.bstrVal << LL_ENDL; + // use characters in the returned Serial Number to create a byte array of size len BSTR serialNumber ( vtProp.bstrVal); + unsigned int serial_size = SysStringLen(serialNumber); unsigned int j = 0; - while( vtProp.bstrVal[j] != 0) + + while (j < serial_size && vtProp.bstrVal[j] != 0) { for (unsigned int i = 0; i < len; i++) { - if (vtProp.bstrVal[j] == 0) + if (j >= serial_size || vtProp.bstrVal[j] == 0) break; - + static_unique_id[i] = (unsigned int)(static_unique_id[i] + serialNumber[j]); j++; } @@ -254,16 +264,8 @@ S32 LLMachineID::init() ret_code = LLUUID::getNodeID(staticPtr); #endif has_static_unique_id = true; - return ret_code; -} - -S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) -{ - if (has_static_unique_id) - { - memcpy ( unique_id, &static_unique_id, len); - LL_INFOS_ONCE("AppInit") << "UniqueID: 0x"; + LL_INFOS("AppInit") << "UniqueID: 0x"; // Code between here and LL_ENDL is not executed unless the LL_DEBUGS // actually produces output for (size_t i = 0; i < len; ++i) @@ -271,11 +273,21 @@ S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) // Copy each char to unsigned int to hexify. Sending an unsigned // char to a std::ostream tries to represent it as a char, not // what we want here. - unsigned byte = unique_id[i]; + unsigned byte = static_unique_id[i]; LL_CONT << std::hex << std::setw(2) << std::setfill('0') << byte; } // Reset default output formatting to avoid nasty surprises! LL_CONT << std::dec << std::setw(0) << std::setfill(' ') << LL_ENDL; + + return ret_code; +} + + +S32 LLMachineID::getUniqueID(unsigned char *unique_id, size_t len) +{ + if (has_static_unique_id) + { + memcpy ( unique_id, &static_unique_id, len); return 1; } return 0; diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 62e0e2d077..d7c5364fba 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -34,6 +34,7 @@ #include "llcachename.h" #include "llfloater.h" #include "llfloaterreg.h" +#include "llfloatersnapshot.h" // gSnapshotFloaterView #include "llinventory.h" #include "llscrolllistitem.h" #include "llscrolllistcell.h" @@ -236,24 +237,30 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) // Spawn at right side of cell LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small"); - LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 ); - - // Should we show a group or an avatar inspector? - bool is_group = hit_item->isGroup(); - bool is_experience = hit_item->isExperience(); - - LLToolTip::Params params; - params.background_visible( false ); - params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience) ); - params.delay_time(0.0f); // spawn instantly on hover - params.image( icon ); - params.message(""); - params.padding(0); - params.pos(pos); - params.sticky_rect(sticky_rect); - - LLToolTipMgr::getInstance()->show(params); - handled = TRUE; + S32 screenX = sticky_rect.mRight - info_icon_size; + S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2; + LLCoordGL pos(screenX, screenY); + + LLFloater* snapshot_floatr = gSnapshotFloaterView->getFrontmostClosableFloater(); + if (!snapshot_floatr || !snapshot_floatr->getRect().pointInRect(screenX + icon->getWidth(), screenY)) + { + // Should we show a group or an avatar inspector? + bool is_group = hit_item->isGroup(); + bool is_experience = hit_item->isExperience(); + + LLToolTip::Params params; + params.background_visible(false); + params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience)); + params.delay_time(0.0f); // spawn instantly on hover + params.image(icon); + params.message(""); + params.padding(0); + params.pos(pos); + params.sticky_rect(sticky_rect); + + LLToolTipMgr::getInstance()->show(params); + handled = TRUE; + } } } } diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp index fef0631fa6..ba831ab2ed 100644 --- a/indra/newview/llnotificationscripthandler.cpp +++ b/indra/newview/llnotificationscripthandler.cpp @@ -35,7 +35,6 @@ #include "llnotificationmanager.h" #include "llnotifications.h" #include "llscriptfloater.h" -#include "llfacebookconnect.h" #include "llavatarname.h" #include "llavatarnamecache.h" diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 3a8378f8df..6573be0aaf 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -97,6 +97,7 @@ enum ESubpart { SUBPART_SKIRT, SUBPART_ALPHA, SUBPART_TATTOO, + SUBPART_UNIVERSAL, SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, @@ -241,7 +242,8 @@ LLEditWearableDictionary::Wearables::Wearables() addEntry(LLWearableType::WT_SKIRT, new WearableEntry(LLWearableType::WT_SKIRT,"edit_skirt_title","skirt_desc_text", texture_vec_t{TEX_SKIRT}, texture_vec_t{TEX_SKIRT}, subpart_vec_t{SUBPART_SKIRT})); addEntry(LLWearableType::WT_ALPHA, new WearableEntry(LLWearableType::WT_ALPHA,"edit_alpha_title","alpha_desc_text", texture_vec_t(), texture_vec_t{TEX_LOWER_ALPHA, TEX_UPPER_ALPHA, TEX_HEAD_ALPHA, TEX_EYES_ALPHA, TEX_HAIR_ALPHA}, subpart_vec_t{SUBPART_ALPHA})); addEntry(LLWearableType::WT_TATTOO, new WearableEntry(LLWearableType::WT_TATTOO,"edit_tattoo_title","tattoo_desc_text", texture_vec_t{TEX_HEAD_TATTOO}, texture_vec_t{TEX_LOWER_TATTOO, TEX_UPPER_TATTOO, TEX_HEAD_TATTOO}, subpart_vec_t{SUBPART_TATTOO})); - addEntry(LLWearableType::WT_PHYSICS, new WearableEntry(LLWearableType::WT_PHYSICS,"edit_physics_title","physics_desc_text", texture_vec_t(), texture_vec_t(), subpart_vec_t{SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, SUBPART_PHYSICS_BELLY_UPDOWN, SUBPART_PHYSICS_BUTT_UPDOWN, SUBPART_PHYSICS_BUTT_LEFTRIGHT, SUBPART_PHYSICS_ADVANCED})); + addEntry(LLWearableType::WT_UNIVERSAL, new WearableEntry(LLWearableType::WT_UNIVERSAL, "edit_universal_title", "universal_desc_text", texture_vec_t{ TEX_HEAD_UNIVERSAL_TATTOO }, texture_vec_t{ TEX_HEAD_UNIVERSAL_TATTOO, TEX_UPPER_UNIVERSAL_TATTOO, TEX_LOWER_UNIVERSAL_TATTOO, TEX_SKIRT_TATTOO, TEX_HAIR_TATTOO, TEX_EYES_TATTOO, TEX_LEFT_ARM_TATTOO, TEX_LEFT_LEG_TATTOO, TEX_AUX1_TATTOO, TEX_AUX2_TATTOO, TEX_AUX3_TATTOO }, subpart_vec_t{ SUBPART_UNIVERSAL })); + addEntry(LLWearableType::WT_PHYSICS, new WearableEntry(LLWearableType::WT_PHYSICS,"edit_physics_title","physics_desc_text", texture_vec_t(), texture_vec_t(), subpart_vec_t{SUBPART_PHYSICS_BREASTS_UPDOWN, SUBPART_PHYSICS_BREASTS_INOUT, SUBPART_PHYSICS_BREASTS_LEFTRIGHT, SUBPART_PHYSICS_BELLY_UPDOWN, SUBPART_PHYSICS_BUTT_UPDOWN, SUBPART_PHYSICS_BUTT_LEFTRIGHT, SUBPART_PHYSICS_ADVANCED})); } LLEditWearableDictionary::WearableEntry::WearableEntry(LLWearableType::EType type, @@ -294,7 +296,9 @@ LLEditWearableDictionary::Subparts::Subparts() addEntry(SUBPART_UNDERPANTS, new SubpartEntry(SUBPART_UNDERPANTS, "mPelvis", "underpants", "underpants_main_param_list", "underpants_main_tab", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f),SEX_BOTH)); addEntry(SUBPART_ALPHA, new SubpartEntry(SUBPART_ALPHA, "mPelvis", "alpha", "alpha_main_param_list", "alpha_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH)); addEntry(SUBPART_TATTOO, new SubpartEntry(SUBPART_TATTOO, "mPelvis", "tattoo", "tattoo_main_param_list", "tattoo_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f),SEX_BOTH)); - addEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, "mTorso", "physics_breasts_updown", "physics_breasts_updown_param_list", "physics_breasts_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE)); + addEntry(SUBPART_UNIVERSAL, new SubpartEntry(SUBPART_UNIVERSAL, "mPelvis", "universal", "universal_main_param_list", "universal_main_tab", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f), SEX_BOTH)); + + addEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BREASTS_UPDOWN, "mTorso", "physics_breasts_updown", "physics_breasts_updown_param_list", "physics_breasts_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE)); addEntry(SUBPART_PHYSICS_BREASTS_INOUT, new SubpartEntry(SUBPART_PHYSICS_BREASTS_INOUT, "mTorso", "physics_breasts_inout", "physics_breasts_inout_param_list", "physics_breasts_inout_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE)); addEntry(SUBPART_PHYSICS_BREASTS_LEFTRIGHT, new SubpartEntry(SUBPART_PHYSICS_BREASTS_LEFTRIGHT, "mTorso", "physics_breasts_leftright", "physics_breasts_leftright_param_list", "physics_breasts_leftright_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_FEMALE)); addEntry(SUBPART_PHYSICS_BELLY_UPDOWN, new SubpartEntry(SUBPART_PHYSICS_BELLY_UPDOWN, "mTorso", "physics_belly_updown", "physics_belly_updown_param_list", "physics_belly_updown_tab", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(0.f, 0.f, 0.f),SEX_BOTH)); @@ -335,6 +339,7 @@ LLEditWearableDictionary::ColorSwatchCtrls::ColorSwatchCtrls() addEntry ( TEX_UPPER_UNDERSHIRT, new PickerControlEntry (TEX_UPPER_UNDERSHIRT, "Color/Tint" )); addEntry ( TEX_LOWER_UNDERPANTS, new PickerControlEntry (TEX_LOWER_UNDERPANTS, "Color/Tint" )); addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry(TEX_HEAD_TATTOO, "Color/Tint" )); + addEntry (TEX_HEAD_UNIVERSAL_TATTOO, new PickerControlEntry(TEX_HEAD_UNIVERSAL_TATTOO, "Color/Tint")); } LLEditWearableDictionary::TextureCtrls::TextureCtrls() @@ -362,6 +367,17 @@ LLEditWearableDictionary::TextureCtrls::TextureCtrls() addEntry ( TEX_LOWER_TATTOO, new PickerControlEntry (TEX_LOWER_TATTOO, "Lower Tattoo", LLUUID::null, TRUE )); addEntry ( TEX_UPPER_TATTOO, new PickerControlEntry (TEX_UPPER_TATTOO, "Upper Tattoo", LLUUID::null, TRUE )); addEntry ( TEX_HEAD_TATTOO, new PickerControlEntry (TEX_HEAD_TATTOO, "Head Tattoo", LLUUID::null, TRUE )); + addEntry ( TEX_LOWER_UNIVERSAL_TATTOO, new PickerControlEntry( TEX_LOWER_UNIVERSAL_TATTOO, "Lower Universal Tattoo", LLUUID::null, TRUE)); + addEntry ( TEX_UPPER_UNIVERSAL_TATTOO, new PickerControlEntry( TEX_UPPER_UNIVERSAL_TATTOO, "Upper Universal Tattoo", LLUUID::null, TRUE)); + addEntry ( TEX_HEAD_UNIVERSAL_TATTOO, new PickerControlEntry( TEX_HEAD_UNIVERSAL_TATTOO, "Head Universal Tattoo", LLUUID::null, TRUE)); + addEntry ( TEX_SKIRT_TATTOO, new PickerControlEntry(TEX_SKIRT_TATTOO, "Skirt Tattoo", LLUUID::null, TRUE)); + addEntry ( TEX_HAIR_TATTOO, new PickerControlEntry(TEX_HAIR_TATTOO, "Hair Tattoo", LLUUID::null, TRUE)); + addEntry ( TEX_EYES_TATTOO, new PickerControlEntry(TEX_EYES_TATTOO, "Eyes Tattoo", LLUUID::null, TRUE)); + addEntry (TEX_LEFT_ARM_TATTOO, new PickerControlEntry(TEX_LEFT_ARM_TATTOO, "Left Arm Tattoo", LLUUID::null, TRUE)); + addEntry (TEX_LEFT_LEG_TATTOO, new PickerControlEntry(TEX_LEFT_LEG_TATTOO, "Left Leg Tattoo", LLUUID::null, TRUE)); + addEntry (TEX_AUX1_TATTOO, new PickerControlEntry(TEX_AUX1_TATTOO, "Aux1 Tattoo", LLUUID::null, TRUE)); + addEntry (TEX_AUX2_TATTOO, new PickerControlEntry(TEX_AUX2_TATTOO, "Aux2 Tattoo", LLUUID::null, TRUE)); + addEntry (TEX_AUX3_TATTOO, new PickerControlEntry(TEX_AUX3_TATTOO, "Aux3 Tattoo", LLUUID::null, TRUE)); } LLEditWearableDictionary::PickerControlEntry::PickerControlEntry(ETextureIndex tex_index, @@ -739,6 +755,7 @@ BOOL LLPanelEditWearable::postBuild() mPanelSkirt = getChild<LLPanel>("edit_skirt_panel"); mPanelAlpha = getChild<LLPanel>("edit_alpha_panel"); mPanelTattoo = getChild<LLPanel>("edit_tattoo_panel"); + mPanelUniversal = getChild<LLPanel>("edit_universal_panel"); mPanelPhysics = getChild<LLPanel>("edit_physics_panel"); mTxtAvatarHeight = mPanelShape->getChild<LLTextBox>("avatar_height"); @@ -1442,6 +1459,10 @@ LLPanel* LLPanelEditWearable::getPanel(LLWearableType::EType type) case LLWearableType::WT_TATTOO: return mPanelTattoo; break; + + case LLWearableType::WT_UNIVERSAL: + return mPanelUniversal; + break; case LLWearableType::WT_PHYSICS: return mPanelPhysics; diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 81acc31863..43d6a3595f 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -167,6 +167,7 @@ private: LLPanel *mPanelSkirt; LLPanel *mPanelAlpha; LLPanel *mPanelTattoo; + LLPanel *mPanelUniversal; LLPanel *mPanelPhysics; typedef std::map<std::string, LLAvatarAppearanceDefines::ETextureIndex> string_texture_index_map_t; diff --git a/indra/newview/llpanelexperiencepicker.cpp b/indra/newview/llpanelexperiencepicker.cpp index a7f2dbafa2..80aeee6da1 100644 --- a/indra/newview/llpanelexperiencepicker.cpp +++ b/indra/newview/llpanelexperiencepicker.cpp @@ -89,7 +89,7 @@ BOOL LLPanelExperiencePicker::postBuild() childSetAction(BTN_PROFILE, boost::bind(&LLPanelExperiencePicker::onBtnProfile, this)); getChildView(BTN_PROFILE)->setEnabled(FALSE); - getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(2); + getChild<LLComboBox>(TEXT_MATURITY)->setCurrentByIndex(gSavedPerAccountSettings.getU32("ExperienceSearchMaturity")); getChild<LLComboBox>(TEXT_MATURITY)->setCommitCallback(boost::bind(&LLPanelExperiencePicker::onMaturity, this)); getChild<LLUICtrl>(TEXT_EDIT)->setFocus(TRUE); @@ -381,6 +381,7 @@ void LLPanelExperiencePicker::filterContent() void LLPanelExperiencePicker::onMaturity() { + gSavedPerAccountSettings.setU32("ExperienceSearchMaturity", getChild<LLComboBox>(TEXT_MATURITY)->getCurrentIndex()); if(mResponse.has("experience_keys") && mResponse["experience_keys"].beginArray() != mResponse["experience_keys"].endArray()) { filterContent(); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 392bacb8d9..c686aab821 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -82,6 +82,8 @@ const S32 ALPHAMODE_MASK = 2; // Alpha masking mode const S32 BUMPY_TEXTURE = 18; // use supplied normal map const S32 SHINY_TEXTURE = 4; // use supplied specular map +BOOST_STATIC_ASSERT(MATTYPE_DIFFUSE == LLRender::DIFFUSE_MAP && MATTYPE_NORMAL == LLRender::NORMAL_MAP && MATTYPE_SPECULAR == LLRender::SPECULAR_MAP); + // // "Use texture" label for normal/specular type comboboxes // Filled in at initialization from translated strings @@ -154,6 +156,7 @@ BOOL LLPanelFace::postBuild() childSetCommitCallback("maskcutoff",&LLPanelFace::onCommitMaterialMaskCutoff, this); childSetAction("button align",&LLPanelFace::onClickAutoFix,this); + childSetAction("button align textures", &LLPanelFace::onAlignTexture, this); LLTextureCtrl* mTextureCtrl; LLTextureCtrl* mShinyTextureCtrl; @@ -439,11 +442,28 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor { BOOL valid; F32 value; - LLSpinCtrl* ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>("TexScaleU"); - LLSpinCtrl* ctrlTexScaleT = mPanel->getChild<LLSpinCtrl>("TexScaleV"); - LLSpinCtrl* ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>("TexOffsetU"); - LLSpinCtrl* ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>("TexOffsetV"); - LLSpinCtrl* ctrlTexRotation = mPanel->getChild<LLSpinCtrl>("TexRot"); + + LLRadioGroup * radio_mat_type = mPanel->getChild<LLRadioGroup>("radio_material_type"); + std::string prefix; + switch (radio_mat_type->getSelectedIndex()) + { + case MATTYPE_DIFFUSE: + prefix = "Tex"; + break; + case MATTYPE_NORMAL: + prefix = "bumpy"; + break; + case MATTYPE_SPECULAR: + prefix = "shiny"; + break; + } + + LLSpinCtrl * ctrlTexScaleS = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleU"); + LLSpinCtrl * ctrlTexScaleT = mPanel->getChild<LLSpinCtrl>(prefix + "ScaleV"); + LLSpinCtrl * ctrlTexOffsetS = mPanel->getChild<LLSpinCtrl>(prefix + "OffsetU"); + LLSpinCtrl * ctrlTexOffsetT = mPanel->getChild<LLSpinCtrl>(prefix + "OffsetV"); + LLSpinCtrl * ctrlTexRotation = mPanel->getChild<LLSpinCtrl>(prefix + "Rot"); + LLComboBox* comboTexGen = mPanel->getChild<LLComboBox>("combobox texgen"); LLCheckBoxCtrl* cb_planar_align = mPanel->getChild<LLCheckBoxCtrl>("checkbox planar align"); bool align_planar = (cb_planar_align && cb_planar_align->get()); @@ -466,8 +486,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor if (align_planar) { - LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te); - LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te); + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, value, te, object->getID()); } } } @@ -491,8 +511,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor if (align_planar) { - LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te); - LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te); + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, value, te, object->getID()); } } } @@ -507,8 +527,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor if (align_planar) { - LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te); - LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te); + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, value, te, object->getID()); } } } @@ -523,8 +543,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor if (align_planar) { - LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te); - LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te); + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, value, te, object->getID()); } } } @@ -539,8 +559,8 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor if (align_planar) { - LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te); - LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te); + LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, value, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, value, te, object->getID()); } } } @@ -612,6 +632,68 @@ private: LLFace* mCenterFace; }; +struct LLPanelFaceSetAlignedConcreteTEFunctor : public LLSelectedTEFunctor +{ + LLPanelFaceSetAlignedConcreteTEFunctor(LLPanelFace* panel, LLFace* center_face, LLRender::eTexIndex map) : + mPanel(panel), + mChefFace(center_face), + mMap(map) + {} + + virtual bool apply(LLViewerObject* object, S32 te) + { + LLFace* facep = object->mDrawable->getFace(te); + if (!facep) + { + return true; + } + + if (facep->getViewerObject()->getVolume()->getNumVolumeFaces() <= te) + { + return true; + } + + if (mChefFace != facep) + { + LLVector2 uv_offset, uv_scale; + F32 uv_rot; + if (facep->calcAlignedPlanarTE(mChefFace, &uv_offset, &uv_scale, &uv_rot, mMap)) + { + switch (mMap) + { + case LLRender::DIFFUSE_MAP: + object->setTEOffset(te, uv_offset.mV[VX], uv_offset.mV[VY]); + object->setTEScale(te, uv_scale.mV[VX], uv_scale.mV[VY]); + object->setTERotation(te, uv_rot); + break; + case LLRender::NORMAL_MAP: + LLPanelFace::LLSelectedTEMaterial::setNormalRotation(mPanel, uv_rot, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetX(mPanel, uv_offset.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setNormalOffsetY(mPanel, uv_offset.mV[VY], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatX(mPanel, uv_scale.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setNormalRepeatY(mPanel, uv_scale.mV[VY], te, object->getID()); + break; + case LLRender::SPECULAR_MAP: + LLPanelFace::LLSelectedTEMaterial::setSpecularRotation(mPanel, uv_rot, te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetX(mPanel, uv_offset.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularOffsetY(mPanel, uv_offset.mV[VY], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatX(mPanel, uv_scale.mV[VX], te, object->getID()); + LLPanelFace::LLSelectedTEMaterial::setSpecularRepeatY(mPanel, uv_scale.mV[VY], te, object->getID()); + break; + default: /*make compiler happy*/ + break; + } + } + } + + return true; + } +private: + LLPanelFace* mPanel; + LLFace* mChefFace; + LLRender::eTexIndex mMap; +}; + // Functor that tests if a face is aligned to mCenterFace struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor { @@ -697,6 +779,17 @@ void LLPanelFace::sendTextureInfo() LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); } +void LLPanelFace::alignTestureLayer() +{ + LLFace* last_face = NULL; + bool identical_face = false; + LLSelectedTE::getFace(last_face, identical_face); + + LLRadioGroup * radio_mat_type = getChild<LLRadioGroup>("radio_material_type"); + LLPanelFaceSetAlignedConcreteTEFunctor setfunc(this, last_face, static_cast<LLRender::eTexIndex>(radio_mat_type->getSelectedIndex())); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); +} + void LLPanelFace::getState() { updateUI(); @@ -921,41 +1014,75 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } updateAlphaControls(); - - if(texture_ctrl) + + if (texture_ctrl) { if (identical_diffuse) { - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); + texture_ctrl->setTentative(FALSE); + texture_ctrl->setEnabled(editable); + texture_ctrl->setImageAssetID(id); getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); getChildView("label alphamode")->setEnabled(editable && mIsAlpha); getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + + bool allAttachments = true; + for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); + iter != LLSelectMgr::getInstance()->getSelection()->end();iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (!object->isAttachment()) + { + allAttachments = false; + break; + } + } + + texture_ctrl->setBakeTextureEnabled(allAttachments); + } else if (id.isNull()) { // None selected - texture_ctrl->setTentative( FALSE ); - texture_ctrl->setEnabled( FALSE ); - texture_ctrl->setImageAssetID( LLUUID::null ); - getChildView("combobox alphamode")->setEnabled( FALSE ); - getChildView("label alphamode")->setEnabled( FALSE ); - getChildView("maskcutoff")->setEnabled( FALSE); - getChildView("label maskcutoff")->setEnabled( FALSE ); + texture_ctrl->setTentative(FALSE); + texture_ctrl->setEnabled(FALSE); + texture_ctrl->setImageAssetID(LLUUID::null); + getChildView("combobox alphamode")->setEnabled(FALSE); + getChildView("label alphamode")->setEnabled(FALSE); + getChildView("maskcutoff")->setEnabled(FALSE); + getChildView("label maskcutoff")->setEnabled(FALSE); + + texture_ctrl->setBakeTextureEnabled(false); } else { // Tentative: multiple selected with different textures - texture_ctrl->setTentative( TRUE ); - texture_ctrl->setEnabled( editable ); - texture_ctrl->setImageAssetID( id ); + texture_ctrl->setTentative(TRUE); + texture_ctrl->setEnabled(editable); + texture_ctrl->setImageAssetID(id); getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f); getChildView("label alphamode")->setEnabled(editable && mIsAlpha); getChildView("maskcutoff")->setEnabled(editable && mIsAlpha); getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha); + + bool allAttachments = true; + for (LLObjectSelection::iterator iter = LLSelectMgr::getInstance()->getSelection()->begin(); + iter != LLSelectMgr::getInstance()->getSelection()->end();iter++) + { + LLSelectNode* node = *iter; + LLViewerObject* object = node->getObject(); + if (!object->isAttachment()) + { + allAttachments = false; + break; + } + } + + texture_ctrl->setBakeTextureEnabled(allAttachments); } + } if (shinytexture_ctrl) @@ -983,6 +1110,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool enabled = (editable && isIdenticalPlanarTexgen()); childSetValue("checkbox planar align", align_planar && enabled); childSetEnabled("checkbox planar align", enabled); + childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1); if (align_planar && enabled) { @@ -2134,7 +2262,18 @@ void LLPanelFace::onCommitMaterialBumpyRot(LLUICtrl* ctrl, void* userdata) } else { - LLSelectedTEMaterial::setNormalRotation(self,self->getCurrentBumpyRot() * DEG_TO_RAD); + if ((bool)self->childGetValue("checkbox planar align").asBoolean()) + { + LLFace* last_face = NULL; + bool identical_face = false; + LLSelectedTE::getFace(last_face, identical_face); + LLPanelFaceSetAlignedTEFunctor setfunc(self, last_face); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); + } + else + { + LLSelectedTEMaterial::setNormalRotation(self, self->getCurrentBumpyRot() * DEG_TO_RAD); + } } } @@ -2151,7 +2290,18 @@ void LLPanelFace::onCommitMaterialShinyRot(LLUICtrl* ctrl, void* userdata) } else { - LLSelectedTEMaterial::setSpecularRotation(self,self->getCurrentShinyRot() * DEG_TO_RAD); + if ((bool)self->childGetValue("checkbox planar align").asBoolean()) + { + LLFace* last_face = NULL; + bool identical_face = false; + LLSelectedTE::getFace(last_face, identical_face); + LLPanelFaceSetAlignedTEFunctor setfunc(self, last_face); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&setfunc); + } + else + { + LLSelectedTEMaterial::setSpecularRotation(self, self->getCurrentShinyRot() * DEG_TO_RAD); + } } } @@ -2408,6 +2558,11 @@ void LLPanelFace::onClickAutoFix(void* userdata) LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); } +void LLPanelFace::onAlignTexture(void* userdata) +{ + LLPanelFace* self = (LLPanelFace*)userdata; + self->alignTestureLayer(); +} // TODO: I don't know who put these in or what these are for??? @@ -2519,6 +2674,16 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) { LLUUID get(LLViewerObject* object, S32 te_index) { + LLTextureEntry *te = object->getTE(te_index); + if (te) + { + if ((te->getID() == IMG_USE_BAKED_EYES) || (te->getID() == IMG_USE_BAKED_HAIR) || (te->getID() == IMG_USE_BAKED_HEAD) || (te->getID() == IMG_USE_BAKED_LOWER) || (te->getID() == IMG_USE_BAKED_SKIRT) || (te->getID() == IMG_USE_BAKED_UPPER) + || (te->getID() == IMG_USE_BAKED_LEFTARM) || (te->getID() == IMG_USE_BAKED_LEFTLEG) || (te->getID() == IMG_USE_BAKED_AUX1) || (te->getID() == IMG_USE_BAKED_AUX2) || (te->getID() == IMG_USE_BAKED_AUX3)) + { + return te->getID(); + } + } + LLUUID id; LLViewerTexture* image = object->getTEImage(te_index); if (image) @@ -2528,7 +2693,6 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical) if (!id.isNull() && LLViewerMedia::textureHasMedia(id)) { - LLTextureEntry *te = object->getTE(te_index); if (te) { LLViewerTexture* tex = te->getID().notNull() ? gTextureList.findImage(te->getID(), TEX_LIST_STANDARD) : NULL; diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 0b40d7d41a..2d57d89a44 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -126,6 +126,7 @@ protected: void sendFullbright(); // applies and sends full bright void sendGlow(); void sendMedia(); + void alignTestureLayer(); // this function is to return TRUE if the drag should succeed. static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); @@ -202,6 +203,7 @@ protected: static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata); static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo); static void onClickAutoFix(void*); + static void onAlignTexture(void*); static F32 valueGlow(LLViewerObject* object, S32 face); diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 82ea8377de..d6b66ee622 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -606,11 +606,30 @@ void LLPanelGroupInvite::updateLists() { if (!mPendingUpdate) { + // Note: this will partially fail if some requests are already in progress LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } + else if (gdatap) + { + // restart requests that were interrupted/dropped/failed to start + if (!gdatap->isRoleDataPending() && !gdatap->isRoleDataComplete()) + { + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + } + if (!gdatap->isRoleMemberDataPending() && !gdatap->isRoleMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID); + } + // sendCapGroupMembersRequest has a per frame send limitation that could have + // interrupted previous request + if (!gdatap->isMemberDataPending() && !gdatap->isMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); + } + } mPendingUpdate = TRUE; } else diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 52a13304df..0efb234015 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1962,6 +1962,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() mRoleDescription(NULL), mMemberVisibleCheck(NULL), mDeleteRoleButton(NULL), + mCopyRoleButton(NULL), mCreateRoleButton(NULL), mFirstOpen(TRUE), mHasRoleChange(FALSE) @@ -2012,6 +2013,14 @@ BOOL LLPanelGroupRolesSubTab::postBuildSubTab(LLView* root) mCreateRoleButton->setClickedCallback(onCreateRole, this); mCreateRoleButton->setEnabled(FALSE); } + + mCopyRoleButton = + parent->getChild<LLButton>("role_copy", recurse); + if ( mCopyRoleButton ) + { + mCopyRoleButton->setClickedCallback(onCopyRole, this); + mCopyRoleButton->setEnabled(FALSE); + } mDeleteRoleButton = parent->getChild<LLButton>("role_delete", recurse); @@ -2226,6 +2235,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) mRoleTitle->clear(); setFooterEnabled(FALSE); mDeleteRoleButton->setEnabled(FALSE); + mCopyRoleButton->setEnabled(FALSE); } } @@ -2336,6 +2346,7 @@ void LLPanelGroupRolesSubTab::handleRoleSelect() mSelectedRole = item->getUUID(); buildMembersList(); + mCopyRoleButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_CREATE)); can_delete = can_delete && gAgent.hasPowerInGroup(mGroupID, GP_ROLE_DELETE); mDeleteRoleButton->setEnabled(can_delete); @@ -2662,6 +2673,57 @@ void LLPanelGroupRolesSubTab::handleCreateRole() } // static +void LLPanelGroupRolesSubTab::onCopyRole(void* user_data) +{ + LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data); + if (!self) return; + + self->handleCopyRole(); +} + +void LLPanelGroupRolesSubTab::handleCopyRole() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + + if (!gdatap) return; + + LLScrollListItem* role_item = mRolesList->getFirstSelected(); + if (!role_item || role_item->getUUID().isNull()) + { + return; + } + + LLRoleData rd; + if (!gdatap->getRoleData(role_item->getUUID(), rd)) + { + return; + } + + LLUUID new_role_id; + new_role_id.generate(); + rd.mRoleName += "(Copy)"; + gdatap->createRole(new_role_id,rd); + + mRolesList->deselectAllItems(TRUE); + LLSD row; + row["id"] = new_role_id; + row["columns"][0]["column"] = "name"; + row["columns"][0]["value"] = rd.mRoleName; + mRolesList->addElement(row, ADD_BOTTOM, this); + mRolesList->selectByID(new_role_id); + + // put focus on name field and select its contents + if(mRoleName) + { + mRoleName->setFocus(TRUE); + mRoleName->onTabInto(); + gFocusMgr.triggerFocusFlash(); + } + + notifyObservers(); +} + +// static void LLPanelGroupRolesSubTab::onDeleteRole(void* user_data) { LLPanelGroupRolesSubTab* self = static_cast<LLPanelGroupRolesSubTab*>(user_data); diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index aafbd242cb..459b77703f 100644 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -269,6 +269,9 @@ public: static void onCreateRole(void*); void handleCreateRole(); + static void onCopyRole(void*); + void handleCopyRole(); + static void onDeleteRole(void*); void handleDeleteRole(); @@ -296,6 +299,7 @@ protected: LLCheckBoxCtrl* mMemberVisibleCheck; LLButton* mDeleteRoleButton; LLButton* mCreateRoleButton; + LLButton* mCopyRoleButton; LLUUID mSelectedRole; BOOL mHasRoleChange; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 142dea83e2..e253557797 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -178,7 +178,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, mPasswordModified = FALSE; - LLPanelLogin::sInstance = this; + sInstance = this; LLView* login_holder = gViewerWindow->getLoginPanelHolder(); if (login_holder) @@ -234,29 +234,44 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect, server_choice_combo->add(LLGridManager::getInstance()->getGridLabel(), current_grid, ADD_TOP); - server_choice_combo->selectFirstItem(); + server_choice_combo->selectFirstItem(); LLSLURL start_slurl(LLStartUp::getStartSLURL()); + // The StartSLURL might have been set either by an explicit command-line + // argument (CmdLineLoginLocation) or by default. + // current_grid might have been set either by an explicit command-line + // argument (CmdLineGridChoice) or by default. + // If the grid specified by StartSLURL is the same as current_grid, the + // distinction is moot. + // If we have an explicit command-line SLURL, use that. + // If we DON'T have an explicit command-line SLURL but we DO have an + // explicit command-line grid, which is different from the default SLURL's + // -- do NOT override the explicit command-line grid with the grid from + // the default SLURL! + bool force_grid{ start_slurl.getGrid() != current_grid && + gSavedSettings.getString("CmdLineLoginLocation").empty() && + ! gSavedSettings.getString("CmdLineGridChoice").empty() }; if ( !start_slurl.isSpatial() ) // has a start been established by the command line or NextLoginLocation ? { // no, so get the preference setting std::string defaultStartLocation = gSavedSettings.getString("LoginLocation"); LL_INFOS("AppInit")<<"default LoginLocation '"<<defaultStartLocation<<"'"<<LL_ENDL; LLSLURL defaultStart(defaultStartLocation); - if ( defaultStart.isSpatial() ) + if ( defaultStart.isSpatial() && ! force_grid ) { LLStartUp::setStartSLURL(defaultStart); } else { - LL_INFOS("AppInit")<<"no valid LoginLocation, using home"<<LL_ENDL; + LL_INFOS("AppInit") << (force_grid? "--grid specified" : "no valid LoginLocation") + << ", using home" << LL_ENDL; LLSLURL homeStart(LLSLURL::SIM_LOCATION_HOME); LLStartUp::setStartSLURL(homeStart); } } - else + else if (! force_grid) { - LLPanelLogin::onUpdateStartSLURL(start_slurl); // updates grid if needed + onUpdateStartSLURL(start_slurl); // updates grid if needed } childSetAction("connect_btn", onClickConnect, this); @@ -380,7 +395,7 @@ void LLPanelLogin::setFocus(BOOL b) { if(b) { - LLPanelLogin::giveFocus(); + giveFocus(); } else { @@ -748,7 +763,10 @@ void LLPanelLogin::closePanel() { if (sInstance) { - LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance ); + if (LLPanelLogin::sInstance->getParent()) + { + LLPanelLogin::sInstance->getParent()->removeChild(LLPanelLogin::sInstance); + } delete sInstance; sInstance = NULL; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index db9d61c637..f63e604927 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -885,7 +885,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() U32 hours = mFilter->getHoursAgo(); U32 date_search_direction = mFilter->getDateSearchDirection(); - LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreator(); + LLInventoryFilter::EFilterCreatorType filter_creator = mFilter->getFilterCreatorType(); bool show_created_by_me = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_SELF)); bool show_created_by_others = ((filter_creator == LLInventoryFilter::FILTERCREATOR_ALL) || (filter_creator == LLInventoryFilter::FILTERCREATOR_OTHERS)); @@ -898,7 +898,6 @@ void LLFloaterInventoryFinder::updateElementsFromFilter() 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_mesh")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MESH)); 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)); @@ -954,12 +953,6 @@ void LLFloaterInventoryFinder::draw() filtered_by_all_types = FALSE; } - if (!getChild<LLUICtrl>("check_mesh")->getValue()) - { - filter &= ~(0x1 << LLInventoryType::IT_MESH); - filtered_by_all_types = FALSE; - } - if (!getChild<LLUICtrl>("check_notecard")->getValue()) { filter &= ~(0x1 << LLInventoryType::IT_NOTECARD); @@ -1108,7 +1101,6 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data) 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_mesh")->setValue(TRUE); self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE); self->getChild<LLUICtrl>("check_object")->setValue(TRUE); self->getChild<LLUICtrl>("check_script")->setValue(TRUE); @@ -1128,7 +1120,6 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data) 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_mesh")->setValue(FALSE); self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE); self->getChild<LLUICtrl>("check_object")->setValue(FALSE); self->getChild<LLUICtrl>("check_script")->setValue(FALSE); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index cd1875e995..6702dae4d6 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1122,92 +1122,6 @@ LLUIImagePtr LLTaskWearableBridge::getIcon() const } ///---------------------------------------------------------------------------- -/// Class LLTaskMeshBridge -///---------------------------------------------------------------------------- - -class LLTaskMeshBridge : public LLTaskInvFVBridge -{ -public: - LLTaskMeshBridge( - LLPanelObjectInventory* panel, - const LLUUID& uuid, - const std::string& name); - - virtual LLUIImagePtr getIcon() const; - virtual void openItem(); - virtual void performAction(LLInventoryModel* model, std::string action); - virtual void buildContextMenu(LLMenuGL& menu, U32 flags); -}; - -LLTaskMeshBridge::LLTaskMeshBridge( - LLPanelObjectInventory* panel, - const LLUUID& uuid, - const std::string& name) : - LLTaskInvFVBridge(panel, uuid, name) -{ -} - -LLUIImagePtr LLTaskMeshBridge::getIcon() const -{ - return LLInventoryIcon::getIcon(LLAssetType::AT_MESH, LLInventoryType::IT_MESH, 0, FALSE); -} - -void LLTaskMeshBridge::openItem() -{ - // open mesh -} - - -// virtual -void LLTaskMeshBridge::performAction(LLInventoryModel* model, std::string action) -{ - if (action == "mesh action") - { - LLInventoryItem* item = findItem(); - if(item) - { - // do action - } - } - LLTaskInvFVBridge::performAction(model, action); -} - -void LLTaskMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags) -{ - LLInventoryItem* item = findItem(); - std::vector<std::string> items; - std::vector<std::string> disabled_items; - if(!item) - { - hide_context_entries(menu, items, disabled_items); - return; - } - - items.push_back(std::string("Task Open")); - if (!isItemCopyable()) - { - disabled_items.push_back(std::string("Task Open")); - } - - items.push_back(std::string("Task Properties")); - if ((flags & FIRST_SELECTED_ITEM) == 0) - { - disabled_items.push_back(std::string("Task Properties")); - } - if(isItemRenameable()) - { - items.push_back(std::string("Task Rename")); - } - if(isItemRemovable()) - { - items.push_back(std::string("Task Remove")); - } - - - hide_context_entries(menu, items, disabled_items); -} - -///---------------------------------------------------------------------------- /// LLTaskInvFVBridge impl //---------------------------------------------------------------------------- @@ -1288,11 +1202,6 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory* object_id, object_name); break; - case LLAssetType::AT_MESH: - new_bridge = new LLTaskMeshBridge(panel, - object_id, - object_name); - break; default: LL_INFOS() << "Unhandled inventory type (llassetstorage.h): " << (S32)type << LL_ENDL; @@ -1498,7 +1407,14 @@ void LLPanelObjectInventory::updateInventory() mIsInventoryEmpty = TRUE; } - mHaveInventory = TRUE; + mHaveInventory = !mIsInventoryEmpty || !objectp->isInventoryDirty(); + if (objectp->isInventoryDirty()) + { + // Inventory is dirty, yet we received inventoryChanged() callback. + // User changed something during ongoing request. + // Rerequest. It will clear dirty flag and won't create dupplicate requests. + objectp->requestInventory(); + } } else { @@ -1768,7 +1684,7 @@ void LLPanelObjectInventory::deleteAllChildren() BOOL LLPanelObjectInventory::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg) { - if (mFolders && mHaveInventory) + if (mFolders) { LLFolderViewItem* folderp = mFolders->getNextFromChild(NULL); if (!folderp) diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index d700c8f4cf..7b9ecfb8f3 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -106,9 +106,9 @@ private: LLUUID mTaskUUID; LLUUID mAttachmentUUID; - BOOL mHaveInventory; - BOOL mIsInventoryEmpty; - BOOL mInventoryNeedsUpdate; + BOOL mHaveInventory; // 'Loading' label and used for initial request + BOOL mIsInventoryEmpty; // 'Empty' label + BOOL mInventoryNeedsUpdate; // for idle, set on changed callback LLFolderViewModelInventory mInventoryViewModel; }; diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index c5bae9c52e..1d87aa6f5d 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -467,6 +467,7 @@ BOOL LLPanelOutfitEdit::postBuild() mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("alpha"), new LLFindActualWearablesOfType(LLWearableType::WT_ALPHA))); mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("tattoo"), new LLFindActualWearablesOfType(LLWearableType::WT_TATTOO))); mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("physics"), new LLFindActualWearablesOfType(LLWearableType::WT_PHYSICS))); + mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("universal"), new LLFindActualWearablesOfType(LLWearableType::WT_UNIVERSAL))); mCurrentOutfitName = getChild<LLTextBox>("curr_outfit_name"); mStatus = getChild<LLTextBox>("status"); diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 2cc8b65001..3c6efac0e7 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -98,6 +98,7 @@ public: LVIT_ALPHA, LVIT_TATTOO, LVIT_PHYSICS, + LVIT_UNIVERSAL, NUM_LIST_VIEW_ITEM_TYPES } EListViewItemType; diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 617ca05281..be174475e1 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -54,7 +54,6 @@ #include "llcallingcard.h" // for LLAvatarTracker #include "llcallbacklist.h" #include "llerror.h" -#include "llfacebookconnect.h" #include "llfloateravatarpicker.h" #include "llfriendcard.h" #include "llgroupactions.h" @@ -537,7 +536,6 @@ public: LLPanelPeople::LLPanelPeople() : LLPanel(), - mTryToConnectToFacebook(true), mTabContainer(NULL), mOnlineFriendList(NULL), mAllFriendList(NULL), @@ -645,11 +643,9 @@ BOOL LLPanelPeople::postBuild() // updater is active only if panel is visible to user. friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2)); friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this)); - friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::updateFacebookList, this, _2)); mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online"); mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all"); - mSuggestedFriends = friends_tab->getChild<LLAvatarList>("suggested_friends"); mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online")); mOnlineFriendList->setShowIcons("FriendsListShowIcons"); mOnlineFriendList->showPermissions("FriendsListShowPermissions"); @@ -685,7 +681,6 @@ BOOL LLPanelPeople::postBuild() mRecentList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu); - mSuggestedFriends->setContextMenu(&LLPanelPeopleMenus::gSuggestedFriendsContextMenu); setSortOrder(mRecentList, (ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"), false); setSortOrder(mAllFriendList, (ESortOrder)gSavedSettings.getU32("FriendsSortOrder"), false); @@ -764,7 +759,7 @@ void LLPanelPeople::updateFriendListHelpText() // Seems sometimes all_friends can be empty because of issue with Inventory loading (clear cache, slow connection...) // So, lets check all lists to avoid overlapping the text with online list. See EXT-6448. - bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches() || mSuggestedFriends->filterHasMatches(); + bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches(); no_friends_text->setVisible(!any_friend_exists); if (no_friends_text->getVisible()) { @@ -831,40 +826,9 @@ void LLPanelPeople::updateFriendList() mAllFriendList->setDirty(true, !mAllFriendList->filterHasMatches()); //update trash and other buttons according to a selected item updateButtons(); - updateSuggestedFriendList(); showFriendsAccordionsIfNeeded(); } -bool LLPanelPeople::updateSuggestedFriendList() -{ - const LLAvatarTracker& av_tracker = LLAvatarTracker::instance(); - uuid_vec_t& suggested_friends = mSuggestedFriends->getIDs(); - suggested_friends.clear(); - - //Add suggested friends - LLSD friends = LLFacebookConnect::instance().getContent(); - for (LLSD::array_const_iterator i = friends.beginArray(); i != friends.endArray(); ++i) - { - LLUUID agent_id = (*i).asUUID(); - bool second_life_buddy = agent_id.notNull() ? av_tracker.isBuddy(agent_id) : false; - - if(!second_life_buddy) - { - //FB+SL but not SL friend - if (agent_id.notNull()) - { - suggested_friends.push_back(agent_id); - } - } - } - - //Force a refresh when there aren't any filter matches (prevent displaying content that shouldn't display) - mSuggestedFriends->setDirty(true, !mSuggestedFriends->filterHasMatches()); - showFriendsAccordionsIfNeeded(); - - return false; -} - void LLPanelPeople::updateNearbyList() { if (!mNearbyList) @@ -888,51 +852,6 @@ void LLPanelPeople::updateRecentList() mRecentList->setDirty(); } -bool LLPanelPeople::onConnectedToFacebook(const LLSD& data) -{ - LLSD::Integer connection_state = data.get("enum").asInteger(); - - if (connection_state == LLFacebookConnect::FB_CONNECTED) - { - LLFacebookConnect::instance().loadFacebookFriends(); - } - else if(connection_state == LLFacebookConnect::FB_NOT_CONNECTED) - { - updateSuggestedFriendList(); - }; - - return false; -} - -void LLPanelPeople::updateFacebookList(bool visible) -{ - if (visible) - { - LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectContent").listen("LLPanelPeople", boost::bind(&LLPanelPeople::updateSuggestedFriendList, this)); - - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople"); // just in case it is already listening - LLEventPumps::instance().obtain("FacebookConnectState").listen("LLPanelPeople", boost::bind(&LLPanelPeople::onConnectedToFacebook, this, _1)); - - if (LLFacebookConnect::instance().isConnected()) - { - LLFacebookConnect::instance().loadFacebookFriends(); - } - else if(mTryToConnectToFacebook) - { - LLFacebookConnect::instance().checkConnectionToFacebook(); - mTryToConnectToFacebook = false; - } - - updateSuggestedFriendList(); - } - else - { - LLEventPumps::instance().obtain("FacebookConnectState").stopListening("LLPanelPeople"); - LLEventPumps::instance().obtain("FacebookConnectContent").stopListening("LLPanelPeople"); - } -} - void LLPanelPeople::updateButtons() { std::string cur_tab = getActiveTabName(); @@ -1151,11 +1070,9 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) mOnlineFriendList->setNameFilter(filter); mAllFriendList->setNameFilter(filter); - mSuggestedFriends->setNameFilter(filter); setAccordionCollapsedByUser("tab_online", false); setAccordionCollapsedByUser("tab_all", false); - setAccordionCollapsedByUser("tab_suggested_friends", false); showFriendsAccordionsIfNeeded(); // restore accordion tabs state _after_ all manipulations @@ -1600,7 +1517,6 @@ void LLPanelPeople::showFriendsAccordionsIfNeeded() // Expand and show accordions if needed, else - hide them showAccordion("tab_online", mOnlineFriendList->filterHasMatches()); showAccordion("tab_all", mAllFriendList->filterHasMatches()); - showAccordion("tab_suggested_friends", mSuggestedFriends->filterHasMatches()); // Rearrange accordions LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion"); diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h index c72c4fc08a..14205cebe2 100644 --- a/indra/newview/llpanelpeople.h +++ b/indra/newview/llpanelpeople.h @@ -57,8 +57,6 @@ public: // when voice is available /*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal); - bool mTryToConnectToFacebook; - // internals class Updater; @@ -80,10 +78,8 @@ private: // methods indirectly called by the updaters void updateFriendListHelpText(); void updateFriendList(); - bool updateSuggestedFriendList(); void updateNearbyList(); void updateRecentList(); - void updateFacebookList(bool visible); bool isItemsFreeOfFriends(const uuid_vec_t& uuids); @@ -131,8 +127,6 @@ private: void onFriendListRefreshComplete(LLUICtrl*ctrl, const LLSD& param); - bool onConnectedToFacebook(const LLSD& data); - void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed); void setAccordionCollapsedByUser(const std::string& name, bool collapsed); bool isAccordionCollapsedByUser(LLUICtrl* acc_tab); @@ -141,7 +135,6 @@ private: LLTabContainer* mTabContainer; LLAvatarList* mOnlineFriendList; LLAvatarList* mAllFriendList; - LLAvatarList* mSuggestedFriends; LLAvatarList* mNearbyList; LLAvatarList* mRecentList; LLGroupList* mGroupList; diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp index 65769ff526..42cecc9986 100644 --- a/indra/newview/llpanelpeoplemenus.cpp +++ b/indra/newview/llpanelpeoplemenus.cpp @@ -52,7 +52,6 @@ namespace LLPanelPeopleMenus PeopleContextMenu gPeopleContextMenu; NearbyPeopleContextMenu gNearbyPeopleContextMenu; -SuggestedFriendsContextMenu gSuggestedFriendsContextMenu; //== PeopleContextMenu =============================================================== @@ -413,36 +412,4 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags) hide_context_entries(menu, items, disabled_items); } -//== SuggestedFriendsContextMenu =============================================================== - -LLContextMenu* SuggestedFriendsContextMenu::createMenu() -{ - // set up the callbacks for all of the avatar menu items - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar; - LLContextMenu* menu; - - // Set up for one person selected menu - const LLUUID& id = mUUIDs.front(); - registrar.add("Avatar.Profile", boost::bind(&LLAvatarActions::showProfile, id)); - registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, id)); - - // create the context menu from the XUI - menu = createFromFile("menu_people_nearby.xml"); - buildContextMenu(*menu, 0x0); - - return menu; -} - -void SuggestedFriendsContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags) -{ - menuentry_vec_t items; - menuentry_vec_t disabled_items; - - items.push_back(std::string("view_profile")); - items.push_back(std::string("add_friend")); - - hide_context_entries(menu, items, disabled_items); -} - } // namespace LLPanelPeopleMenus diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h index 5ed20e0064..3bc1f8caf7 100644 --- a/indra/newview/llpanelpeoplemenus.h +++ b/indra/newview/llpanelpeoplemenus.h @@ -62,21 +62,8 @@ protected: /*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags); }; -/** - * Menu used in the suggested friends list. - */ -class SuggestedFriendsContextMenu : public PeopleContextMenu -{ -public: - /*virtual*/ LLContextMenu * createMenu(); - -protected: - /*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags); -}; - extern PeopleContextMenu gPeopleContextMenu; extern NearbyPeopleContextMenu gNearbyPeopleContextMenu; -extern SuggestedFriendsContextMenu gSuggestedFriendsContextMenu; } // namespace LLPanelPeopleMenus diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 610b3a6396..104316e253 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -563,11 +563,8 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, mSaleToText->setText(getString("anyone")); } - const U8* sign = (U8*)getString("price_text").c_str(); - const U8* sqm = (U8*)getString("area_text").c_str(); - - mSalesPriceText->setText(llformat("%s%d ", sign, parcel->getSalePrice())); - mAreaText->setText(llformat("%d %s", area, sqm)); + mSalesPriceText->setText(llformat("%s%d ", getString("price_text").c_str(), parcel->getSalePrice())); + mAreaText->setText(llformat("%d %s", area, getString("area_text").c_str())); mTrafficText->setText(llformat("%.0f", dwell)); // Can't have more than region max tasks, regardless of parcel @@ -575,10 +572,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, S32 primitives = llmin(ll_round(parcel->getMaxPrimCapacity() * parcel->getParcelPrimBonus()), (S32)region->getMaxTasks()); - const U8* available = (U8*)getString("available").c_str(); - const U8* allocated = (U8*)getString("allocated").c_str(); - - mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, available, parcel->getPrimCount(), allocated)); + mPrimitivesText->setText(llformat("%d %s, %d %s", primitives, getString("available").c_str(), parcel->getPrimCount(), getString("allocated").c_str())); if (parcel->getAllowOtherScripts()) { diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp index 95c14e4226..23747a8efd 100644 --- a/indra/newview/llpanelsnapshotoptions.cpp +++ b/indra/newview/llpanelsnapshotoptions.cpp @@ -32,7 +32,6 @@ #include "llfloatersnapshot.h" // FIXME: create a snapshot model #include "llfloaterreg.h" -#include "llfloaterfacebook.h" #include "llfloaterflickr.h" #include "llfloatertwitter.h" @@ -59,7 +58,6 @@ private: void onSaveToEmail(); void onSaveToInventory(); void onSaveToComputer(); - void onSendToFacebook(); void onSendToTwitter(); void onSendToFlickr(); @@ -74,7 +72,6 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions() mCommitCallbackRegistrar.add("Snapshot.SaveToEmail", boost::bind(&LLPanelSnapshotOptions::onSaveToEmail, this)); mCommitCallbackRegistrar.add("Snapshot.SaveToInventory", boost::bind(&LLPanelSnapshotOptions::onSaveToInventory, this)); mCommitCallbackRegistrar.add("Snapshot.SaveToComputer", boost::bind(&LLPanelSnapshotOptions::onSaveToComputer, this)); - mCommitCallbackRegistrar.add("Snapshot.SendToFacebook", boost::bind(&LLPanelSnapshotOptions::onSendToFacebook, this)); mCommitCallbackRegistrar.add("Snapshot.SendToTwitter", boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this)); mCommitCallbackRegistrar.add("Snapshot.SendToFlickr", boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this)); LLGlobalEconomy::getInstance()->addObserver(this); @@ -138,18 +135,6 @@ void LLPanelSnapshotOptions::onSaveToComputer() openPanel("panel_snapshot_local"); } -void LLPanelSnapshotOptions::onSendToFacebook() -{ - LLFloaterReg::hideInstance("snapshot"); - - LLFloaterFacebook* facebook_floater = dynamic_cast<LLFloaterFacebook*>(LLFloaterReg::getInstance("facebook")); - if (facebook_floater) - { - facebook_floater->showPhotoPanel(); - } - LLFloaterReg::showInstance("facebook"); -} - void LLPanelSnapshotOptions::onSendToTwitter() { LLFloaterReg::hideInstance("snapshot"); diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 96dd309fa4..735eaa423d 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -383,6 +383,29 @@ void LLPanelVolume::getState( ) } } getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(enabled_animated_object_box); + + //refresh any bakes + if (root_volobjp) + { + root_volobjp->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = root_volobjp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + if (gAgentAvatarp) + { + gAgentAvatarp->updateMeshVisibility(); + } + } + // Flexible properties BOOL is_flexible = volobjp && volobjp->isFlexible(); @@ -953,6 +976,28 @@ void LLPanelVolume::onCommitAnimatedMeshCheckbox(LLUICtrl *, void*) { volobjp->setExtendedMeshFlags(new_flags); } + + //refresh any bakes + if (volobjp) + { + volobjp->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = volobjp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + if (gAgentAvatarp) + { + gAgentAvatarp->updateMeshVisibility(); + } + } } void LLPanelVolume::onCommitIsFlexible(LLUICtrl *, void*) diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index d4a8bbdf45..1533a27469 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -32,6 +32,7 @@ #include "llagent.h" #include "lldraghandle.h" +#include "llexternaleditor.h" #include "llviewerwindow.h" #include "llbutton.h" #include "llfloaterreg.h" @@ -43,6 +44,7 @@ #include "roles_constants.h" #include "llscrollbar.h" #include "llselectmgr.h" +#include "lltrans.h" #include "llviewertexteditor.h" #include "llvfile.h" #include "llviewerinventory.h" @@ -63,7 +65,8 @@ // Default constructor LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id, - : LLPreview( key ) + : LLPreview( key ), + mLiveFile(NULL) { const LLInventoryItem *item = getItem(); if (item) @@ -74,13 +77,14 @@ LLPreviewNotecard::LLPreviewNotecard(const LLSD& key) //const LLUUID& item_id, LLPreviewNotecard::~LLPreviewNotecard() { + delete mLiveFile; } BOOL LLPreviewNotecard::postBuild() { - LLViewerTextEditor *ed = getChild<LLViewerTextEditor>("Notecard Editor"); - ed->setNotecardInfo(mItemUUID, mObjectID, getKey()); - ed->makePristine(); + mEditor = getChild<LLViewerTextEditor>("Notecard Editor"); + mEditor->setNotecardInfo(mItemUUID, mObjectID, getKey()); + mEditor->makePristine(); childSetAction("Save", onClickSave, this); getChildView("lock")->setVisible( FALSE); @@ -88,6 +92,8 @@ BOOL LLPreviewNotecard::postBuild() childSetAction("Delete", onClickDelete, this); getChildView("Delete")->setEnabled(false); + childSetAction("Edit", onClickEdit, this); + const LLInventoryItem* item = getItem(); childSetCommitCallback("desc", LLPreview::onText, this); @@ -408,6 +414,16 @@ void LLPreviewNotecard::onClickDelete(void* user_data) } } +// static +void LLPreviewNotecard::onClickEdit(void* user_data) +{ + LLPreviewNotecard* preview = (LLPreviewNotecard*)user_data; + if (preview) + { + preview->openInExternalEditor(); + } +} + struct LLSaveNotecardInfo { LLPreviewNotecard* mSelf; @@ -468,7 +484,7 @@ void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUI } } -bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) +bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync) { LLViewerTextEditor* editor = getChild<LLViewerTextEditor>("Notecard Editor"); @@ -487,7 +503,10 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) } editor->makePristine(); - + if (sync) + { + syncExternal(); + } const LLInventoryItem* item = getItem(); // save it out to database if (item) @@ -566,6 +585,18 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem) return true; } +void LLPreviewNotecard::syncExternal() +{ + // Sync with external editor. + std::string tmp_file = getTmpFileName(); + llstat s; + if (LLFile::stat(tmp_file, &s) == 0) // file exists + { + if (mLiveFile) mLiveFile->ignoreNextUpdate(); + writeToFile(tmp_file); + } +} + void LLPreviewNotecard::deleteNotecard() { LLNotificationsUtil::add("DeleteNotecard", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleConfirmDeleteDialog,this, _1, _2)); @@ -714,4 +745,128 @@ bool LLPreviewNotecard::handleConfirmDeleteDialog(const LLSD& notification, cons return false; } +void LLPreviewNotecard::openInExternalEditor() +{ + delete mLiveFile; // deletes file + + // Save the notecard to a temporary file. + std::string filename = getTmpFileName(); + writeToFile(filename); + + // Start watching file changes. + mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLPreviewNotecard::onExternalChange, this, _1)); + mLiveFile->addToEventTimer(); + + // Open it in external editor. + { + LLExternalEditor ed; + LLExternalEditor::EErrorCode status; + std::string msg; + + status = ed.setCommand("LL_SCRIPT_EDITOR"); + if (status != LLExternalEditor::EC_SUCCESS) + { + if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error. + { + msg = LLTrans::getString("ExternalEditorNotSet"); + } + else + { + msg = LLExternalEditor::getErrorMessage(status); + } + + LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg)); + return; + } + + status = ed.run(filename); + if (status != LLExternalEditor::EC_SUCCESS) + { + msg = LLExternalEditor::getErrorMessage(status); + LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg)); + } + } +} + +bool LLPreviewNotecard::onExternalChange(const std::string& filename) +{ + if (!loadNotecardText(filename)) + { + return false; + } + + // Disable sync to avoid recursive load->save->load calls. + saveIfNeeded(NULL, false); + return true; +} + +bool LLPreviewNotecard::loadNotecardText(const std::string& filename) +{ + if (filename.empty()) + { + LL_WARNS() << "Empty file name" << LL_ENDL; + return false; + } + + LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ + if (!file) + { + LL_WARNS() << "Error opening " << filename << LL_ENDL; + return false; + } + + // read in the whole file + fseek(file, 0L, SEEK_END); + size_t file_length = (size_t)ftell(file); + fseek(file, 0L, SEEK_SET); + char* buffer = new char[file_length + 1]; + size_t nread = fread(buffer, 1, file_length, file); + if (nread < file_length) + { + LL_WARNS() << "Short read" << LL_ENDL; + } + buffer[nread] = '\0'; + fclose(file); + + mEditor->setText(LLStringExplicit(buffer)); + delete[] buffer; + + return true; +} + +bool LLPreviewNotecard::writeToFile(const std::string& filename) +{ + LLFILE* fp = LLFile::fopen(filename, "wb"); + if (!fp) + { + LL_WARNS() << "Unable to write to " << filename << LL_ENDL; + return false; + } + + std::string utf8text = mEditor->getText(); + + if (utf8text.size() == 0) + { + utf8text = " "; + } + + fputs(utf8text.c_str(), fp); + fclose(fp); + return true; +} + + +std::string LLPreviewNotecard::getTmpFileName() +{ + std::string notecard_id = mObjectID.asString() + "_" + mItemUUID.asString(); + + // Use MD5 sum to make the file name shorter and not exceed maximum path length. + char notecard_id_hash_str[33]; /* Flawfinder: ignore */ + LLMD5 notecard_id_hash((const U8 *)notecard_id.c_str()); + notecard_id_hash.hex_digest(notecard_id_hash_str); + + return std::string(LLFile::tmpdir()) + "sl_notecard_" + notecard_id_hash_str + ".txt"; +} + + // EOF diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h index 46a6d0ef50..d9c14815c1 100644 --- a/indra/newview/llpreviewnotecard.h +++ b/indra/newview/llpreviewnotecard.h @@ -29,6 +29,7 @@ #include "llpreview.h" #include "llassetstorage.h" +#include "llpreviewscript.h" #include "lliconctrl.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -47,18 +48,18 @@ public: virtual ~LLPreviewNotecard(); bool saveItem(); - void setObjectID(const LLUUID& object_id); + void setObjectID(const LLUUID& object_id) override; // llview - virtual void draw(); - virtual BOOL handleKeyHere(KEY key, MASK mask); - virtual void setEnabled( BOOL enabled ); + void draw() override; + BOOL handleKeyHere(KEY key, MASK mask) override; + void setEnabled( BOOL enabled ) override; // llfloater - virtual BOOL canClose(); + BOOL canClose() override; // llpanel - virtual BOOL postBuild(); + BOOL postBuild() override; // reach into the text editor, and grab the drag item const LLInventoryItem* getDragItem(); @@ -72,11 +73,13 @@ public: // asset system. :( void refreshFromInventory(const LLUUID& item_id = LLUUID::null); + void syncExternal(); + protected: - void updateTitleButtons(); - virtual void loadAsset(); - bool saveIfNeeded(LLInventoryItem* copyitem = NULL); + void updateTitleButtons() override; + void loadAsset() override; + bool saveIfNeeded(LLInventoryItem* copyitem = NULL, bool sync = true); void deleteNotecard(); @@ -89,6 +92,8 @@ protected: static void onClickDelete(void* data); + static void onClickEdit(void* data); + static void onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status); @@ -99,6 +104,12 @@ protected: static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId); static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId); + void openInExternalEditor(); + bool onExternalChange(const std::string& filename); + bool loadNotecardText(const std::string& filename); + bool writeToFile(const std::string& filename); + std::string getTmpFileName(); + protected: LLViewerTextEditor* mEditor; LLButton* mSaveBtn; @@ -106,6 +117,8 @@ protected: LLUUID mAssetID; LLUUID mObjectID; + + LLLiveLSLFile* mLiveFile; }; diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 9431914ba3..f1bb0bc27d 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -41,7 +41,6 @@ #include "llinventorymodel.h" #include "llkeyboard.h" #include "lllineeditor.h" -#include "lllivefile.h" #include "llhelp.h" #include "llnotificationsutil.h" #include "llresmgr.h" @@ -120,22 +119,6 @@ static bool have_script_upload_cap(LLUUID& object_id) /// --------------------------------------------------------------------------- /// LLLiveLSLFile /// --------------------------------------------------------------------------- -class LLLiveLSLFile : public LLLiveFile -{ -public: - typedef boost::function<bool (const std::string& filename)> change_callback_t; - - LLLiveLSLFile(std::string file_path, change_callback_t change_cb); - ~LLLiveLSLFile(); - - void ignoreNextUpdate() { mIgnoreNextUpdate = true; } - -protected: - /*virtual*/ bool loadFile(); - - change_callback_t mOnChangeCallback; - bool mIgnoreNextUpdate; -}; LLLiveLSLFile::LLLiveLSLFile(std::string file_path, change_callback_t change_cb) : mOnChangeCallback(change_cb) @@ -1069,7 +1052,7 @@ void LLScriptEdCore::openInExternalEditor() { if (status == LLExternalEditor::EC_NOT_SPECIFIED) // Use custom message for this error. { - msg = getString("external_editor_not_set"); + msg = LLTrans::getString("ExternalEditorNotSet"); } else { diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 69cf9d9158..74e4c00d43 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -34,6 +34,7 @@ #include "lliconctrl.h" #include "llframetimer.h" #include "llfloatergotoline.h" +#include "lllivefile.h" #include "llsyntaxid.h" class LLLiveLSLFile; @@ -53,6 +54,23 @@ class LLScriptEdContainer; class LLFloaterGotoLine; class LLFloaterExperienceProfile; +class LLLiveLSLFile : public LLLiveFile +{ +public: + typedef boost::function<bool(const std::string& filename)> change_callback_t; + + LLLiveLSLFile(std::string file_path, change_callback_t change_cb); + ~LLLiveLSLFile(); + + void ignoreNextUpdate() { mIgnoreNextUpdate = true; } + +protected: + /*virtual*/ bool loadFile(); + + change_callback_t mOnChangeCallback; + bool mIgnoreNextUpdate; +}; + // Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these. class LLScriptEdCore : public LLPanel { diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp index de90896548..93143eb33f 100644 --- a/indra/newview/llsearchableui.cpp +++ b/indra/newview/llsearchableui.cpp @@ -125,17 +125,13 @@ void ll::statusbar::SearchableItem::setNotHighlighted( ) } } -bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter ) +bool ll::statusbar::SearchableItem::hightlightAndHide(LLWString const &aFilter, bool hide) { - if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch ) + if ((mMenu && !mMenu->getVisible() && !mWasHiddenBySearch) || dynamic_cast<LLMenuItemTearOffGL*>(mMenu)) return false; setNotHighlighted( ); - bool bVisible(false); - for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) - bVisible |= (*itr)->hightlightAndHide( aFilter ); - if( aFilter.empty() ) { if( mCtrl ) @@ -143,17 +139,22 @@ bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter return true; } + bool bHighlighted(!hide); if( mLabel.find( aFilter ) != LLWString::npos ) { if( mCtrl ) mCtrl->setHighlighted( true ); - return true; + bHighlighted = true; } - if( mCtrl && !bVisible ) + bool bVisible(false); + for (tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr) + bVisible |= (*itr)->hightlightAndHide(aFilter, !bHighlighted); + + if (mCtrl && !bVisible && !bHighlighted) { mWasHiddenBySearch = true; mMenu->setVisible(FALSE); } - return bVisible; + return bVisible || bHighlighted; } diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h index 42b2866fb6..9741557e49 100644 --- a/indra/newview/llsearchableui.h +++ b/indra/newview/llsearchableui.h @@ -107,7 +107,7 @@ namespace ll SearchableItem(); void setNotHighlighted( ); - bool hightlightAndHide( LLWString const &aFilter ); + bool hightlightAndHide( LLWString const &aFilter, bool hide = true ); }; struct SearchData diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index b36df244f8..90f8f84ea4 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -96,6 +96,7 @@ #include "llviewershadermgr.h" #include "llpanelface.h" #include "llglheaders.h" +#include "llinventoryobserver.h" LLViewerObject* getSelectedParentObject(LLViewerObject *object) ; // @@ -180,7 +181,7 @@ LLSelectMgr::LLSelectMgr() sHighlightThickness = gSavedSettings.getF32("SelectionHighlightThickness"); sHighlightUScale = gSavedSettings.getF32("SelectionHighlightUScale"); sHighlightVScale = gSavedSettings.getF32("SelectionHighlightVScale"); - sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha"); + sHighlightAlpha = gSavedSettings.getF32("SelectionHighlightAlpha") * 2; sHighlightAlphaTest = gSavedSettings.getF32("SelectionHighlightAlphaTest"); sHighlightUAnim = gSavedSettings.getF32("SelectionHighlightUAnim"); sHighlightVAnim = gSavedSettings.getF32("SelectionHighlightVAnim"); @@ -1656,6 +1657,7 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid) // * Can just apply the texture and be done with it. objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); } + return true; } }; @@ -1855,6 +1857,7 @@ BOOL LLSelectMgr::selectionRevertTextures() else { object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)); + } } } @@ -3861,6 +3864,14 @@ BOOL LLSelectMgr::selectGetAggregateTexturePermissions(LLAggregatePermissions& r return TRUE; } +BOOL LLSelectMgr::isSelfAvatarSelected() +{ + if (mAllowSelectAvatar) + { + return (getSelection()->getObjectCount() == 1) && (getSelection()->getFirstRootObject() == gAgentAvatarp); + } + return FALSE; +} //-------------------------------------------------------------------- // Duplicate objects @@ -3883,6 +3894,17 @@ void LLSelectMgr::selectDuplicate(const LLVector3& offset, BOOL select_copy) make_ui_sound("UISndInvalidOp"); return; } + if (!canDuplicate()) + { + LLSelectNode* node = getSelection()->getFirstRootNode(NULL, true); + if (node) + { + LLSD args; + args["OBJ_NAME"] = node->mName; + LLNotificationsUtil::add("NoCopyPermsNoObject", args); + return; + } + } LLDuplicateData data; data.offset = offset; @@ -5838,6 +5860,84 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) gGL.scalef(cur_zoom, cur_zoom, cur_zoom); } + bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections; + F32 fogCfx = (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0); + + static LLColor4 sParentColor = LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha); + static LLColor4 sChildColor = LLColor4(sSilhouetteChildColor[VRED], sSilhouetteChildColor[VGREEN], sSilhouetteChildColor[VBLUE], LLSelectMgr::sHighlightAlpha); + + auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor) + { + //Need to because crash on ATI 3800 (and similar cards) MAINT-5018 + LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + + LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + + if (shader) + { + gDebugProgram.bind(); + } + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + + BOOL is_hud_object = objectp->isHUDAttachment(); + + if (!is_hud_object) + { + gGL.loadIdentity(); + gGL.multMatrix(gGLModelView); + } + + if (objectp->mDrawable->isActive()) + { + gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix); + } + else if (!is_hud_object) + { + LLVector3 trans = objectp->getRegion()->getOriginAgent(); + gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]); + } + + bool bRenderHidenSelection = node->isTransient() ? false : LLSelectMgr::sRenderHiddenSelections; + + + LLVOVolume* vobj = objectp->mDrawable->getVOVolume(); + if (vobj) + { + LLVertexBuffer::unbind(); + gGL.pushMatrix(); + gGL.multMatrix((F32*)vobj->getRelativeXform().mMatrix); + + if (objectp->mDrawable->isState(LLDrawable::RIGGED)) + { + vobj->updateRiggedVolume(true); + } + } + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + objectp->mDrawable->getFace(te)->renderOneWireframe(hlColor, fogCfx, wireframe_selection, bRenderHidenSelection, nullptr != shader); + } + } + + gGL.popMatrix(); + gGL.popMatrix(); + + glLineWidth(1.f); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + if (shader) + { + shader->bind(); + } + }; + if (mSelectedObjects->getNumNodes()) { LLUUID inspect_item_id= LLUUID::null; @@ -5855,9 +5955,6 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) } } - bool wireframe_selection = (gFloaterTools && gFloaterTools->getVisible()) || LLSelectMgr::sRenderHiddenSelections; - F32 fogCfx = (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0); - LLUUID focus_item_id = LLViewerMediaFocus::getInstance()->getFocusedObjectID(); for (S32 pass = 0; pass < 2; pass++) { @@ -5865,33 +5962,28 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) iter != mSelectedObjects->end(); iter++) { LLSelectNode* node = *iter; + + if (getTEMode() && !node->hasSelectedTE()) + continue; + LLViewerObject* objectp = node->getObject(); if (!objectp) continue; - if(getTEMode() && !node->hasSelectedTE()) - continue; - if (objectp->mDrawable && objectp->mDrawable->getVOVolume() && objectp->mDrawable->getVOVolume()->isMesh()) { - S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces - for (S32 te = 0; te < num_tes; ++te) + LLColor4 hlColor = objectp->isRootEdit() ? sParentColor : sChildColor; + if (objectp->getID() == inspect_item_id) { - if (!getTEMode()) - { - objectp->mDrawable->getFace(te)->renderOneWireframe( - LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha * 2) - , fogCfx, wireframe_selection, node->isTransient() ? FALSE : LLSelectMgr::sRenderHiddenSelections); - } - else if(node->isTESelected(te)) - { - objectp->mDrawable->getFace(te)->renderOneWireframe( - LLColor4(sSilhouetteParentColor[VRED], sSilhouetteParentColor[VGREEN], sSilhouetteParentColor[VBLUE], LLSelectMgr::sHighlightAlpha * 2) - , fogCfx, wireframe_selection, node->isTransient() ? FALSE : LLSelectMgr::sRenderHiddenSelections); - } + hlColor = sHighlightInspectColor; } + else if (node->isTransient()) + { + hlColor = sContextSilhouetteColor; + } + renderMeshSelection_f(node, objectp, hlColor); } else { @@ -5944,14 +6036,20 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud) { continue; } - - if (subtracting_from_selection) + + LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor; + if (objectp->mDrawable + && objectp->mDrawable->getVOVolume() + && objectp->mDrawable->getVOVolume()->isMesh()) + { + renderMeshSelection_f(node, objectp, subtracting_from_selection ? LLColor4::red : highlight_color); + } + else if (subtracting_from_selection) { node->renderOneSilhouette(LLColor4::red); } else if (!objectp->isSelected()) { - LLColor4 highlight_color = objectp->isRoot() ? sHighlightParentColor : sHighlightChildColor; node->renderOneSilhouette(highlight_color); } } @@ -6450,7 +6548,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) gGL.texCoord2fv(tc[0].mV); gGL.vertex3fv( v[0].mV ); - gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); + gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha); gGL.texCoord2fv( tc[1].mV ); gGL.vertex3fv( v[1].mV ); @@ -6460,7 +6558,7 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color) gGL.vertex3fv( v[2].mV ); - gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2); + gGL.color4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha); gGL.texCoord2fv( tc[1].mV ); gGL.vertex3fv( v[1].mV ); @@ -6686,8 +6784,28 @@ void LLSelectMgr::pauseAssociatedAvatars() mSelectedObjects->mSelectType = getSelectTypeForObject(object); + bool is_attached = false; if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && - isAgentAvatarValid() && object->getParent() != NULL) + isAgentAvatarValid()) + { + // Selection can be obsolete, confirm that this is an attachment + LLViewerObject* parent = (LLViewerObject*)object->getParent(); + while (parent != NULL) + { + if (parent->isAvatar()) + { + is_attached = true; + break; + } + else + { + parent = (LLViewerObject*)parent->getParent(); + } + } + } + + + if (is_attached) { if (object->isAnimatedObject()) { @@ -6705,14 +6823,12 @@ void LLSelectMgr::pauseAssociatedAvatars() mPauseRequests.push_back(gAgentAvatarp->requestPause()); } } - else + else if (object && object->isAnimatedObject() && object->getControlAvatar()) { - if (object && object->isAnimatedObject() && object->getControlAvatar()) - { - // Is a non-attached animated object. Pause the control avatar. - mPauseRequests.push_back(object->getControlAvatar()->requestPause()); - } + // Is a non-attached animated object. Pause the control avatar. + mPauseRequests.push_back(object->getControlAvatar()->requestPause()); } + } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index ce0fee8803..3e8bfdb00e 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -714,6 +714,8 @@ public: LLPermissions* findObjectPermissions(const LLViewerObject* object); + BOOL isSelfAvatarSelected(); + void selectDelete(); // Delete on simulator void selectForceDelete(); // just delete, no into trash void selectDuplicate(const LLVector3& offset, BOOL select_copy); // Duplicate on simulator diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp index 689734e36a..ea7e649792 100644 --- a/indra/newview/llsidepanelinventory.cpp +++ b/indra/newview/llsidepanelinventory.cpp @@ -564,6 +564,7 @@ void LLSidepanelInventory::updateVerbs() mWearBtn->setEnabled(FALSE); mPlayBtn->setVisible(FALSE); mPlayBtn->setEnabled(FALSE); + mPlayBtn->setToolTip(std::string("")); mTeleportBtn->setVisible(FALSE); mTeleportBtn->setEnabled(FALSE); mShopBtn->setVisible(TRUE); @@ -588,11 +589,23 @@ void LLSidepanelInventory::updateVerbs() mShopBtn->setVisible(FALSE); break; case LLInventoryType::IT_SOUND: + mPlayBtn->setVisible(TRUE); + mPlayBtn->setEnabled(TRUE); + mPlayBtn->setToolTip(LLTrans::getString("InventoryPlaySoundTooltip")); + mShopBtn->setVisible(FALSE); + break; case LLInventoryType::IT_GESTURE: + mPlayBtn->setVisible(TRUE); + mPlayBtn->setEnabled(TRUE); + mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayGestureTooltip")); + mShopBtn->setVisible(FALSE); + break; case LLInventoryType::IT_ANIMATION: mPlayBtn->setVisible(TRUE); mPlayBtn->setEnabled(TRUE); - mShopBtn->setVisible(FALSE); + mPlayBtn->setEnabled(TRUE); + mPlayBtn->setToolTip(LLTrans::getString("InventoryPlayAnimationTooltip")); + mShopBtn->setVisible(FALSE); break; case LLInventoryType::IT_LANDMARK: mTeleportBtn->setVisible(TRUE); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 5a40af14a3..f5fea9dece 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -34,7 +34,6 @@ #include "lleconomy.h" #include "llfloaterperms.h" #include "llfloaterreg.h" -#include "llfloaterfacebook.h" #include "llfloaterflickr.h" #include "llfloatertwitter.h" #include "llimagefilter.h" @@ -572,7 +571,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update) if (mThumbnailSubsampled) { - // The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook) + // The thumbnail is be a subsampled version of the preview (used in SL Share previews, i.e. Flickr, Twitter) raw->resize( mPreviewImage->getWidth(), mPreviewImage->getHeight(), mPreviewImage->getComponents()); @@ -638,7 +637,7 @@ LLViewerTexture* LLSnapshotLivePreview::getBigThumbnailImage() if (raw) { - // The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter, Facebook) + // The big thumbnail is a new filtered version of the preview (used in SL Share previews, i.e. Flickr, Twitter) mBigThumbnailWidth = mPreviewImage->getWidth(); mBigThumbnailHeight = mPreviewImage->getHeight(); raw->resize( mBigThumbnailWidth, diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index d28a7cc048..f6cf714db4 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -99,7 +99,7 @@ void LLSurfacePatch::dirty() } else { - LL_WARNS() << "No viewer object for this surface patch!" << LL_ENDL; + LL_WARNS("Terrain") << "No viewer object for this surface patch!" << LL_ENDL; } mDirtyZStats = TRUE; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 1396a8546d..8a2fc881a9 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -32,6 +32,7 @@ #include "llrender.h" #include "llagent.h" #include "llviewertexturelist.h" +#include "llselectmgr.h" #include "llcheckboxctrl.h" #include "llcombobox.h" #include "llbutton.h" @@ -70,6 +71,8 @@ #include "lllocalbitmaps.h" #include "llerror.h" +#include "llavatarappearancedefines.h" + static const F32 CONTEXT_CONE_IN_ALPHA = 0.0f; static const F32 CONTEXT_CONE_OUT_ALPHA = 1.f; static const F32 CONTEXT_FADE_TIME = 0.08f; @@ -118,7 +121,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker( mOnFloaterCommitCallback(NULL), mOnFloaterCloseCallback(NULL), mSetImageAssetIDCallback(NULL), - mOnUpdateImageStatsCallback(NULL) + mOnUpdateImageStatsCallback(NULL), + mBakeTextureEnabled(FALSE) { buildFromFile("floater_texture_ctrl.xml"); mCanApplyImmediately = can_apply_immediately; @@ -136,26 +140,47 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti mNoCopyTextureSelected = FALSE; mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? mImageAssetID = image_id; - LLUUID item_id = findItemID(mImageAssetID, FALSE); - if (item_id.isNull()) + + if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { - mInventoryPanel->getRootFolder()->clearSelection(); + if ( mBakeTextureEnabled && mModeSelector->getSelectedIndex() != 2) + { + mModeSelector->setSelectedIndex(2, 0); + onModeSelect(0,this); + } } else { - LLInventoryItem* itemp = gInventory.getItem(image_id); - if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) + if (mModeSelector->getSelectedIndex() == 2) { - // no copy texture - getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE); - mNoCopyTextureSelected = TRUE; + mModeSelector->setSelectedIndex(0, 0); + onModeSelect(0,this); + } + + LLUUID item_id = findItemID(mImageAssetID, FALSE); + if (item_id.isNull()) + { + mInventoryPanel->getRootFolder()->clearSelection(); + } + else + { + LLInventoryItem* itemp = gInventory.getItem(image_id); + if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID())) + { + // no copy texture + getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE); + mNoCopyTextureSelected = TRUE; + } } - } - if (set_selection) - { - mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO); + if (set_selection) + { + mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO); + } } + + + } } @@ -341,6 +366,10 @@ BOOL LLFloaterTexturePicker::postBuild() mInventoryPanel = getChild<LLInventoryPanel>("inventory panel"); + mModeSelector = getChild<LLRadioGroup>("mode_selection"); + mModeSelector->setCommitCallback(onModeSelect, this); + mModeSelector->setSelectedIndex(0, 0); + if(mInventoryPanel) { U32 filter_types = 0x0; @@ -366,16 +395,15 @@ BOOL LLFloaterTexturePicker::postBuild() // don't put keyboard focus on selected item, because the selection callback // will assume that this was user input - if(!mImageAssetID.isNull()) + + + + if (!mImageAssetID.isNull()) { mInventoryPanel->setSelection(findItemID(mImageAssetID, FALSE), TAKE_FOCUS_NO); } } - mModeSelector = getChild<LLRadioGroup>("mode_selection"); - mModeSelector->setCommitCallback(onModeSelect, this); - mModeSelector->setSelectedIndex(0, 0); - childSetAction("l_add_btn", LLFloaterTexturePicker::onBtnAdd, this); childSetAction("l_rem_btn", LLFloaterTexturePicker::onBtnRemove, this); childSetAction("l_upl_btn", LLFloaterTexturePicker::onBtnUpload, this); @@ -404,6 +432,10 @@ BOOL LLFloaterTexturePicker::postBuild() LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1)); + getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this); + getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setCommitCallback(onHideBaseMeshRegionCheck, this); + + setBakeTextureEnabled(FALSE); return TRUE; } @@ -478,7 +510,24 @@ void LLFloaterTexturePicker::draw() mTexturep = NULL; if(mImageAssetID.notNull()) { - mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID); + LLPointer<LLViewerFetchedTexture> texture = NULL; + + if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) + { + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (obj) + { + LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); + texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL; + } + } + + if (texture.isNull()) + { + texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID); + } + + mTexturep = texture; mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW); } @@ -697,6 +746,7 @@ void LLFloaterTexturePicker::onBtnSelect(void* userdata) local_id = LLLocalBitmapMgr::getWorldID(temp_id); } } + if (self->mOnFloaterCommitCallback) { self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_SELECT, local_id); @@ -760,22 +810,81 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - bool mode = (self->mModeSelector->getSelectedIndex() == 0); + int mode = self->mModeSelector->getSelectedIndex(); - self->getChild<LLButton>("Default")->setVisible(mode); - self->getChild<LLButton>("Blank")->setVisible(mode); - self->getChild<LLButton>("None")->setVisible(mode); - self->getChild<LLButton>("Pipette")->setVisible(mode); - self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode); - self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode); + self->getChild<LLButton>("Default")->setVisible(mode == 0); + self->getChild<LLButton>("Blank")->setVisible(mode == 0); + self->getChild<LLButton>("None")->setVisible(mode == 0); + self->getChild<LLButton>("Pipette")->setVisible(mode == 0); + self->getChild<LLFilterEditor>("inventory search editor")->setVisible(mode == 0); + self->getChild<LLInventoryPanel>("inventory panel")->setVisible(mode == 0); /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode); no idea under which conditions the above is even shown, needs testing. */ - self->getChild<LLButton>("l_add_btn")->setVisible(!mode); - self->getChild<LLButton>("l_rem_btn")->setVisible(!mode); - self->getChild<LLButton>("l_upl_btn")->setVisible(!mode); - self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(!mode); + self->getChild<LLButton>("l_add_btn")->setVisible(mode == 1); + self->getChild<LLButton>("l_rem_btn")->setVisible(mode == 1); + self->getChild<LLButton>("l_upl_btn")->setVisible(mode == 1); + self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(mode == 1); + + self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(mode == 2); + self->getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(false);// mode == 2); + + if (mode == 2) + { + self->stopUsingPipette(); + + S8 val = -1; + + LLUUID imageID = self->mImageAssetID; + if (imageID == IMG_USE_BAKED_HEAD) + { + val = 0; + } + else if (imageID == IMG_USE_BAKED_UPPER) + { + val = 1; + } + else if (imageID == IMG_USE_BAKED_LOWER) + { + val = 2; + } + else if (imageID == IMG_USE_BAKED_EYES) + { + val = 3; + } + else if (imageID == IMG_USE_BAKED_SKIRT) + { + val = 4; + } + else if (imageID == IMG_USE_BAKED_HAIR) + { + val = 5; + } + else if (imageID == IMG_USE_BAKED_LEFTARM) + { + val = 6; + } + else if (imageID == IMG_USE_BAKED_LEFTLEG) + { + val = 7; + } + else if (imageID == IMG_USE_BAKED_AUX1) + { + val = 8; + } + else if (imageID == IMG_USE_BAKED_AUX2) + { + val = 9; + } + else if (imageID == IMG_USE_BAKED_AUX3) + { + val = 10; + } + + + self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setSelectedByValue(val, TRUE); + } } // static @@ -896,6 +1005,86 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da picker->commitIfImmediateSet(); } +//static +void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data) +{ + LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)user_data; + LLComboBox* combo_box = (LLComboBox*)ctrl; + + S8 type = combo_box->getValue().asInteger(); + + LLUUID imageID = self->mDefaultImageAssetID; + if (type == 0) + { + imageID = IMG_USE_BAKED_HEAD; + } + else if (type == 1) + { + imageID = IMG_USE_BAKED_UPPER; + } + else if (type == 2) + { + imageID = IMG_USE_BAKED_LOWER; + } + else if (type == 3) + { + imageID = IMG_USE_BAKED_EYES; + } + else if (type == 4) + { + imageID = IMG_USE_BAKED_SKIRT; + } + else if (type == 5) + { + imageID = IMG_USE_BAKED_HAIR; + } + else if (type == 6) + { + imageID = IMG_USE_BAKED_LEFTARM; + } + else if (type == 7) + { + imageID = IMG_USE_BAKED_LEFTLEG; + } + else if (type == 8) + { + imageID = IMG_USE_BAKED_AUX1; + } + else if (type == 9) + { + imageID = IMG_USE_BAKED_AUX2; + } + else if (type == 10) + { + imageID = IMG_USE_BAKED_AUX3; + } + + self->setImageID(imageID); + self->mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? + + if (!self->mPreviewSettingChanged) + { + self->mCanPreview = gSavedSettings.getBOOL("TextureLivePreview"); + } + else + { + self->mPreviewSettingChanged = false; + } + + if (self->mCanPreview) + { + // only commit intentional selections, not implicit ones + self->commitIfImmediateSet(); + } +} + +//static +void LLFloaterTexturePicker::onHideBaseMeshRegionCheck(LLUICtrl* ctrl, void *user_data) +{ + //LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data; + //LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl; +} + void LLFloaterTexturePicker::updateFilterPermMask() { //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss. @@ -951,6 +1140,28 @@ void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled) mModeSelector->setIndexEnabled(1,enabled); } +void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) +{ + BOOL changed = (enabled != mBakeTextureEnabled); + + mBakeTextureEnabled = enabled; + mModeSelector->setIndexEnabled(2, enabled); + + if (!mBakeTextureEnabled && (mModeSelector->getSelectedIndex() == 2)) + { + mModeSelector->setSelectedIndex(0, 0); + } + + if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) + { + if (mModeSelector->getSelectedIndex() != 2) + { + mModeSelector->setSelectedIndex(2, 0); + } + } + onModeSelect(0, this); +} + void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te ) { LLUUID inventory_item_id = findItemID(te.getID(), TRUE); @@ -1000,7 +1211,8 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p) mImageAssetID(p.image_id), mDefaultImageAssetID(p.default_image_id), mDefaultImageName(p.default_image_name), - mFallbackImage(p.fallback_image) + mFallbackImage(p.fallback_image), + mBakeTextureEnabled(FALSE) { // Default of defaults is white image for diff tex @@ -1191,6 +1403,10 @@ void LLTextureCtrl::showPicker(BOOL take_focus) { texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1)); } + if (texture_floaterp) + { + texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled); + } LLFloater* root_floater = gFloaterView->getParentFloater(this); if (root_floater) @@ -1366,6 +1582,16 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) } } +void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled) +{ + mBakeTextureEnabled = enabled; + LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); + if (floaterp) + { + floaterp->setBakeTextureEnabled(enabled); + } +} + BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, @@ -1420,7 +1646,23 @@ void LLTextureCtrl::draw() } else if (!mImageAssetID.isNull()) { - LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES,LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLPointer<LLViewerFetchedTexture> texture = NULL; + + if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) + { + LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (obj) + { + LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID); + texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL; + } + + } + + if (texture.isNull()) + { + texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW); texture->forceToSaveRawImage(0) ; diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 6bcf9c3a75..b2a34a37c4 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -201,6 +201,8 @@ public: LLViewerFetchedTexture* getTexture() { return mTexturep; } + void setBakeTextureEnabled(BOOL enabled); + private: BOOL allowDrop(LLInventoryItem* item); BOOL doDrop(LLInventoryItem* item); @@ -237,6 +239,7 @@ private: BOOL mShowLoadingPlaceholder; std::string mLoadingPlaceholderString; S32 mLabelWidth; + BOOL mBakeTextureEnabled; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -326,7 +329,11 @@ public: static void onBtnUpload(void* userdata); static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata); + static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata); + static void onHideBaseMeshRegionCheck(LLUICtrl* ctrl, void *userdata); + void setLocalTextureEnabled(BOOL enabled); + void setBakeTextureEnabled(BOOL enabled); protected: LLPointer<LLViewerTexture> mTexturep; @@ -368,11 +375,14 @@ private: bool mCanPreview; bool mPreviewSettingChanged; + texture_selected_callback mTextureSelectedCallback; floater_close_callback mOnFloaterCloseCallback; floater_commit_callback mOnFloaterCommitCallback; set_image_asset_id_callback mSetImageAssetIDCallback; set_on_update_image_stats_callback mOnUpdateImageStatsCallback; + + BOOL mBakeTextureEnabled; }; #endif // LL_LLTEXTURECTRL_H diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index c9133338fb..f6cb787156 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -66,6 +66,7 @@ bool LLTextureFetchDebugger::sDebuggerEnabled = false ; LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit"); LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt"); +LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits"); LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sCacheReadLatency("texture_cache_read_latency"); LLTrace::SampleStatHandle<F32Seconds> LLTextureFetch::sTexDecodeLatency("texture_decode_latency"); @@ -1311,6 +1312,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS(LOG_TXT) << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize() << " Size: " << llformat("%dx%d",mFormattedImage->getWidth(),mFormattedImage->getHeight()) << " Desired Discard: " << mDesiredDiscard << " Desired Size: " << mDesiredSize << LL_ENDL; + record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1)); } else { @@ -1326,7 +1328,7 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_DEBUGS(LOG_TXT) << mID << ": Not in Cache" << LL_ENDL; setState(LOAD_FROM_NETWORK); } - + record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0)); // fall through } } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index a01c01847e..cdf8868597 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -312,6 +312,7 @@ public: static LLTrace::SampleStatHandle<F32Seconds> sCacheReadLatency; static LLTrace::SampleStatHandle<F32Seconds> sTexDecodeLatency; static LLTrace::SampleStatHandle<F32Seconds> sTexFetchLatency; + static LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > sCacheHitRate; private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 392c103d7c..f9c327b46e 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -267,7 +267,7 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask) BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask) { mMouseDown = TRUE; - gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); + gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE, LLFloaterReg::instanceVisible("build")); return TRUE; } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index f184b22ccb..2a87bce134 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -111,9 +111,64 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) mMouseOutsideSlop = FALSE; mMouseDownX = x; mMouseDownY = y; + LLTimer pick_timer; + BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); + LLPickInfo transparent_pick = gViewerWindow->pickImmediate(x, y, TRUE /*includes transparent*/, pick_rigged); + LLPickInfo visible_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged); + LLViewerObject *transp_object = transparent_pick.getObject(); + LLViewerObject *visible_object = visible_pick.getObject(); + + // Current set of priorities + // 1. Transparent attachment pick + // 2. Transparent actionable pick + // 3. Visible attachment pick (e.x we click on attachment under invisible floor) + // 4. Visible actionable pick + // 5. Transparent pick (e.x. movement on transparent object/floor, our default pick) + // left mouse down always picks transparent (but see handleMouseUp). + // Also see LLToolPie::handleHover() - priorities are a bit different there. + // Todo: we need a more consistent set of rules to work with + if (transp_object == visible_object || !visible_object) + { + // Note: if transparent object is null, then visible object is also null + // since transparent pick includes non-tranpsarent one. + // !transparent_object check will be covered by transparent_object == visible_object. + mPick = transparent_pick; + } + else + { + // Select between two non-null picks + LLViewerObject *transp_parent = transp_object->getRootEdit(); + LLViewerObject *visible_parent = visible_object->getRootEdit(); + if (transp_object->isAttachment()) + { + // 1. Transparent attachment + mPick = transparent_pick; + } + else if (transp_object->getClickAction() != CLICK_ACTION_DISABLED + && (useClickAction(mask, transp_object, transp_parent) || transp_object->flagHandleTouch() || (transp_parent && transp_parent->flagHandleTouch()))) + { + // 2. Transparent actionable pick + mPick = transparent_pick; + } + else if (visible_object->isAttachment()) + { + // 3. Visible attachment pick + mPick = visible_pick; + } + else if (visible_object->getClickAction() != CLICK_ACTION_DISABLED + && (useClickAction(mask, visible_object, visible_parent) || visible_object->flagHandleTouch() || (visible_parent && visible_parent->flagHandleTouch()))) + { + // 4. Visible actionable pick + mPick = visible_pick; + } + else + { + // 5. Default: transparent + mPick = transparent_pick; + } + } + LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL; - //left mouse down always picks transparent (but see handleMouseUp) - mPick = gViewerWindow->pickImmediate(x, y, TRUE, FALSE); mPick.mKeyMask = mask; mMouseButtonDown = true; diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp index 1936e24761..e424983cf8 100644 --- a/indra/newview/lltranslate.cpp +++ b/indra/newview/lltranslate.cpp @@ -38,8 +38,12 @@ #include "llcoros.h" #include "reader.h" #include "llcorehttputil.h" +#include "llurlregistry.h" +static const std::string BING_NOTRANSLATE_OPENING_TAG("<div class=\"notranslate\">"); +static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>"); + /** * Handler of an HTTP machine translation service. * @@ -99,6 +103,8 @@ public: */ virtual bool isConfigured() const = 0; + virtual LLTranslate::EService getCurrentService() = 0; + virtual void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) = 0; virtual void translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure); @@ -248,6 +254,8 @@ public: std::string& err_msg) const; /*virtual*/ bool isConfigured() const; + /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_GOOGLE; } + /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc); private: @@ -409,6 +417,8 @@ public: std::string& err_msg) const; /*virtual*/ bool isConfigured() const; + /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_BING; } + /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc); private: static std::string getAPIKey(); @@ -520,7 +530,59 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri { LLTranslationAPIHandler& handler = getPreferredHandler(); - handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), mesg, success, failure); + handler.translateMessage(LLTranslationAPIHandler::LanguagePair_t(from_lang, to_lang), addNoTranslateTags(mesg), success, failure); +} + +std::string LLTranslate::addNoTranslateTags(std::string mesg) +{ + if (getPreferredHandler().getCurrentService() != SERVICE_BING) + { + return mesg; + } + + std::string upd_msg(mesg); + LLUrlMatch match; + S32 dif = 0; + //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation + while (LLUrlRegistry::instance().findUrl(mesg, match)) + { + upd_msg.insert(dif + match.getStart(), BING_NOTRANSLATE_OPENING_TAG); + upd_msg.insert(dif + BING_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, BING_NOTRANSLATE_CLOSING_TAG); + mesg.erase(match.getStart(), match.getEnd() - match.getStart()); + dif += match.getEnd() - match.getStart() + BING_NOTRANSLATE_OPENING_TAG.size() + BING_NOTRANSLATE_CLOSING_TAG.size(); + } + return upd_msg; +} + +std::string LLTranslate::removeNoTranslateTags(std::string mesg) +{ + if (getPreferredHandler().getCurrentService() != SERVICE_BING) + { + return mesg; + } + std::string upd_msg(mesg); + LLUrlMatch match; + S32 opening_tag_size = BING_NOTRANSLATE_OPENING_TAG.size(); + S32 closing_tag_size = BING_NOTRANSLATE_CLOSING_TAG.size(); + S32 dif = 0; + //remove 'no-translate' tags we added to the links before + while (LLUrlRegistry::instance().findUrl(mesg, match)) + { + if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == BING_NOTRANSLATE_OPENING_TAG) + { + upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size); + dif -= opening_tag_size; + + if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == BING_NOTRANSLATE_CLOSING_TAG) + { + upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " "); + dif -= closing_tag_size - 1; + } + } + mesg.erase(match.getStart(), match.getUrl().size()); + dif += match.getUrl().size(); + } + return upd_msg; } /*static*/ diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h index bf431cdfbb..e0722fbd83 100644 --- a/indra/newview/lltranslate.h +++ b/indra/newview/lltranslate.h @@ -91,6 +91,9 @@ public : */ static bool isTranslationConfigured(); + static std::string addNoTranslateTags(std::string mesg); + static std::string removeNoTranslateTags(std::string mesg); + private: static LLTranslationAPIHandler& getPreferredHandler(); static LLTranslationAPIHandler& getHandler(EService service); diff --git a/indra/newview/lltwitterconnect.cpp b/indra/newview/lltwitterconnect.cpp index 5d598aaebe..b2d2fa9d77 100644 --- a/indra/newview/lltwitterconnect.cpp +++ b/indra/newview/lltwitterconnect.cpp @@ -28,6 +28,7 @@ #include "llviewerprecompiledheaders.h" #include "lltwitterconnect.h" +#include "llflickrconnect.h" #include "llagent.h" #include "llcallingcard.h" // for LLAvatarTracker @@ -65,6 +66,49 @@ void toast_user_for_twitter_success() LLNotificationsUtil::add("TwitterConnect", args); } +class LLTwitterConnectHandler : public LLCommandHandler +{ +public: + LLTwitterConnectHandler() : LLCommandHandler("fbc", UNTRUSTED_THROTTLE) {} + + bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) + { + if (tokens.size() >= 1) + { + if (tokens[0].asString() == "connect") + { + if (tokens.size() >= 2 && tokens[1].asString() == "twitter") + { + // this command probably came from the twitter_web browser, so close it + LLFloaterReg::hideInstance("twitter_web"); + + // connect to twitter + if (query_map.has("oauth_token")) + { + LLTwitterConnect::instance().connectToTwitter(query_map["oauth_token"], query_map.get("oauth_verifier")); + } + return true; + } + else if (tokens.size() >= 2 && tokens[1].asString() == "flickr") + { + // this command probably came from the flickr_web browser, so close it + LLFloaterReg::hideInstance("flickr_web"); + + // connect to flickr + if (query_map.has("oauth_token")) + { + LLFlickrConnect::instance().connectToFlickr(query_map["oauth_token"], query_map.get("oauth_verifier")); + } + return true; + } + } + } + return false; + } +}; +LLTwitterConnectHandler gTwitterConnectHandler; + + /////////////////////////////////////////////////////////////////////////////// // void LLTwitterConnect::twitterConnectCoro(std::string requestToken, std::string oauthVerifier) diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index 78268944fc..da31e4f542 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -47,6 +47,7 @@ // library includes #include "llnotificationsutil.h" #include "llsd.h" +#include "stringize.h" static LLURLDispatcherListener sURLDispatcherListener; @@ -255,14 +256,23 @@ void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& // Teleportation links are handled here because they are tightly coupled // to SLURL parsing and sim-fragment parsing -class LLTeleportHandler : public LLCommandHandler +class LLTeleportHandler : public LLCommandHandler, public LLEventAPI { public: // Teleport requests *must* come from a trusted browser // inside the app, otherwise a malicious web page could // cause a constant teleport loop. JC - LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_THROTTLE) { } - + LLTeleportHandler() : + LLCommandHandler("teleport", UNTRUSTED_THROTTLE), + LLEventAPI("LLTeleportHandler", "Low-level teleport API") + { + LLEventAPI::add("teleport", + "Teleport to specified [\"regionname\"] at\n" + "specified region-relative [\"x\"], [\"y\"], [\"z\"].\n" + "If [\"regionname\"] omitted, teleport to GLOBAL\n" + "coordinates [\"x\"], [\"y\"], [\"z\"].", + &LLTeleportHandler::from_event); + } bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web) @@ -293,6 +303,41 @@ public: return true; } + void from_event(const LLSD& params) const + { + Response response(LLSD(), params); + if (params.has("regionname")) + { + // region specified, coordinates (if any) are region-local + LLVector3 local_pos( + params.has("x")? params["x"].asReal() : 128, + params.has("y")? params["y"].asReal() : 128, + params.has("z")? params["z"].asReal() : 0); + std::string regionname(params["regionname"]); + std::string destination(LLSLURL(regionname, local_pos).getSLURLString()); + // have to resolve region's global coordinates first + teleport_via_slapp(regionname, destination); + response["message"] = "Teleporting to " + destination; + } + else // no regionname + { + // coordinates are global, and at least (x, y) are required + if (! (params.has("x") && params.has("y"))) + { + return response.error("Specify either regionname or global (x, y)"); + } + LLVector3d global_pos(params["x"].asReal(), params["y"].asReal(), + params["z"].asReal()); + gAgent.teleportViaLocation(global_pos); + LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance(); + if (instance) + { + instance->trackLocation(global_pos); + } + response["message"] = STRINGIZE("Teleporting to global " << global_pos); + } + } + static void teleport_via_slapp(std::string region_name, std::string callback_url) { diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 64f6123f5d..e2554bc9bc 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -237,6 +237,7 @@ void display_stats() static LLTrace::BlockTimerStatHandle FTM_PICK("Picking"); static LLTrace::BlockTimerStatHandle FTM_RENDER("Render"); +static LLTrace::BlockTimerStatHandle FTM_RENDER_HUD("Render HUD"); static LLTrace::BlockTimerStatHandle FTM_UPDATE_SKY("Update Sky"); static LLTrace::BlockTimerStatHandle FTM_UPDATE_DYNAMIC_TEXTURES("Update Dynamic Textures"); static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images"); @@ -568,6 +569,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) if (gDisconnected) { LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected"); + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); render_ui(); swap(); } @@ -1293,7 +1295,8 @@ void render_ui(F32 zoom_factor, int subfield) { gPipeline.renderBloom(gSnapshot, zoom_factor, subfield); } - + + LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); render_hud_elements(); render_hud_attachments(); } @@ -1308,8 +1311,6 @@ void render_ui(F32 zoom_factor, int subfield) gGL.color4f(1,1,1,1); if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); - if (!gDisconnected) { render_ui_3d(); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 2a61c26b30..f475ab7d66 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -67,7 +67,6 @@ #include "llfloaterexperiences.h" #include "llfloaterexperiencepicker.h" #include "llfloaterevent.h" -#include "llfloaterfacebook.h" #include "llfloaterflickr.h" #include "llfloaterfonttest.h" #include "llfloatergesture.h" @@ -353,11 +352,9 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); - LLFloaterReg::add("fbc_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); LLFloaterReg::add("flickr_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); LLFloaterReg::add("twitter_web", "floater_fbc_web.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create); - LLFloaterReg::add("facebook", "floater_facebook.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFacebook>); LLFloaterReg::add("flickr", "floater_flickr.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFlickr>); LLFloaterReg::add("twitter", "floater_twitter.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTwitter>); LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 1ab7ec0156..61857d6fb1 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -138,6 +138,7 @@ LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary() mInventoryItemsDict["New Skirt"] = LLTrans::getString("New Skirt"); mInventoryItemsDict["New Alpha"] = LLTrans::getString("New Alpha"); mInventoryItemsDict["New Tattoo"] = LLTrans::getString("New Tattoo"); + mInventoryItemsDict["New Universal"] = LLTrans::getString("New Universal"); mInventoryItemsDict["New Physics"] = LLTrans::getString("New Physics"); mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable"); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index b89e1497a1..e930eb20d3 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -64,7 +64,12 @@ LLViewerKeyboard gViewerKeyboard; void agent_jump( EKeystate s ) { - if( KEYSTATE_UP == s ) return; + static BOOL first_fly_attempt(TRUE); + if (KEYSTATE_UP == s) + { + first_fly_attempt = TRUE; + return; + } F32 time = gKeyboard->getCurKeyElapsedTime(); S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount()); @@ -77,7 +82,8 @@ void agent_jump( EKeystate s ) } else { - gAgent.setFlying(TRUE); + gAgent.setFlying(TRUE, first_fly_attempt); + first_fly_attempt = FALSE; gAgent.moveUp(1); } } diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index d8745b1eca..a27a083a2a 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1707,7 +1707,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ // HACK: we always try to keep a spare running webkit plugin around to improve launch times. // If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it. - // Do not use a spare if launching with full viewer control (e.g. Facebook, Twitter and few others) + // Do not use a spare if launching with full viewer control (e.g. Twitter and few others) if ((plugin_basename == "media_plugin_cef") && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins") && !clean_browser) { @@ -1901,21 +1901,8 @@ void LLViewerMediaImpl::loadURI() // trim whitespace from front and back of URL - fixes EXT-5363 LLStringUtil::trim( mMediaURL ); - // *HACK: we don't know if the URI coming in is properly escaped - // (the contract doesn't specify whether it is escaped or not. - // but LLQtWebKit expects it to be, so we do our best to encode - // special characters) - // The strings below were taken right from http://www.ietf.org/rfc/rfc1738.txt - // Note especially that '%' and '/' are there. - std::string uri = LLURI::escape(mMediaURL, - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - "0123456789" - "$-_.+" - "!*'()," - "{}|\\^~[]`" - "<>#%" - ";/?:@&=", - false); + // URI often comes unescaped + std::string uri = LLURI::escapePathAndData(mMediaURL); { // Do not log the query parts LLURI u(uri); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index ba68ce4cf4..52b2c631fa 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -54,7 +54,6 @@ #include "lldaycyclemanager.h" #include "lldebugview.h" #include "llenvmanager.h" -#include "llfacebookconnect.h" #include "llfilepicker.h" #include "llfirstuse.h" #include "llfloaterabout.h" @@ -4066,10 +4065,8 @@ void near_sit_down_point(BOOL success, void *) if (success) { gAgent.setFlying(FALSE); + gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); - - // Might be first sit - //LLFirstUse::useSit(); } } @@ -4754,6 +4751,12 @@ void handle_take() category_id.setNull(); } + // check inbox + const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX); + if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id)) + { + category_id.setNull(); + } } } if(category_id.isNull()) @@ -9207,7 +9210,6 @@ void initialize_menus() enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1)); view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn"); - enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance())); view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse"); enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute)); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index e50c8ee9f0..c8f75c79c4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -2415,7 +2415,7 @@ void translateSuccess(LLChat chat, LLSD toastArgs, std::string originalMsg, std: && ((detected_language.empty()) || (expectLang != detected_language)) && (LLStringUtil::compareInsensitive(translation, originalMsg) != 0)) { - chat.mText += " (" + translation + ")"; + chat.mText += " (" + LLTranslate::removeNoTranslateTags(translation) + ")"; } LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ec1095813b..1353a27982 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4707,13 +4707,76 @@ void LLViewerObject::sendTEUpdate() const msg->sendReliable( regionp->getHost() ); } +LLViewerTexture* LLViewerObject::getBakedTextureForMagicId(const LLUUID& id) +{ + if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) + { + return NULL; + } + + LLViewerObject *root = getRootEdit(); + if (root && root->isAnimatedObject()) + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + LLAvatarAppearanceDefines::EBakedTextureIndex texIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::assetIdToBakedTextureIndex(id); + LLViewerTexture* bakedTexture = avatar->getBakedTexture(texIndex); + if (bakedTexture == NULL || bakedTexture->isMissingAsset()) + { + return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + else + { + return bakedTexture; + } + } + else + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + } + +} + +void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id) +{ + if (id == old_id) + { + return; + } + + if (!LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(old_id) && !LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) + { + return; + } + + LLVOAvatar* avatar = getAvatar(); + if (avatar) + { + avatar->updateMeshVisibility(); + } +} + void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) { + LLUUID old_image_id; + if (getTE(te)) + { + old_image_id = getTE(te)->getID(); + } + LLPrimitive::setTE(te, texture_entry); const LLUUID& image_id = getTE(te)->getID(); - mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + updateAvatarMeshVisibility(image_id,old_image_id); + if (getTE(te)->getMaterialParams().notNull()) { const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); @@ -4724,12 +4787,31 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) } } +void LLViewerObject::refreshBakeTexture() +{ + for (int face_index = 0; face_index < getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = getTE(face_index); + if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) + { + const LLUUID& image_id = tex_entry->getID(); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + changeTEImage(face_index, bakedTexture); + } + } +} + void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) { if (mTEImages[te] != imagep) { - mTEImages[te] = imagep; + LLUUID old_image_id = getTE(te) ? getTE(te)->getID() : LLUUID::null; + LLPrimitive::setTETexture(te, imagep->getID()); + + LLViewerTexture* baked_texture = getBakedTextureForMagicId(imagep->getID()); + mTEImages[te] = baked_texture ? baked_texture : imagep; + updateAvatarMeshVisibility(imagep->getID(), old_image_id); setChanged(TEXTURE); if (mDrawable.notNull()) { @@ -4740,13 +4822,16 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep) S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image) { + LLUUID old_image_id = getTE(te)->getID(); const LLUUID& uuid = image->getID(); S32 retval = 0; if (uuid != getTE(te)->getID() || uuid == LLUUID::null) { retval = LLPrimitive::setTETexture(te, uuid); - mTEImages[te] = image; + LLViewerTexture* baked_texture = getBakedTextureForMagicId(uuid); + mTEImages[te] = baked_texture ? baked_texture : image; + updateAvatarMeshVisibility(uuid,old_image_id); setChanged(TEXTURE); if (mDrawable.notNull()) { @@ -4837,7 +4922,7 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid) // Invalid host == get from the agent's sim LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture( uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost()); - return setTETextureCore(te,image); + return setTETextureCore(te, image); } S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 8b1535851e..873b300489 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -588,6 +588,10 @@ public: friend class LLViewerMediaList; public: + LLViewerTexture* getBakedTextureForMagicId(const LLUUID& id); + void updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& old_id); + void refreshBakeTexture(); +public: static void unpackVector3(LLDataPackerBinaryBuffer* dp, LLVector3& value, std::string name); static void unpackUUID(LLDataPackerBinaryBuffer* dp, LLUUID& value, std::string name); static void unpackU32(LLDataPackerBinaryBuffer* dp, U32& value, std::string name); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 4d9288f152..5b227c641b 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2895,7 +2895,6 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("EstateAccess"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); - capabilityNames.append("FacebookConnect"); capabilityNames.append("FlickrConnect"); capabilityNames.append("TwitterConnect"); @@ -3235,6 +3234,12 @@ bool LLViewerRegion::meshUploadEnabled() const mSimulatorFeatures["MeshUploadEnabled"].asBoolean()); } +bool LLViewerRegion::bakesOnMeshEnabled() const +{ + return (mSimulatorFeatures.has("BakesOnMeshEnabled") && + mSimulatorFeatures["BakesOnMeshEnabled"].asBoolean()); +} + bool LLViewerRegion::meshRezEnabled() const { return (mSimulatorFeatures.has("MeshRezEnabled") && diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index d5266ec873..2548ff1423 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -304,6 +304,8 @@ public: bool meshRezEnabled() const; bool meshUploadEnabled() const; + bool bakesOnMeshEnabled() const; + // has region received its simulator features list? Requires an additional query after caps received. void requestSimulatorFeatures(); void setSimulatorFeaturesReceived(bool); diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp index 66e5742911..7f7d190b92 100644 --- a/indra/newview/llviewertexlayer.cpp +++ b/indra/newview/llviewertexlayer.cpp @@ -58,6 +58,8 @@ LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, mNeedsUpdate(TRUE), mNumLowresUpdates(0) { + mGLTexturep->setNeedsAlphaAndPickMask(FALSE); + LLViewerTexLayerSetBuffer::sGLByteCount += getSize(); mNeedsUpdateTimer.start(); } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 68a9994bee..a81b3aaef9 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1219,6 +1219,7 @@ void LLViewerFetchedTexture::loadFromFastCache() F32 cachReadTime = fastCacheTimer.getElapsedTimeF32(); add(LLTextureFetch::sCacheHit, 1.0); + record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(1)); sample(LLTextureFetch::sCacheReadLatency, cachReadTime); mFullWidth = mRawImage->getWidth() << mRawDiscardLevel; @@ -1251,6 +1252,10 @@ void LLViewerFetchedTexture::loadFromFastCache() addToCreateTexture(); } } + else + { + record(LLTextureFetch::sCacheHitRate, LLUnits::Ratio::fromValue(0)); + } } void LLViewerFetchedTexture::setForSculpt() diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 4308405c64..06524847d1 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -512,7 +512,7 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id, if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM) { // Workaround: we need BOOST_ALM texture for something, 'rise' to NONE - imagep->setDecodePriority(LLViewerTexture::BOOST_NONE); + imagep->setBoostLevel(LLViewerTexture::BOOST_NONE); } LLViewerFetchedTexture *texture = imagep.get(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5b764f97fb..4c6a3dd33d 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1775,7 +1775,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) // Get the real window rect the window was created with (since there are various OS-dependent reasons why // the size of a window or fullscreen context may have been adjusted slightly...) - F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getSystemUISize(); + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); mDisplayScale *= ui_scale_factor; @@ -3819,7 +3819,7 @@ void LLViewerWindow::renderSelections( BOOL for_gl_pick, BOOL pick_parcel_walls, BOOL draw_handles = TRUE; - if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move) + if (tool == LLToolCompTranslate::getInstance() && !all_selected_objects_move && !LLSelectMgr::getInstance()->isSelfAvatarSelected()) { draw_handles = FALSE; } @@ -4620,7 +4620,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) && (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) { - if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true)) + if (scratch_space.allocate(image_width, image_height, GL_DEPTH_COMPONENT, true, true)) { original_width = gPipeline.mDeferredScreen.getWidth(); original_height = gPipeline.mDeferredScreen.getHeight(); @@ -4734,6 +4734,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei { // Required for showing the GUI in snapshots and performing bloom composite overlay // Call even if show_ui is FALSE + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); render_ui(scale_factor, subfield); swap(); } @@ -5348,7 +5349,7 @@ F32 LLViewerWindow::getWorldViewAspectRatio() const void LLViewerWindow::calcDisplayScale() { - F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE) * mWindow->getSystemUISize(); + F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor") * mWindow->getSystemUISize(), MIN_UI_SCALE, MAX_UI_SCALE); LLVector2 display_scale; display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f)); display_scale *= ui_scale_factor; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c4430f4308..c63c5f6b23 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -99,6 +99,8 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) { return; } + // This is terrain texture, but we are not setting it as BOOST_TERRAIN + // since we will be manipulating it later as needed. mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); mDetailTextures[corner]->setNoDelete() ; mRawImages[corner] = NULL; @@ -241,6 +243,7 @@ BOOL LLVLComposition::generateComposition() } mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail mDetailTextures[i]->setMinDiscardLevel(ddiscard); + mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority return FALSE; } } @@ -287,7 +290,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { mDetailTextures[i]->destroyRawImage() ; } - LL_DEBUGS() << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << LL_ENDL; + LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } @@ -323,12 +326,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (x_end > mWidth) { - LL_WARNS() << "x end > width" << LL_ENDL; + LL_WARNS("Terrain") << "x end > width" << LL_ENDL; x_end = mWidth; } if (y_end > mWidth) { - LL_WARNS() << "y end > width" << LL_ENDL; + LL_WARNS("Terrain") << "y end > width" << LL_ENDL; y_end = mWidth; } @@ -358,7 +361,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (tex_comps != st_comps) { - LL_WARNS() << "Base texture comps != input texture comps" << LL_ENDL; + LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL; return FALSE; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 20fa327790..5584efeb7b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -751,8 +751,8 @@ std::string LLVOAvatar::avString() const } else { - std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); - return " Avatar '" + getFullname() + "' " + viz_string + " "; + std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus()); + return " Avatar '" + getFullname() + "' " + viz_string + " "; } } @@ -829,7 +829,8 @@ BOOL LLVOAvatar::isFullyBaked() for (U32 i = 0; i < mBakedTextureDatas.size(); i++) { if (!isTextureDefined(mBakedTextureDatas[i].mTextureIndex) - && ( (i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ) ) + && ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)) + && (i != BAKED_LEFT_ARM) && (i != BAKED_LEFT_LEG) && (i != BAKED_AUX1) && (i != BAKED_AUX2) && (i != BAKED_AUX3)) { return FALSE; } @@ -1322,7 +1323,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) if (dist_vec(zero_pos, mPelvisp->getWorldPosition())<0.001) { // Don't use pelvis until av initialized - pos.load3(getRenderPosition().mV); + pos.load3(getRenderPosition().mV); } else { @@ -1336,16 +1337,16 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) //displayed, can give inaccurate boxes due to joints stuck at (0,0,0). if ((box_detail>=1) && !isControlAvatar()) { - for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) - { - LLPolyMesh* mesh = i->second; - for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++) - { - LLVector4a trans; - trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); - update_min_max(newMin, newMax, trans); - } - } + for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i) + { + LLPolyMesh* mesh = i->second; + for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++) + { + LLVector4a trans; + trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV); + update_min_max(newMin, newMax, trans); + } + } } @@ -1362,22 +1363,22 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { float max_attachment_span = get_default_max_prim_scale() * 5.0f; - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); - iter != mAttachmentPoints.end(); - ++iter) - { - LLViewerJointAttachment* attachment = iter->second; + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; - if (attachment->getValid()) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { + if (attachment->getValid()) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { // Don't we need to look at children of attached_object as well? - const LLViewerObject* attached_object = (*attachment_iter); - if (attached_object && !attached_object->isHUDAttachment()) - { + const LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isHUDAttachment()) + { const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object); if (vol && vol->isAnimatedObject()) { @@ -1399,33 +1400,33 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) { continue; } - LLDrawable* drawable = attached_object->mDrawable; - if (drawable && !drawable->isState(LLDrawable::RIGGED)) - { - LLSpatialBridge* bridge = drawable->getSpatialBridge(); - if (bridge) - { - const LLVector4a* ext = bridge->getSpatialExtents(); - LLVector4a distance; - distance.setSub(ext[1], ext[0]); - LLVector4a max_span(max_attachment_span); + LLDrawable* drawable = attached_object->mDrawable; + if (drawable && !drawable->isState(LLDrawable::RIGGED)) + { + LLSpatialBridge* bridge = drawable->getSpatialBridge(); + if (bridge) + { + const LLVector4a* ext = bridge->getSpatialExtents(); + LLVector4a distance; + distance.setSub(ext[1], ext[0]); + LLVector4a max_span(max_attachment_span); - S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; + S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7; - // Only add the prim to spatial extents calculations if it isn't a megaprim. - // max_attachment_span calculated at the start of the function - // (currently 5 times our max prim size) - if (lt == 0x7) - { - update_min_max(newMin,newMax,ext[0]); - update_min_max(newMin,newMax,ext[1]); - } - } - } - } - } - } - } + // Only add the prim to spatial extents calculations if it isn't a megaprim. + // max_attachment_span calculated at the start of the function + // (currently 5 times our max prim size) + if (lt == 0x7) + { + update_min_max(newMin,newMax,ext[0]); + update_min_max(newMin,newMax,ext[1]); + } + } + } + } + } + } + } } // Stretch bounding box by rigged mesh joint boxes @@ -1949,7 +1950,7 @@ void LLVOAvatar::buildCharacter() // Currently disabled for control avatars (animated objects), enabled for all others. if (mEnableDefaultMotions) { - startDefaultMotions(); + startDefaultMotions(); } //------------------------------------------------------------------------- @@ -2066,8 +2067,8 @@ void LLVOAvatar::resetSkeleton(bool reset_animations) // Reset tweakable params to preserved state if (mLastProcessedAppearance) { - bool slam_params = true; - applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); + bool slam_params = true; + applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params); } updateVisualParams(); @@ -2119,15 +2120,15 @@ void LLVOAvatar::releaseMeshData() LLFace* facep = mDrawable->getFace(0); if (facep) { - facep->setSize(0, 0); - for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) - { - facep = mDrawable->getFace(i); + facep->setSize(0, 0); + for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++) + { + facep = mDrawable->getFace(i); if (facep) { - facep->setSize(0, 0); - } - } + facep->setSize(0, 0); + } + } } } @@ -2385,6 +2386,7 @@ LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUU { result->setIsMissingAsset(false); } + } return result; } @@ -2770,13 +2772,13 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (mDrawable.notNull()) { - mDrawable->movePartition(); - - //force a move if sitting on an active object - if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) - { - gPipeline.markMoved(mDrawable, TRUE); - } + mDrawable->movePartition(); + + //force a move if sitting on an active object + if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) + { + gPipeline.markMoved(mDrawable, TRUE); + } } } @@ -3539,66 +3541,67 @@ bool LLVOAvatar::isInMuteList() void LLVOAvatar::updateAppearanceMessageDebugText() { - S32 central_bake_version = -1; - if (getRegion()) - { - central_bake_version = getRegion()->getCentralBakeVersion(); - } - bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded(); - bool all_local_downloaded = allLocalTexturesCompletelyDownloaded(); - std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d", - isSelf() ? (all_local_downloaded ? "L" : "l") : "-", - all_baked_downloaded ? "B" : "b", - mUseLocalAppearance, mIsEditingAppearance, - 1, central_bake_version); - std::string origin_string = bakedTextureOriginInfo(); - debug_line += " [" + origin_string + "]"; - S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); - S32 last_request_cof_version = mLastUpdateRequestCOFVersion; - S32 last_received_cof_version = mLastUpdateReceivedCOFVersion; - if (isSelf()) - { - debug_line += llformat(" - cof: %d req: %d rcv:%d", - curr_cof_version, last_request_cof_version, last_received_cof_version); - if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure")) + S32 central_bake_version = -1; + if (getRegion()) + { + central_bake_version = getRegion()->getCentralBakeVersion(); + } + bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded(); + bool all_local_downloaded = allLocalTexturesCompletelyDownloaded(); + std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d", + isSelf() ? (all_local_downloaded ? "L" : "l") : "-", + all_baked_downloaded ? "B" : "b", + mUseLocalAppearance, mIsEditingAppearance, + 1, central_bake_version); + std::string origin_string = bakedTextureOriginInfo(); + debug_line += " [" + origin_string + "]"; + S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion(); + S32 last_request_cof_version = mLastUpdateRequestCOFVersion; + S32 last_received_cof_version = mLastUpdateReceivedCOFVersion; + if (isSelf()) + { + debug_line += llformat(" - cof: %d req: %d rcv:%d", + curr_cof_version, last_request_cof_version, last_received_cof_version); + if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure")) + { + debug_line += " FORCING ERRS"; + } + } + else + { + debug_line += llformat(" - cof rcv:%d", last_received_cof_version); + } + debug_line += llformat(" bsz-z: %.3f", mBodySize[2]); + if (mAvatarOffset[2] != 0.0f) { - debug_line += " FORCING ERRS"; + debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]); } - } - else - { - debug_line += llformat(" - cof rcv:%d", last_received_cof_version); - } - debug_line += llformat(" bsz-z: %.3f", mBodySize[2]); - if (mAvatarOffset[2] != 0.0f) - { - debug_line += llformat("avofs-z: %.3f", mAvatarOffset[2]); - } - bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled(); - debug_line += hover_enabled ? " H" : " h"; - const LLVector3& hover_offset = getHoverOffset(); - if (hover_offset[2] != 0.0) - { - debug_line += llformat(" hov_z: %.3f", hover_offset[2]); + bool hover_enabled = getRegion() && getRegion()->avatarHoverHeightEnabled(); + debug_line += hover_enabled ? " H" : " h"; + const LLVector3& hover_offset = getHoverOffset(); + if (hover_offset[2] != 0.0) + { + debug_line += llformat(" hov_z: %.3f", hover_offset[2]); debug_line += llformat(" %s", (isSitting() ? "S" : "T")); - debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-")); - } - LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); - LLVector3 normal; - LLVector3 ankle_right_ground_agent = ankle_right_pos_agent; - resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal); - F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]); - debug_line += llformat(" relev %.3f", rightElev); + debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-")); + } + + LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); + LLVector3 normal; + LLVector3 ankle_right_ground_agent = ankle_right_pos_agent; + resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal); + F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]); + debug_line += llformat(" relev %.3f", rightElev); - LLVector3 root_pos = mRoot->getPosition(); - LLVector3 pelvis_pos = mPelvisp->getPosition(); - debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]); + LLVector3 root_pos = mRoot->getPosition(); + LLVector3 pelvis_pos = mPelvisp->getPosition(); + debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]); S32 is_visible = (S32) isVisible(); S32 is_m_visible = (S32) mVisible; debug_line += llformat(" v %d/%d", is_visible, is_m_visible); - addDebugText(debug_line); + addDebugText(debug_line); } LLViewerInventoryItem* getObjectInventoryItem(LLViewerObject *vobj, LLUUID asset_id) @@ -3610,7 +3613,7 @@ LLViewerInventoryItem* getObjectInventoryItem(LLViewerObject *vobj, LLUUID asset if (vobj->getInventorySerial()<=0) { vobj->requestInventory(); - } + } item = vobj->getInventoryItemByAsset(asset_id); } return item; @@ -3628,23 +3631,23 @@ LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLU LLViewerObject *childp = *it; item = getObjectInventoryItem(childp, asset_id); if (item) - { + { break; } } - } + } return item; } void LLVOAvatar::updateAnimationDebugText() { - for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); - iter != mMotionController.getActiveMotions().end(); ++iter) - { - LLMotion* motionp = *iter; - if (motionp->getMinPixelArea() < getPixelArea()) - { - std::string output; + for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin(); + iter != mMotionController.getActiveMotions().end(); ++iter) + { + LLMotion* motionp = *iter; + if (motionp->getMinPixelArea() < getPixelArea()) + { + std::string output; std::string motion_name = motionp->getName(); if (motion_name.empty()) { @@ -3661,73 +3664,73 @@ void LLVOAvatar::updateAnimationDebugText() } } if (motion_name.empty()) - { - std::string name; - if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf()) - { - name = motionp->getID().asString(); - LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); - for (; anim_it != mAnimationSources.end(); ++anim_it) - { - if (anim_it->second == motionp->getID()) - { - LLViewerObject* object = gObjectList.findObject(anim_it->first); - if (!object) - { - break; - } - if (object->isAvatar()) - { - if (mMotionController.mIsSelf) - { - // Searching inventory by asset id is really long - // so just mark as inventory - // Also item is likely to be named by LLPreviewAnim - name += "(inventory)"; - } - } - else - { - LLViewerInventoryItem* item = NULL; - if (!object->isInventoryDirty()) - { - item = object->getInventoryItemByAsset(motionp->getID()); - } - if (item) - { - name = item->getName(); - } - else if (object->isAttachment()) - { - name += "(" + getAttachmentItemName() + ")"; - } - else - { - // in-world object, name or content unknown - name += "(in-world)"; - } - } - break; - } - } - } - else - { - name = LLUUID::null.asString(); - } - output = llformat("%s - %d", - name.c_str(), - (U32)motionp->getPriority()); - } - else - { - output = llformat("%s - %d", + { + std::string name; + if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf()) + { + name = motionp->getID().asString(); + LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin(); + for (; anim_it != mAnimationSources.end(); ++anim_it) + { + if (anim_it->second == motionp->getID()) + { + LLViewerObject* object = gObjectList.findObject(anim_it->first); + if (!object) + { + break; + } + if (object->isAvatar()) + { + if (mMotionController.mIsSelf) + { + // Searching inventory by asset id is really long + // so just mark as inventory + // Also item is likely to be named by LLPreviewAnim + name += "(inventory)"; + } + } + else + { + LLViewerInventoryItem* item = NULL; + if (!object->isInventoryDirty()) + { + item = object->getInventoryItemByAsset(motionp->getID()); + } + if (item) + { + name = item->getName(); + } + else if (object->isAttachment()) + { + name += "(" + getAttachmentItemName() + ")"; + } + else + { + // in-world object, name or content unknown + name += "(in-world)"; + } + } + break; + } + } + } + else + { + name = LLUUID::null.asString(); + } + output = llformat("%s - %d", + name.c_str(), + (U32)motionp->getPriority()); + } + else + { + output = llformat("%s - %d", motion_name.c_str(), - (U32)motionp->getPriority()); - } - addDebugText(output); - } - } + (U32)motionp->getPriority()); + } + addDebugText(output); + } + } } void LLVOAvatar::updateDebugText() @@ -3760,7 +3763,7 @@ void LLVOAvatar::updateDebugText() { setDebugText(mDebugText); } - mDebugText.clear(); + mDebugText.clear(); } //------------------------------------------------------------------------ @@ -3774,7 +3777,7 @@ void LLVOAvatar::updateFootstepSounds() { return; } - + //------------------------------------------------------------------------- // Find the ground under each foot, these are used for a variety // of things that follow @@ -3799,7 +3802,7 @@ void LLVOAvatar::updateFootstepSounds() if (!mInAir) { if ((leftElev < 0.0f) || (rightElev < 0.0f)) - { + { ankle_left_pos_agent = mFootLeftp->getWorldPosition(); ankle_right_pos_agent = mFootRightp->getWorldPosition(); leftElev = ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]; @@ -3828,10 +3831,10 @@ void LLVOAvatar::updateFootstepSounds() // did right foot hit the ground? if ( onGroundRight && !mWasOnGroundRight ) - { + { foot_pos_agent = ankle_right_pos_agent; playSound = TRUE; - } + } mWasOnGroundLeft = onGroundLeft; mWasOnGroundRight = onGroundRight; @@ -3920,153 +3923,153 @@ void LLVOAvatar::computeUpdatePeriod() //------------------------------------------------------------------------ void LLVOAvatar::updateOrientation(LLAgent& agent, F32 speed, F32 delta_time) { - LLQuaternion iQ; - LLVector3 upDir( 0.0f, 0.0f, 1.0f ); + LLQuaternion iQ; + LLVector3 upDir( 0.0f, 0.0f, 1.0f ); - // Compute a forward direction vector derived from the primitive rotation - // and the velocity vector. When walking or jumping, don't let body deviate - // more than 90 from the view, if necessary, flip the velocity vector. + // Compute a forward direction vector derived from the primitive rotation + // and the velocity vector. When walking or jumping, don't let body deviate + // more than 90 from the view, if necessary, flip the velocity vector. - LLVector3 primDir; - if (isSelf()) - { - primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector()); - primDir.normalize(); - } - else - { - primDir = getRotation().getMatrix3().getFwdRow(); - } - LLVector3 velDir = getVelocity(); - velDir.normalize(); - if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end()) - { - F32 vpD = velDir * primDir; - if (vpD < -0.5f) - { - velDir *= -1.0f; - } - } - LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f)); - if (isSelf() && gAgentCamera.cameraMouselook()) - { - // make sure fwdDir stays in same general direction as primdir - if (gAgent.getFlying()) - { - fwdDir = LLViewerCamera::getInstance()->getAtAxis(); - } - else - { - LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis(); - LLVector3 up_vector = gAgent.getReferenceUpVector(); - at_axis -= up_vector * (at_axis * up_vector); - at_axis.normalize(); + LLVector3 primDir; + if (isSelf()) + { + primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector()); + primDir.normalize(); + } + else + { + primDir = getRotation().getMatrix3().getFwdRow(); + } + LLVector3 velDir = getVelocity(); + velDir.normalize(); + if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end()) + { + F32 vpD = velDir * primDir; + if (vpD < -0.5f) + { + velDir *= -1.0f; + } + } + LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f)); + if (isSelf() && gAgentCamera.cameraMouselook()) + { + // make sure fwdDir stays in same general direction as primdir + if (gAgent.getFlying()) + { + fwdDir = LLViewerCamera::getInstance()->getAtAxis(); + } + else + { + LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis(); + LLVector3 up_vector = gAgent.getReferenceUpVector(); + at_axis -= up_vector * (at_axis * up_vector); + at_axis.normalize(); - F32 dot = fwdDir * at_axis; - if (dot < 0.f) - { - fwdDir -= 2.f * at_axis * dot; - fwdDir.normalize(); - } - } - } + F32 dot = fwdDir * at_axis; + if (dot < 0.f) + { + fwdDir -= 2.f * at_axis * dot; + fwdDir.normalize(); + } + } + } - LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); - F32 root_roll, root_pitch, root_yaw; - root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); + LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion(); + F32 root_roll, root_pitch, root_yaw; + root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); - // When moving very slow, the pelvis is allowed to deviate from the + // When moving very slow, the pelvis is allowed to deviate from the // forward direction to allow it to hold its position while the torso - // and head turn. Once in motion, it must conform however. - BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); + // and head turn. Once in motion, it must conform however. + BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook(); - LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV ); + LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV ); - static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0); - static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0); + static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow", 60.0); + static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast", 2.0); - F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); + F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, s_pelvis_rot_threshold_slow, s_pelvis_rot_threshold_fast); - if (self_in_mouselook) - { - pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; - } - pelvis_rot_threshold *= DEG_TO_RAD; + if (self_in_mouselook) + { + pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; + } + pelvis_rot_threshold *= DEG_TO_RAD; - F32 angle = angle_between( pelvisDir, fwdDir ); + F32 angle = angle_between( pelvisDir, fwdDir ); - // The avatar's root is allowed to have a yaw that deviates widely - // from the forward direction, but if roll or pitch are off even - // a little bit we need to correct the rotation. - if(root_roll < 1.f * DEG_TO_RAD - && root_pitch < 5.f * DEG_TO_RAD) - { - // smaller correction vector means pelvis follows prim direction more closely - if (!mTurning && angle > pelvis_rot_threshold*0.75f) - { - mTurning = TRUE; - } + // The avatar's root is allowed to have a yaw that deviates widely + // from the forward direction, but if roll or pitch are off even + // a little bit we need to correct the rotation. + if(root_roll < 1.f * DEG_TO_RAD + && root_pitch < 5.f * DEG_TO_RAD) + { + // smaller correction vector means pelvis follows prim direction more closely + if (!mTurning && angle > pelvis_rot_threshold*0.75f) + { + mTurning = TRUE; + } - // use tighter threshold when turning - if (mTurning) - { - pelvis_rot_threshold *= 0.4f; - } + // use tighter threshold when turning + if (mTurning) + { + pelvis_rot_threshold *= 0.4f; + } - // am I done turning? - if (angle < pelvis_rot_threshold) - { - mTurning = FALSE; - } + // am I done turning? + if (angle < pelvis_rot_threshold) + { + mTurning = FALSE; + } - LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f); - fwdDir += correction_vector; - } - else - { - mTurning = FALSE; - } + LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f); + fwdDir += correction_vector; + } + else + { + mTurning = FALSE; + } - // Now compute the full world space rotation for the whole body (wQv) - LLVector3 leftDir = upDir % fwdDir; - leftDir.normalize(); - fwdDir = leftDir % upDir; - LLQuaternion wQv( fwdDir, leftDir, upDir ); + // Now compute the full world space rotation for the whole body (wQv) + LLVector3 leftDir = upDir % fwdDir; + leftDir.normalize(); + fwdDir = leftDir % upDir; + LLQuaternion wQv( fwdDir, leftDir, upDir ); - if (isSelf() && mTurning) - { - if ((fwdDir % pelvisDir) * upDir > 0.f) - { - gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT); - } - else - { - gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT); - } - } + if (isSelf() && mTurning) + { + if ((fwdDir % pelvisDir) * upDir > 0.f) + { + gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT); + } + else + { + gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT); + } + } - // Set the root rotation, but do so incrementally so that it - // lags in time by some fixed amount. - //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG); - F32 pelvis_lag_time = 0.f; - if (self_in_mouselook) - { - pelvis_lag_time = PELVIS_LAG_MOUSELOOK; - } - else if (mInAir) - { - pelvis_lag_time = PELVIS_LAG_FLYING; - // increase pelvis lag time when moving slowly - pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f); - } - else - { - pelvis_lag_time = PELVIS_LAG_WALKING; - } + // Set the root rotation, but do so incrementally so that it + // lags in time by some fixed amount. + //F32 u = LLSmoothInterpolation::getInterpolant(PELVIS_LAG); + F32 pelvis_lag_time = 0.f; + if (self_in_mouselook) + { + pelvis_lag_time = PELVIS_LAG_MOUSELOOK; + } + else if (mInAir) + { + pelvis_lag_time = PELVIS_LAG_FLYING; + // increase pelvis lag time when moving slowly + pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f); + } + else + { + pelvis_lag_time = PELVIS_LAG_WALKING; + } F32 u = llclamp((delta_time / pelvis_lag_time), 0.0f, 1.0f); - mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) ); + mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) ); } //------------------------------------------------------------------------ @@ -4128,7 +4131,7 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w mRoot->setWorldPosition( getPositionAgent() ); // first frame mRoot->setWorldRotation( getRotation() ); } - + //-------------------------------------------------------------------- // dont' let dT get larger than 1/5th of a second //-------------------------------------------------------------------- @@ -4366,7 +4369,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mRoot->updateWorldMatrixChildren(); // System avatar mesh vertices need to be reskinned. - mNeedsSkin = TRUE; + mNeedsSkin = TRUE; return TRUE; } @@ -4880,14 +4883,14 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass) first_pass = FALSE; } if (isTextureVisible(TEX_HAIR_BAKED)) - { - LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); - if (hair_mesh) - { - num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); - } - first_pass = FALSE; - } + { + LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR); + if (hair_mesh) + { + num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy); + } + first_pass = FALSE; + } if (LLPipeline::sImpostorRender) { gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); @@ -4995,22 +4998,22 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) gGL.flush(); } { - LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); + LLGLEnable test(GL_ALPHA_TEST); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); - gGL.color4ubv(color.mV); - gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0,0); - gGL.vertex3fv((pos+left-up).mV); - gGL.texCoord2f(1,0); - gGL.vertex3fv((pos-left-up).mV); - gGL.texCoord2f(1,1); - gGL.vertex3fv((pos-left+up).mV); - gGL.texCoord2f(0,1); - gGL.vertex3fv((pos+left+up).mV); - gGL.end(); - gGL.flush(); + gGL.color4ubv(color.mV); + gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); + gGL.begin(LLRender::QUADS); + gGL.texCoord2f(0,0); + gGL.vertex3fv((pos+left-up).mV); + gGL.texCoord2f(1,0); + gGL.vertex3fv((pos-left-up).mV); + gGL.texCoord2f(1,1); + gGL.vertex3fv((pos-left+up).mV); + gGL.texCoord2f(0,1); + gGL.vertex3fv((pos+left+up).mV); + gGL.end(); + gGL.flush(); } return 6; @@ -5510,8 +5513,8 @@ void LLVOAvatar::processAnimationStateChanges() stopMotion(ANIM_AGENT_WALK_ADJUST); if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_FLY_ADJUST); - } + startMotion(ANIM_AGENT_FLY_ADJUST); + } } else { @@ -5523,7 +5526,7 @@ void LLVOAvatar::processAnimationStateChanges() { if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_TARGET); + startMotion(ANIM_AGENT_TARGET); } stopMotion(ANIM_AGENT_BODY_NOISE); } @@ -5532,8 +5535,8 @@ void LLVOAvatar::processAnimationStateChanges() stopMotion(ANIM_AGENT_TARGET); if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_BODY_NOISE); - } + startMotion(ANIM_AGENT_BODY_NOISE); + } } // clear all current animations @@ -5901,10 +5904,10 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) if (pSkinData && pSkinData->mJointNames.size() > JOINT_COUNT_REQUIRED_FOR_FULLRIG // full rig && pSkinData->mAlternateBindMatrix.size() > 0 ) - { - mesh_id = pSkinData->mMeshID; - return true; - } + { + mesh_id = pSkinData->mMeshID; + return true; + } } } return false; @@ -5913,14 +5916,14 @@ bool LLVOAvatar::getRiggedMeshID(LLViewerObject* pVO, LLUUID& mesh_id) bool LLVOAvatar::jointIsRiggedTo(const LLJoint *joint) const { if (joint) - { + { const LLJointRiggingInfoTab& tab = mJointRiggingInfoTab; S32 joint_num = joint->getJointNum(); if (joint_num < tab.size() && tab[joint_num].isRiggedTo()) - { - return true; + { + return true; + } } - } return false; } @@ -5929,25 +5932,25 @@ void LLVOAvatar::clearAttachmentOverrides() LLScopedContextString str("clearAttachmentOverrides " + getFullname()); for (S32 i=0; i<LL_CHARACTER_MAX_ANIMATED_JOINTS; i++) - { + { LLJoint *pJoint = getJoint(i); if (pJoint) { pJoint->clearAttachmentPosOverrides(); pJoint->clearAttachmentScaleOverrides(); } - } + } if (mPelvisFixups.count()>0) { mPelvisFixups.clear(); LLJoint* pJointPelvis = getJoint("mPelvis"); if (pJointPelvis) - { + { pJointPelvis->setPosition( LLVector3( 0.0f, 0.0f, 0.0f) ); } postPelvisSetRecalc(); - } + } mActiveOverrideMeshes.clear(); onActiveOverrideMeshesChanged(); @@ -5968,7 +5971,7 @@ void LLVOAvatar::rebuildAttachmentOverrides() // Handle the case that we're resetting the skeleton of an animated object. LLControlAvatar *control_av = dynamic_cast<LLControlAvatar*>(this); if (control_av) - { + { LLVOVolume *volp = control_av->mRootVolp; if (volp) { @@ -6105,9 +6108,9 @@ void LLVOAvatar::updateAttachmentOverrides() if (scale_overrides_by_joint[joint_num] != joint->m_attachmentScaleOverrides) { mismatched = true; - } } } + } if (pelvis_fixups != mPelvisFixups) { mismatched = true; @@ -6126,10 +6129,10 @@ void LLVOAvatar::updateAttachmentOverrides() void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LLUUID>* meshes_seen, bool recursive) { if (vo->getAvatar() != this && vo->getAvatarAncestor() != this) - { + { LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL; return; - } + } LLScopedContextString str("addAttachmentOverridesForObject " + getFullname()); @@ -6139,14 +6142,14 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL // Process all children if (recursive) { - LLViewerObject::const_child_list_t& children = vo->getChildren(); - for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); - it != children.end(); ++it) - { - LLViewerObject *childp = *it; + LLViewerObject::const_child_list_t& children = vo->getChildren(); + for (LLViewerObject::const_child_list_t::const_iterator it = children.begin(); + it != children.end(); ++it) + { + LLViewerObject *childp = *it; addAttachmentOverridesForObject(childp, meshes_seen, true); } - } + } LLVOVolume *vobj = dynamic_cast<LLVOVolume*>(vo); bool pelvisGotSet = false; @@ -6407,7 +6410,7 @@ void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id) LLJoint* pJointPelvis = getJoint("mPelvis"); const std::string av_string = avString(); for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) - { + { LLJoint *pJoint = getJoint(joint_num); if ( pJoint ) { @@ -7017,6 +7020,22 @@ const LLViewerJointAttachment *LLVOAvatar::attachObject(LLViewerObject *viewer_o LLSelectMgr::getInstance()->updatePointAt(); } + viewer_object->refreshBakeTexture(); + + + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + updateMeshVisibility(); + return attachment; } @@ -7220,7 +7239,6 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO ) //----------------------------------------------------------------------------- BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { - for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) @@ -7231,12 +7249,28 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) { updateVisualComplexity(); bool is_animated_object = viewer_object->isAnimatedObject(); - cleanupAttachedMesh( viewer_object ); + cleanupAttachedMesh(viewer_object); + attachment->removeObject(viewer_object); if (!is_animated_object) { updateAttachmentOverrides(); } + viewer_object->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = viewer_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectp = *iter1; + if (objectp) + { + objectp->refreshBakeTexture(); + } + } + + updateMeshVisibility(); + LL_DEBUGS() << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << LL_ENDL; return TRUE; } @@ -7372,7 +7406,7 @@ void LLVOAvatar::getOffObject() if (mEnableDefaultMotions) { - startMotion(ANIM_AGENT_BODY_NOISE); + startMotion(ANIM_AGENT_BODY_NOISE); } if (isSelf()) @@ -7838,8 +7872,8 @@ bool LLVOAvatar::isTooComplex() const // yes, this leaves them vulnerable to griefing objects... their choice too_complex = ( max_render_cost > 0 && (mVisualComplexity > max_render_cost - || (max_attachment_area > 0.0f && mAttachmentSurfaceArea > max_attachment_area) - )); + || (max_attachment_area > 0.0f && mAttachmentSurfaceArea > max_attachment_area) + )); } return too_complex; @@ -7872,6 +7906,115 @@ void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color) } } + +//----------------------------------------------------------------------------- +// updateMeshVisibility() +// Hide the mesh joints if attachments are using baked textures +//----------------------------------------------------------------------------- +void LLVOAvatar::updateMeshVisibility() +{ + bool bake_flag[BAKED_NUM_INDICES]; + memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool)); + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + if (attachment) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject *objectp = (*attachment_iter); + if (objectp) + { + for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = objectp->getTE(face_index); + bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); + bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); + bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); + bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); + bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); + bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); + } + } + + LLViewerObject::const_child_list_t& child_list = objectp->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin(); + iter1 != child_list.end(); ++iter1) + { + LLViewerObject* objectchild = *iter1; + if (objectchild) + { + for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++) + { + LLTextureEntry* tex_entry = objectchild->getTE(face_index); + bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD); + bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES); + bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR); + bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER); + bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER); + bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT); + bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM); + bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG); + bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1); + bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2); + bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3); + } + } + } + } + } + } + + //LL_INFOS() << "head " << bake_flag[BAKED_HEAD] << "eyes " << bake_flag[BAKED_EYES] << "hair " << bake_flag[BAKED_HAIR] << "lower " << bake_flag[BAKED_LOWER] << "upper " << bake_flag[BAKED_UPPER] << "skirt " << bake_flag[BAKED_SKIRT] << LL_ENDL; + + for (S32 i = 0; i < mMeshLOD.size(); i++) + { + LLAvatarJoint* joint = mMeshLOD[i]; + if (i == MESH_ID_HAIR) + { + joint->setVisible(!bake_flag[BAKED_HAIR], TRUE); + } + else if (i == MESH_ID_HEAD) + { + joint->setVisible(!bake_flag[BAKED_HEAD], TRUE); + } + else if (i == MESH_ID_SKIRT) + { + joint->setVisible(!bake_flag[BAKED_SKIRT], TRUE); + } + else if (i == MESH_ID_UPPER_BODY) + { + joint->setVisible(!bake_flag[BAKED_UPPER], TRUE); + } + else if (i == MESH_ID_LOWER_BODY) + { + joint->setVisible(!bake_flag[BAKED_LOWER], TRUE); + } + else if (i == MESH_ID_EYEBALL_LEFT) + { + joint->setVisible(!bake_flag[BAKED_EYES], TRUE); + } + else if (i == MESH_ID_EYEBALL_RIGHT) + { + joint->setVisible(!bake_flag[BAKED_EYES], TRUE); + } + else if (i == MESH_ID_EYELASH) + { + joint->setVisible(!bake_flag[BAKED_HEAD], TRUE); + } + } +} + //----------------------------------------------------------------------------- // updateMeshTextures() // Uses the current TE values to set the meshes' and layersets' textures. @@ -8089,6 +8232,39 @@ void LLVOAvatar::updateMeshTextures() removeMissingBakedTextures(); // May call back into this function if anything is removed call_remove_missing = true; } + + //refresh bakes on any attached objects + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = (*attachment_iter); + if (attached_object && !attached_object->isDead()) + { + attached_object->refreshBakeTexture(); + + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* objectp = *iter; + if (objectp && !objectp->isDead()) + { + objectp->refreshBakeTexture(); + } + } + } + } + } + + + } // virtual @@ -8732,7 +8908,7 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte { if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex) && mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT - && baked_index != BAKED_SKIRT) + && baked_index != BAKED_SKIRT && baked_index != BAKED_LEFT_ARM && baked_index != BAKED_LEFT_LEG && baked_index != BAKED_AUX1 && baked_index != BAKED_AUX2 && baked_index != BAKED_AUX3) { LL_DEBUGS("Avatar") << avString() << " baked_index " << (S32) baked_index << " using mLastTextureID " << mBakedTextureDatas[baked_index].mLastTextureID << LL_ENDL; setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, @@ -8865,6 +9041,39 @@ void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& conte } updateMeshTextures(); + updateMeshVisibility(); + +} + +LLViewerTexture* LLVOAvatar::getBakedTexture(const U8 te) +{ + if (te < 0 || te >= BAKED_NUM_INDICES) + { + return NULL; + } + + BOOL is_layer_baked = isTextureDefined(mBakedTextureDatas[te].mTextureIndex); + + LLViewerTexLayerSet* layerset = NULL; + layerset = getTexLayerSet(te); + + + if (!isEditingAppearance() && is_layer_baked) + { + LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage(mBakedTextureDatas[te].mTextureIndex, 0), TRUE); + return baked_img; + } + else if (layerset && isEditingAppearance()) + { + layerset->createComposite(); + layerset->setUpdatesEnabled(TRUE); + + return layerset->getViewerComposite(); + } + + return NULL; + + } // static @@ -9100,6 +9309,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) } } } + dirtyMesh(); } @@ -9972,122 +10182,122 @@ void LLVOAvatar::accountRenderComplexityForObject( hud_complexity_list_t& hud_complexity_list) { if (attached_object && !attached_object->isHUDAttachment()) - { + { mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount(); mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax(); mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); - textures.clear(); - const LLDrawable* drawable = attached_object->mDrawable; - if (drawable) - { - const LLVOVolume* volume = drawable->getVOVolume(); - if (volume) - { - F32 attachment_total_cost = 0; - F32 attachment_volume_cost = 0; - F32 attachment_texture_cost = 0; - F32 attachment_children_cost = 0; + textures.clear(); + const LLDrawable* drawable = attached_object->mDrawable; + if (drawable) + { + const LLVOVolume* volume = drawable->getVOVolume(); + if (volume) + { + F32 attachment_total_cost = 0; + F32 attachment_volume_cost = 0; + F32 attachment_texture_cost = 0; + F32 attachment_children_cost = 0; const F32 animated_object_attachment_surcharge = 1000; if (attached_object->isAnimatedObject()) { attachment_volume_cost += animated_object_attachment_surcharge; } - attachment_volume_cost += volume->getRenderCost(textures); + attachment_volume_cost += volume->getRenderCost(textures); - const_child_list_t children = volume->getChildren(); - for (const_child_list_t::const_iterator child_iter = children.begin(); - child_iter != children.end(); - ++child_iter) - { - LLViewerObject* child_obj = *child_iter; - LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); - if (child) - { - attachment_children_cost += child->getRenderCost(textures); - } - } + const_child_list_t children = volume->getChildren(); + for (const_child_list_t::const_iterator child_iter = children.begin(); + child_iter != children.end(); + ++child_iter) + { + LLViewerObject* child_obj = *child_iter; + LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj ); + if (child) + { + attachment_children_cost += child->getRenderCost(textures); + } + } - for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); - volume_texture != textures.end(); - ++volume_texture) + for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); + volume_texture != textures.end(); + ++volume_texture) + { + // add the cost of each individual texture in the linkset + attachment_texture_cost += volume_texture->second; + } + attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost; + LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID() + << " total: " << attachment_total_cost + << ", volume: " << attachment_volume_cost + << ", textures: " << attachment_texture_cost + << ", " << volume->numChildren() + << " children: " << attachment_children_cost + << LL_ENDL; + // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI + cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity); + } + } + } + if (isSelf() + && attached_object + && attached_object->isHUDAttachment() + && !attached_object->isTempAttachment() + && attached_object->mDrawable) { - // add the cost of each individual texture in the linkset - attachment_texture_cost += volume_texture->second; - } - attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost; - LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID() - << " total: " << attachment_total_cost - << ", volume: " << attachment_volume_cost - << ", textures: " << attachment_texture_cost - << ", " << volume->numChildren() - << " children: " << attachment_children_cost - << LL_ENDL; - // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI - cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity); - } - } - } - if (isSelf() - && attached_object - && attached_object->isHUDAttachment() - && !attached_object->isTempAttachment() - && attached_object->mDrawable) - { - textures.clear(); + textures.clear(); mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); - const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); - if (volume) - { - LLHUDComplexity hud_object_complexity; - hud_object_complexity.objectName = attached_object->getAttachmentItemName(); - hud_object_complexity.objectId = attached_object->getAttachmentItemID(); - std::string joint_name; - gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name); - hud_object_complexity.jointName = joint_name; - // get cost and individual textures - hud_object_complexity.objectsCost += volume->getRenderCost(textures); - hud_object_complexity.objectsCount++; - - LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); ++iter) - { - LLViewerObject* childp = *iter; - const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp); - if (chld_volume) - { - // get cost and individual textures - hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures); - hud_object_complexity.objectsCount++; - } - } + const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); + if (volume) + { + LLHUDComplexity hud_object_complexity; + hud_object_complexity.objectName = attached_object->getAttachmentItemName(); + hud_object_complexity.objectId = attached_object->getAttachmentItemID(); + std::string joint_name; + gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name); + hud_object_complexity.jointName = joint_name; + // get cost and individual textures + hud_object_complexity.objectsCost += volume->getRenderCost(textures); + hud_object_complexity.objectsCount++; + + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); ++iter) + { + LLViewerObject* childp = *iter; + const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp); + if (chld_volume) + { + // get cost and individual textures + hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures); + hud_object_complexity.objectsCount++; + } + } - hud_object_complexity.texturesCount += textures.size(); + hud_object_complexity.texturesCount += textures.size(); - for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); - volume_texture != textures.end(); - ++volume_texture) - { - // add the cost of each individual texture (ignores duplicates) - hud_object_complexity.texturesCost += volume_texture->second; - LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first); - if (tex) - { - // Note: Texture memory might be incorect since texture might be still loading. - hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory(); - if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) - { - hud_object_complexity.largeTexturesCount++; + for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin(); + volume_texture != textures.end(); + ++volume_texture) + { + // add the cost of each individual texture (ignores duplicates) + hud_object_complexity.texturesCost += volume_texture->second; + LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first); + if (tex) + { + // Note: Texture memory might be incorect since texture might be still loading. + hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory(); + if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE) + { + hud_object_complexity.largeTexturesCount++; + } + } + } + hud_complexity_list.push_back(hud_object_complexity); } } - } - hud_complexity_list.push_back(hud_object_complexity); - } - } } // Calculations for mVisualComplexity value diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index b603381e6d..00dccc5d12 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -617,6 +617,7 @@ public: public: /*virtual*/ LLTexLayerSet* createTexLayerSet(); // Return LLViewerTexLayerSet void releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY ! + protected: static void onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); static void onInitialBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata); @@ -701,6 +702,9 @@ public: void updateSexDependentLayerSets(); virtual void dirtyMesh(); // Dirty the avatar mesh void updateMeshData(); + void updateMeshVisibility(); + LLViewerTexture* getBakedTexture(const U8 te); + protected: void releaseMeshData(); virtual void restoreMeshData(); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 0d3f65502a..e10ba77e16 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -658,6 +658,8 @@ void LLVivoxVoiceClient::voiceControlCoro() mIsCoroutineActive = true; LLCoros::set_consuming(true); + U32 retry = 0; + while (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { LL_DEBUGS("Voice") << "Suspending voiceControlCoro() momentarily for teleport. Tuning: " << mTuningMode << ". Relog: " << mRelogRequested << LL_ENDL; @@ -666,7 +668,8 @@ void LLVivoxVoiceClient::voiceControlCoro() do { - if (startAndConnectSession()) + bool success = startAndConnectSession(); + if (success) { if (mTuningMode) { @@ -677,6 +680,7 @@ void LLVivoxVoiceClient::voiceControlCoro() LL_DEBUGS("Voice") << "lost channel RelogRequested=" << mRelogRequested << LL_ENDL; endAndDisconnectSession(); + retry = 0; } // if we hit this and mRelogRequested is true, that indicates @@ -689,7 +693,19 @@ void LLVivoxVoiceClient::voiceControlCoro() << LL_ENDL; if (mRelogRequested) { - LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL; + if (!success) + { + // We failed to connect, give it a bit time before retrying. + retry++; + F32 delay = llmin(5.f * (F32)retry, 60.f); + llcoro::suspendUntilTimeout(delay); + LL_INFOS("Voice") << "Voice failed to establish session after " << retry << " tries. Will attempt to reconnect." << LL_ENDL; + } + else + { + LL_INFOS("Voice") << "will attempt to reconnect to voice" << LL_ENDL; + } + while (isGatewayRunning() || gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { LL_INFOS("Voice") << "waiting for SLVoice to exit" << LL_ENDL; @@ -770,12 +786,16 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon() { #ifndef VIVOXDAEMON_REMOTEHOST // Launch the voice daemon - std::string exe_path = gDirUtilp->getAppRODataDir(); #if LL_WINDOWS + // On windows use exe (not work or RO) directory + std::string exe_path = gDirUtilp->getExecutableDir(); gDirUtilp->append(exe_path, "SLVoice.exe"); #elif LL_DARWIN + // On MAC use resource directory + std::string exe_path = gDirUtilp->getAppRODataDir(); gDirUtilp->append(exe_path, "SLVoice"); #else + std::string exe_path = gDirUtilp->getExecutableDir(); gDirUtilp->append(exe_path, "SLVoice"); #endif // See if the vivox executable exists diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3793d6b9b2..33a9c771ea 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -85,6 +85,7 @@ #include "llviewerinventory.h" #include "llcallstack.h" #include "llsculptidsize.h" +#include "llavatarappearancedefines.h" const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; @@ -2445,7 +2446,13 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE: case LLMaterial::DIFFUSE_ALPHA_MODE_MASK: { //all of them modes available only for 32 bit textures - if(GL_RGBA != img_diffuse->getPrimaryFormat()) + LLTextureEntry* tex_entry = getTE(te); + bool bIsBakedImageId = false; + if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID())) + { + bIsBakedImageId = true; + } + if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId) { bSetDiffuseNone = true; } @@ -5531,6 +5538,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) U32 mask = mat->getShaderMask(alpha_mode); pool->addRiggedFace(facep, mask); } + + if(vobj->isAnimatedObject() && vobj->isRiggedMesh()) + { + pool->updateRiggedVertexBuffers(vobj->getAvatar()); + } } else if (mat) { diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index ee2270c323..e7bbee5efd 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -455,6 +455,7 @@ clothing_to_string_map_t init_clothing_string_map() w_map.insert(std::make_pair(LLWearableType::WT_SKIRT, "skirt_not_worn")); w_map.insert(std::make_pair(LLWearableType::WT_ALPHA, "alpha_not_worn")); w_map.insert(std::make_pair(LLWearableType::WT_TATTOO, "tattoo_not_worn")); + w_map.insert(std::make_pair(LLWearableType::WT_UNIVERSAL, "universal_not_worn")); w_map.insert(std::make_pair(LLWearableType::WT_PHYSICS, "physics_not_worn")); return w_map; } diff --git a/indra/newview/llwlparamset.cpp b/indra/newview/llwlparamset.cpp index 066cb9a0ac..986f167d8d 100644 --- a/indra/newview/llwlparamset.cpp +++ b/indra/newview/llwlparamset.cpp @@ -337,14 +337,19 @@ void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight) setStarBrightness((1 - weight) * (F32) src.getStarBrightness() + weight * (F32) dest.getStarBrightness()); - llassert(src.getSunAngle() >= - F_PI && - src.getSunAngle() <= 3 * F_PI); - llassert(dest.getSunAngle() >= - F_PI && - dest.getSunAngle() <= 3 * F_PI); - llassert(src.getEastAngle() >= 0 && - src.getEastAngle() <= 4 * F_PI); - llassert(dest.getEastAngle() >= 0 && - dest.getEastAngle() <= 4 * F_PI); + // FIXME: we have established that this assert fails + // frequently. Someone who understands the code needs to figure + // out if it matters. In the meantime, disabling the checks so we + // can stop interfering with other development. + + //llassert(src.getSunAngle() >= - F_PI && + // src.getSunAngle() <= 3 * F_PI); + //llassert(dest.getSunAngle() >= - F_PI && + // dest.getSunAngle() <= 3 * F_PI); + //llassert(src.getEastAngle() >= 0 && + // src.getEastAngle() <= 4 * F_PI); + //llassert(dest.getEastAngle() >= 0 && + // dest.getEastAngle() <= 4 * F_PI); // sun angle and east angle require some handling to make sure // they go in circles. Yes quaternions would work better. diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index b27257a262..86249badaa 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -887,14 +887,8 @@ void LLWorldMapView::drawFrustum() F32 half_width_pixels = half_width_meters * meters_to_pixels; // Compute the frustum coordinates. Take the UI scale into account. -#if defined(LL_DARWIN) - F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor"); - F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * ui_scale_factor) * LLUI::getScaleFactor().mV[VX]; - F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * ui_scale_factor) * LLUI::getScaleFactor().mV[VY]; -#else F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]); F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]); -#endif gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 325f66ec4d..0710eb8813 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4062,7 +4062,6 @@ void LLPipeline::postSort(LLCamera& camera) void render_hud_elements() { - LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); gPipeline.disableLights(); LLGLDisable fog(GL_FOG); diff --git a/indra/newview/skins/default/textures/icons/Inv_Universal.png b/indra/newview/skins/default/textures/icons/Inv_Universal.png Binary files differnew file mode 100644 index 0000000000..470febb9b5 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Universal.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 2540ee148d..5aba0546f3 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -133,7 +133,6 @@ with the same filename but different name <texture name="Command_Chat_Icon" file_name="toolbar_icons/chat.png" preload="true" /> <texture name="Command_Compass_Icon" file_name="toolbar_icons/land.png" preload="true" /> <texture name="Command_Destinations_Icon" file_name="toolbar_icons/destinations.png" preload="true" /> - <texture name="Command_Facebook_Icon" file_name="toolbar_icons/facebook.png" preload="true" /> <texture name="Command_Flickr_Icon" file_name="toolbar_icons/flickr.png" preload="true" /> <texture name="Command_Gestures_Icon" file_name="toolbar_icons/gestures.png" preload="true" /> <texture name="Command_Grid_Status_Icon" file_name="toolbar_icons/grid_status.png" preload="true" /> @@ -205,8 +204,6 @@ with the same filename but different name <texture name="ExternalBrowser_Off" file_name="icons/ExternalBrowser_Off.png" preload="false" /> <texture name="Edit_Wrench" file_name="icons/Edit_Wrench.png" preload="false" /> - <texture name="Facebook_Icon" file_name="icons/Facebook.png" preload="false" /> - <texture name="Presets_Icon" file_name="icons/Presets_Icon.png" preload="true" /> <texture name="Favorite_Star_Active" file_name="navbar/Favorite_Star_Active.png" preload="false" /> @@ -316,6 +313,7 @@ with the same filename but different name <texture name="Inv_SysClosed" file_name="icons/Inv_SysClosed.png" preload="false" /> <texture name="Inv_SysOpen" file_name="icons/Inv_SysOpen.png" preload="false" /> <texture name="Inv_Tattoo" file_name="icons/Inv_Tattoo.png" preload="false" /> + <texture name="Inv_Universal" file_name="icons/Inv_Universal.png" preload="false" /> <texture name="Inv_Physics" file_name="icons/Inv_Physics.png" preload="false" /> <texture name="Inv_Texture" file_name="icons/Inv_Texture.png" preload="false" /> <texture name="Inv_TrashClosed" file_name="icons/Inv_TrashClosed.png" preload="false" /> @@ -592,7 +590,6 @@ with the same filename but different name <texture name="Snapshot_Email" file_name="snapshot_email.png" preload="false" /> <texture name="Snapshot_Inventory" file_name="toolbar_icons/inventory.png" preload="false" /> <texture name="Snapshot_Profile" file_name="toolbar_icons/profile.png" preload="false" /> - <texture name="Snapshot_Facebook" file_name="toolbar_icons/facebook.png" preload="false" /> <texture name="startup_logo" file_name="windows/startup_logo.png" preload="true" /> diff --git a/indra/newview/skins/default/xui/de/floater_about_land.xml b/indra/newview/skins/default/xui/de/floater_about_land.xml index 1e18ab20e8..2bff6d3e2f 100644 --- a/indra/newview/skins/default/xui/de/floater_about_land.xml +++ b/indra/newview/skins/default/xui/de/floater_about_land.xml @@ -21,7 +21,7 @@ <floater.string name="Remaining"> Restzeit </floater.string> - <tab_container name="landtab" tab_min_width="40" width="489"> + <tab_container name="landtab" tab_min_width="40"> <panel label="ALLGEMEIN" name="land_general_panel"> <panel.string name="new users only"> Nur neue Benutzer @@ -361,8 +361,8 @@ Nur große Parzellen können in der Suche aufgeführt werden. <text name="landing_point"> Landepunkt: [LANDING] </text> - <button label="Festlegen" label_selected="Festlegen" left="234" name="Set" right="-88" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/> - <button label="Löschen" label_selected="Löschen" left="312" name="Clear" tool_tip="Landepunkt löschen" width="70"/> + <button label="Festlegen" label_selected="Festlegen" name="Set" tool_tip="Legt Ihren Standort als Landepunkt fest, an dem Besucher ankommen. Legt die Position Ihres Avatars innerhalb dieser Parzelle fest." width="70"/> + <button label="Löschen" label_selected="Löschen" name="Clear" tool_tip="Landepunkt löschen" width="70"/> <text name="Teleport Routing: "> Teleport-Route: </text> @@ -433,7 +433,7 @@ Nur große Parzellen können in der Suche aufgeführt werden. <panel.string name="estate_override"> Eine oder mehrere dieser Optionen gelten auf Grundbesitzebene </panel.string> - <check_box label="Alle Besucher sind zugelassen (Bei Deaktivierung dieser Option werden Bannlinien generiert)" name="public_access"/> + <check_box label="Alle Besucher sind zugelassen" tool_tip="Bei Deaktivierung dieser Option werden Bannlinien generiert" name="public_access"/> <check_box label="Muss 18+ sein [ESTATE_AGE_LIMIT]" name="limit_age_verified" tool_tip="Nur Einwohner, die mindestens 18 Jahre alt sind, können diese Parzelle betreten. Weitere Informationen finden Sie unter [SUPPORT_SITE]."/> <check_box label="Muss über Zahlungsinfo in Datei [ESTATE_PAYMENT_LIMIT] verfügen" name="limit_payment" tool_tip="Um diese Parzelle besuchen zu können, müssen Einwohner Zahlungsinformationen hinterlegt haben. Weitere Informationen finden Sie auf [SUPPORT_SITE]."/> <check_box label="Gruppe [GROUP] ohne Beschränkungen zulassen" name="GroupCheck" tool_tip="Gruppe im Register „Allgemein“ festlegen."/> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index d04e738b22..9f853fd960 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -163,6 +163,7 @@ layout="topleft" left_pad="2" name="Description" + spellcheck="true" top_delta="0" width="365" word_wrap="true" /> @@ -1268,6 +1269,7 @@ Only large parcels can be listed in search. layout="topleft" left_pad="2" name="edit objects check" + tool_tip="If checked, Residents can create and rez objects on your land." width="130" /> <check_box height="16" @@ -1275,6 +1277,7 @@ Only large parcels can be listed in search. layout="topleft" left_pad="2" name="edit group objects check" + tool_tip="If checked, parcel group members can create and rez objects on your land." width="70" /> <text type="string" @@ -1293,6 +1296,7 @@ Only large parcels can be listed in search. layout="topleft" left_pad="2" name="all object entry check" + tool_tip="If checked, Residents can move existing objects from other parcels onto this parcel." top_delta="0" width="130" /> <check_box @@ -1301,6 +1305,7 @@ Only large parcels can be listed in search. layout="topleft" left_pad="2" name="group object entry check" + tool_tip="If checked, parcel group members can move existing objects from other parcels onto this parcel." top_delta="0" width="70" /> <text @@ -1320,6 +1325,7 @@ Only large parcels can be listed in search. layout="topleft" left_pad="2" name="check other scripts" + tool_tip="If checked, Residents can run scripts on your parcel, including attachments." top_delta="0" width="130" /> <check_box @@ -1328,6 +1334,7 @@ Only large parcels can be listed in search. layout="topleft" left_pad="2" name="check group scripts" + tool_tip="If checked, parcel group members can run scripts on your parcel, including attachments." top_delta="0" width="70" /> <panel @@ -1466,11 +1473,12 @@ Only large parcels can be listed in search. length="1" follows="left|top" text_color="LtGray" + text_readonly_color="LabelDisabledColor" height="32" layout="topleft" left="274" top="150" - name="allow_label5" + name="allow_see_label" width="205" word_wrap="true"> Avatars on other parcels can see and chat with avatars on this parcel @@ -1908,6 +1916,7 @@ Only large parcels can be listed in search. layout="topleft" left="8" name="public_access" + tool_tip="" label="Anyone can visit (Unchecking this will create ban lines)" top_pad="10" width="278" /> diff --git a/indra/newview/skins/default/xui/en/floater_ban_duration.xml b/indra/newview/skins/default/xui/en/floater_ban_duration.xml index 5562f28877..6c537cc08d 100644 --- a/indra/newview/skins/default/xui/en/floater_ban_duration.xml +++ b/indra/newview/skins/default/xui/en/floater_ban_duration.xml @@ -28,12 +28,12 @@ draw_border="false" enabled="true" follows="left|top" - height="40" + height="47" left="20" mouse_opaque="true" name="ban_duration_radio" tab_stop="true" - width="200"> + width="150"> <radio_item type="string" follows="left|top" @@ -75,7 +75,7 @@ left_delta="70" name="hours_textbox" top_delta="5" - width="75"> + width="70"> hours. </text> diff --git a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml index 2dfba1ac44..f275fec066 100644 --- a/indra/newview/skins/default/xui/en/floater_experienceprofile.xml +++ b/indra/newview/skins/default/xui/en/floater_experienceprofile.xml @@ -493,6 +493,7 @@ layout="topleft" left="11" name="edit_experience_description" + spellcheck="true" max_length="2048" text_color="black" right="-11" diff --git a/indra/newview/skins/default/xui/en/floater_facebook.xml b/indra/newview/skins/default/xui/en/floater_facebook.xml deleted file mode 100644 index b34d70516a..0000000000 --- a/indra/newview/skins/default/xui/en/floater_facebook.xml +++ /dev/null @@ -1,95 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> -<floater - positioning="cascading" - can_close="true" - help_topic="floater_facebook" - layout="topleft" - name="floater_facebook" - save_rect="true" - single_instance="true" - reuse_instance="true" - title="POST TO FACEBOOK" - min_height="462" - min_width="304" - height="462" - width="272"> - <tab_container - name="tabs" - tab_group="1" - tab_min_width="64" - tab_height="21" - tab_position="top" - top="7" - height="437" - follows="all" - halign="center"> - <panel - filename="panel_facebook_status.xml" - class="llfacebookstatuspanel" - follows="all" - label="STATUS" - name="panel_facebook_status"/> - <panel - filename="panel_facebook_photo.xml" - class="llfacebookphotopanel" - follows="all" - label="PHOTO" - name="panel_facebook_photo"/> - <panel - filename="panel_facebook_place.xml" - class="llfacebookcheckinpanel" - follows="all" - label="CHECK IN" - name="panel_facebook_place"/> - <panel - filename="panel_facebook_friends.xml" - class="llfacebookfriendspanel" - follows="all" - label="FRIENDS" - name="panel_facebook_friends"/> - <!--<panel - filename="panel_facebook_account.xml" - class="llfacebookaccountpanel" - follows="all" - label="ACCOUNT" - name="panel_facebook_account"/>--> - </tab_container> - <text - name="connection_error_text" - type="string" - follows="left|bottom|right" - bottom="-5" - left="10" - width="250" - height="20" - wrap="true" - halign="left" - valign="center" - text_color="DrYellow" - font="SansSerif"> - Error - </text> - <loading_indicator - follows="left|bottom" - height="24" - width="24" - name="connection_loading_indicator" - top_delta="-2" - left="10" - visible="true"/> - <text - name="connection_loading_text" - type="string" - follows="left|bottom|right" - top_delta="2" - left_pad="5" - width="250" - height="20" - wrap="true" - halign="left" - valign="center" - text_color="EmphasisColor" - font="SansSerif"> - Loading... - </text> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_fast_timers.xml b/indra/newview/skins/default/xui/en/floater_fast_timers.xml index fa7147d9ca..645003cc14 100644 --- a/indra/newview/skins/default/xui/en/floater_fast_timers.xml +++ b/indra/newview/skins/default/xui/en/floater_fast_timers.xml @@ -60,10 +60,21 @@ min_width="100"> <panel top="0" left="0" - width="220" + width="204" height="440" name="legend" follows="all"/> + <scroll_bar + top ="0" + right="-1" + height="440" + width="15" + follows="top|right|bottom" + name="scroll_vert" + orientation="vertical" + step_size="16" + doc_size="3000" + /> </layout_panel> <layout_panel name="timers_panel" auto_resize="true" diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index 200e9b9537..9f051d9f8d 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -119,6 +119,7 @@ follows="left|bottom" height="23" label="Edit" + tool_tip="Open window for editing selected gesture." layout="topleft" left="6" name="edit_btn" @@ -128,6 +129,7 @@ follows="left|bottom" height="23" label="Play" + tool_tip="Execute selected gesture in-world." layout="topleft" left_pad="6" name="play_btn" diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml index 1b4992b4ca..ca1d299553 100644 --- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml +++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_minimize="false" - height="468" + height="448" layout="topleft" name="Inventory Finder" help_topic="inventory_finder" @@ -112,29 +112,12 @@ width="126" /> <icon height="16" - image_name="Inv_Mesh" - layout="topleft" - left="8" - mouse_opaque="true" - name="icon_mesh" - top="142" - width="16" /> - <check_box - height="16" - label="Meshes" - layout="topleft" - left_pad="2" - name="check_mesh" - top_delta="0" - width="126" /> - <icon - height="16" image_name="Inv_Object" layout="topleft" left="8" mouse_opaque="true" name="icon_object" - top="162" + top="142" width="16" /> <check_box height="16" @@ -151,7 +134,7 @@ left="8" mouse_opaque="true" name="icon_script" - top="182" + top="162" width="16" /> <check_box height="16" @@ -168,7 +151,7 @@ left="8" mouse_opaque="true" name="icon_sound" - top="202" + top="182" width="16" /> <check_box height="16" @@ -185,7 +168,7 @@ left="8" mouse_opaque="true" name="icon_texture" - top="222" + top="202" width="16" /> <check_box height="16" @@ -202,7 +185,7 @@ left="8" mouse_opaque="true" name="icon_snapshot" - top="242" + top="222" width="16" /> <check_box height="16" @@ -220,7 +203,7 @@ layout="topleft" left="8" name="All" - top="262" + top="242" width="100" /> <button height="20" @@ -274,7 +257,7 @@ width="260"/> <check_box height="16" - top="352" + top="332" label="Since Logoff" layout="topleft" left_delta="0" @@ -290,7 +273,7 @@ layout="topleft" left_delta="0" name="- OR -" - top="370" + top="350" width="144"> - OR - </text> @@ -298,7 +281,7 @@ height="16" layout="topleft" name="date_search_direction" - top="388" + top="368" left="8" width="270"> <radio_item @@ -368,6 +351,6 @@ layout="topleft" name="Close" right="-6" - top="434" + top="414" width="76" /> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml index 93bfe53aae..659033efd4 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_proxy.xml @@ -58,12 +58,12 @@ label_width="95" layout="topleft" left_delta="210" - max_val="12000" + max_val="65535" min_val="10" name="web_proxy_port" top_delta="0" tool_tip="The port of the HTTP proxy you would like to use." - width="145" /> + width="150" /> <check_box control_name="Socks5ProxyEnabled" height="16" @@ -111,11 +111,11 @@ label_width="95" layout="topleft" left_delta="210" - max_val="12000" + max_val="65535" min_val="10" name="socks_proxy_port" top_delta="0" - width="145" + width="150" tool_tip="The port of the SOCKS 5 proxy you would like to use." commit_callback.function="Proxy.Change" /> <text diff --git a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml index 2e1c8ce670..dcbdfa8794 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml @@ -6,7 +6,7 @@ height="361" layout="topleft" min_height="243" - min_width="234" + min_width="330" name="preview notecard" help_topic="preview_notecard" title="NOTECARD:" @@ -77,6 +77,16 @@ word_wrap="true"> Loading... </text_editor> + <button + follows="left|bottom" + height="22" + label="Edit..." + label_selected="Edit" + layout="topleft" + left="4" + name="Edit" + top="332" + width="100" /> <button follows="right|bottom" height="22" diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml index 8fa5b49573..d07e3cb31b 100644 --- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml +++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml @@ -246,7 +246,7 @@ name="Land__Encroachment__Objects_textures" value="63" /> <combo_box.item - label="Gaming Policy Violation" + label="Skill Gaming Policy Violation" name="Wagering_gambling" value="67" /> </combo_box> diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index e50747cb5f..832c2ee7da 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -24,10 +24,6 @@ Sending Email </string> <string - name="facebook_progress_str"> - Posting to Facebook - </string> - <string name="profile_progress_str"> Posting </string> @@ -40,10 +36,6 @@ Saving to Computer </string> <string - name="facebook_succeeded_str"> - Image uploaded - </string> - <string name="profile_succeeded_str"> Image uploaded </string> @@ -60,10 +52,6 @@ Saved to Computer! </string> <string - name="facebook_failed_str"> - Failed to upload image to your Facebook timeline. - </string> - <string name="profile_failed_str"> Failed to upload image to your Profile Feed. </string> diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index 53618b684b..d122d7491c 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -52,7 +52,7 @@ control_name="mode_selection" height="20" layout="topleft" - left="18" + left="0" top_pad="80" name="mode_selection" follows="left|top"> @@ -64,7 +64,7 @@ height="16" left="0" value="0" - width="80" /> + width="70" /> <radio_item label="Local" left_pad="0" @@ -73,7 +73,16 @@ height="16" name="local" value="1" - width="75" /> + width="50" /> + <radio_item + label="Bake" + left_pad="0" + layout="topleft" + top_delta="0" + height="16" + name="bake" + value="2" + width="50" /> </radio_group> <!-- --> @@ -83,7 +92,7 @@ follows="left|top" height="14" layout="topleft" - left_delta="-12" + left_delta="12" name="unknown" top_pad="4"> Size: [DIMENSIONS] @@ -225,7 +234,80 @@ <column name="unit_name" label="Name" dynamicwidth="true" /> <column name="unit_id_HIDDEN" label="ID" width="0" /> </scroll_list> - + +<!-- middle: bake mode --> + <combo_box + left="180" + top="30" + height="19" + top_delta="15" + layout="topleft" + follows="left|top" + name="l_bake_use_texture_combo_box" + tool_tip="Choose the bake texture" + width="118" + visible="false"> + <combo_box.item + label="None" + name="None" + value="-1" /> + <combo_box.item + label="BAKED_HEAD" + name="BAKED_HEAD" + value="0" /> + <combo_box.item + label="BAKED_UPPER" + name="BAKED_UPPER" + value="1" /> + <combo_box.item + label="BAKED_LOWER" + name="BAKED_LOWER" + value="2" /> + <combo_box.item + label="BAKED_EYES" + name="BAKED_EYES" + value="3" /> + <combo_box.item + label="BAKED_SKIRT" + name="BAKED_SKIRT" + value="4" /> + <combo_box.item + label="BAKED_HAIR" + name="BAKED_HAIR" + value="5" /> + <combo_box.item + label="BAKED_LEFTARM" + name="BAKED_LEFTARM" + value="6" /> + <combo_box.item + label="BAKED_LEFTLEG" + name="BAKED_LEFTLEG" + value="7" /> + <combo_box.item + label="BAKED_AUX1" + name="BAKED_AUX1" + value="8" /> + <combo_box.item + label="BAKED_AUX2" + name="BAKED_AUX2" + value="9" /> + <combo_box.item + label="BAKED_AUX3" + name="BAKED_AUX3" + value="10" /> + </combo_box> + <check_box + follows="left|top" + height="20" + initial_value="false" + label="Hide Base Mesh Region" + layout="topleft" + name="hide_base_mesh_region" + left_delta="0" + top_pad="10" + top_delta="0" + width="120" + visible="false"/> <!-- bottom static --> <button follows="bottom" diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index 8b1d50e58f..2d5263b78f 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -10,6 +10,8 @@ <file>simhei.ttf</file> <file>ArialUni.ttf</file> <file>msyh.ttc</file> + <file load_collection="true">Cambria.ttc</file> + <file>malgun.ttf</file> </os> <os name="Mac"> <file>ヒラギノ角ゴシック W3.ttc</file> @@ -21,6 +23,7 @@ <file>AppleSDGothicNeo-Regular.otf</file> <file>华文细黑.ttf</file> <file>PingFang.ttc</file> + <file>STIXGeneral.otf</file> </os> </font> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 3ea9e77a03..3bdbbb04d7 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -268,6 +268,14 @@ parameter="tattoo" /> </menu_item_call> <menu_item_call + label="New Universal" + layout="topleft" + name="New Universal"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="universal" /> + </menu_item_call> + <menu_item_call label="New Physics" layout="topleft" name="New Physics"> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml index afeb1bf226..29724b0270 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml @@ -194,6 +194,14 @@ function="Inventory.DoCreate" parameter="tattoo" /> </menu_item_call> + <menu_item_call + label="New Universal" + layout="topleft" + name="New Universal"> + <menu_item_call.on_click + function="Inventory.DoCreate" + parameter="universal" /> + </menu_item_call> <menu_item_call label="New Physics" layout="topleft" 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 7faa4f3d71..61cb74f230 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -175,6 +175,14 @@ function="Gear.Create" parameter="tattoo" /> </menu_item_call> + <menu_item_call + label="New Universal" + layout="topleft" + name="New Universal"> + <menu_item_call.on_click + function="Gear.Create" + parameter="universal" /> + </menu_item_call> </menu> <menu height="85" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index cac84cfccf..7bb7b5d62c 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -307,13 +307,6 @@ </menu_item_check> <menu_item_separator/> <menu_item_call - label="Facebook..." - name="Facebook"> - <menu_item_call.on_click - function="Floater.Toggle" - parameter="facebook"/> - </menu_item_call> - <menu_item_call label="Twitter..." name="Twitter"> <menu_item_call.on_click @@ -1051,8 +1044,7 @@ shortcut="control|D"> <menu_item_call.on_click function="Object.Duplicate" /> - <menu_item_call.on_enable - function="Object.EnableDuplicate" /> + </menu_item_call> </menu> <menu @@ -1507,8 +1499,7 @@ </menu_item_call> <menu_item_call label="Set UI Size to Default" - name="Set UI Size to Default" - shortcut="control|alt|shift|R"> + name="Set UI Size to Default" shortcut="control|alt|shift|R"> <menu_item_call.on_click function="View.DefaultUISize" /> </menu_item_call> @@ -4013,6 +4004,16 @@ parameter="tattoo" /> </menu_item_call> <menu_item_call + label="Universal" + name="Universal"> + <menu_item_call.on_click + function="Edit.TakeOff" + parameter="tattoo" /> + <menu_item_call.on_enable + function="Edit.EnableTakeOff" + parameter="universal" /> + </menu_item_call> + <menu_item_call label="Physics" name="Physics"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index b7cd6517ea..053c041849 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6705,13 +6705,6 @@ Please select at least one type of content to search (General, Moderate, or Adul [MESSAGE] </notification> - <notification - icon="notify.tga" - name="FacebookConnect" - type="notifytip"> -[MESSAGE] - </notification> - <notification icon="notify.tga" name="FlickrConnect" @@ -8639,6 +8632,7 @@ Please check your network and firewall setup. icon="alertmodal.tga" name="NoVoiceConnect" type="alertmodal"> + <unique/> We are unable to connect to the voice server: [HOSTID] diff --git a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml index 97f1a1a658..8fa85dce5f 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml @@ -1,85 +1,98 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> - <panel - background_visible="true" - follows="all" - height="400" - layout="topleft" - left="0" - name="edit_tattoo_panel" - top_pad="10" - width="333" > - <panel - border="false" - bg_alpha_color="DkGray2" - bg_opaque_color="DkGray2" - background_visible="true" - background_opaque="true" - follows="all" - height="400" - left="10" - layout="topleft" - name="avatar_tattoo_color_panel" - top="0" - width="313" > - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="115" - label="Head Tattoo" - layout="topleft" - left="20" - name="Head Tattoo" - tool_tip="Click to choose a picture" - top="10" - width="115" > - <texture_picker.commit_callback - function="TexturePicker.Commit" /> - </texture_picker> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="115" - label="Upper Tattoo" - layout="topleft" - left_pad="30" - name="Upper Tattoo" - tool_tip="Click to choose a picture" - top="10" - width="115" > - <texture_picker.commit_callback - function="TexturePicker.Commit" /> - </texture_picker> - <texture_picker - can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="115" - label="Lower Tattoo" - layout="topleft" - left="20" - name="Lower Tattoo" - tool_tip="Click to choose a picture" - top_pad="10" - width="115" > - <texture_picker.commit_callback - function="TexturePicker.Commit" /> - </texture_picker> - <color_swatch - can_apply_immediately="true" - follows="left|top" - height="115" - label="Color/Tint" - layout="topleft" - left_pad="30" - name="Color/Tint" - tool_tip="Click to open color picker" - top_delta="0" - width="115" > - <color_swatch.commit_callback - function="ColorSwatch.Commit" /> - </color_swatch> - </panel> +<panel + background_visible="true" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_tattoo_panel" + top_pad="10" + width="333" > + <scroll_container + color="DkGray2" + follows="all" + height="400" + layout="topleft" + left="9" + name="avatar_tattoo_scroll" + opaque="true" + top_pad="10" + width="314"> + <panel + border="false" + bg_alpha_color="DkGray2" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + follows="all" + height="800" + left="10" + layout="topleft" + name="avatar_tattoo_color_panel" + top="0" + width="313" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Head Tattoo" + layout="topleft" + left="20" + name="Head Tattoo" + tool_tip="Click to choose a picture" + top="10" + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Upper Tattoo" + layout="topleft" + left_pad="30" + name="Upper Tattoo" + tool_tip="Click to choose a picture" + top="10" + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Lower Tattoo" + layout="topleft" + left="20" + name="Lower Tattoo" + tool_tip="Click to choose a picture" + top_pad="10" + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + + + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="115" + label="Color/Tint" + layout="topleft" + left_pad="30" + name="Color/Tint" + tool_tip="Click to open color picker" + top_delta="0" + width="115" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> + </panel> + </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_edit_universal.xml b/indra/newview/skins/default/xui/en/panel_edit_universal.xml new file mode 100644 index 0000000000..11cabdfe6e --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_edit_universal.xml @@ -0,0 +1,231 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + background_visible="true" + follows="all" + height="400" + layout="topleft" + left="0" + name="edit_universal_panel" + top_pad="10" + width="333" > + <scroll_container + color="DkGray2" + follows="all" + height="380" + layout="topleft" + left="9" + name="avatar_universal_scroll" + opaque="true" + top_pad="10" + width="323"> + <panel + border="false" + bg_alpha_color="DkGray2" + bg_opaque_color="DkGray2" + background_visible="true" + background_opaque="true" + follows="all" + height="800" + left="10" + layout="topleft" + name="avatar_universal_color_panel" + top="0" + width="313" > + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Head Tattoo" + layout="topleft" + left="20" + top_pad="10" + name="Head Universal Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Upper Tattoo" + layout="topleft" + left_pad="30" + top_delta="0" + name="Upper Universal Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Lower Tattoo" + layout="topleft" + left="20" + top_pad="10" + name="Lower Universal Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Skirt Tattoo" + layout="topleft" + left_pad="30" + top_delta="0" + name="Skirt Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Hair Tattoo" + layout="topleft" + left="20" + top_pad="10" + name="Hair Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Eyes Tattoo" + layout="topleft" + left_pad="30" + top_delta="0" + name="Eyes Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Left Arm Tattoo" + layout="topleft" + left="20" + top_pad="10" + name="Left Arm Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Left Leg Tattoo" + layout="topleft" + left_pad="30" + top_delta="0" + name="Left Leg Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Aux1 Tattoo" + layout="topleft" + left="20" + top_pad="10" + name="Aux1 Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Aux2 Tattoo" + layout="topleft" + left_pad="30" + top_delta="0" + name="Aux2 Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + <texture_picker + can_apply_immediately="true" + default_image_name="Default" + follows="left|top" + height="115" + label="Aux3 Tattoo" + layout="topleft" + left="20" + top_pad="10" + name="Aux3 Tattoo" + tool_tip="Click to choose a picture" + + width="115" > + <texture_picker.commit_callback + function="TexturePicker.Commit" /> + </texture_picker> + + <color_swatch + can_apply_immediately="true" + follows="left|top" + height="115" + label="Color/Tint" + layout="topleft" + left_pad="30" + top_delta="0" + name="Color/Tint" + tool_tip="Click to open color picker" + + width="115" > + <color_swatch.commit_callback + function="ColorSwatch.Commit" /> + </color_swatch> + </panel> + </scroll_container> +</panel> + diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index f34b913218..dc1553e6a3 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -71,6 +71,10 @@ name="edit_tattoo_title"> Editing Tattoo </string> + <string + name="edit_universal_title"> + Editing Universal + </string> <string name="edit_physics_title"> Editing Physics @@ -135,6 +139,10 @@ name="tattoo_desc_text"> Tattoo: </string> + <string + name="universal_desc_text"> + Universal: + </string> <string name="physics_desc_text"> Physics: @@ -418,6 +426,16 @@ top="8" visible="false" width="333" /> + <panel + filename="panel_edit_universal.xml" + follows="all" + height="425" + layout="topleft" + left="0" + name="edit_universal_panel" + top="8" + visible="false" + width="333" /> <panel filename="panel_edit_physics.xml" follows="all" diff --git a/indra/newview/skins/default/xui/en/panel_facebook_friends.xml b/indra/newview/skins/default/xui/en/panel_facebook_friends.xml deleted file mode 100644 index 97994fb08b..0000000000 --- a/indra/newview/skins/default/xui/en/panel_facebook_friends.xml +++ /dev/null @@ -1,73 +0,0 @@ -<panel - height="400" - width="272" - layout="topleft" - follows="all" - name="panel_facebook_friends"> - <string - name="facebook_friends_empty" - value="You currently do not have any Facebook friends who are also Second Life residents. Ask your Facebook friends to join Second Life today!" /> - <string - name="facebook_friends_no_connected" - value="You're currently not connected to Facebook. Please go to the Status tab to connect and enable this feature." /> - <accordion - background_visible="false" - bg_alpha_color="DkGray2" - bg_opaque_color="DkGray2" - follows="all" - height="383" - layout="topleft" - left="10" - name="friends_accordion" - right="-10" - top_pad="2"> - <accordion_tab - layout="topleft" - height="173" - name="tab_second_life_friends" - title="SL friends"> - <avatar_list - ignore_online_status="true" - allow_select="true" - follows="all" - height="173" - layout="topleft" - left="0" - name="second_life_friends" - show_permissions_granted="true" - top="0" - width="272" /> - </accordion_tab> - <accordion_tab - layout="topleft" - height="173" - name="tab_suggested_friends" - title="Add these people as SL friends"> - <avatar_list - ignore_online_status="true" - allow_select="true" - follows="all" - height="173" - layout="topleft" - left="0" - name="suggested_friends" - show_permissions_granted="true" - top="0" - width="272" /> - </accordion_tab> - </accordion> - <text - layout="topleft" - word_wrap="true" - height="64" - width="250" - follows="top|left|right" - font="SansSerif" - left="10" - right="-10" - name="facebook_friends_status" - top="5" - type="string"> - Not connected to Facebook. - </text> -</panel> diff --git a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml b/indra/newview/skins/default/xui/en/panel_facebook_photo.xml deleted file mode 100644 index 22e6598352..0000000000 --- a/indra/newview/skins/default/xui/en/panel_facebook_photo.xml +++ /dev/null @@ -1,168 +0,0 @@ - <panel - height="400" - width="272" - layout="topleft" - follows="all" - name="panel_facebook_photo"> - <combo_box - control_name="FacebookPhotoResolution" - follows="left|top" - layout="topleft" - top="7" - left="10" - name="resolution_combobox" - tool_tip="Image resolution" - height="21" - width="124"> - <combo_box.item - label="Current Window" - name="CurrentWindow" - value="[i0,i0]" /> - <combo_box.item - label="640x480" - name="640x480" - value="[i640,i480]" /> - <combo_box.item - label="800x600" - name="800x600" - value="[i800,i600]" /> - <combo_box.item - label="1024x768" - name="1024x768" - value="[i1024,i768]" /> - <combo_box.item - label="1200x630" - name="1200x630" - value="[i1200,i630]" /> - </combo_box> - <combo_box - control_name="FacebookPhotoFilters" - follows="left|top" - layout="topleft" - name="filters_combobox" - tool_tip="Image filters" - top="7" - left_pad="4" - height="21" - width="124"> - <combo_box.item - label="No Filter" - name="NoFilter" - value="NoFilter" /> - </combo_box> - <panel - height="150" - width="252" - visible="true" - layout="topleft" - name="thumbnail_placeholder" - top_pad="5" - follows="left|top|rith" - right="-10" - left="10"> - </panel> - <text - follows="left|top" - layout="topleft" - font="SansSerif" - text_color="EmphasisColor" - height="14" - top_pad="2" - left="10" - length="1" - halign="center" - name="working_lbl" - translate="false" - type="string" - visible="true" - width="251"> - Refreshing... - </text> - <view_border - bevel_style="in" - follows="left|top" - layout="topleft" - height="1" - left="10" - name="refresh_border" - width="250" - top_pad="0"/> - <button - follows="left|top" - layout="topleft" - height="23" - label="Refresh" - left="10" - top_pad="5" - name="new_snapshot_btn" - tool_tip="Click to refresh" - visible="true" - width="100" > - <button.commit_callback - function="SocialSharing.RefreshPhoto" /> - </button> - <button - follows="right|top" - layout="topleft" - height="23" - label="Preview" - right="-10" - top_delta="0" - name="big_preview_btn" - tool_tip="Click to toggle preview" - is_toggle="true" - visible="true" - width="100" > - <button.commit_callback - function="SocialSharing.BigPreview" /> - </button> - <text - length="1" - follows="top|left|right" - layout="topleft" - font="SansSerif" - height="16" - left="10" - name="caption_label" - top_pad="20" - type="string"> - Comment (optional): - </text> - <text_editor - follows="left|top|right|bottom" - layout="topleft" - height="87" - width="250" - left="10" - right="-10" - length="1" - max_length="700" - name="photo_caption" - type="string" - word_wrap="true"> - </text_editor> - <button - follows="left|top" - layout="topleft" - top_pad="22" - left="10" - height="23" - label="Post" - name="post_photo_btn" - width="100"> - <button.commit_callback - function="SocialSharing.SendPhoto" /> - </button> - <button - follows="right|top" - layout="topleft" - height="23" - label="Cancel" - name="cancel_photo_btn" - right="-10" - top_delta="0" - width="100"> - <button.commit_callback - function="SocialSharing.Cancel" /> - </button> - </panel> diff --git a/indra/newview/skins/default/xui/en/panel_facebook_place.xml b/indra/newview/skins/default/xui/en/panel_facebook_place.xml deleted file mode 100644 index f87b008c4e..0000000000 --- a/indra/newview/skins/default/xui/en/panel_facebook_place.xml +++ /dev/null @@ -1,113 +0,0 @@ - <panel - height="400" - width="272" - layout="topleft" - follows="all" - name="panel_facebook_place"> - <text - length="1" - follows="top|left|right" - layout="topleft" - font="SansSerif" - height="16" - left="10" - name="place_caption_label" - top="5" - type="string"> - Say something about where you are: - </text> - <text_editor - follows="top|left|right" - layout="topleft" - height="70" - width="250" - left="10" - right="-10" - length="1" - max_length="700" - name="place_caption" - type="string" - word_wrap="true"> - </text_editor> - <check_box - follows="left|top" - layout="topleft" - initial_value="false" - height="16" - top_pad="8" - width="8" - label="Include overhead view of location" - name="add_place_view_cb" - left="10"/> - <panel - follows="left|top" - layout="topleft" - height="243" - width="250" - background_visible="true" - bg_opaque_color="Black" - bg_alpha_color="Black" - top_pad="8" - left="10" - right="-12" - visible="true" - name="map_border"> - </panel> - <icon - follows="left|top" - layout="topleft" - height="243" - width="250" - image_name="Map_Placeholder_Icon" - top_delta="0" - right="-12" - left="10" - visible="true" - name="map_placeholder"> - </icon> - <icon - follows="left|top" - layout="topleft" - height="243" - width="250" - image_name="Map_Placeholder_Icon" - top_delta="0" - left="10" - right="-12" - visible="true" - name="map_default"> - </icon> - <loading_indicator - follows="left|top" - layout="topleft" - height="24" - width="24" - name="map_loading_indicator" - top_delta="116" - left="126" - visible="false"/> - <button - follows="left|bottom" - layout="topleft" - top_pad="95" - left="10" - height="23" - label="Post" - name="post_place_btn" - width="100"> - <button.commit_callback - function="SocialSharing.SendCheckin" /> - </button> - <button - follows="right|bottom" - layout="topleft" - height="23" - label="Cancel" - name="cancel_place_btn" - right="-10" - top_delta="0" - width="100"> - <button.commit_callback - function="SocialSharing.Cancel" /> - </button> - </panel> diff --git a/indra/newview/skins/default/xui/en/panel_facebook_status.xml b/indra/newview/skins/default/xui/en/panel_facebook_status.xml deleted file mode 100644 index fe0f3c9279..0000000000 --- a/indra/newview/skins/default/xui/en/panel_facebook_status.xml +++ /dev/null @@ -1,130 +0,0 @@ - <panel - height="400" - width="272" - follows="all" - layout="topleft" - name="panel_facebook_status"> - <string - name="facebook_connected" - value="You are connected to Facebook as:" /> - <string - name="facebook_disconnected" - value="Not connected to Facebook" /> - <text - layout="topleft" - length="1" - follows="top|left" - font="SansSerif" - height="16" - left="10" - name="account_caption_label" - top="5" - type="string"> - Not connected to Facebook. - </text> - <text - layout="topleft" - top_pad="2" - length="1" - follows="top|left" - font="SansSerif" - height="16" - left="10" - name="account_name_label" - parse_urls="true" - type="string"/> - <panel - layout="topleft" - follows="left|top" - name="panel_buttons" - height="60" - left="0"> - <button - layout="topleft" - follows="left|top" - top_pad="9" - left="10" - visible="true" - height="23" - label="Connect..." - name="connect_btn" - width="251"> - <commit_callback function="SocialSharing.Connect"/> - </button> - - <button - layout="topleft" - follows="left|top|right" - top_delta="0" - left="10" - right="-10" - height="23" - label="Disconnect" - name="disconnect_btn" - width="210" - visible="false"> - <commit_callback function="SocialSharing.Disconnect"/> - </button> - <text - layout="topleft" - length="1" - follows="top|left|right" - left="10" - right="-10" - height="16" - name="account_learn_more_label" - top_pad="5" - type="string"> - [http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Share-Facebook/ta-p/2149711 Learn about posting to Facebook] - </text> - </panel> - - <text - length="1" - layout="topleft" - follows="top|left|right" - font="SansSerif" - height="16" - left="10" - name="status_caption_label" - top_pad="5" - type="string"> - What's on your mind? - </text> - <text_editor - follows="left|top|right" - layout="topleft" - height="150" - width="252" - left="10" - length="1" - max_length="700" - name="status_message" - type="string" - word_wrap="true"> - </text_editor> - <button - follows="left|top" - layout="topleft" - top_pad="6" - left="10" - height="23" - label="Post" - name="post_status_btn" - width="100"> - <button.commit_callback - function="SocialSharing.SendStatus" /> - </button> - <button - follows="right|top" - layout="topleft" - height="23" - label="Cancel" - name="cancel_status_btn" - right="-10" - top_delta="0" - width="100"> - <button.commit_callback - function="SocialSharing.Cancel" /> - </button> - </panel> diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml index 6074ab9ef6..7fb2291423 100644 --- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml @@ -158,6 +158,7 @@ length="1" max_length="700" name="photo_description" + spellcheck="true" type="string" word_wrap="true"> </text_editor> diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 26f54bacbc..e34335a2af 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -214,7 +214,7 @@ Hover your mouse over the options for more help. layout="topleft" left="10" name="group_mature_check" - tool_tip="Sets whether your group contains information rated as Moderate" + tool_tip="Maturity ratings designate the type of content and behavior allowed in a group" top_pad="4" width="190"> <combo_item name="select_mature" value="Select"> diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 714d4166c0..f15f79e9aa 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -212,7 +212,15 @@ clicking on their names. layout="topleft" left="0" name="role_create" - width="120" /> + width="100" /> + <button + follows="top|left" + height="23" + label="Copy Role" + layout="topleft" + left_pad="10" + name="role_copy" + width="100" /> <button height="23" follows="top|left" @@ -220,7 +228,7 @@ clicking on their names. layout="topleft" left_pad="10" name="role_delete" - width="120" /> + width="100" /> </panel> <panel border="false" diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index fd6e96b9a7..13986c4030 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -277,6 +277,7 @@ max_length="127" name="notes_editor" read_only="true" + spellcheck="true" text_readonly_color="white" text_type="ascii_with_newline" top_pad="5" diff --git a/indra/newview/skins/default/xui/en/panel_login_first.xml b/indra/newview/skins/default/xui/en/panel_login_first.xml index 213f9a6b0c..726e713595 100644 --- a/indra/newview/skins/default/xui/en/panel_login_first.xml +++ b/indra/newview/skins/default/xui/en/panel_login_first.xml @@ -111,7 +111,6 @@ combo_editor.font="SansSerifLarge" max_chars="128" top="0" - commit_on_focus_lost="false" combo_editor.prevalidate_callback="ascii" tool_tip="The username you chose when you registered, like bobsmith12 or Steller Sunshine" name="username_combo" @@ -141,7 +140,7 @@ follows="left|top" image_unselected="PushButton_Login" image_pressed="PushButton_Login_Pressed" - image_hover="PushButton_Login_Over" + image_hover_unselected="PushButton_Login_Over" label="Log In" label_color="White" font="SansSerifLarge" diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 8fc0f6f642..a47121ae99 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -367,24 +367,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M show_permissions_granted="true" top="0" width="307" /> - </accordion_tab> - <accordion_tab - layout="topleft" - height="173" - name="tab_suggested_friends" - title="People you may want to friend"> - <avatar_list - ignore_online_status="true" - allow_select="true" - follows="all" - height="173" - layout="topleft" - left="0" - name="suggested_friends" - show_permissions_granted="true" - top="0" - width="307" /> - </accordion_tab> + </accordion_tab> </accordion> <text follows="all" diff --git a/indra/newview/skins/default/xui/en/panel_postcard_message.xml b/indra/newview/skins/default/xui/en/panel_postcard_message.xml index 331a08b4bb..63c7259878 100644 --- a/indra/newview/skins/default/xui/en/panel_postcard_message.xml +++ b/indra/newview/skins/default/xui/en/panel_postcard_message.xml @@ -80,6 +80,7 @@ left="5" max_length="700" name="msg_form" + spellcheck="true" right="-4" top_pad="5" word_wrap="true"> diff --git a/indra/newview/skins/default/xui/en/panel_region_terrain.xml b/indra/newview/skins/default/xui/en/panel_region_terrain.xml index 5d060c0a0d..8243c2715d 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -94,6 +94,7 @@ layout="topleft" left_delta="0" name="texture_detail_0" + default_image_id="0bc58228-74a0-7e83-89bc-5c23464bcec5" top_delta="20" width="100" /> <texture_picker @@ -102,6 +103,7 @@ layout="topleft" left_pad="10" name="texture_detail_1" + default_image_id="63338ede-0037-c4fd-855b-015d77112fc8" top_delta="0" width="100" /> <texture_picker @@ -110,6 +112,7 @@ layout="topleft" left_pad="10" name="texture_detail_2" + default_image_id="303cd381-8560-7579-23f1-f0a880799740" top_delta="0" width="100" /> <texture_picker @@ -118,6 +121,7 @@ layout="topleft" left_pad="10" name="texture_detail_3" + default_image_id="53a2f406-4895-1d13-d541-d2e3b86bc19c" top_delta="0" width="100" /> <text diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml index c56a5e17cd..ed37e9e2cc 100644 --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml @@ -28,10 +28,6 @@ name="Title"> Script: [NAME] </panel.string> - <panel.string - name="external_editor_not_set"> - Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting. - </panel.string> <menu_bar bg_visible="false" follows="left|top" 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 305cce1cbe..981b9ab881 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml @@ -61,23 +61,6 @@ font="SansSerif" halign="left" height="22" - image_overlay="Snapshot_Facebook" - image_overlay_alignment="left" - image_top_pad="0" - imgoverlay_label_space="10" - label="Share to Facebook" - layout="topleft" - left_delta="0" - name="send_to_facebook_btn" - top_pad="5"> - <button.commit_callback - function="Snapshot.SendToFacebook"/> - </button> - <button - follows="left|top" - font="SansSerif" - halign="left" - height="22" image_overlay="Command_Twitter_Icon" image_overlay_alignment="left" image_top_pad="0" diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml index d86cb92981..2fdbee49f0 100644 --- a/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_snapshot_profile.xml @@ -126,6 +126,7 @@ length="1" max_length="700" name="caption" + spellcheck="true" width="200" top_pad="2" type="string" 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 67b99ca588..90f32ae452 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -770,6 +770,17 @@ tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping." top_delta="16" width="260" /> + <button + left="10" + top="222" + height="20" + label="Align" + label_selected="Align current texture layers" + layout="topleft" + name="button align textures" + top_delta="0" + tool_tip="Align current texture layers" + width="66" /> <web_browser visible="false" enabled="false" diff --git a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml index 9a460ceead..8774d09a03 100644 --- a/indra/newview/skins/default/xui/en/panel_twitter_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_twitter_photo.xml @@ -39,6 +39,7 @@ length="1" max_length="140" name="photo_status" + spellcheck="true" type="string" word_wrap="true"> </text_editor> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 1c5e51d2c8..c386cb9457 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -58,6 +58,9 @@ Advanced Lighting Model: [GPU_SHADERS] Texture memory: [TEXTURE_MEMORY]MB VFS (cache) creation time: [VFS_TIME] </string> + <string name="AboutOSXHiDPI"> +HiDPI display mode: [HIDPI] + </string> <string name="AboutLibs"> J2C Decoder Version: [J2C_VERSION] Audio Driver Version: [AUDIO_DRIVER_VERSION] @@ -199,13 +202,7 @@ Please try logging in again in a minute.</string> <string name="SentToInvalidRegion">You were sent to an invalid region.</string> <string name="TestingDisconnect">Testing viewer disconnect</string> - <!-- SLShare: Facebook, Flickr, and Twitter --> - <string name="SocialFacebookConnecting">Connecting to Facebook...</string> - <string name="SocialFacebookPosting">Posting...</string> - <string name="SocialFacebookDisconnecting">Disconnecting from Facebook...</string> - <string name="SocialFacebookErrorConnecting">Problem connecting to Facebook</string> - <string name="SocialFacebookErrorPosting">Problem posting to Facebook</string> - <string name="SocialFacebookErrorDisconnecting">Problem disconnecting from Facebook</string> + <!-- SLShare: Flickr and Twitter --> <string name="SocialFlickrConnecting">Connecting to Flickr...</string> <string name="SocialFlickrPosting">Posting...</string> <string name="SocialFlickrDisconnecting">Disconnecting from Flickr...</string> @@ -2209,6 +2206,7 @@ For AI Character: Get the closest navigable point to the point provided. <string name="skirt">Skirt</string> <string name="alpha">Alpha</string> <string name="tattoo">Tattoo</string> + <string name="universal">Universal</string> <string name="physics">Physics</string> <string name="invalid">invalid</string> <string name="none">none</string> @@ -2225,6 +2223,7 @@ For AI Character: Get the closest navigable point to the point provided. <string name="skirt_not_worn">Skirt not worn</string> <string name="alpha_not_worn">Alpha not worn</string> <string name="tattoo_not_worn">Tattoo not worn</string> + <string name="universal_not_worn">Universal not worn</string> <string name="physics_not_worn">Physics not worn</string> <string name="invalid_not_worn">invalid</string> @@ -2244,6 +2243,7 @@ For AI Character: Get the closest navigable point to the point provided. <string name="create_new_skirt">Create new skirt</string> <string name="create_new_alpha">Create new alpha</string> <string name="create_new_tattoo">Create new tattoo</string> + <string name="create_new_universal">Create new universal</string> <string name="create_new_physics">Create new physics</string> <string name="create_new_invalid">invalid</string> @@ -2299,6 +2299,9 @@ For AI Character: Get the closest navigable point to the point provided. <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">Open window with Play options.</string> + <string name="InventoryPlayGestureTooltip">Execute selected gesture in-world.</string> + <string name="InventoryPlaySoundTooltip">Open window with Play options.</string> <string name="InventoryOutboxNotMerchantTitle">Anyone can sell items on the Marketplace.</string> <string name="InventoryOutboxNotMerchantTooltip"></string> <string name="InventoryOutboxNotMerchant"> @@ -3650,9 +3653,6 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. Drag items from inventory here </string> - <string name="facebook_post_success"> - You posted to Facebook. - </string> <string name="flickr_post_success"> You posted to Flickr. </string> @@ -3809,6 +3809,7 @@ Abuse Report</string> <string name="New Skirt">New Skirt</string> <string name="New Alpha">New Alpha</string> <string name="New Tattoo">New Tattoo</string> + <string name="New Universal">New Universal</string> <string name="New Physics">New Physics</string> <string name="Invalid Wearable">Invalid Wearable</string> <string name="New Gesture">New Gesture</string> @@ -3939,7 +3940,7 @@ Please check http://status.secondlifegrid.net to see if there is a known problem <string name="EmptyOutfitText">There are no items in this outfit</string> <!-- External editor status codes --> - <string name="ExternalEditorNotSet">Select an editor using the ExternalEditor setting.</string> + <string name="ExternalEditorNotSet">Select an editor by setting the environment variable LL_SCRIPT_EDITOR or the ExternalEditor setting.</string> <string name="ExternalEditorNotFound">Cannot find the external editor you specified. Try enclosing path to the editor with double quotes. (e.g. "/path to my/editor" "%s")</string> @@ -4084,7 +4085,6 @@ Try enclosing path to the editor with double quotes. <string name="Command_Conversations_Label">Conversations</string> <string name="Command_Compass_Label">Compass</string> <string name="Command_Destinations_Label">Destinations</string> - <string name="Command_Facebook_Label">Facebook</string> <string name="Command_Flickr_Label">Flickr</string> <string name="Command_Gestures_Label">Gestures</string> <string name="Command_Grid_Status_Label">Grid status</string> @@ -4117,7 +4117,6 @@ Try enclosing path to the editor with double quotes. <string name="Command_Conversations_Tooltip">Converse with everyone</string> <string name="Command_Compass_Tooltip">Compass</string> <string name="Command_Destinations_Tooltip">Destinations of interest</string> - <string name="Command_Facebook_Tooltip">Post to Facebook</string> <string name="Command_Flickr_Tooltip">Upload to Flickr</string> <string name="Command_Gestures_Tooltip">Gestures for your avatar</string> <string name="Command_Grid_Status_Tooltip">Show current Grid status</string> diff --git a/indra/newview/skins/default/xui/en/widgets/person_view.xml b/indra/newview/skins/default/xui/en/widgets/person_view.xml index 46c1b7ff75..bfe6941a8a 100644 --- a/indra/newview/skins/default/xui/en/widgets/person_view.xml +++ b/indra/newview/skins/default/xui/en/widgets/person_view.xml @@ -13,16 +13,6 @@ text_pad_right="4" arrow_size="10" max_folder_item_overlap="2"> - <facebook_icon - follows="left" - height="14" - image_name="Facebook_Icon" - left="5" - bottom="6" - name="facebook_icon" - tool_tip="Facebook User" - visible="false" - width="14" /> <avatar_icon follows="left" layout="topleft" diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 3ac2cfb69b..4239c949fd 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -2987,7 +2987,7 @@ Si vous restez dans cette région, vous serez déconnecté(e). Si vous restez dans cette région, vous serez déconnecté(e). </notification> <notification name="LoadWebPage"> - Charger la page Web [URL] ? +Charger la page Web [URL] ? [MESSAGE] |