diff options
author | Mark Palange (Mani) <palange@lindenlab.com> | 2009-10-16 16:42:45 -0700 |
---|---|---|
committer | Mark Palange (Mani) <palange@lindenlab.com> | 2009-10-16 16:42:45 -0700 |
commit | 3e10fa4d51a23bf6f1ced23e8d90c636d84fa5db (patch) | |
tree | d4991e4c1a9dd934f48d33804e55eb8ffa085679 /indra | |
parent | e9f7205ba9f4dfb3422759218609b62d61972722 (diff) | |
parent | f20e9521a9b70f4e83cbb6888feae08a70681ea7 (diff) |
merge from latest svn/viewer-2-0 to hg/viewer-2-0
Diffstat (limited to 'indra')
521 files changed, 22440 insertions, 5037 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 3a7a5c7c8a..cbdcf4cef4 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -170,6 +170,8 @@ if (LINUX) if (NOT STANDALONE) # this stops us requiring a really recent glibc at runtime add_definitions(-fno-stack-protector) + # linking can be so slow - give us a chance to figure out why + set(CMAKE_CXX_LINK_FLAGS "-Wl,--stats,--no-keep-memory") endif (NOT STANDALONE) endif (VIEWER) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index ca8da05bbb..499bf19afd 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -12,7 +12,7 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) # # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code # - # WARNING: do NOT modify this code without working with poppy or daveh - + # WARNING: do NOT modify this code without working with poppy - # there is another branch that will conflict heavily with any changes here. INCLUDE(GoogleMock) @@ -26,11 +26,20 @@ INCLUDE(GoogleMock) # Setup includes, paths, etc SET(alltest_SOURCE_FILES ${CMAKE_SOURCE_DIR}/test/test.cpp + ${CMAKE_SOURCE_DIR}/test/lltut.cpp ) SET(alltest_DEP_TARGETS + # needed by the test harness itself + ${APRUTIL_LIBRARIES} + ${APR_LIBRARIES} llcommon - llmath ) + IF(NOT "${project}" STREQUAL "llmath") + # add llmath as a dep unless the tested module *is* llmath! + LIST(APPEND alltest_DEP_TARGETS + llmath + ) + ENDIF(NOT "${project}" STREQUAL "llmath") SET(alltest_INCLUDE_DIRS ${LLMATH_INCLUDE_DIRS} ${LLCOMMON_INCLUDE_DIRS} diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake index c0efa27f6e..a5b9cf47a4 100644 --- a/indra/cmake/LLWindow.cmake +++ b/indra/cmake/LLWindow.cmake @@ -13,9 +13,9 @@ if (STANDALONE) SDL_LIBRARY ) else (STANDALONE) - use_prebuilt_binary(SDL) use_prebuilt_binary(mesa) if (LINUX AND VIEWER) + use_prebuilt_binary(SDL) set (SDL_FOUND TRUE) set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux) set (SDL_LIBRARY SDL) diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake index 4f86d3234e..0901c1b7a2 100644 --- a/indra/cmake/Python.cmake +++ b/indra/cmake/Python.cmake @@ -13,6 +13,10 @@ if (WINDOWS) [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath] + [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath] ) elseif (EXISTS /etc/debian_version) # On Debian and Ubuntu, avoid Python 2.4 if possible. diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index 6f6754ed7a..4b19e28066 100644 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -38,7 +38,7 @@ list(APPEND linux_crash_logger_SOURCE_FILES ${linux_crash_logger_HEADER_FILES} ) -list(APPEND CMAKE_EXE_LINKER_FLAGS -Wl,--as-needed) +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES}) diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 099c4eba40..ae959eaa81 100644 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -43,6 +43,8 @@ #include "llassetstorage.h" #include "llrefcount.h" +#include "llvorbisencode.h" + #include "vorbis/codec.h" #include "vorbis/vorbisfile.h" @@ -218,11 +220,42 @@ BOOL LLVorbisDecodeState::initDecode() return(FALSE); } - size_t size_guess = (size_t)ov_pcm_total(&mVF, -1); + S32 sample_count = ov_pcm_total(&mVF, -1); + size_t size_guess = (size_t)sample_count; vorbis_info* vi = ov_info(&mVF, -1); size_guess *= vi->channels; size_guess *= 2; size_guess += 2048; + + bool abort_decode = false; + + if( vi->channels < 1 || vi->channels > LLVORBIS_CLIP_MAX_CHANNELS ) + { + abort_decode = true; + llwarns << "Bad channel count: " << vi->channels << llendl; + } + + if( (size_t)sample_count > LLVORBIS_CLIP_REJECT_SAMPLES ) + { + abort_decode = true; + llwarns << "Illegal sample count: " << sample_count << llendl; + } + + if( size_guess > LLVORBIS_CLIP_REJECT_SIZE ) + { + abort_decode = true; + llwarns << "Illegal sample size: " << size_guess << llendl; + } + + if( abort_decode ) + { + llwarns << "Canceling initDecode. Bad asset: " << mUUID << llendl; + llwarns << "Bad asset encoded by: " << ov_comment(&mVF,-1)->vendor << llendl; + delete mInFilep; + mInFilep = NULL; + return FALSE; + } + mWAVBuffer.reserve(size_guess); mWAVBuffer.resize(WAV_HEADER_SIZE); diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp index 7b12b62d53..d7f58defca 100644 --- a/indra/llaudio/llaudioengine_fmod.cpp +++ b/indra/llaudio/llaudioengine_fmod.cpp @@ -132,6 +132,7 @@ bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) bool audio_ok = false; if (!audio_ok) + { if (NULL == getenv("LL_BAD_FMOD_ESD")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL; @@ -148,8 +149,9 @@ bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) } else { LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL; } - + } if (!audio_ok) + { if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL; @@ -165,8 +167,9 @@ bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) } else { LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; } - + } if (!audio_ok) + { if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/ { LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; @@ -182,7 +185,7 @@ bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) } else { LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; } - + } if (!audio_ok) { LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp index 8ee082a245..0c1ad8191c 100644 --- a/indra/llaudio/llvorbisencode.cpp +++ b/indra/llaudio/llvorbisencode.cpp @@ -162,13 +162,13 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro return(LLVORBISENC_PCM_FORMAT_ERR); } - if ((num_channels < 1) || (num_channels > 2)) + if ((num_channels < 1) || (num_channels > LLVORBIS_CLIP_MAX_CHANNELS)) { error_msg = "SoundFileInvalidChannelCount"; return(LLVORBISENC_MULTICHANNEL_ERR); } - if (sample_rate != 44100) + if (sample_rate != LLVORBIS_CLIP_SAMPLE_RATE) { error_msg = "SoundFileInvalidSampleRate"; return(LLVORBISENC_UNSUPPORTED_SAMPLE_RATE); @@ -188,7 +188,7 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro F32 clip_length = (F32)raw_data_length/(F32)bytes_per_sec; - if (clip_length > 10.0f) + if (clip_length > LLVORBIS_CLIP_MAX_TIME) { error_msg = "SoundFileInvalidTooLong"; return(LLVORBISENC_CLIP_TOO_LONG); diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h index ff5ce3a053..6531c1919e 100644 --- a/indra/llaudio/llvorbisencode.h +++ b/indra/llaudio/llvorbisencode.h @@ -45,6 +45,17 @@ const S32 LLVORBISENC_UNSUPPORTED_SAMPLE_RATE = 8; // unsupported sample ra const S32 LLVORBISENC_UNSUPPORTED_WORD_SIZE = 9; // unsupported word size const S32 LLVORBISENC_CLIP_TOO_LONG = 10; // source file is too long +const F32 LLVORBIS_CLIP_MAX_TIME = 10.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); +const U32 LLVORBIS_CLIP_MAX_SAMPLES = LLVORBIS_CLIP_MAX_SAMPLES_PER_CHANNEL * LLVORBIS_CLIP_MAX_CHANNELS; +const size_t LLVORBIS_CLIP_MAX_SAMPLE_DATA = LLVORBIS_CLIP_MAX_SAMPLES * 2; // 2 = 16-bit + +// Treat anything this long as a bad asset. A little fudge factor at the end: +// Make that a lot of fudge factor. We're allowing 30 sec for now - 3x legal upload +const size_t LLVORBIS_CLIP_REJECT_SAMPLES = LLVORBIS_CLIP_MAX_SAMPLES * 3; +const size_t LLVORBIS_CLIP_REJECT_SIZE = LLVORBIS_CLIP_MAX_SAMPLE_DATA * 3; S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg); S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname); diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt index 612229d16b..85e3f97092 100644 --- a/indra/llcharacter/CMakeLists.txt +++ b/indra/llcharacter/CMakeLists.txt @@ -75,3 +75,13 @@ set_source_files_properties(${llcharacter_HEADER_FILES} list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES}) add_library (llcharacter ${llcharacter_SOURCE_FILES}) + + +# Add tests +include(LLAddBuildTest) +# UNIT TESTS +SET(llcharacter_TEST_SOURCE_FILES + lljoint.cpp + ) +LL_ADD_PROJECT_UNIT_TESTS(llcharacter "${llcharacter_TEST_SOURCE_FILES}") + diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 24391eb8f3..3dd54b4760 100644 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -91,7 +91,9 @@ const char *LLBVHLoader::ST_NO_XLT_EASEIN = "Can't get easeIn values."; const char *LLBVHLoader::ST_NO_XLT_EASEOUT = "Can't get easeOut values."; const char *LLBVHLoader::ST_NO_XLT_HAND = "Can't get hand morph value."; const char *LLBVHLoader::ST_NO_XLT_EMOTE = "Can't read emote name."; +const char *LLBVHLoader::ST_BAD_ROOT = "Illegal ROOT joint."; */ + //------------------------------------------------------------------------ // find_next_whitespace() //------------------------------------------------------------------------ @@ -777,6 +779,17 @@ ELoadStatus LLBVHLoader::loadBVHFile(const char *buffer, char* error_text, S32 & return E_ST_NO_NAME; } + //--------------------------------------------------------------- + // we require the root joint be "hip" - DEV-26188 + //--------------------------------------------------------------- + const char* FORCED_ROOT_NAME = "hip"; + if ( (mJoints.size() == 0 ) && ( !strstr(jointName, FORCED_ROOT_NAME) ) ) + { + strncpy(error_text, line.c_str(), 127); /* Flawfinder: ignore */ + return E_ST_BAD_ROOT; + } + + //---------------------------------------------------------------- // add a set of keyframes for this joint //---------------------------------------------------------------- diff --git a/indra/llcharacter/llbvhloader.h b/indra/llcharacter/llbvhloader.h index ecdfc95478..85ab035e61 100644 --- a/indra/llcharacter/llbvhloader.h +++ b/indra/llcharacter/llbvhloader.h @@ -216,7 +216,8 @@ typedef enum e_load_status E_ST_NO_XLT_EASEIN, E_ST_NO_XLT_EASEOUT, E_ST_NO_XLT_HAND, - E_ST_NO_XLT_EMOTE + E_ST_NO_XLT_EMOTE, + E_ST_BAD_ROOT } ELoadStatus; //------------------------------------------------------------------------ @@ -235,7 +236,7 @@ public: /* // Status Codes - typedef const char *Status; + typedef const char *status_t; static const char *ST_OK; static const char *ST_EOF; static const char *ST_NO_CONSTRAINT; @@ -267,6 +268,7 @@ public: static const char *ST_NO_XLT_EASEOUT; static const char *ST_NO_XLT_HAND; static const char *ST_NO_XLT_EMOTE; + static const char *ST_BAD_ROOT; */ // Loads the specified translation table. ELoadStatus loadTranslationTable(const char *fileName); @@ -325,6 +327,7 @@ protected: BOOL mInitialized; ELoadStatus mStatus; + // computed values F32 mDuration; }; diff --git a/indra/llcharacter/llgesture.cpp b/indra/llcharacter/llgesture.cpp index 4ee29fe100..83e4e35b00 100644 --- a/indra/llcharacter/llgesture.cpp +++ b/indra/llcharacter/llgesture.cpp @@ -304,7 +304,7 @@ BOOL LLGestureList::trigger(KEY key, MASK mask) } else { - llwarns << "NULL gesture in gesture list (" << i << ")" << llendl + llwarns << "NULL gesture in gesture list (" << i << ")" << llendl; } } return FALSE; diff --git a/indra/llcharacter/lljointsolverrp3.cpp b/indra/llcharacter/lljointsolverrp3.cpp index 0ea92a2d77..6599a76b16 100644 --- a/indra/llcharacter/lljointsolverrp3.cpp +++ b/indra/llcharacter/lljointsolverrp3.cpp @@ -211,7 +211,7 @@ void LLJointSolverRP3::solve() //------------------------------------------------------------------------- LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec)); -// llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl +// llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl; //------------------------------------------------------------------------- // compute the normal of the original ABC plane (and store for later) diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp new file mode 100644 index 0000000000..e43e164dd1 --- /dev/null +++ b/indra/llcharacter/tests/lljoint_test.cpp @@ -0,0 +1,246 @@ +/** + * @file lljoint_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief lljoint test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "m4math.h" +#include "v3math.h" + +#include "../lljoint.h" + +#include "../test/lltut.h" + + +namespace tut +{ + struct lljoint_data + { + }; + typedef test_group<lljoint_data> lljoint_test; + typedef lljoint_test::object lljoint_object; + tut::lljoint_test lljoint_testcase("lljoint"); + + template<> template<> + void lljoint_object::test<1>() + { + LLJoint lljoint; + LLJoint* jnt = lljoint.getParent(); + ensure("getParent() failed ", (NULL == jnt)); + ensure("getRoot() failed ", (&lljoint == lljoint.getRoot())); + } + + template<> template<> + void lljoint_object::test<2>() + { + std::string str = "LLJoint"; + LLJoint parent(str), child; + child.setup(str, &parent); + LLJoint* jnt = child.getParent(); + ensure("setup() failed ", (&parent == jnt)); + } + + template<> template<> + void lljoint_object::test<3>() + { + LLJoint parent, child; + std::string str = "LLJoint"; + child.setup(str, &parent); + LLJoint* jnt = parent.findJoint(str); + ensure("findJoint() failed ", (&child == jnt)); + } + + template<> template<> + void lljoint_object::test<4>() + { + LLJoint parent; + std::string str1 = "LLJoint", str2; + parent.setName(str1); + str2 = parent.getName(); + ensure("setName() failed ", (str1 == str2)); + } + + template<> template<> + void lljoint_object::test<5>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + lljoint.setPosition(vec3); + LLVector3 pos = lljoint.getPosition(); + ensure("setPosition()/getPosition() failed ", (vec3 == pos)); + } + + template<> template<> + void lljoint_object::test<6>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + lljoint.setWorldPosition(vec3); + LLVector3 pos = lljoint.getWorldPosition(); + ensure("1:setWorldPosition()/getWorldPosition() failed ", (vec3 == pos)); + LLVector3 lastPos = lljoint.getLastWorldPosition(); + ensure("2:getLastWorldPosition failed ", (vec3 == lastPos)); + } + + template<> template<> + void lljoint_object::test<7>() + { + LLJoint lljoint("LLJoint"); + LLQuaternion q(2.3f,30.f,10.f,1.f); + lljoint.setRotation(q); + LLQuaternion rot = lljoint.getRotation(); + ensure("setRotation()/getRotation() failed ", (q == rot)); + } + template<> template<> + void lljoint_object::test<8>() + { + LLJoint lljoint("LLJoint"); + LLQuaternion q(2.3f,30.f,10.f,1.f); + lljoint.setWorldRotation(q); + LLQuaternion rot = lljoint.getWorldRotation(); + ensure("1:setWorldRotation()/getWorldRotation() failed ", (q == rot)); + LLQuaternion lastRot = lljoint.getLastWorldRotation(); + ensure("2:getLastWorldRotation failed ", (q == lastRot)); + } + + template<> template<> + void lljoint_object::test<9>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + lljoint.setScale(vec3); + LLVector3 scale = lljoint.getScale(); + ensure("setScale()/getScale failed ", (vec3 == scale)); + } + + template<> template<> + void lljoint_object::test<10>() + { + LLJoint lljoint("LLJoint"); + LLMatrix4 mat; + mat.setIdentity(); + lljoint.setWorldMatrix(mat);//giving warning setWorldMatrix not correctly implemented; + LLMatrix4 mat4 = lljoint.getWorldMatrix(); + ensure("setWorldMatrix()/getWorldMatrix failed ", (mat4 == mat)); + } + + template<> template<> + void lljoint_object::test<11>() + { + LLJoint lljoint("parent"); + S32 joint_num = 12; + lljoint.setJointNum(joint_num); + S32 jointNum = lljoint.getJointNum(); + ensure("setJointNum()/getJointNum failed ", (jointNum == joint_num)); + } + + template<> template<> + void lljoint_object::test<12>() + { + LLJoint lljoint; + LLVector3 vec3(2.3f,30.f,10.f); + lljoint.setSkinOffset(vec3); + LLVector3 offset = lljoint.getSkinOffset(); + ensure("1:setSkinOffset()/getSkinOffset() failed ", (vec3 == offset)); + } + + template<> template<> + void lljoint_object::test<13>() + { + LLJoint lljointgp("gparent"); + LLJoint lljoint("parent"); + LLJoint lljoint1("child1"); + lljoint.addChild(&lljoint1); + LLJoint lljoint2("child2"); + lljoint.addChild(&lljoint2); + LLJoint lljoint3("child3"); + lljoint.addChild(&lljoint3); + + LLJoint* jnt = NULL; + jnt = lljoint2.getParent(); + ensure("addChild() failed ", (&lljoint == jnt)); + LLJoint* jnt1 = lljoint.findJoint("child3"); + ensure("findJoint() failed ", (&lljoint3 == jnt1)); + lljoint.removeChild(&lljoint3); + LLJoint* jnt2 = lljoint.findJoint("child3"); + ensure("removeChild() failed ", (NULL == jnt2)); + + lljointgp.addChild(&lljoint); + ensure("GetParent() failed ", (&lljoint== lljoint2.getParent())); + ensure("getRoot() failed ", (&lljointgp == lljoint2.getRoot())); + + ensure("getRoot() failed ", &lljoint1 == lljoint.findJoint("child1")); + + lljointgp.removeAllChildren(); + // parent removed from grandparent - so should not be able to locate child + ensure("removeAllChildren() failed ", (NULL == lljointgp.findJoint("child1"))); + // it should still exist in parent though + ensure("removeAllChildren() failed ", (&lljoint1 == lljoint.findJoint("child1"))); + } + + template<> template<> + void lljoint_object::test<14>() + { + LLJoint lljointgp("gparent"); + + LLJoint llparent1("parent1"); + LLJoint llparent2("parent2"); + + LLJoint llchild("child1"); + LLJoint lladoptedchild("child2"); + llparent1.addChild(&llchild); + llparent1.addChild(&lladoptedchild); + + llparent2.addChild(&lladoptedchild); + ensure("1. addChild failed to remove prior parent", lladoptedchild.getParent() == &llparent2); + ensure("2. addChild failed to remove prior parent", llparent1.findJoint("child2") == NULL); + } + + + /* + Test cases for the following not added. They perform operations + on underlying LLXformMatrix and LLVector3 elements which have + been unit tested separately. + Unit Testing these functions will basically require re-implementing + logic of these function in the test case itself + + 1) void WorldMatrixChildren(); + 2) void updateWorldMatrixParent(); + 3) void updateWorldPRSParent(); + 4) void updateWorldMatrix(); + 5) LLXformMatrix *getXform() { return &mXform; } + 6) void setConstraintSilhouette(LLDynamicArray<LLVector3>& silhouette); + 7) void clampRotation(LLQuaternion old_rot, LLQuaternion new_rot); + + */ +} + diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 1c84c9e21e..13778f0f3b 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -3,7 +3,6 @@ project(llcommon) include(00-Common) -include(LLAddBuildTest) include(LLCommon) include(Linking) include(Boost) @@ -291,16 +290,27 @@ add_dependencies(llcommon stage_third_party_libs) include(LLAddBuildTest) SET(llcommon_TEST_SOURCE_FILES + # unit-testing llcommon is not possible right now as the test-harness *itself* depends upon llcommon, causing a circular dependency. Add your 'unit' tests as integration tests for now. ) LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}") #set(TEST_DEBUG on) set(test_libs llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES} ${GOOGLEMOCK_LIBRARIES}) -# Have to treat lllazy test as an integration test until this issue is resolved: -# https://jira.lindenlab.com/jira/browse/DEV-29456 -LL_ADD_INTEGRATION_TEST(lllazy lllazy.cpp "${test_libs}") +LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llbase64 "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(lldate "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llerror "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(lltreeiterators "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(lluri "" "${test_libs}") # *TODO - reenable these once tcmalloc libs no longer break the build. #ADD_BUILD_TEST(llallocator llcommon) #ADD_BUILD_TEST(llallocator_heap_profile llcommon) #ADD_BUILD_TEST(llmemtype llcommon) + diff --git a/indra/llcommon/bitpack.cpp b/indra/llcommon/bitpack.cpp new file mode 100644 index 0000000000..8db403febf --- /dev/null +++ b/indra/llcommon/bitpack.cpp @@ -0,0 +1,36 @@ +/** + * @file bitpack.cpp + * @brief LLBitPack class implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes. +#include "bitpack.h" diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h index 5b1ec9295f..5c28a076cd 100644 --- a/indra/llcommon/lldate.h +++ b/indra/llcommon/lldate.h @@ -35,6 +35,8 @@ #ifndef LL_LLDATE_H #define LL_LLDATE_H +#include "linden_common.h" + #include <iosfwd> #include <string> diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 4f68fb9f76..5a4c644859 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -239,7 +239,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; */ #define lllog(level, broadTag, narrowTag, once) \ - { \ + do { \ static LLError::CallSite _site( \ level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, broadTag, narrowTag, once);\ if (_site.shouldLog()) \ @@ -252,7 +252,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; LLError::End(); \ LLError::Log::flush(_out, _site); \ } \ - } + } while(0) // DEPRECATED: Use the new macros that allow tags and *look* like macros. #define lldebugs lllog(LLError::LEVEL_DEBUG, NULL, NULL, false) diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index aef50ff8f9..905d736d62 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -37,7 +37,75 @@ #define FAST_TIMER_ON 1
-LL_COMMON_API U64 get_cpu_clock_count();
+#if LL_WINDOWS
+
+// shift off lower 8 bits for lower resolution but longer term timing
+// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
+inline U32 get_cpu_clock_count_32()
+{
+ U32 ret_val;
+ __asm
+ {
+ _emit 0x0f
+ _emit 0x31
+ shr eax,8
+ shl edx,24
+ or eax, edx
+ mov dword ptr [ret_val], eax
+ }
+ return ret_val;
+}
+
+// return full timer value, still shifted by 8 bits
+inline U64 get_cpu_clock_count_64()
+{
+ U64 ret_val;
+ __asm
+ {
+ _emit 0x0f
+ _emit 0x31
+ mov eax,eax
+ mov edx,edx
+ mov dword ptr [ret_val+4], edx
+ mov dword ptr [ret_val], eax
+ }
+ return ret_val >> 8;
+}
+
+#endif // LL_WINDOWS
+
+#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
+inline U32 get_cpu_clock_count_32()
+{
+ U64 x;
+ __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
+ return (U32)x >> 8;
+}
+
+inline U32 get_cpu_clock_count_64()
+{
+ U64 x;
+ __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
+ return x >> 8;
+}
+#endif
+
+#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__))) || (LL_SOLARIS && defined(__sparc__))
+//
+// Mac PPC (deprecated) & Solaris SPARC implementation of CPU clock
+//
+// Just use gettimeofday implementation for now
+
+inline U32 get_cpu_clock_count_32()
+{
+ return (U32)get_clock_count();
+}
+
+inline U32 get_cpu_clock_count_64()
+{
+ return get_clock_count();
+}
+#endif
class LLMutex;
@@ -52,13 +120,14 @@ public: class LL_COMMON_API NamedTimer
: public LLInstanceTracker<NamedTimer>
{
+ friend class DeclareTimer;
public:
~NamedTimer();
enum { HISTORY_NUM = 60 };
- const std::string& getName() { return mName; }
- NamedTimer* getParent() { return mParent; }
+ const std::string& getName() const { return mName; }
+ NamedTimer* getParent() const { return mParent; }
void setParent(NamedTimer* parent);
S32 getDepth();
std::string getToolTip(S32 history_index = -1);
@@ -71,11 +140,11 @@ public: void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
bool getCollapsed() const { return mCollapsed; }
- U64 getCountAverage() const { return mCountAverage; }
- U64 getCallAverage() const { return mCallAverage; }
+ U32 getCountAverage() const { return mCountAverage; }
+ U32 getCallAverage() const { return mCallAverage; }
- U64 getHistoricalCount(S32 history_index = 0) const;
- U64 getHistoricalCalls(S32 history_index = 0) const;
+ U32 getHistoricalCount(S32 history_index = 0) const;
+ U32 getHistoricalCalls(S32 history_index = 0) const;
static NamedTimer& getRootNamedTimer();
@@ -83,8 +152,7 @@ public: {
FrameState(NamedTimer* timerp);
- U64 mSelfTimeCounter;
- U64 mLastStartTime; // most recent time when this timer was started
+ U32 mSelfTimeCounter;
U32 mCalls;
FrameState* mParent; // info for caller timer
FrameState* mLastCaller; // used to bootstrap tree construction
@@ -93,11 +161,6 @@ public: bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame
};
- FrameState& getFrameStateFast() const
- {
- return (*sTimerInfos)[mFrameStateIndex];
- }
-
S32 getFrameStateIndex() const { return mFrameStateIndex; }
FrameState& getFrameState() const;
@@ -122,10 +185,7 @@ public: static void resetFrame();
static void reset();
- typedef std::vector<FrameState> info_list_t;
- static info_list_t& getFrameStateList();
- static void createFrameStateList(); // must call before any call to getFrameStateList()
-
+
//
// members
//
@@ -133,13 +193,13 @@ public: std::string mName;
- U64 mTotalTimeCounter;
+ U32 mTotalTimeCounter;
- U64 mCountAverage;
- U64 mCallAverage;
+ U32 mCountAverage;
+ U32 mCallAverage;
- U64* mCountHistory;
- U64* mCallHistory;
+ U32* mCountHistory;
+ U32* mCallHistory;
// tree structure
NamedTimer* mParent; // NamedTimer of caller(parent)
@@ -147,41 +207,46 @@ public: bool mCollapsed; // don't show children
bool mNeedsSorting; // sort children whenever child added
- static info_list_t* sTimerInfos;
};
// used to statically declare a new named timer
class LL_COMMON_API DeclareTimer
+ : public LLInstanceTracker<DeclareTimer>
{
public:
DeclareTimer(const std::string& name, bool open);
DeclareTimer(const std::string& name);
+ static void updateCachedPointers();
+
// convertable to NamedTimer::FrameState for convenient usage of LLFastTimer(declared_timer)
- operator NamedTimer::FrameState&() { return mNamedTimer.getFrameStateFast(); }
+ operator NamedTimer::FrameState&() { return *mFrameState; }
private:
- NamedTimer& mNamedTimer;
+ NamedTimer& mTimer;
+ NamedTimer::FrameState* mFrameState;
};
public:
- enum RootTimerMarker { ROOT };
-
static LLMutex* sLogLock;
static std::queue<LLSD> sLogQueue;
static BOOL sLog;
static BOOL sMetricLog;
+ typedef std::vector<NamedTimer::FrameState> info_list_t;
+ static info_list_t& getFrameStateList();
+
+ enum RootTimerMarker { ROOT };
LLFastTimer(RootTimerMarker);
LLFastTimer(NamedTimer::FrameState& timer)
: mFrameState(&timer)
{
#if FAST_TIMER_ON
- NamedTimer::FrameState* frame_state = mFrameState;
- U64 cur_time = get_cpu_clock_count();
- frame_state->mLastStartTime = cur_time;
+ NamedTimer::FrameState* frame_state = &timer;
+ U32 cur_time = get_cpu_clock_count_32();
mStartSelfTime = cur_time;
+ mStartTotalTime = cur_time;
frame_state->mActiveCount++;
frame_state->mCalls++;
@@ -197,7 +262,7 @@ public: {
#if FAST_TIMER_ON
NamedTimer::FrameState* frame_state = mFrameState;
- U64 cur_time = get_cpu_clock_count();
+ U32 cur_time = get_cpu_clock_count_32();
frame_state->mSelfTimeCounter += cur_time - mStartSelfTime;
frame_state->mActiveCount--;
@@ -208,7 +273,7 @@ public: frame_state->mLastCaller = last_timer->mFrameState;
// we are only tracking self time, so subtract our total time delta from parents
- U64 total_time = cur_time - frame_state->mLastStartTime;
+ U32 total_time = cur_time - mStartTotalTime;
last_timer->mStartSelfTime += total_time;
#endif
}
@@ -240,9 +305,11 @@ private: static LLFastTimer* sCurTimer;
static S32 sCurFrameIndex;
static S32 sLastFrameIndex;
+ static U64 sLastFrameTime;
+ static info_list_t* sTimerInfos;
- static F64 sCPUClockFrequency;
- U64 mStartSelfTime; // start time + time of all child timers
+ U32 mStartSelfTime; // start time + time of all child timers
+ U32 mStartTotalTime; // start time + time of all child timers
NamedTimer::FrameState* mFrameState;
LLFastTimer* mLastTimer;
};
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index ea50acbbc5..de25e364fa 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -71,17 +71,13 @@ private: static std::map<KEY, T*>& getMap() { - if (! sInstances) - { - sInstances = new std::map<KEY, T*>; - } + static std::map<KEY, T*>* sInstances = new std::map<KEY, T*>(); return *sInstances; } private: KEY mKey; - static std::map<KEY, T*>* sInstances; }; // explicit specialization for default case where KEY is T* @@ -105,17 +101,10 @@ protected: static std::set<T*>& getSet() // called after getReady() but before go() { - if (! sInstances) - { - sInstances = new std::set<T*>; - } + static std::set<T*>* sInstances = new std::set<T*>(); return *sInstances; } - - static std::set<T*>* sInstances; }; -template <typename T, typename KEY> std::map<KEY, T*>* LLInstanceTracker<T, KEY>::sInstances = NULL; -template <typename T> std::set<T*>* LLInstanceTracker<T, T*>::sInstances = NULL; #endif diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 6516d1779e..f2edd5c559 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -1018,7 +1018,11 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions) bool found_replacement = false; std::string replacement; - if (tokens.size() == 1) + if (tokens.size() == 0) + { + found_replacement = false; + } + else if (tokens.size() == 1) { found_replacement = simpleReplacement (replacement, tokens[0], substitutions); } @@ -1054,9 +1058,9 @@ S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions) } else { - // we had no replacement, so leave the string we searched for so that it gets noticed by QA - // "hello [NAME_NOT_FOUND]" is output - output += std::string("[") + tokens[0] + std::string("]"); + // we had no replacement, use the string as is + // e.g. "hello [MISSING_REPLACEMENT]" or "-=[Stylized Name]=-" + output += std::string(s, key_start, start-key_start); } tokens.clear(); } @@ -1092,7 +1096,11 @@ S32 LLStringUtil::format(std::string& s, const LLSD& substitutions) bool found_replacement = false; std::string replacement; - if (tokens.size() == 1) + if (tokens.size() == 0) + { + found_replacement = false; + } + else if (tokens.size() == 1) { found_replacement = simpleReplacement (replacement, tokens[0], substitutions); } @@ -1120,9 +1128,9 @@ S32 LLStringUtil::format(std::string& s, const LLSD& substitutions) } else { - // we had no replacement, so leave the string we searched for so that it gets noticed by QA - // "hello [NAME_NOT_FOUND]" is output - output += std::string("[") + tokens[0] + std::string("]"); + // we had no replacement, use the string as is + // e.g. "hello [MISSING_REPLACEMENT]" or "-=[Stylized Name]=-" + output += std::string(s, key_start, start-key_start); } tokens.clear(); } diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index d280c51226..0f2f05a0d8 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -34,6 +34,7 @@ #define LL_LLSTRING_H
#include <string>
+#include <cstdio>
#include <locale>
#include <iomanip>
#include "llsd.h"
@@ -998,14 +999,15 @@ void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string) {
return;
}
- char* c_string = new char[string.size() + 1];
+ size_t src_size = string.size();
+ char* c_string = new char[src_size + 1];
if(c_string == NULL)
{
return;
}
- strcpy(c_string, string.c_str()); /*Flawfinder: ignore*/
+ copy(c_string, string.c_str(), src_size+1);
char* write_head = &c_string[0];
- for (size_type i = 0; i < string.size(); i++)
+ for (size_type i = 0; i < src_size; i++)
{
char* read_head = &string[i];
write_head = &c_string[j];
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 127baa737d..3652eeba72 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -124,9 +124,42 @@ LLOSInfo::LLOSInfo() : } else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) { - if(osvi.wProductType == VER_NT_WORKSTATION) - mOSStringSimple = "Microsoft Windows Vista "; - else mOSStringSimple = "Microsoft Windows Vista Server "; + ///get native system info if available.. + typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ///function pointer for loading GetNativeSystemInfo + SYSTEM_INFO si; //System Info object file contains architecture info + PGNSI pGNSI; //pointer object + ZeroMemory(&si, sizeof(SYSTEM_INFO)); //zero out the memory in information + pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); //load kernel32 get function + if(NULL != pGNSI) //check if it has failed + pGNSI(&si); //success + else + GetSystemInfo(&si); //if it fails get regular system info + //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) + + //msdn microsoft finds 32 bit and 64 bit flavors this way.. + //http://msdn.microsoft.com/en-us/library/ms724429(VS.85).aspx (example code that contains quite a few more flavors + //of windows than this code does (in case it is needed for the future) + if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) //check for 64 bit + { + if(osvi.wProductType == VER_NT_WORKSTATION) + mOSStringSimple = "Microsoft Windows Vista 64-bit "; + else + mOSStringSimple = "Microsoft Windows Vista Server 64-bit "; + } + else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL ) + { + if(osvi.wProductType == VER_NT_WORKSTATION) + mOSStringSimple = "Microsoft Windows Vista 32-bit "; + else + mOSStringSimple = "Microsoft Windows Vista Server 32-bit "; + } + else // PROCESSOR_ARCHITECTURE_IA64 || PROCESSOR_ARCHITECTURE_UNKNOWN not checked + { + if(osvi.wProductType == VER_NT_WORKSTATION) + mOSStringSimple = "Microsoft Windows Vista "; + else + mOSStringSimple = "Microsoft Windows Vista Server "; + } } else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) { diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp new file mode 100644 index 0000000000..09fd037f02 --- /dev/null +++ b/indra/llcommon/tests/bitpack_test.cpp @@ -0,0 +1,125 @@ +/** + * @file bitpack_test.cpp + * @author Adroit + * @date 2007-02 + * @brief llstreamtools test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../bitpack.h" + +#include "../test/lltut.h" + + +namespace tut +{ + struct bit_pack + { + }; + typedef test_group<bit_pack> bit_pack_t; + typedef bit_pack_t::object bit_pack_object_t; + tut::bit_pack_t tut_bit_pack("bitpack"); + + // pack -> unpack + template<> template<> + void bit_pack_object_t::test<1>() + { + U8 packbuffer[255]; + U8 unpackbuffer[255]; + int pack_bufsize = 0; + int unpack_bufsize = 0; + + LLBitPack bitpack(packbuffer, 255); + + char str[] = "SecondLife is a 3D virtual world"; + int len = sizeof(str); + pack_bufsize = bitpack.bitPack((U8*) str, len*8); + pack_bufsize = bitpack.flushBitPack(); + + LLBitPack bitunpack(packbuffer, pack_bufsize*8); + unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, len*8); + ensure("bitPack: unpack size should be same as string size prior to pack", len == unpack_bufsize); + ensure_memory_matches("str->bitPack->bitUnpack should be equal to string", str, len, unpackbuffer, unpack_bufsize); + } + + // pack large, unpack in individual bytes + template<> template<> + void bit_pack_object_t::test<2>() + { + U8 packbuffer[255]; + U8 unpackbuffer[255]; + int pack_bufsize = 0; + int unpack_bufsize = 0; + + LLBitPack bitpack(packbuffer, 255); + + char str[] = "SecondLife"; + int len = sizeof(str); + pack_bufsize = bitpack.bitPack((U8*) str, len*8); + pack_bufsize = bitpack.flushBitPack(); + + LLBitPack bitunpack(packbuffer, pack_bufsize*8); + unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + ensure("bitPack: individual unpack: 0", unpackbuffer[0] == (U8) str[0]); + unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + ensure("bitPack: individual unpack: 1", unpackbuffer[0] == (U8) str[1]); + unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + ensure("bitPack: individual unpack: 2", unpackbuffer[0] == (U8) str[2]); + unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + ensure("bitPack: individual unpack: 3", unpackbuffer[0] == (U8) str[3]); + unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + ensure("bitPack: individual unpack: 4", unpackbuffer[0] == (U8) str[4]); + unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8); + ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]); + unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life + ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4); + } + + // U32 packing + template<> template<> + void bit_pack_object_t::test<3>() + { + U8 packbuffer[255]; + int pack_bufsize = 0; + + LLBitPack bitpack(packbuffer, 255); + U32 num = 0x41fab67a; + pack_bufsize = bitpack.bitPack((U8*)&num, 8*sizeof(U32)); + pack_bufsize = bitpack.flushBitPack(); + + LLBitPack bitunpack(packbuffer, pack_bufsize*8); + U32 res = 0; + // since packing and unpacking is done on same machine in the unit test run, + // endianness should not matter + bitunpack.bitUnpack((U8*) &res, sizeof(res)*8); + ensure("U32->bitPack->bitUnpack->U32 should be equal", num == res); + } +} diff --git a/indra/llcommon/tests/commonmisc_test.cpp b/indra/llcommon/tests/commonmisc_test.cpp new file mode 100644 index 0000000000..ca27fe9b23 --- /dev/null +++ b/indra/llcommon/tests/commonmisc_test.cpp @@ -0,0 +1,677 @@ +/** + * @file common.cpp + * @author Phoenix + * @date 2005-10-12 + * @brief Common templates for test framework + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/** + * + * THOROUGH_DESCRIPTION of common.cpp + * + */ + +#include <algorithm> +#include <iomanip> +#include <iterator> + +#include "linden_common.h" + +#include "../llmemorystream.h" +#include "../llsd.h" +#include "../llsdserialize.h" +#include "../u64.h" +#include "../llhash.h" + +#include "../test/lltut.h" + + +#if LL_WINDOWS +// disable overflow warnings +#pragma warning(disable: 4307) +#endif + +namespace tut +{ + struct sd_data + { + }; + typedef test_group<sd_data> sd_test; + typedef sd_test::object sd_object; + tut::sd_test sd("llsd"); + + template<> template<> + void sd_object::test<1>() + { + std::ostringstream resp; + resp << "{'connect':true, 'position':[r128,r128,r128], 'look_at':[r0,r1,r0], 'agent_access':'M', 'region_x':i8192, 'region_y':i8192}"; + std::string str = resp.str(); + LLMemoryStream mstr((U8*)str.c_str(), str.size()); + LLSD response; + S32 count = LLSDSerialize::fromNotation(response, mstr, str.size()); + ensure("stream parsed", response.isDefined()); + ensure_equals("stream parse count", count, 13); + ensure_equals("sd type", response.type(), LLSD::TypeMap); + ensure_equals("map element count", response.size(), 6); + ensure_equals("value connect", response["connect"].asBoolean(), true); + ensure_equals("value region_x", response["region_x"].asInteger(),8192); + ensure_equals("value region_y", response["region_y"].asInteger(),8192); + } + + template<> template<> + void sd_object::test<2>() + { + const std::string decoded("random"); + //const std::string encoded("cmFuZG9t\n"); + const std::string streamed("b(6)\"random\""); + typedef std::vector<U8> buf_t; + buf_t buf; + std::copy( + decoded.begin(), + decoded.end(), + std::back_insert_iterator<buf_t>(buf)); + LLSD sd; + sd = buf; + std::stringstream str; + S32 count = LLSDSerialize::toNotation(sd, str); + ensure_equals("output count", count, 1); + std::string actual(str.str()); + ensure_equals("formatted binary encoding", actual, streamed); + sd.clear(); + LLSDSerialize::fromNotation(sd, str, str.str().size()); + std::vector<U8> after; + after = sd.asBinary(); + ensure_equals("binary decoded size", after.size(), decoded.size()); + ensure("binary decoding", (0 == memcmp( + &after[0], + decoded.c_str(), + decoded.size()))); + } + + template<> template<> + void sd_object::test<3>() + { + for(S32 i = 0; i < 100; ++i) + { + // gen up a starting point + typedef std::vector<U8> buf_t; + buf_t source; + srand(i); /* Flawfinder: ignore */ + S32 size = rand() % 1000 + 10; + std::generate_n( + std::back_insert_iterator<buf_t>(source), + size, + rand); + LLSD sd(source); + std::stringstream str; + S32 count = LLSDSerialize::toNotation(sd, str); + sd.clear(); + ensure_equals("format count", count, 1); + LLSD sd2; + count = LLSDSerialize::fromNotation(sd2, str, str.str().size()); + ensure_equals("parse count", count, 1); + buf_t dest = sd2.asBinary(); + str.str(""); + str << "binary encoding size " << i; + ensure_equals(str.str().c_str(), dest.size(), source.size()); + str.str(""); + str << "binary encoding " << i; + ensure(str.str().c_str(), (source == dest)); + } + } + + template<> template<> + void sd_object::test<4>() + { + std::ostringstream ostr; + ostr << "{'task_id':u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}\n" + << "{\n\tname\tObject|\n}\n"; + std::string expected = ostr.str(); + std::stringstream serialized; + serialized << "'" << LLSDNotationFormatter::escapeString(expected) + << "'"; + LLSD sd; + S32 count = LLSDSerialize::fromNotation( + sd, + serialized, + serialized.str().size()); + ensure_equals("parse count", count, 1); + ensure_equals("String streaming", sd.asString(), expected); + } + + template<> template<> + void sd_object::test<5>() + { + for(S32 i = 0; i < 100; ++i) + { + // gen up a starting point + typedef std::vector<U8> buf_t; + buf_t source; + srand(666 + i); /* Flawfinder: ignore */ + S32 size = rand() % 1000 + 10; + std::generate_n( + std::back_insert_iterator<buf_t>(source), + size, + rand); + std::stringstream str; + str << "b(" << size << ")\""; + str.write((const char*)&source[0], size); + str << "\""; + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size()); + ensure_equals("binary parse", count, 1); + buf_t actual = sd.asBinary(); + ensure_equals("binary size", actual.size(), (size_t)size); + ensure("binary data", (0 == memcmp(&source[0], &actual[0], size))); + } + } + + template<> template<> + void sd_object::test<6>() + { + std::string expected("'{\"task_id\":u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}'\t\n\t\t"); + std::stringstream str; + str << "s(" << expected.size() << ")'"; + str.write(expected.c_str(), expected.size()); + str << "'"; + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size()); + ensure_equals("parse count", count, 1); + std::string actual = sd.asString(); + ensure_equals("string sizes", actual.size(), expected.size()); + ensure_equals("string content", actual, expected); + } + + template<> template<> + void sd_object::test<7>() + { + std::string msg("come on in"); + std::stringstream stream; + stream << "{'connect':1, 'message':'" << msg << "'," + << " 'position':[r45.65,r100.1,r25.5]," + << " 'look_at':[r0,r1,r0]," + << " 'agent_access':'PG'}"; + LLSD sd; + S32 count = LLSDSerialize::fromNotation( + sd, + stream, + stream.str().size()); + ensure_equals("parse count", count, 12); + ensure_equals("bool value", sd["connect"].asBoolean(), true); + ensure_equals("message value", sd["message"].asString(), msg); + ensure_equals("pos x", sd["position"][0].asReal(), 45.65); + ensure_equals("pos y", sd["position"][1].asReal(), 100.1); + ensure_equals("pos z", sd["position"][2].asReal(), 25.5); + ensure_equals("look x", sd["look_at"][0].asReal(), 0.0); + ensure_equals("look y", sd["look_at"][1].asReal(), 1.0); + ensure_equals("look z", sd["look_at"][2].asReal(), 0.0); + } + + template<> template<> + void sd_object::test<8>() + { + std::stringstream resp; + resp << "{'label':'short string test', 'singlechar':'a', 'empty':'', 'endoftest':'end' }"; + LLSD response; + S32 count = LLSDSerialize::fromNotation( + response, + resp, + resp.str().size()); + ensure_equals("parse count", count, 5); + ensure_equals("sd type", response.type(), LLSD::TypeMap); + ensure_equals("map element count", response.size(), 4); + ensure_equals("singlechar", response["singlechar"].asString(), "a"); + ensure_equals("empty", response["empty"].asString(), ""); + } + + template<> template<> + void sd_object::test<9>() + { + std::ostringstream resp; + resp << "{'label':'short binary test', 'singlebinary':b(1)\"A\", 'singlerawstring':s(1)\"A\", 'endoftest':'end' }"; + std::string str = resp.str(); + LLSD sd; + LLMemoryStream mstr((U8*)str.c_str(), str.size()); + S32 count = LLSDSerialize::fromNotation(sd, mstr, str.size()); + ensure_equals("parse count", count, 5); + ensure("sd created", sd.isDefined()); + ensure_equals("sd type", sd.type(), LLSD::TypeMap); + ensure_equals("map element count", sd.size(), 4); + ensure_equals( + "label", + sd["label"].asString(), + "short binary test"); + std::vector<U8> bin = sd["singlebinary"].asBinary(); + std::vector<U8> expected; + expected.resize(1); + expected[0] = 'A'; + ensure("single binary", (0 == memcmp(&bin[0], &expected[0], 1))); + ensure_equals( + "single string", + sd["singlerawstring"].asString(), + std::string("A")); + ensure_equals("end", sd["endoftest"].asString(), "end"); + } + + template<> template<> + void sd_object::test<10>() + { + + std::string message("parcel '' is naughty."); + std::stringstream str; + str << "{'message':'" << LLSDNotationFormatter::escapeString(message) + << "'}"; + std::string expected_str("{'message':'parcel \\'\\' is naughty.'}"); + std::string actual_str = str.str(); + ensure_equals("stream contents", actual_str, expected_str); + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, str, actual_str.size()); + ensure_equals("parse count", count, 2); + ensure("valid parse", sd.isDefined()); + std::string actual = sd["message"].asString(); + ensure_equals("message contents", actual, message); + } + + template<> template<> + void sd_object::test<11>() + { + std::string expected("\"\"\"\"''''''\""); + std::stringstream str; + str << "'" << LLSDNotationFormatter::escapeString(expected) << "'"; + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size()); + ensure_equals("parse count", count, 1); + ensure_equals("string value", sd.asString(), expected); + } + + template<> template<> + void sd_object::test<12>() + { + std::string expected("mytest\\"); + std::stringstream str; + str << "'" << LLSDNotationFormatter::escapeString(expected) << "'"; + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, str, str.str().size()); + ensure_equals("parse count", count, 1); + ensure_equals("string value", sd.asString(), expected); + } + + template<> template<> + void sd_object::test<13>() + { + for(S32 i = 0; i < 1000; ++i) + { + // gen up a starting point + std::string expected; + srand(1337 + i); /* Flawfinder: ignore */ + S32 size = rand() % 30 + 5; + std::generate_n( + std::back_insert_iterator<std::string>(expected), + size, + rand); + std::stringstream str; + str << "'" << LLSDNotationFormatter::escapeString(expected) << "'"; + LLSD sd; + S32 count = LLSDSerialize::fromNotation(sd, str, expected.size()); + ensure_equals("parse count", count, 1); + std::string actual = sd.asString(); +/* + if(actual != expected) + { + llwarns << "iteration " << i << llendl; + std::ostringstream e_str; + std::string::iterator iter = expected.begin(); + std::string::iterator end = expected.end(); + for(; iter != end; ++iter) + { + e_str << (S32)((U8)(*iter)) << " "; + } + e_str << std::endl; + llsd_serialize_string(e_str, expected); + llwarns << "expected size: " << expected.size() << llendl; + llwarns << "expected: " << e_str.str() << llendl; + + std::ostringstream a_str; + iter = actual.begin(); + end = actual.end(); + for(; iter != end; ++iter) + { + a_str << (S32)((U8)(*iter)) << " "; + } + a_str << std::endl; + llsd_serialize_string(a_str, actual); + llwarns << "actual size: " << actual.size() << llendl; + llwarns << "actual: " << a_str.str() << llendl; + } +*/ + ensure_equals("string value", actual, expected); + } + } + + template<> template<> + void sd_object::test<14>() + { +//#if LL_WINDOWS && _MSC_VER >= 1400 +// skip_fail("Fails on VS2005 due to broken LLSDSerialize::fromNotation() parser."); +//#endif + std::string param = "[{'version':i1},{'data':{'binary_bucket':b(0)\"\"},'from_id':u3c115e51-04f4-523c-9fa6-98aff1034730,'from_name':'Phoenix Linden','id':u004e45e5-5576-277a-fba7-859d6a4cb5c8,'message':'hey','offline':i0,'timestamp':i0,'to_id':u3c5f1bb4-5182-7546-6401-1d329b4ff2f8,'type':i0},{'agent_id':u3c115e51-04f4-523c-9fa6-98aff1034730,'god_level':i0,'limited_to_estate':i1}]"; + std::istringstream istr; + istr.str(param); + LLSD param_sd; + LLSDSerialize::fromNotation(param_sd, istr, param.size()); + ensure_equals("parsed type", param_sd.type(), LLSD::TypeArray); + LLSD version_sd = param_sd[0]; + ensure_equals("version type", version_sd.type(), LLSD::TypeMap); + ensure("has version", version_sd.has("version")); + ensure_equals("version number", version_sd["version"].asInteger(), 1); + LLSD src_sd = param_sd[1]; + ensure_equals("src type", src_sd.type(), LLSD::TypeMap); + LLSD dst_sd = param_sd[2]; + ensure_equals("dst type", dst_sd.type(), LLSD::TypeMap); + } + + template<> template<> + void sd_object::test<15>() + { + std::string val = "[{'failures':!,'successfuls':[u3c115e51-04f4-523c-9fa6-98aff1034730]}]"; + std::istringstream istr; + istr.str(val); + LLSD sd; + LLSDSerialize::fromNotation(sd, istr, val.size()); + ensure_equals("parsed type", sd.type(), LLSD::TypeArray); + ensure_equals("parsed size", sd.size(), 1); + LLSD failures = sd[0]["failures"]; + ensure("no failures.", failures.isUndefined()); + LLSD success = sd[0]["successfuls"]; + ensure_equals("success type", success.type(), LLSD::TypeArray); + ensure_equals("success size", success.size(), 1); + ensure_equals("success instance type", success[0].type(), LLSD::TypeUUID); + } + + template<> template<> + void sd_object::test<16>() + { + std::string val = "[f,t,0,1,{'foo':t,'bar':f}]"; + std::istringstream istr; + istr.str(val); + LLSD sd; + LLSDSerialize::fromNotation(sd, istr, val.size()); + ensure_equals("parsed type", sd.type(), LLSD::TypeArray); + ensure_equals("parsed size", sd.size(), 5); + ensure_equals("element 0 false", sd[0].asBoolean(), false); + ensure_equals("element 1 true", sd[1].asBoolean(), true); + ensure_equals("element 2 false", sd[2].asBoolean(), false); + ensure_equals("element 3 true", sd[3].asBoolean(), true); + LLSD map = sd[4]; + ensure_equals("element 4 type", map.type(), LLSD::TypeMap); + ensure_equals("map foo type", map["foo"].type(), LLSD::TypeBoolean); + ensure_equals("map foo value", map["foo"].asBoolean(), true); + ensure_equals("map bar type", map["bar"].type(), LLSD::TypeBoolean); + ensure_equals("map bar value", map["bar"].asBoolean(), false); + } + +/* + template<> template<> + void sd_object::test<16>() + { + } +*/ +} + +#if 0 +'{\'task_id\':u1fd77b79-a8e7-25a5-9454-02a4d948ba1c}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t00082000\n\t\tcreator_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t00000000-0000-0000-0000-000000000000\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t10284\n\ttotal_crc\t35\n\ttype\t1\n\ttask_valid\t2\n\ttravel_access\t21\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t0\t0\t0\n\toldpos\t0\t0\t0\n\trotation\t4.371139183945160766597837e-08\t1\t4.371139183945160766597837e-08\t0\n\tvelocity\t0\t0\t0\n\tangvel\t0\t0\t0\n\tscale\t0.2816932\t0.2816932\t0.2816932\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t80\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t16\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\tscale_x\t1\n\t\t\tscale_y\t1\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t1\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t6\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\t89556747-24cb-43ed-920b-47caed15465f\n\t\tcolors\t1 1 1 1\n\t\tscales\t0.56\n\t\tscalet\t0.56\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t1132625972249870\n\tbirthtime\t1132625953120694\n\treztime\t1132625953120694\n\tparceltime\t1132625953120694\n\ttax_rate\t1.01615\n\tnamevalue\tAttachmentOrientation VEC3 RW DS -3.141593, 0.000000, -3.141593\n\tnamevalue\tAttachmentOffset VEC3 RW DS 0.000000, 0.000000, 0.000000\n\tnamevalue\tAttachPt U32 RW S 5\n\tnamevalue\tAttachItemID STRING RW SV 1f9975c0-2951-1b93-dd83-46e2b932fcc8\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t52019cdd-b464-ba19-e66d-3da751fef9da\n\torig_item_id\t1f9975c0-2951-1b93-dd83-46e2b932fcc8\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n' +#endif + +namespace tut +{ + struct mem_data + { + }; + typedef test_group<mem_data> mem_test; + typedef mem_test::object mem_object; + tut::mem_test mem_stream("memory_stream"); + + template<> template<> + void mem_object::test<1>() + { + const char HELLO_WORLD[] = "hello world"; + LLMemoryStream mem((U8*)&HELLO_WORLD[0], strlen(HELLO_WORLD)); /* Flawfinder: ignore */ + std::string hello; + std::string world; + mem >> hello >> world; + ensure_equals("first word", hello, std::string("hello")); + ensure_equals("second word", world, std::string("world")); + } +} + +namespace tut +{ + struct U64_data + { + }; + typedef test_group<U64_data> U64_test; + typedef U64_test::object U64_object; + tut::U64_test U64_testcase("U64_conversion"); + + // U64_to_str + template<> template<> + void U64_object::test<1>() + { + U64 val; + std::string val_str; + char result[256]; + std::string result_str; + + val = U64L(18446744073709551610); // slightly less than MAX_U64 + val_str = "18446744073709551610"; + + U64_to_str(val, result, sizeof(result)); + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.1", val_str, result_str); + + val = 0; + val_str = "0"; + U64_to_str(val, result, sizeof(result)); + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.2", val_str, result_str); + + val = U64L(18446744073709551615); // 0xFFFFFFFFFFFFFFFF + val_str = "18446744073709551615"; + U64_to_str(val, result, sizeof(result)); + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.3", val_str, result_str); + + // overflow - will result in warning at compile time + val = U64L(18446744073709551615) + 1; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0 + val_str = "0"; + U64_to_str(val, result, sizeof(result)); + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.4", val_str, result_str); + + val = U64L(-1); // 0xFFFFFFFFFFFFFFFF == 18446744073709551615 + val_str = "18446744073709551615"; + U64_to_str(val, result, sizeof(result)); + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.5", val_str, result_str); + + val = U64L(10000000000000000000); // testing preserving of 0s + val_str = "10000000000000000000"; + U64_to_str(val, result, sizeof(result)); + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.6", val_str, result_str); + + val = 1; // testing no leading 0s + val_str = "1"; + U64_to_str(val, result, sizeof(result)); + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.7", val_str, result_str); + + val = U64L(18446744073709551615); // testing exact sized buffer for result + val_str = "18446744073709551615"; + memset(result, 'A', sizeof(result)); // initialize buffer with all 'A' + U64_to_str(val, result, sizeof("18446744073709551615")); //pass in the exact size + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.8", val_str, result_str); + + val = U64L(18446744073709551615); // testing smaller sized buffer for result + val_str = "1844"; + memset(result, 'A', sizeof(result)); // initialize buffer with all 'A' + U64_to_str(val, result, 5); //pass in a size of 5. should only copy first 4 integers and add a null terminator + result_str = (const char*) result; + ensure_equals("U64_to_str converted 1.9", val_str, result_str); + } + + // str_to_U64 + template<> template<> + void U64_object::test<2>() + { + U64 val; + U64 result; + + val = U64L(18446744073709551610); // slightly less than MAX_U64 + result = str_to_U64("18446744073709551610"); + ensure_equals("str_to_U64 converted 2.1", val, result); + + val = U64L(0); // empty string + result = str_to_U64(LLStringUtil::null); + ensure_equals("str_to_U64 converted 2.2", val, result); + + val = U64L(0); // 0 + result = str_to_U64("0"); + ensure_equals("str_to_U64 converted 2.3", val, result); + + val = U64L(18446744073709551615); // 0xFFFFFFFFFFFFFFFF + result = str_to_U64("18446744073709551615"); + ensure_equals("str_to_U64 converted 2.4", val, result); + + // overflow - will result in warning at compile time + val = U64L(18446744073709551615) + 1; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0 + result = str_to_U64("18446744073709551616"); + ensure_equals("str_to_U64 converted 2.5", val, result); + + val = U64L(1234); // process till first non-integral character + result = str_to_U64("1234A5678"); + ensure_equals("str_to_U64 converted 2.6", val, result); + + val = U64L(5678); // skip all non-integral characters + result = str_to_U64("ABCD5678"); + ensure_equals("str_to_U64 converted 2.7", val, result); + + // should it skip negative sign and process + // rest of string or return 0 + val = U64L(1234); // skip initial negative sign + result = str_to_U64("-1234"); + ensure_equals("str_to_U64 converted 2.8", val, result); + + val = U64L(5678); // stop at negative sign in the middle + result = str_to_U64("5678-1234"); + ensure_equals("str_to_U64 converted 2.9", val, result); + + val = U64L(0); // no integers + result = str_to_U64("AaCD"); + ensure_equals("str_to_U64 converted 2.10", val, result); + } + + // U64_to_F64 + template<> template<> + void U64_object::test<3>() + { + F64 val; + F64 result; + + result = 18446744073709551610.0; + val = U64_to_F64(U64L(18446744073709551610)); + ensure_equals("U64_to_F64 converted 3.1", val, result); + + result = 18446744073709551615.0; // 0xFFFFFFFFFFFFFFFF + val = U64_to_F64(U64L(18446744073709551615)); + ensure_equals("U64_to_F64 converted 3.2", val, result); + + result = 0.0; // overflow 0xFFFFFFFFFFFFFFFF + 1 == 0 + // overflow - will result in warning at compile time + val = U64_to_F64(U64L(18446744073709551615)+1); + ensure_equals("U64_to_F64 converted 3.3", val, result); + + result = 0.0; // 0 + val = U64_to_F64(U64L(0)); + ensure_equals("U64_to_F64 converted 3.4", val, result); + + result = 1.0; // odd + val = U64_to_F64(U64L(1)); + ensure_equals("U64_to_F64 converted 3.5", val, result); + + result = 2.0; // even + val = U64_to_F64(U64L(2)); + ensure_equals("U64_to_F64 converted 3.6", val, result); + + result = U64L(0x7FFFFFFFFFFFFFFF) * 1.0L; // 0x7FFFFFFFFFFFFFFF + val = U64_to_F64(U64L(0x7FFFFFFFFFFFFFFF)); + ensure_equals("U64_to_F64 converted 3.7", val, result); + } + + // llstrtou64 + // seems to be deprecated - could not find it being used + // anywhere in the tarball - skipping unit tests for now +} + + +namespace tut +{ + struct hash_data + { + }; + typedef test_group<hash_data> hash_test; + typedef hash_test::object hash_object; + tut::hash_test hash_tester("hash_test"); + + template<> template<> + void hash_object::test<1>() + { + const char * str1 = "test string one"; + const char * same_as_str1 = "test string one"; + + size_t hash1 = llhash(str1); + size_t same_as_hash1 = llhash(same_as_str1); + + + ensure("Hashes from identical strings should be equal", hash1 == same_as_hash1); + + char str[100]; + strcpy( str, "Another test" ); + + size_t hash2 = llhash(str); + + strcpy( str, "Different string, same pointer" ); + + size_t hash3 = llhash(str); + + ensure("Hashes from same pointer but different string should not be equal", hash2 != hash3); + } +} diff --git a/indra/llcommon/tests/llbase64_test.cpp b/indra/llcommon/tests/llbase64_test.cpp new file mode 100644 index 0000000000..dde43b5169 --- /dev/null +++ b/indra/llcommon/tests/llbase64_test.cpp @@ -0,0 +1,83 @@ +/** + * @file llbase64_tut.cpp + * @author James Cook + * @date 2007-02-04 + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include <string> + +#include "linden_common.h" + +#include "../llbase64.h" +#include "../lluuid.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct base64_data + { + }; + typedef test_group<base64_data> base64_test; + typedef base64_test::object base64_object; + tut::base64_test base64("base64"); + + template<> template<> + void base64_object::test<1>() + { + std::string result; + + result = LLBase64::encode(NULL, 0); + ensure("encode nothing", (result == "") ); + + LLUUID nothing; + result = LLBase64::encode(¬hing.mData[0], UUID_BYTES); + ensure("encode blank uuid", + (result == "AAAAAAAAAAAAAAAAAAAAAA==") ); + + LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e"); + result = LLBase64::encode(&id.mData[0], UUID_BYTES); + ensure("encode random uuid", + (result == "UmoeB6Gduu2ExP8IpIjRXg==") ); + + } + + template<> template<> + void base64_object::test<2>() + { + std::string result; + + U8 blob[40] = { 115, 223, 172, 255, 140, 70, 49, 125, 236, 155, 45, 199, 101, 17, 164, 131, 230, 19, 80, 64, 112, 53, 135, 98, 237, 12, 26, 72, 126, 14, 145, 143, 118, 196, 11, 177, 132, 169, 195, 134 }; + result = LLBase64::encode(&blob[0], 40); + ensure("encode 40 bytes", + (result == "c9+s/4xGMX3smy3HZRGkg+YTUEBwNYdi7QwaSH4OkY92xAuxhKnDhg==") ); + } + +} diff --git a/indra/llcommon/tests/lldate_test.cpp b/indra/llcommon/tests/lldate_test.cpp new file mode 100644 index 0000000000..1e36fdd119 --- /dev/null +++ b/indra/llcommon/tests/lldate_test.cpp @@ -0,0 +1,219 @@ +/** + * @file lldate_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief LLDate test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../llstring.h" +#include "../lldate.h" + +#include "../test/lltut.h" + + +#define VALID_DATE "2003-04-30T04:00:00Z" +#define VALID_DATE_LEAP "2004-02-29T04:00:00Z" +#define VALID_DATE_HOUR_BOUNDARY "2003-04-30T23:59:59Z" +#define VALID_DATE_FRACTIONAL_SECS "2007-09-26T20:31:33.70Z" + +// invalid format +#define INVALID_DATE_MISSING_YEAR "-04-30T22:59:59Z" +#define INVALID_DATE_MISSING_MONTH "1900-0430T22:59:59Z" +#define INVALID_DATE_MISSING_DATE "1900-0430-T22:59:59Z" +#define INVALID_DATE_MISSING_T "1900-04-30-22:59:59Z" +#define INVALID_DATE_MISSING_HOUR "1900-04-30T:59:59Z" +#define INVALID_DATE_MISSING_MIN "1900-04-30T01::59Z" +#define INVALID_DATE_MISSING_SEC "1900-04-30T01:59Z" +#define INVALID_DATE_MISSING_Z "1900-04-30T01:59:23" +#define INVALID_DATE_EMPTY "" + +// invalid values +// apr 1.1.1 seems to not care about constraining the date to valid +// dates. Put these back when the parser checks. +#define LL_DATE_PARSER_CHECKS_BOUNDARY 0 +//#define INVALID_DATE_24HOUR_BOUNDARY "2003-04-30T24:00:00Z" +//#define INVALID_DATE_LEAP "2003-04-29T04:00:00Z" +//#define INVALID_DATE_HOUR "2003-04-30T24:59:59Z" +//#define INVALID_DATE_MIN "2003-04-30T22:69:59Z" +//#define INVALID_DATE_SEC "2003-04-30T22:59:69Z" +//#define INVALID_DATE_YEAR "0-04-30T22:59:59Z" +//#define INVALID_DATE_MONTH "2003-13-30T22:59:59Z" +//#define INVALID_DATE_DAY "2003-04-35T22:59:59Z" + +namespace tut +{ + struct date_test + { + + }; + typedef test_group<date_test> date_test_t; + typedef date_test_t::object date_test_object_t; + tut::date_test_t tut_date_test("date_test"); + + /* format validation */ + template<> template<> + void date_test_object_t::test<1>() + { + LLDate date(VALID_DATE); + std::string expected_string; + bool result; + expected_string = VALID_DATE; + ensure_equals("Valid Date failed" , expected_string, date.asString()); + + result = date.fromString(VALID_DATE_LEAP); + expected_string = VALID_DATE_LEAP; + ensure_equals("VALID_DATE_LEAP failed" , expected_string, date.asString()); + + result = date.fromString(VALID_DATE_HOUR_BOUNDARY); + expected_string = VALID_DATE_HOUR_BOUNDARY; + ensure_equals("VALID_DATE_HOUR_BOUNDARY failed" , expected_string, date.asString()); + + result = date.fromString(VALID_DATE_FRACTIONAL_SECS); + expected_string = VALID_DATE_FRACTIONAL_SECS; + ensure_equals("VALID_DATE_FRACTIONAL_SECS failed" , expected_string, date.asString()); + + result = date.fromString(INVALID_DATE_MISSING_YEAR); + ensure_equals("INVALID_DATE_MISSING_YEAR should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MISSING_MONTH); + ensure_equals("INVALID_DATE_MISSING_MONTH should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MISSING_DATE); + ensure_equals("INVALID_DATE_MISSING_DATE should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MISSING_T); + ensure_equals("INVALID_DATE_MISSING_T should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MISSING_HOUR); + ensure_equals("INVALID_DATE_MISSING_HOUR should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MISSING_MIN); + ensure_equals("INVALID_DATE_MISSING_MIN should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MISSING_SEC); + ensure_equals("INVALID_DATE_MISSING_SEC should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MISSING_Z); + ensure_equals("INVALID_DATE_MISSING_Z should have failed" , result, false); + + result = date.fromString(INVALID_DATE_EMPTY); + ensure_equals("INVALID_DATE_EMPTY should have failed" , result, false); + } + + /* Invalid Value Handling */ + template<> template<> + void date_test_object_t::test<2>() + { +#if LL_DATE_PARSER_CHECKS_BOUNDARY + LLDate date; + std::string expected_string; + bool result; + + result = date.fromString(INVALID_DATE_24HOUR_BOUNDARY); + ensure_equals("INVALID_DATE_24HOUR_BOUNDARY should have failed" , result, false); + ensure_equals("INVALID_DATE_24HOUR_BOUNDARY date still set to old value on failure!" , date.secondsSinceEpoch(), 0); + + result = date.fromString(INVALID_DATE_LEAP); + ensure_equals("INVALID_DATE_LEAP should have failed" , result, false); + + result = date.fromString(INVALID_DATE_HOUR); + ensure_equals("INVALID_DATE_HOUR should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MIN); + ensure_equals("INVALID_DATE_MIN should have failed" , result, false); + + result = date.fromString(INVALID_DATE_SEC); + ensure_equals("INVALID_DATE_SEC should have failed" , result, false); + + result = date.fromString(INVALID_DATE_YEAR); + ensure_equals("INVALID_DATE_YEAR should have failed" , result, false); + + result = date.fromString(INVALID_DATE_MONTH); + ensure_equals("INVALID_DATE_MONTH should have failed" , result, false); + + result = date.fromString(INVALID_DATE_DAY); + ensure_equals("INVALID_DATE_DAY should have failed" , result, false); +#endif + } + + /* API checks */ + template<> template<> + void date_test_object_t::test<3>() + { + LLDate date; + std::istringstream stream(VALID_DATE); + std::string expected_string = VALID_DATE; + date.fromStream(stream); + ensure_equals("fromStream failed", date.asString(), expected_string); + } + + template<> template<> + void date_test_object_t::test<4>() + { + LLDate date1(VALID_DATE); + LLDate date2(date1); + ensure_equals("LLDate(const LLDate& date) constructor failed", date1.asString(), date2.asString()); + } + + template<> template<> + void date_test_object_t::test<5>() + { + LLDate date1(VALID_DATE); + LLDate date2(date1.secondsSinceEpoch()); + ensure_equals("secondsSinceEpoch not equal",date1.secondsSinceEpoch(), date2.secondsSinceEpoch()); + ensure_equals("LLDate created using secondsSinceEpoch not equal", date1.asString(), date2.asString()); + } + + template<> template<> + void date_test_object_t::test<6>() + { + LLDate date(VALID_DATE); + std::ostringstream stream; + stream << date; + std::string expected_str = VALID_DATE; + ensure_equals("ostringstream failed", expected_str, stream.str()); + } + + template<> template<> + void date_test_object_t::test<7>() + { + LLDate date; + std::istringstream stream(VALID_DATE); + stream >> date; + std::string expected_str = VALID_DATE; + std::ostringstream out_stream; + out_stream << date; + + ensure_equals("<< failed", date.asString(),expected_str); + ensure_equals("<< to >> failed", stream.str(),out_stream.str()); + } +} diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp new file mode 100644 index 0000000000..8055647b94 --- /dev/null +++ b/indra/llcommon/tests/llerror_test.cpp @@ -0,0 +1,768 @@ +/** + * @file llerror_tut.cpp + * @date December 2006 + * @brief error unit tests + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include <vector> + +#include "linden_common.h" + +#include "../llerror.h" + +#include "../llerrorcontrol.h" +#include "../llsd.h" + +#include "../test/lltut.h" + +namespace +{ + void test_that_error_h_includes_enough_things_to_compile_a_message() + { + llinfos << "!" << llendl; + } +} + +namespace +{ + static bool fatalWasCalled; + void fatalCall(const std::string&) { fatalWasCalled = true; } + + class TestRecorder : public LLError::Recorder + { + public: + TestRecorder() : mWantsTime(false) { } + ~TestRecorder() { LLError::removeRecorder(this); } + + void recordMessage(LLError::ELevel level, + const std::string& message) + { + mMessages.push_back(message); + } + + int countMessages() { return (int) mMessages.size(); } + void clearMessages() { mMessages.clear(); } + + void setWantsTime(bool t) { mWantsTime = t; } + bool wantsTime() { return mWantsTime; } + + std::string message(int n) + { + std::ostringstream test_name; + test_name << "testing message " << n << ", not enough messages"; + + tut::ensure(test_name.str(), n < countMessages()); + return mMessages[n]; + } + + private: + typedef std::vector<std::string> MessageVector; + MessageVector mMessages; + + bool mWantsTime; + }; +} + +namespace tut +{ + struct ErrorTestData + { + TestRecorder mRecorder; + LLError::Settings* mPriorErrorSettings; + + ErrorTestData() + { + fatalWasCalled = false; + + mPriorErrorSettings = LLError::saveAndResetSettings(); + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + LLError::setFatalFunction(fatalCall); + LLError::addRecorder(&mRecorder); + } + + ~ErrorTestData() + { + LLError::removeRecorder(&mRecorder); + LLError::restoreSettings(mPriorErrorSettings); + } + + void ensure_message_count(int expectedCount) + { + ensure_equals("message count", mRecorder.countMessages(), expectedCount); + } + + void ensure_message_contains(int n, const std::string& expectedText) + { + std::ostringstream test_name; + test_name << "testing message " << n; + + ensure_contains(test_name.str(), mRecorder.message(n), expectedText); + } + + void ensure_message_does_not_contain(int n, const std::string& expectedText) + { + std::ostringstream test_name; + test_name << "testing message " << n; + + ensure_does_not_contain(test_name.str(), mRecorder.message(n), expectedText); + } + }; + + typedef test_group<ErrorTestData> ErrorTestGroup; + typedef ErrorTestGroup::object ErrorTestObject; + + ErrorTestGroup errorTestGroup("error"); + + template<> template<> + void ErrorTestObject::test<1>() + // basic test of output + { + llinfos << "test" << llendl; + llinfos << "bob" << llendl; + + ensure_message_contains(0, "test"); + ensure_message_contains(1, "bob"); + } +} + +namespace +{ + void writeSome() + { + lldebugs << "one" << llendl; + llinfos << "two" << llendl; + llwarns << "three" << llendl; + llerrs << "four" << llendl; + // fatal messages write out and addtional "error" message + } +}; + +namespace tut +{ + template<> template<> + void ErrorTestObject::test<2>() + // messages are filtered based on default level + { + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + writeSome(); + ensure_message_contains(0, "one"); + ensure_message_contains(1, "two"); + ensure_message_contains(2, "three"); + ensure_message_contains(3, "error"); + ensure_message_contains(4, "four"); + ensure_message_count(5); + + LLError::setDefaultLevel(LLError::LEVEL_INFO); + writeSome(); + ensure_message_contains(5, "two"); + ensure_message_contains(6, "three"); + ensure_message_contains(7, "error"); + ensure_message_contains(8, "four"); + ensure_message_count(9); + + LLError::setDefaultLevel(LLError::LEVEL_WARN); + writeSome(); + ensure_message_contains(9, "three"); + ensure_message_contains(10, "error"); + ensure_message_contains(11, "four"); + ensure_message_count(12); + + LLError::setDefaultLevel(LLError::LEVEL_ERROR); + writeSome(); + ensure_message_contains(12, "error"); + ensure_message_contains(13, "four"); + ensure_message_count(14); + + LLError::setDefaultLevel(LLError::LEVEL_NONE); + writeSome(); + ensure_message_count(14); + } + + template<> template<> + void ErrorTestObject::test<3>() + // error type string in output + { + writeSome(); + ensure_message_contains(0, "DEBUG: "); + ensure_message_contains(1, "INFO: "); + ensure_message_contains(2, "WARNING: "); + ensure_message_does_not_contain(3, "ERROR"); + ensure_message_contains(4, "ERROR: "); + ensure_message_count(5); + } + + template<> template<> + void ErrorTestObject::test<4>() + // file abbreviation + { + std::string thisFile = __FILE__; + std::string abbreviateFile = LLError::abbreviateFile(thisFile); + + ensure_ends_with("file name abbreviation", + abbreviateFile, + "llcommon/tests/llerror_test.cpp" + ); + ensure_does_not_contain("file name abbreviation", + abbreviateFile, "indra"); + + std::string someFile = +#if LL_WINDOWS + "C:/amy/bob/cam.cpp" +#else + "/amy/bob/cam.cpp" +#endif + ; + std::string someAbbreviation = LLError::abbreviateFile(someFile); + + ensure_equals("non-indra file abbreviation", + someAbbreviation, someFile); + } +} + +namespace +{ + std::string locationString(int line) + { + std::ostringstream location; + location << LLError::abbreviateFile(__FILE__) + << "(" << line << ") : "; + + return location.str(); + } + + std::string writeReturningLocation() + { + llinfos << "apple" << llendl; int this_line = __LINE__; + return locationString(this_line); + } + + std::string writeReturningLocationAndFunction() + { + llinfos << "apple" << llendl; int this_line = __LINE__; + return locationString(this_line) + __FUNCTION__; + } + + std::string errorReturningLocation() + { + llerrs << "die" << llendl; int this_line = __LINE__; + return locationString(this_line); + } +} + +namespace tut +{ + template<> template<> + void ErrorTestObject::test<5>() + // file and line information in log messages + { + std::string location = writeReturningLocation(); + // expecting default to not print location information + + LLError::setPrintLocation(true); + writeReturningLocation(); + + LLError::setPrintLocation(false); + writeReturningLocation(); + + ensure_message_does_not_contain(0, location); + ensure_message_contains(1, location); + ensure_message_does_not_contain(2, location); + } +} + +/* The following helper functions and class members all log a simple message + from some particular function scope. Each function takes a bool argument + that indicates if it should log its own name or not (in the manner that + existing log messages often do.) The functions all return their C++ + name so that test can be substantial mechanized. + */ + +std::string logFromGlobal(bool id) +{ + llinfos << (id ? "logFromGlobal: " : "") << "hi" << llendl; + return "logFromGlobal"; +} + +static std::string logFromStatic(bool id) +{ + llinfos << (id ? "logFromStatic: " : "") << "hi" << llendl; + return "logFromStatic"; +} + +namespace +{ + std::string logFromAnon(bool id) + { + llinfos << (id ? "logFromAnon: " : "") << "hi" << llendl; + return "logFromAnon"; + } +} + +namespace Foo { + std::string logFromNamespace(bool id) + { + llinfos << (id ? "Foo::logFromNamespace: " : "") << "hi" << llendl; + //return "Foo::logFromNamespace"; + // there is no standard way to get the namespace name, hence + // we won't be testing for it + return "logFromNamespace"; + } +} + +namespace +{ + class ClassWithNoLogType { + public: + std::string logFromMember(bool id) + { + llinfos << (id ? "ClassWithNoLogType::logFromMember: " : "") << "hi" << llendl; + return "ClassWithNoLogType::logFromMember"; + } + static std::string logFromStatic(bool id) + { + llinfos << (id ? "ClassWithNoLogType::logFromStatic: " : "") << "hi" << llendl; + return "ClassWithNoLogType::logFromStatic"; + } + }; + + class ClassWithLogType { + LOG_CLASS(ClassWithLogType); + public: + std::string logFromMember(bool id) + { + llinfos << (id ? "ClassWithLogType::logFromMember: " : "") << "hi" << llendl; + return "ClassWithLogType::logFromMember"; + } + static std::string logFromStatic(bool id) + { + llinfos << (id ? "ClassWithLogType::logFromStatic: " : "") << "hi" << llendl; + return "ClassWithLogType::logFromStatic"; + } + }; + + std::string logFromNamespace(bool id) { return Foo::logFromNamespace(id); } + std::string logFromClassWithNoLogTypeMember(bool id) { ClassWithNoLogType c; return c.logFromMember(id); } + std::string logFromClassWithNoLogTypeStatic(bool id) { return ClassWithNoLogType::logFromStatic(id); } + std::string logFromClassWithLogTypeMember(bool id) { ClassWithLogType c; return c.logFromMember(id); } + std::string logFromClassWithLogTypeStatic(bool id) { return ClassWithLogType::logFromStatic(id); } + + void ensure_has(const std::string& message, + const std::string& actual, const std::string& expected) + { + std::string::size_type n1 = actual.find(expected); + if (n1 == std::string::npos) + { + std::stringstream ss; + ss << message << ": " << "expected to find a copy of " << expected + << " in actual " << actual; + throw tut::failure(ss.str().c_str()); + } + } + + typedef std::string (*LogFromFunction)(bool); + void testLogName(TestRecorder& recorder, LogFromFunction f, + const std::string& class_name = "") + { + recorder.clearMessages(); + std::string name = f(false); + f(true); + + std::string messageWithoutName = recorder.message(0); + std::string messageWithName = recorder.message(1); + + ensure_has(name + " logged without name", + messageWithoutName, name); + ensure_has(name + " logged with name", + messageWithName, name); + + if (!class_name.empty()) + { + ensure_has(name + "logged without name", + messageWithoutName, class_name); + ensure_has(name + "logged with name", + messageWithName, class_name); + } + } +} + +namespace tut +{ + template<> template<> + // class/function information in output + void ErrorTestObject::test<6>() + { + testLogName(mRecorder, logFromGlobal); + testLogName(mRecorder, logFromStatic); + testLogName(mRecorder, logFromAnon); + testLogName(mRecorder, logFromNamespace); + //testLogName(mRecorder, logFromClassWithNoLogTypeMember, "ClassWithNoLogType"); + //testLogName(mRecorder, logFromClassWithNoLogTypeStatic, "ClassWithNoLogType"); + // XXX: figure out what the exepcted response is for these + testLogName(mRecorder, logFromClassWithLogTypeMember, "ClassWithLogType"); + testLogName(mRecorder, logFromClassWithLogTypeStatic, "ClassWithLogType"); + } +} + +namespace +{ + std::string innerLogger() + { + llinfos << "inside" << llendl; + return "moo"; + } + + std::string outerLogger() + { + llinfos << "outside(" << innerLogger() << ")" << llendl; + return "bar"; + } + + void uberLogger() + { + llinfos << "uber(" << outerLogger() << "," << innerLogger() << ")" << llendl; + } + + class LogWhileLogging + { + public: + void print(std::ostream& out) const + { + llinfos << "logging" << llendl; + out << "baz"; + } + }; + + std::ostream& operator<<(std::ostream& out, const LogWhileLogging& l) + { l.print(out); return out; } + + void metaLogger() + { + LogWhileLogging l; + llinfos << "meta(" << l << ")" << llendl; + } + +} + +namespace tut +{ + template<> template<> + // handle nested logging + void ErrorTestObject::test<7>() + { + outerLogger(); + ensure_message_contains(0, "inside"); + ensure_message_contains(1, "outside(moo)"); + ensure_message_count(2); + + uberLogger(); + ensure_message_contains(2, "inside"); + ensure_message_contains(3, "inside"); + ensure_message_contains(4, "outside(moo)"); + ensure_message_contains(5, "uber(bar,moo)"); + ensure_message_count(6); + + metaLogger(); + ensure_message_contains(6, "logging"); + ensure_message_contains(7, "meta(baz)"); + ensure_message_count(8); + } + + template<> template<> + // special handling of llerrs calls + void ErrorTestObject::test<8>() + { + LLError::setPrintLocation(false); + std::string location = errorReturningLocation(); + + ensure_message_contains(0, location + "error"); + ensure_message_contains(1, "die"); + ensure_message_count(2); + + ensure("fatal callback called", fatalWasCalled); + } +} + +namespace +{ + std::string roswell() + { + return "1947-07-08T03:04:05Z"; + } + + void ufoSighting() + { + llinfos << "ufo" << llendl; + } +} + +namespace tut +{ + template<> template<> + // time in output (for recorders that need it) + void ErrorTestObject::test<9>() + { + LLError::setTimeFunction(roswell); + + mRecorder.setWantsTime(false); + ufoSighting(); + ensure_message_contains(0, "ufo"); + ensure_message_does_not_contain(0, roswell()); + + mRecorder.setWantsTime(true); + ufoSighting(); + ensure_message_contains(1, "ufo"); + ensure_message_contains(1, roswell()); + } + + template<> template<> + // output order + void ErrorTestObject::test<10>() + { + LLError::setPrintLocation(true); + LLError::setTimeFunction(roswell); + mRecorder.setWantsTime(true); + std::string locationAndFunction = writeReturningLocationAndFunction(); + + ensure_equals("order is time type location function message", + mRecorder.message(0), + roswell() + " INFO: " + locationAndFunction + ": apple"); + } + + template<> template<> + // multiple recorders + void ErrorTestObject::test<11>() + { + TestRecorder altRecorder; + LLError::addRecorder(&altRecorder); + + llinfos << "boo" << llendl; + + ensure_message_contains(0, "boo"); + ensure_equals("alt recorder count", altRecorder.countMessages(), 1); + ensure_contains("alt recorder message 0", altRecorder.message(0), "boo"); + + LLError::setTimeFunction(roswell); + + TestRecorder anotherRecorder; + anotherRecorder.setWantsTime(true); + LLError::addRecorder(&anotherRecorder); + + llinfos << "baz" << llendl; + + std::string when = roswell(); + + ensure_message_does_not_contain(1, when); + ensure_equals("alt recorder count", altRecorder.countMessages(), 2); + ensure_does_not_contain("alt recorder message 1", altRecorder.message(1), when); + ensure_equals("another recorder count", anotherRecorder.countMessages(), 1); + ensure_contains("another recorder message 0", anotherRecorder.message(0), when); + } +} + +class TestAlpha +{ + LOG_CLASS(TestAlpha); +public: + static void doDebug() { lldebugs << "add dice" << llendl; } + static void doInfo() { llinfos << "any idea" << llendl; } + static void doWarn() { llwarns << "aim west" << llendl; } + static void doError() { llerrs << "ate eels" << llendl; } + static void doAll() { doDebug(); doInfo(); doWarn(); doError(); } +}; + +class TestBeta +{ + LOG_CLASS(TestBeta); +public: + static void doDebug() { lldebugs << "bed down" << llendl; } + static void doInfo() { llinfos << "buy iron" << llendl; } + static void doWarn() { llwarns << "bad word" << llendl; } + static void doError() { llerrs << "big easy" << llendl; } + static void doAll() { doDebug(); doInfo(); doWarn(); doError(); } +}; + +namespace tut +{ + template<> template<> + // filtering by class + void ErrorTestObject::test<12>() + { + LLError::setDefaultLevel(LLError::LEVEL_WARN); + LLError::setClassLevel("TestBeta", LLError::LEVEL_INFO); + + TestAlpha::doAll(); + TestBeta::doAll(); + + ensure_message_contains(0, "aim west"); + ensure_message_contains(1, "error"); + ensure_message_contains(2, "ate eels"); + ensure_message_contains(3, "buy iron"); + ensure_message_contains(4, "bad word"); + ensure_message_contains(5, "error"); + ensure_message_contains(6, "big easy"); + ensure_message_count(7); + } + + template<> template<> + // filtering by function, and that it will override class filtering + void ErrorTestObject::test<13>() + { + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + LLError::setClassLevel("TestBeta", LLError::LEVEL_WARN); + LLError::setFunctionLevel("TestBeta::doInfo", LLError::LEVEL_DEBUG); + LLError::setFunctionLevel("TestBeta::doError", LLError::LEVEL_NONE); + + TestBeta::doAll(); + ensure_message_contains(0, "buy iron"); + ensure_message_contains(1, "bad word"); + ensure_message_count(2); + } + + template<> template<> + // filtering by file + // and that it is overridden by both class and function filtering + void ErrorTestObject::test<14>() + { + LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + LLError::setFileLevel(LLError::abbreviateFile(__FILE__), + LLError::LEVEL_WARN); + LLError::setClassLevel("TestAlpha", LLError::LEVEL_INFO); + LLError::setFunctionLevel("TestAlpha::doError", + LLError::LEVEL_NONE); + LLError::setFunctionLevel("TestBeta::doError", + LLError::LEVEL_NONE); + + TestAlpha::doAll(); + TestBeta::doAll(); + ensure_message_contains(0, "any idea"); + ensure_message_contains(1, "aim west"); + ensure_message_contains(2, "bad word"); + ensure_message_count(3); + } + + template<> template<> + // proper cached, efficient lookup of filtering + void ErrorTestObject::test<15>() + { + LLError::setDefaultLevel(LLError::LEVEL_NONE); + + TestAlpha::doInfo(); + ensure_message_count(0); + ensure_equals("first check", LLError::shouldLogCallCount(), 1); + TestAlpha::doInfo(); + ensure_message_count(0); + ensure_equals("second check", LLError::shouldLogCallCount(), 1); + + LLError::setClassLevel("TestAlpha", LLError::LEVEL_DEBUG); + TestAlpha::doInfo(); + ensure_message_count(1); + ensure_equals("third check", LLError::shouldLogCallCount(), 2); + TestAlpha::doInfo(); + ensure_message_count(2); + ensure_equals("fourth check", LLError::shouldLogCallCount(), 2); + + LLError::setClassLevel("TestAlpha", LLError::LEVEL_WARN); + TestAlpha::doInfo(); + ensure_message_count(2); + ensure_equals("fifth check", LLError::shouldLogCallCount(), 3); + TestAlpha::doInfo(); + ensure_message_count(2); + ensure_equals("sixth check", LLError::shouldLogCallCount(), 3); + } + + template<> template<> + // configuration from LLSD + void ErrorTestObject::test<16>() + { + std::string this_file = LLError::abbreviateFile(__FILE__); + LLSD config; + config["print-location"] = true; + config["default-level"] = "DEBUG"; + + LLSD set1; + set1["level"] = "WARN"; + set1["files"][0] = this_file; + + LLSD set2; + set2["level"] = "INFO"; + set2["classes"][0] = "TestAlpha"; + + LLSD set3; + set3["level"] = "NONE"; + set3["functions"][0] = "TestAlpha::doError"; + set3["functions"][1] = "TestBeta::doError"; + + config["settings"][0] = set1; + config["settings"][1] = set2; + config["settings"][2] = set3; + + LLError::configure(config); + + TestAlpha::doAll(); + TestBeta::doAll(); + ensure_message_contains(0, "any idea"); + ensure_message_contains(0, this_file); + ensure_message_contains(1, "aim west"); + ensure_message_contains(2, "bad word"); + ensure_message_count(3); + + // make sure reconfiguring works + LLSD config2; + config2["default-level"] = "WARN"; + + LLError::configure(config2); + + TestAlpha::doAll(); + TestBeta::doAll(); + ensure_message_contains(3, "aim west"); + ensure_message_does_not_contain(3, this_file); + ensure_message_contains(4, "error"); + ensure_message_contains(5, "ate eels"); + ensure_message_contains(6, "bad word"); + ensure_message_contains(7, "error"); + ensure_message_contains(8, "big easy"); + ensure_message_count(9); + } +} + +/* Tests left: + handling of classes without LOG_CLASS + + live update of filtering from file + + syslog recorder + file recorder + cerr/stderr recorder + fixed buffer recorder + windows recorder + + mutex use when logging (?) + strange careful about to crash handling (?) +*/ diff --git a/indra/llcommon/tests/llframetimer_test.cpp b/indra/llcommon/tests/llframetimer_test.cpp new file mode 100644 index 0000000000..737c996d0f --- /dev/null +++ b/indra/llcommon/tests/llframetimer_test.cpp @@ -0,0 +1,118 @@ +/** + * @file lltiming_tut.cpp + * @date 2006-07-23 + * @brief Tests the timers. + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../llframetimer.h" +#include "../llsd.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct frametimer_test + { + frametimer_test() + { + LLFrameTimer::updateFrameTime(); + } + }; + typedef test_group<frametimer_test> frametimer_group_t; + typedef frametimer_group_t::object frametimer_object_t; + tut::frametimer_group_t frametimer_instance("frametimer"); + + template<> template<> + void frametimer_object_t::test<1>() + { + F64 seconds_since_epoch = LLFrameTimer::getTotalSeconds(); + LLFrameTimer timer; + timer.setExpiryAt(seconds_since_epoch); + F64 expires_at = timer.expiresAt(); + ensure_distance( + "set expiry matches get expiry", + expires_at, + seconds_since_epoch, + 0.001); + } + + template<> template<> + void frametimer_object_t::test<2>() + { + F64 seconds_since_epoch = LLFrameTimer::getTotalSeconds(); + seconds_since_epoch += 10.0; + LLFrameTimer timer; + timer.setExpiryAt(seconds_since_epoch); + F64 expires_at = timer.expiresAt(); + ensure_distance( + "set expiry matches get expiry 1", + expires_at, + seconds_since_epoch, + 0.001); + seconds_since_epoch += 10.0; + timer.setExpiryAt(seconds_since_epoch); + expires_at = timer.expiresAt(); + ensure_distance( + "set expiry matches get expiry 2", + expires_at, + seconds_since_epoch, + 0.001); + } + template<> template<> + void frametimer_object_t::test<3>() + { + F64 seconds_since_epoch = LLFrameTimer::getTotalSeconds(); + seconds_since_epoch += 2.0; + LLFrameTimer timer; + timer.setExpiryAt(seconds_since_epoch); + ensure("timer not expired on create", !timer.hasExpired()); + int ii; + for(ii = 0; ii < 10; ++ii) + { + ms_sleep(150); + LLFrameTimer::updateFrameTime(); + } + ensure("timer not expired after a bit", !timer.hasExpired()); + for(ii = 0; ii < 10; ++ii) + { + ms_sleep(100); + LLFrameTimer::updateFrameTime(); + } + ensure("timer expired", timer.hasExpired()); + } +/* + template<> template<> + void frametimer_object_t::test<4>() + { + } +*/ +} diff --git a/indra/llcommon/tests/llrand_test.cpp b/indra/llcommon/tests/llrand_test.cpp new file mode 100644 index 0000000000..e5100e51dc --- /dev/null +++ b/indra/llcommon/tests/llrand_test.cpp @@ -0,0 +1,133 @@ +/** + * @file llrandom_tut.cpp + * @author Phoenix + * @date 2007-01-25 + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../llrand.h" + + +namespace tut +{ + struct random + { + }; + + typedef test_group<random> random_t; + typedef random_t::object random_object_t; + tut::random_t tut_random("random"); + + template<> template<> + void random_object_t::test<1>() + { + F32 number = 0.0f; + for(S32 ii = 0; ii < 100000; ++ii) + { + number = ll_frand(); + ensure("frand >= 0", (number >= 0.0f)); + ensure("frand < 1", (number < 1.0f)); + } + } + + template<> template<> + void random_object_t::test<2>() + { + F64 number = 0.0f; + for(S32 ii = 0; ii < 100000; ++ii) + { + number = ll_drand(); + ensure("drand >= 0", (number >= 0.0)); + ensure("drand < 1", (number < 1.0)); + } + } + + template<> template<> + void random_object_t::test<3>() + { + F32 number = 0.0f; + for(S32 ii = 0; ii < 100000; ++ii) + { + number = ll_frand(2.0f) - 1.0f; + ensure("frand >= 0", (number >= -1.0f)); + ensure("frand < 1", (number <= 1.0f)); + } + } + + template<> template<> + void random_object_t::test<4>() + { + F32 number = 0.0f; + for(S32 ii = 0; ii < 100000; ++ii) + { + number = ll_frand(-7.0); + ensure("drand <= 0", (number <= 0.0)); + ensure("drand > -7", (number > -7.0)); + } + } + + template<> template<> + void random_object_t::test<5>() + { + F64 number = 0.0f; + for(S32 ii = 0; ii < 100000; ++ii) + { + number = ll_drand(-2.0); + ensure("drand <= 0", (number <= 0.0)); + ensure("drand > -2", (number > -2.0)); + } + } + + template<> template<> + void random_object_t::test<6>() + { + S32 number = 0; + for(S32 ii = 0; ii < 100000; ++ii) + { + number = ll_rand(100); + ensure("rand >= 0", (number >= 0)); + ensure("rand < 100", (number < 100)); + } + } + + template<> template<> + void random_object_t::test<7>() + { + S32 number = 0; + for(S32 ii = 0; ii < 100000; ++ii) + { + number = ll_rand(-127); + ensure("rand <= 0", (number <= 0)); + ensure("rand > -127", (number > -127)); + } + } +} diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp new file mode 100644 index 0000000000..8f6d9d8e26 --- /dev/null +++ b/indra/llcommon/tests/llsdserialize_test.cpp @@ -0,0 +1,1504 @@ +/** + * @file llsdserialize_tut.cpp + * @date 2006-04 + * @brief LLSDSerialize unit tests + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#if !LL_WINDOWS +#include <netinet/in.h> +#endif + +#include "linden_common.h" +#include "../llsd.h" +#include "../llsdserialize.h" +#include "../llformat.h" + +#include "../test/lltut.h" + + +#if LL_WINDOWS +#include <winsock2.h> +typedef U32 uint32_t; +#endif + +std::vector<U8> string_to_vector(std::string str) +{ + // bc LLSD can't... + size_t len = (size_t)str.length(); + std::vector<U8> v(len); + for (size_t i = 0; i < len ; i++) + { + v[i] = str[i]; + } + return v; +} + +namespace tut +{ + struct sd_xml_data + { + sd_xml_data() + { + mFormatter = new LLSDXMLFormatter; + } + LLSD mSD; + LLPointer<LLSDXMLFormatter> mFormatter; + void xml_test(const char* name, const std::string& expected) + { + std::ostringstream ostr; + mFormatter->format(mSD, ostr); + ensure_equals(name, ostr.str(), expected); + } + }; + + typedef test_group<sd_xml_data> sd_xml_test; + typedef sd_xml_test::object sd_xml_object; + tut::sd_xml_test sd_xml_stream("sd_xml_serialization"); + + template<> template<> + void sd_xml_object::test<1>() + { + // random atomic tests + std::string expected; + + expected = "<llsd><undef /></llsd>\n"; + xml_test("undef", expected); + + mSD = 3463; + expected = "<llsd><integer>3463</integer></llsd>\n"; + xml_test("integer", expected); + + mSD = ""; + expected = "<llsd><string /></llsd>\n"; + xml_test("empty string", expected); + + mSD = "foobar"; + expected = "<llsd><string>foobar</string></llsd>\n"; + xml_test("string", expected); + + mSD = LLUUID::null; + expected = "<llsd><uuid /></llsd>\n"; + xml_test("null uuid", expected); + + mSD = LLUUID("c96f9b1e-f589-4100-9774-d98643ce0bed"); + expected = "<llsd><uuid>c96f9b1e-f589-4100-9774-d98643ce0bed</uuid></llsd>\n"; + xml_test("uuid", expected); + + mSD = LLURI("https://secondlife.com/login"); + expected = "<llsd><uri>https://secondlife.com/login</uri></llsd>\n"; + xml_test("uri", expected); + + mSD = LLDate("2006-04-24T16:11:33Z"); + expected = "<llsd><date>2006-04-24T16:11:33Z</date></llsd>\n"; + xml_test("date", expected); + + // Generated by: echo -n 'hello' | openssl enc -e -base64 + std::vector<U8> hello; + hello.push_back('h'); + hello.push_back('e'); + hello.push_back('l'); + hello.push_back('l'); + hello.push_back('o'); + mSD = hello; + expected = "<llsd><binary encoding=\"base64\">aGVsbG8=</binary></llsd>\n"; + xml_test("binary", expected); + } + + template<> template<> + void sd_xml_object::test<2>() + { + // tests with boolean values. + std::string expected; + + mFormatter->boolalpha(true); + mSD = true; + expected = "<llsd><boolean>true</boolean></llsd>\n"; + xml_test("bool alpha true", expected); + mSD = false; + expected = "<llsd><boolean>false</boolean></llsd>\n"; + xml_test("bool alpha false", expected); + + mFormatter->boolalpha(false); + mSD = true; + expected = "<llsd><boolean>1</boolean></llsd>\n"; + xml_test("bool true", expected); + mSD = false; + expected = "<llsd><boolean>0</boolean></llsd>\n"; + xml_test("bool false", expected); + } + + + template<> template<> + void sd_xml_object::test<3>() + { + // tests with real values. + std::string expected; + + mFormatter->realFormat("%.2f"); + mSD = 1.0; + expected = "<llsd><real>1.00</real></llsd>\n"; + xml_test("real 1", expected); + + mSD = -34379.0438; + expected = "<llsd><real>-34379.04</real></llsd>\n"; + xml_test("real reduced precision", expected); + mFormatter->realFormat("%.4f"); + expected = "<llsd><real>-34379.0438</real></llsd>\n"; + xml_test("higher precision", expected); + + mFormatter->realFormat("%.0f"); + mSD = 0.0; + expected = "<llsd><real>0</real></llsd>\n"; + xml_test("no decimal 0", expected); + mSD = 3287.4387; + expected = "<llsd><real>3287</real></llsd>\n"; + xml_test("no decimal real number", expected); + } + + template<> template<> + void sd_xml_object::test<4>() + { + // tests with arrays + std::string expected; + + mSD = LLSD::emptyArray(); + expected = "<llsd><array /></llsd>\n"; + xml_test("empty array", expected); + + mSD.append(LLSD()); + expected = "<llsd><array><undef /></array></llsd>\n"; + xml_test("1 element array", expected); + + mSD.append(1); + expected = "<llsd><array><undef /><integer>1</integer></array></llsd>\n"; + xml_test("2 element array", expected); + } + + template<> template<> + void sd_xml_object::test<5>() + { + // tests with arrays + std::string expected; + + mSD = LLSD::emptyMap(); + expected = "<llsd><map /></llsd>\n"; + xml_test("empty map", expected); + + mSD["foo"] = "bar"; + expected = "<llsd><map><key>foo</key><string>bar</string></map></llsd>\n"; + xml_test("1 element map", expected); + + mSD["baz"] = LLSD(); + expected = "<llsd><map><key>baz</key><undef /><key>foo</key><string>bar</string></map></llsd>\n"; + xml_test("2 element map", expected); + } + + template<> template<> + void sd_xml_object::test<6>() + { + // tests with binary + std::string expected; + + // Generated by: echo -n 'hello' | openssl enc -e -base64 + mSD = string_to_vector("hello"); + expected = "<llsd><binary encoding=\"base64\">aGVsbG8=</binary></llsd>\n"; + xml_test("binary", expected); + + mSD = string_to_vector("6|6|asdfhappybox|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|00000000-0000-0000-0000-000000000000|7fffffff|7fffffff|0|0|82000|450fe394-2904-c9ad-214c-a07eb7feec29|(No Description)|0|10|0"); + expected = "<llsd><binary encoding=\"base64\">Nnw2fGFzZGZoYXBweWJveHw2MGU0NGVjNS0zMDVjLTQzYzItOWExOS1iNGI4OWIxYWUyYTZ8NjBlNDRlYzUtMzA1Yy00M2MyLTlhMTktYjRiODliMWFlMmE2fDYwZTQ0ZWM1LTMwNWMtNDNjMi05YTE5LWI0Yjg5YjFhZTJhNnwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDB8N2ZmZmZmZmZ8N2ZmZmZmZmZ8MHwwfDgyMDAwfDQ1MGZlMzk0LTI5MDQtYzlhZC0yMTRjLWEwN2ViN2ZlZWMyOXwoTm8gRGVzY3JpcHRpb24pfDB8MTB8MA==</binary></llsd>\n"; + xml_test("binary", expected); + } + + class TestLLSDSerializeData + { + public: + TestLLSDSerializeData(); + ~TestLLSDSerializeData(); + + void doRoundTripTests(const std::string&); + void checkRoundTrip(const std::string&, const LLSD& v); + + LLPointer<LLSDFormatter> mFormatter; + LLPointer<LLSDParser> mParser; + }; + + TestLLSDSerializeData::TestLLSDSerializeData() + { + } + + TestLLSDSerializeData::~TestLLSDSerializeData() + { + } + + void TestLLSDSerializeData::checkRoundTrip(const std::string& msg, const LLSD& v) + { + std::stringstream stream; + mFormatter->format(v, stream); + //llinfos << "checkRoundTrip: length " << stream.str().length() << llendl; + LLSD w; + mParser->reset(); // reset() call is needed since test code re-uses mParser + mParser->parse(stream, w, stream.str().size()); + + try + { + ensure_equals(msg.c_str(), w, v); + } + catch (...) + { + std::cerr << "the serialized string was:" << std::endl; + std::cerr << stream.str() << std::endl; + throw; + } + } + + static void fillmap(LLSD& root, U32 width, U32 depth) + { + if(depth == 0) + { + root["foo"] = "bar"; + return; + } + + for(U32 i = 0; i < width; ++i) + { + std::string key = llformat("child %d", i); + root[key] = LLSD::emptyMap(); + fillmap(root[key], width, depth - 1); + } + } + + void TestLLSDSerializeData::doRoundTripTests(const std::string& msg) + { + LLSD v; + checkRoundTrip(msg + " undefined", v); + + v = true; + checkRoundTrip(msg + " true bool", v); + + v = false; + checkRoundTrip(msg + " false bool", v); + + v = 1; + checkRoundTrip(msg + " positive int", v); + + v = 0; + checkRoundTrip(msg + " zero int", v); + + v = -1; + checkRoundTrip(msg + " negative int", v); + + v = 1234.5f; + checkRoundTrip(msg + " positive float", v); + + v = 0.0f; + checkRoundTrip(msg + " zero float", v); + + v = -1234.5f; + checkRoundTrip(msg + " negative float", v); + + // FIXME: need a NaN test + + v = LLUUID::null; + checkRoundTrip(msg + " null uuid", v); + + LLUUID newUUID; + newUUID.generate(); + v = newUUID; + checkRoundTrip(msg + " new uuid", v); + + v = ""; + checkRoundTrip(msg + " empty string", v); + + v = "some string"; + checkRoundTrip(msg + " non-empty string", v); + + v = +"Second Life is a 3-D virtual world entirely built and owned by its residents. " +"Since opening to the public in 2003, it has grown explosively and today is " +"inhabited by nearly 100,000 people from around the globe.\n" +"\n" +"From the moment you enter the World you'll discover a vast digital continent, " +"teeming with people, entertainment, experiences and opportunity. Once you've " +"explored a bit, perhaps you'll find a perfect parcel of land to build your " +"house or business.\n" +"\n" +"You'll also be surrounded by the Creations of your fellow residents. Because " +"residents retain the rights to their digital creations, they can buy, sell " +"and trade with other residents.\n" +"\n" +"The Marketplace currently supports millions of US dollars in monthly " +"transactions. This commerce is handled with the in-world currency, the Linden " +"dollar, which can be converted to US dollars at several thriving online " +"currency exchanges.\n" +"\n" +"Welcome to Second Life. We look forward to seeing you in-world!\n" + ; + checkRoundTrip(msg + " long string", v); + + static const U32 block_size = 0x000020; + for (U32 block = 0x000000; block <= 0x10ffff; block += block_size) + { + std::ostringstream out; + + for (U32 c = block; c < block + block_size; ++c) + { + if (c <= 0x000001f + && c != 0x000009 + && c != 0x00000a) + { + // see XML standard, sections 2.2 and 4.1 + continue; + } + if (0x00d800 <= c && c <= 0x00dfff) { continue; } + if (0x00fdd0 <= c && c <= 0x00fdef) { continue; } + if ((c & 0x00fffe) == 0x00fffe) { continue; } + // see Unicode standard, section 15.8 + + if (c <= 0x00007f) + { + out << (char)(c & 0x7f); + } + else if (c <= 0x0007ff) + { + out << (char)(0xc0 | ((c >> 6) & 0x1f)); + out << (char)(0x80 | ((c >> 0) & 0x3f)); + } + else if (c <= 0x00ffff) + { + out << (char)(0xe0 | ((c >> 12) & 0x0f)); + out << (char)(0x80 | ((c >> 6) & 0x3f)); + out << (char)(0x80 | ((c >> 0) & 0x3f)); + } + else + { + out << (char)(0xf0 | ((c >> 18) & 0x07)); + out << (char)(0x80 | ((c >> 12) & 0x3f)); + out << (char)(0x80 | ((c >> 6) & 0x3f)); + out << (char)(0x80 | ((c >> 0) & 0x3f)); + } + } + + v = out.str(); + + std::ostringstream blockmsg; + blockmsg << msg << " unicode string block 0x" << std::hex << block; + checkRoundTrip(blockmsg.str(), v); + } + + LLDate epoch; + v = epoch; + checkRoundTrip(msg + " epoch date", v); + + LLDate aDay("2002-12-07T05:07:15.00Z"); + v = aDay; + checkRoundTrip(msg + " date", v); + + LLURI path("http://slurl.com/secondlife/Ambleside/57/104/26/"); + v = path; + checkRoundTrip(msg + " url", v); + + const char source[] = "it must be a blue moon again"; + std::vector<U8> data; + copy(&source[0], &source[sizeof(source)], back_inserter(data)); + + v = data; + checkRoundTrip(msg + " binary", v); + + v = LLSD::emptyMap(); + checkRoundTrip(msg + " empty map", v); + + v = LLSD::emptyMap(); + v["name"] = "luke"; //v.insert("name", "luke"); + v["age"] = 3; //v.insert("age", 3); + checkRoundTrip(msg + " map", v); + + v.clear(); + v["a"]["1"] = true; + v["b"]["0"] = false; + checkRoundTrip(msg + " nested maps", v); + + v = LLSD::emptyArray(); + checkRoundTrip(msg + " empty array", v); + + v = LLSD::emptyArray(); + v.append("ali"); + v.append(28); + checkRoundTrip(msg + " array", v); + + v.clear(); + v[0][0] = true; + v[1][0] = false; + checkRoundTrip(msg + " nested arrays", v); + + v = LLSD::emptyMap(); + fillmap(v, 10, 6); // 10^6 maps + checkRoundTrip(msg + " many nested maps", v); + } + + typedef tut::test_group<TestLLSDSerializeData> TestLLSDSerialzeGroup; + typedef TestLLSDSerialzeGroup::object TestLLSDSerializeObject; + TestLLSDSerialzeGroup gTestLLSDSerializeGroup("llsd serialization"); + + template<> template<> + void TestLLSDSerializeObject::test<1>() + { + mFormatter = new LLSDNotationFormatter(); + mParser = new LLSDNotationParser(); + doRoundTripTests("notation serialization"); + } + + template<> template<> + void TestLLSDSerializeObject::test<2>() + { + mFormatter = new LLSDXMLFormatter(); + mParser = new LLSDXMLParser(); + doRoundTripTests("xml serialization"); + } + + template<> template<> + void TestLLSDSerializeObject::test<3>() + { + mFormatter = new LLSDBinaryFormatter(); + mParser = new LLSDBinaryParser(); + doRoundTripTests("binary serialization"); + } + + + /** + * @class TestLLSDParsing + * @brief Base class for of a parse tester. + */ + template <class parser_t> + class TestLLSDParsing + { + public: + TestLLSDParsing() + { + mParser = new parser_t; + } + + void ensureParse( + const std::string& msg, + const std::string& in, + const LLSD& expected_value, + S32 expected_count) + { + std::stringstream input; + input.str(in); + + LLSD parsed_result; + mParser->reset(); // reset() call is needed since test code re-uses mParser + S32 parsed_count = mParser->parse(input, parsed_result, in.size()); + ensure_equals(msg.c_str(), parsed_result, expected_value); + + // This count check is really only useful for expected + // parse failures, since the ensures equal will already + // require eqality. + std::string count_msg(msg); + count_msg += " (count)"; + ensure_equals(count_msg, parsed_count, expected_count); + } + + LLPointer<parser_t> mParser; + }; + + + /** + * @class TestLLSDXMLParsing + * @brief Concrete instance of a parse tester. + */ + class TestLLSDXMLParsing : public TestLLSDParsing<LLSDXMLParser> + { + public: + TestLLSDXMLParsing() {} + }; + + typedef tut::test_group<TestLLSDXMLParsing> TestLLSDXMLParsingGroup; + typedef TestLLSDXMLParsingGroup::object TestLLSDXMLParsingObject; + TestLLSDXMLParsingGroup gTestLLSDXMLParsingGroup("llsd XML parsing"); + + template<> template<> + void TestLLSDXMLParsingObject::test<1>() + { + // test handling of xml not recognized as llsd results in an + // LLSD Undefined + ensureParse( + "malformed xml", + "<llsd><string>ha ha</string>", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "not llsd", + "<html><body><p>ha ha</p></body></html>", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "value without llsd", + "<string>ha ha</string>", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "key without llsd", + "<key>ha ha</key>", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + + template<> template<> + void TestLLSDXMLParsingObject::test<2>() + { + // test handling of unrecognized or unparseable llsd values + LLSD v; + v["amy"] = 23; + v["bob"] = LLSD(); + v["cam"] = 1.23; + + ensureParse( + "unknown data type", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<key>bob</key><bigint>99999999999999999</bigint>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + } + + template<> template<> + void TestLLSDXMLParsingObject::test<3>() + { + // test handling of nested bad data + + LLSD v; + v["amy"] = 23; + v["cam"] = 1.23; + + ensureParse( + "map with html", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<html><body>ha ha</body></html>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + + v.clear(); + v["amy"] = 23; + v["cam"] = 1.23; + ensureParse( + "map with value for key", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<string>ha ha</string>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + + v.clear(); + v["amy"] = 23; + v["bob"] = LLSD::emptyMap(); + v["cam"] = 1.23; + ensureParse( + "map with map of html", + "<llsd><map>" + "<key>amy</key><integer>23</integer>" + "<key>bob</key>" + "<map>" + "<html><body>ha ha</body></html>" + "</map>" + "<key>cam</key><real>1.23</real>" + "</map></llsd>", + v, + v.size() + 1); + + v.clear(); + v[0] = 23; + v[1] = LLSD(); + v[2] = 1.23; + + ensureParse( + "array value of html", + "<llsd><array>" + "<integer>23</integer>" + "<html><body>ha ha</body></html>" + "<real>1.23</real>" + "</array></llsd>", + v, + v.size() + 1); + + v.clear(); + v[0] = 23; + v[1] = LLSD::emptyMap(); + v[2] = 1.23; + ensureParse( + "array with map of html", + "<llsd><array>" + "<integer>23</integer>" + "<map>" + "<html><body>ha ha</body></html>" + "</map>" + "<real>1.23</real>" + "</array></llsd>", + v, + v.size() + 1); + } + + template<> template<> + void TestLLSDXMLParsingObject::test<4>() + { + // test handling of binary object in XML + std::string xml; + LLSD expected; + + // Generated by: echo -n 'hello' | openssl enc -e -base64 + expected = string_to_vector("hello"); + xml = "<llsd><binary encoding=\"base64\">aGVsbG8=</binary></llsd>\n"; + ensureParse( + "the word 'hello' packed in binary encoded base64", + xml, + expected, + 1); + + expected = string_to_vector("6|6|asdfhappybox|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|00000000-0000-0000-0000-000000000000|7fffffff|7fffffff|0|0|82000|450fe394-2904-c9ad-214c-a07eb7feec29|(No Description)|0|10|0"); + xml = "<llsd><binary encoding=\"base64\">Nnw2fGFzZGZoYXBweWJveHw2MGU0NGVjNS0zMDVjLTQzYzItOWExOS1iNGI4OWIxYWUyYTZ8NjBlNDRlYzUtMzA1Yy00M2MyLTlhMTktYjRiODliMWFlMmE2fDYwZTQ0ZWM1LTMwNWMtNDNjMi05YTE5LWI0Yjg5YjFhZTJhNnwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDB8N2ZmZmZmZmZ8N2ZmZmZmZmZ8MHwwfDgyMDAwfDQ1MGZlMzk0LTI5MDQtYzlhZC0yMTRjLWEwN2ViN2ZlZWMyOXwoTm8gRGVzY3JpcHRpb24pfDB8MTB8MA==</binary></llsd>\n"; + ensureParse( + "a common binary blob for object -> agent offline inv transfer", + xml, + expected, + 1); + + expected = string_to_vector("6|6|asdfhappybox|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|60e44ec5-305c-43c2-9a19-b4b89b1ae2a6|00000000-0000-0000-0000-000000000000|7fffffff|7fffffff|0|0|82000|450fe394-2904-c9ad-214c-a07eb7feec29|(No Description)|0|10|0"); + xml = "<llsd><binary encoding=\"base64\">Nnw2fGFzZGZoYXBweWJveHw2MGU0NGVjNS0zMDVjLTQzYzItOWExOS1iNGI4OWIxYWUyYTZ8NjBl\n"; + xml += "NDRlYzUtMzA1Yy00M2MyLTlhMTktYjRiODliMWFlMmE2fDYwZTQ0ZWM1LTMwNWMtNDNjMi05YTE5\n"; + xml += "LWI0Yjg5YjFhZTJhNnwwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDB8N2ZmZmZm\n"; + xml += "ZmZ8N2ZmZmZmZmZ8MHwwfDgyMDAwfDQ1MGZlMzk0LTI5MDQtYzlhZC0yMTRjLWEwN2ViN2ZlZWMy\n"; + xml += "OXwoTm8gRGVzY3JpcHRpb24pfDB8MTB8MA==</binary></llsd>\n"; + ensureParse( + "a common binary blob for object -> agent offline inv transfer", + xml, + expected, + 1); + } + /* + TODO: + test XML parsing + binary with unrecognized encoding + nested LLSD tags + multiple values inside an LLSD + */ + + + /** + * @class TestLLSDNotationParsing + * @brief Concrete instance of a parse tester. + */ + class TestLLSDNotationParsing : public TestLLSDParsing<LLSDNotationParser> + { + public: + TestLLSDNotationParsing() {} + }; + + typedef tut::test_group<TestLLSDNotationParsing> TestLLSDNotationParsingGroup; + typedef TestLLSDNotationParsingGroup::object TestLLSDNotationParsingObject; + TestLLSDNotationParsingGroup gTestLLSDNotationParsingGroup( + "llsd notation parsing"); + + template<> template<> + void TestLLSDNotationParsingObject::test<1>() + { + // test handling of xml not recognized as llsd results in an + // LLSD Undefined + ensureParse( + "malformed notation map", + "{'ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed notation array", + "['ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed notation string", + "'ha ha", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "bad notation noise", + "g48ejlnfr", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<2>() + { + ensureParse("valid undef", "!", LLSD(), 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<3>() + { + LLSD val = false; + ensureParse("valid boolean false 0", "false", val, 1); + ensureParse("valid boolean false 1", "f", val, 1); + ensureParse("valid boolean false 2", "0", val, 1); + ensureParse("valid boolean false 3", "F", val, 1); + ensureParse("valid boolean false 4", "FALSE", val, 1); + val = true; + ensureParse("valid boolean true 0", "true", val, 1); + ensureParse("valid boolean true 1", "t", val, 1); + ensureParse("valid boolean true 2", "1", val, 1); + ensureParse("valid boolean true 3", "T", val, 1); + ensureParse("valid boolean true 4", "TRUE", val, 1); + + val.clear(); + ensureParse("invalid true", "TR", val, LLSDParser::PARSE_FAILURE); + ensureParse("invalid false", "FAL", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<4>() + { + LLSD val = 123; + ensureParse("valid integer", "i123", val, 1); + val.clear(); + ensureParse("invalid integer", "421", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<5>() + { + LLSD val = 456.7; + ensureParse("valid real", "r456.7", val, 1); + val.clear(); + ensureParse("invalid real", "456.7", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<6>() + { + LLUUID id; + LLSD val = id; + ensureParse( + "unparseable uuid", + "u123", + LLSD(), + LLSDParser::PARSE_FAILURE); + id.generate(); + val = id; + std::string uuid_str("u"); + uuid_str += id.asString(); + ensureParse("valid uuid", uuid_str.c_str(), val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<7>() + { + LLSD val = std::string("foolish"); + ensureParse("valid string 1", "\"foolish\"", val, 1); + val = std::string("g'day"); + ensureParse("valid string 2", "\"g'day\"", val, 1); + val = std::string("have a \"nice\" day"); + ensureParse("valid string 3", "'have a \"nice\" day'", val, 1); + val = std::string("whatever"); + ensureParse("valid string 4", "s(8)\"whatever\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<8>() + { + ensureParse( + "invalid string 1", + "s(7)\"whatever\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "invalid string 2", + "s(9)\"whatever\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<9>() + { + LLSD val = LLURI("http://www.google.com"); + ensureParse("valid uri", "l\"http://www.google.com\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<10>() + { + LLSD val = LLDate("2007-12-28T09:22:53.10Z"); + ensureParse("valid date", "d\"2007-12-28T09:22:53.10Z\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<11>() + { + std::vector<U8> vec; + vec.push_back((U8)'a'); vec.push_back((U8)'b'); vec.push_back((U8)'c'); + vec.push_back((U8)'3'); vec.push_back((U8)'2'); vec.push_back((U8)'1'); + LLSD val = vec; + ensureParse("valid binary b64", "b64\"YWJjMzIx\"", val, 1); + ensureParse("valid bainry b16", "b16\"616263333231\"", val, 1); + ensureParse("valid bainry raw", "b(6)\"abc321\"", val, 1); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<12>() + { + ensureParse( + "invalid -- binary length specified too long", + "b(7)\"abc321\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "invalid -- binary length specified way too long", + "b(1000000)\"abc321\"", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<13>() + { + LLSD val; + val["amy"] = 23; + val["bob"] = LLSD(); + val["cam"] = 1.23; + ensureParse("simple map", "{'amy':i23,'bob':!,'cam':r1.23}", val, 4); + + val["bob"] = LLSD::emptyMap(); + val["bob"]["vehicle"] = std::string("bicycle"); + ensureParse( + "nested map", + "{'amy':i23,'bob':{'vehicle':'bicycle'},'cam':r1.23}", + val, + 5); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<14>() + { + LLSD val; + val.append(23); + val.append(LLSD()); + val.append(1.23); + ensureParse("simple array", "[i23,!,r1.23]", val, 4); + val[1] = LLSD::emptyArray(); + val[1].append("bicycle"); + ensureParse("nested array", "[i23,['bicycle'],r1.23]", val, 5); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<15>() + { + LLSD val; + val["amy"] = 23; + val["bob"]["dogs"] = LLSD::emptyArray(); + val["bob"]["dogs"].append(LLSD::emptyMap()); + val["bob"]["dogs"][0]["name"] = std::string("groove"); + val["bob"]["dogs"][0]["breed"] = std::string("samoyed"); + val["bob"]["dogs"].append(LLSD::emptyMap()); + val["bob"]["dogs"][1]["name"] = std::string("greyley"); + val["bob"]["dogs"][1]["breed"] = std::string("chow/husky"); + val["cam"] = 1.23; + ensureParse( + "nested notation", + "{'amy':i23," + " 'bob':{'dogs':[" + "{'name':'groove', 'breed':'samoyed'}," + "{'name':'greyley', 'breed':'chow/husky'}]}," + " 'cam':r1.23}", + val, + 11); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<16>() + { + // text to make sure that incorrect sizes bail because + std::string bad_str("s(5)\"hi\""); + ensureParse( + "size longer than bytes left", + bad_str, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDNotationParsingObject::test<17>() + { + // text to make sure that incorrect sizes bail because + std::string bad_bin("b(5)\"hi\""); + ensureParse( + "size longer than bytes left", + bad_bin, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + /** + * @class TestLLSDBinaryParsing + * @brief Concrete instance of a parse tester. + */ + class TestLLSDBinaryParsing : public TestLLSDParsing<LLSDBinaryParser> + { + public: + TestLLSDBinaryParsing() {} + }; + + typedef tut::test_group<TestLLSDBinaryParsing> TestLLSDBinaryParsingGroup; + typedef TestLLSDBinaryParsingGroup::object TestLLSDBinaryParsingObject; + TestLLSDBinaryParsingGroup gTestLLSDBinaryParsingGroup( + "llsd binary parsing"); + + template<> template<> + void TestLLSDBinaryParsingObject::test<1>() + { + std::vector<U8> vec; + vec.resize(6); + vec[0] = 'a'; vec[1] = 'b'; vec[2] = 'c'; + vec[3] = '3'; vec[4] = '2'; vec[5] = '1'; + std::string string_expected((char*)&vec[0], vec.size()); + LLSD value = string_expected; + + vec.resize(11); + vec[0] = 's'; // for string + vec[5] = 'a'; vec[6] = 'b'; vec[7] = 'c'; + vec[8] = '3'; vec[9] = '2'; vec[10] = '1'; + + uint32_t size = htonl(6); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse("correct string parse", str_good, value, 1); + + size = htonl(7); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size string parse", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + size = htonl(100000); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size string parse", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<2>() + { + std::vector<U8> vec; + vec.resize(6); + vec[0] = 'a'; vec[1] = 'b'; vec[2] = 'c'; + vec[3] = '3'; vec[4] = '2'; vec[5] = '1'; + LLSD value = vec; + + vec.resize(11); + vec[0] = 'b'; // for binary + vec[5] = 'a'; vec[6] = 'b'; vec[7] = 'c'; + vec[8] = '3'; vec[9] = '2'; vec[10] = '1'; + + uint32_t size = htonl(6); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse("correct binary parse", str_good, value, 1); + + size = htonl(7); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size binary parse 1", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + size = htonl(100000); + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "incorrect size binary parse 2", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<3>() + { + // test handling of xml not recognized as llsd results in an + // LLSD Undefined + ensureParse( + "malformed binary map", + "{'ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed binary array", + "['ha ha'", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "malformed binary string", + "'ha ha", + LLSD(), + LLSDParser::PARSE_FAILURE); + ensureParse( + "bad noise", + "g48ejlnfr", + LLSD(), + LLSDParser::PARSE_FAILURE); + } + template<> template<> + void TestLLSDBinaryParsingObject::test<4>() + { + ensureParse("valid undef", "!", LLSD(), 1); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<5>() + { + LLSD val = false; + ensureParse("valid boolean false 2", "0", val, 1); + val = true; + ensureParse("valid boolean true 2", "1", val, 1); + + val.clear(); + ensureParse("invalid true", "t", val, LLSDParser::PARSE_FAILURE); + ensureParse("invalid false", "f", val, LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<6>() + { + std::vector<U8> vec; + vec.push_back('{'); + vec.resize(vec.size() + 4); + uint32_t size = htonl(1); + memcpy(&vec[1], &size, sizeof(uint32_t)); + vec.push_back('k'); + int key_size_loc = vec.size(); + size = htonl(1); // 1 too short + vec.resize(vec.size() + 4); + memcpy(&vec[key_size_loc], &size, sizeof(uint32_t)); + vec.push_back('a'); vec.push_back('m'); vec.push_back('y'); + vec.push_back('i'); + int integer_loc = vec.size(); + vec.resize(vec.size() + 4); + uint32_t val_int = htonl(23); + memcpy(&vec[integer_loc], &val_int, sizeof(uint32_t)); + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "invalid key size", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check with correct size, but unterminated map (missing '}') + size = htonl(3); // correct size + memcpy(&vec[key_size_loc], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "valid key size, unterminated map", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check w/ correct size and correct map termination + LLSD val; + val["amy"] = 23; + vec.push_back('}'); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse( + "valid map", + str_good, + val, + 2); + + // check w/ incorrect sizes and correct map termination + size = htonl(0); // 1 too few (for the map entry) + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_3((char*)&vec[0], vec.size()); + ensureParse( + "invalid map too long", + str_bad_3, + LLSD(), + LLSDParser::PARSE_FAILURE); + + size = htonl(2); // 1 too many + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_4((char*)&vec[0], vec.size()); + ensureParse( + "invalid map too short", + str_bad_4, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<7>() + { + std::vector<U8> vec; + vec.push_back('['); + vec.resize(vec.size() + 4); + uint32_t size = htonl(1); // 1 too short + memcpy(&vec[1], &size, sizeof(uint32_t)); + vec.push_back('"'); vec.push_back('a'); vec.push_back('m'); + vec.push_back('y'); vec.push_back('"'); vec.push_back('i'); + int integer_loc = vec.size(); + vec.resize(vec.size() + 4); + uint32_t val_int = htonl(23); + memcpy(&vec[integer_loc], &val_int, sizeof(uint32_t)); + + std::string str_bad_1((char*)&vec[0], vec.size()); + ensureParse( + "invalid array size", + str_bad_1, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check with correct size, but unterminated map (missing ']') + size = htonl(2); // correct size + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_2((char*)&vec[0], vec.size()); + ensureParse( + "unterminated array", + str_bad_2, + LLSD(), + LLSDParser::PARSE_FAILURE); + + // check w/ correct size and correct map termination + LLSD val; + val.append("amy"); + val.append(23); + vec.push_back(']'); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse( + "valid array", + str_good, + val, + 3); + + // check with too many elements + size = htonl(3); // 1 too long + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_bad_3((char*)&vec[0], vec.size()); + ensureParse( + "array too short", + str_bad_3, + LLSD(), + LLSDParser::PARSE_FAILURE); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<8>() + { + std::vector<U8> vec; + vec.push_back('{'); + vec.resize(vec.size() + 4); + memset(&vec[1], 0, 4); + vec.push_back('}'); + std::string str_good((char*)&vec[0], vec.size()); + LLSD val = LLSD::emptyMap(); + ensureParse( + "empty map", + str_good, + val, + 1); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<9>() + { + std::vector<U8> vec; + vec.push_back('['); + vec.resize(vec.size() + 4); + memset(&vec[1], 0, 4); + vec.push_back(']'); + std::string str_good((char*)&vec[0], vec.size()); + LLSD val = LLSD::emptyArray(); + ensureParse( + "empty array", + str_good, + val, + 1); + } + + template<> template<> + void TestLLSDBinaryParsingObject::test<10>() + { + std::vector<U8> vec; + vec.push_back('l'); + vec.resize(vec.size() + 4); + uint32_t size = htonl(14); // 1 too long + memcpy(&vec[1], &size, sizeof(uint32_t)); + vec.push_back('h'); vec.push_back('t'); vec.push_back('t'); + vec.push_back('p'); vec.push_back(':'); vec.push_back('/'); + vec.push_back('/'); vec.push_back('s'); vec.push_back('l'); + vec.push_back('.'); vec.push_back('c'); vec.push_back('o'); + vec.push_back('m'); + std::string str_bad((char*)&vec[0], vec.size()); + ensureParse( + "invalid uri length size", + str_bad, + LLSD(), + LLSDParser::PARSE_FAILURE); + + LLSD val; + val = LLURI("http://sl.com"); + size = htonl(13); // correct length + memcpy(&vec[1], &size, sizeof(uint32_t)); + std::string str_good((char*)&vec[0], vec.size()); + ensureParse( + "valid key size", + str_good, + val, + 1); + } + +/* + template<> template<> + void TestLLSDBinaryParsingObject::test<11>() + { + } +*/ + + /** + * @class TestLLSDCrossCompatible + * @brief Miscellaneous serialization and parsing tests + */ + class TestLLSDCrossCompatible + { + public: + TestLLSDCrossCompatible() {} + + void ensureBinaryAndNotation( + const std::string& msg, + const LLSD& input) + { + // to binary, and back again + std::stringstream str1; + S32 count1 = LLSDSerialize::toBinary(input, str1); + LLSD actual_value_bin; + S32 count2 = LLSDSerialize::fromBinary( + actual_value_bin, + str1, + LLSDSerialize::SIZE_UNLIMITED); + ensure_equals( + "ensureBinaryAndNotation binary count", + count2, + count1); + + // to notation and back again + std::stringstream str2; + S32 count3 = LLSDSerialize::toNotation(actual_value_bin, str2); + ensure_equals( + "ensureBinaryAndNotation notation count1", + count3, + count2); + LLSD actual_value_notation; + S32 count4 = LLSDSerialize::fromNotation( + actual_value_notation, + str2, + LLSDSerialize::SIZE_UNLIMITED); + ensure_equals( + "ensureBinaryAndNotation notation count2", + count4, + count3); + ensure_equals( + (msg + " (binaryandnotation)").c_str(), + actual_value_notation, + input); + } + + void ensureBinaryAndXML( + const std::string& msg, + const LLSD& input) + { + // to binary, and back again + std::stringstream str1; + S32 count1 = LLSDSerialize::toBinary(input, str1); + LLSD actual_value_bin; + S32 count2 = LLSDSerialize::fromBinary( + actual_value_bin, + str1, + LLSDSerialize::SIZE_UNLIMITED); + ensure_equals( + "ensureBinaryAndXML binary count", + count2, + count1); + + // to xml and back again + std::stringstream str2; + S32 count3 = LLSDSerialize::toXML(actual_value_bin, str2); + ensure_equals( + "ensureBinaryAndXML xml count1", + count3, + count2); + LLSD actual_value_xml; + S32 count4 = LLSDSerialize::fromXML(actual_value_xml, str2); + ensure_equals( + "ensureBinaryAndXML xml count2", + count4, + count3); + ensure_equals((msg + " (binaryandxml)").c_str(), actual_value_xml, input); + } + }; + + typedef tut::test_group<TestLLSDCrossCompatible> TestLLSDCompatibleGroup; + typedef TestLLSDCompatibleGroup::object TestLLSDCompatibleObject; + TestLLSDCompatibleGroup gTestLLSDCompatibleGroup( + "llsd serialize compatible"); + + template<> template<> + void TestLLSDCompatibleObject::test<1>() + { + LLSD test; + ensureBinaryAndNotation("undef", test); + ensureBinaryAndXML("undef", test); + test = true; + ensureBinaryAndNotation("boolean true", test); + ensureBinaryAndXML("boolean true", test); + test = false; + ensureBinaryAndNotation("boolean false", test); + ensureBinaryAndXML("boolean false", test); + test = 0; + ensureBinaryAndNotation("integer zero", test); + ensureBinaryAndXML("integer zero", test); + test = 1; + ensureBinaryAndNotation("integer positive", test); + ensureBinaryAndXML("integer positive", test); + test = -234567; + ensureBinaryAndNotation("integer negative", test); + ensureBinaryAndXML("integer negative", test); + test = 0.0; + ensureBinaryAndNotation("real zero", test); + ensureBinaryAndXML("real zero", test); + test = 1.0; + ensureBinaryAndNotation("real positive", test); + ensureBinaryAndXML("real positive", test); + test = -1.0; + ensureBinaryAndNotation("real negative", test); + ensureBinaryAndXML("real negative", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<2>() + { + LLSD test; + test = "foobar"; + ensureBinaryAndNotation("string", test); + ensureBinaryAndXML("string", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<3>() + { + LLSD test; + LLUUID id; + id.generate(); + test = id; + ensureBinaryAndNotation("uuid", test); + ensureBinaryAndXML("uuid", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<4>() + { + LLSD test; + test = LLDate(12345.0); + ensureBinaryAndNotation("date", test); + ensureBinaryAndXML("date", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<5>() + { + LLSD test; + test = LLURI("http://www.secondlife.com/"); + ensureBinaryAndNotation("uri", test); + ensureBinaryAndXML("uri", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<6>() + { + LLSD test; + typedef std::vector<U8> buf_t; + buf_t val; + for(int ii = 0; ii < 100; ++ii) + { + srand(ii); /* Flawfinder: ignore */ + S32 size = rand() % 100 + 10; + std::generate_n( + std::back_insert_iterator<buf_t>(val), + size, + rand); + } + test = val; + ensureBinaryAndNotation("binary", test); + ensureBinaryAndXML("binary", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<7>() + { + LLSD test; + test = LLSD::emptyArray(); + test.append(1); + test.append("hello"); + ensureBinaryAndNotation("array", test); + ensureBinaryAndXML("array", test); + } + + template<> template<> + void TestLLSDCompatibleObject::test<8>() + { + LLSD test; + test = LLSD::emptyArray(); + test["foo"] = "bar"; + test["baz"] = 100; + ensureBinaryAndNotation("map", test); + ensureBinaryAndXML("map", test); + } +} + diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp new file mode 100644 index 0000000000..6a2ebc61f5 --- /dev/null +++ b/indra/llcommon/tests/llstring_test.cpp @@ -0,0 +1,750 @@ +/** + * @file llstring_test.cpp + * @author Adroit, Steve Linden, Tofu Linden + * @date 2006-12-24 + * @brief Test cases of llstring.cpp + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "../test/lltut.h" + +#include "../llstring.h" + +namespace tut +{ + struct string_index + { + }; + typedef test_group<string_index> string_index_t; + typedef string_index_t::object string_index_object_t; + tut::string_index_t tut_string_index("string_test"); + + template<> template<> + void string_index_object_t::test<1>() + { + std::string llstr1; + ensure("Empty std::string", (llstr1.size() == 0) && llstr1.empty()); + + std::string llstr2("Hello"); + ensure("std::string = Hello", (!strcmp(llstr2.c_str(), "Hello")) && (llstr2.size() == 5) && !llstr2.empty()); + + std::string llstr3(llstr2); + ensure("std::string = std::string(std::string)", (!strcmp(llstr3.c_str(), "Hello")) && (llstr3.size() == 5) && !llstr3.empty()); + + std::string str("Hello World"); + std::string llstr4(str, 6); + ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (!strcmp(llstr4.c_str(), "World")) && (llstr4.size() == 5) && !llstr4.empty()); + + std::string llstr5(str, str.size()); + ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (llstr5.size() == 0) && llstr5.empty()); + + std::string llstr6(5, 'A'); + ensure("std::string = std::string(count, c)", (!strcmp(llstr6.c_str(), "AAAAA")) && (llstr6.size() == 5) && !llstr6.empty()); + + std::string llstr7("Hello World", 5); + ensure("std::string(s, n)", (!strcmp(llstr7.c_str(), "Hello")) && (llstr7.size() == 5) && !llstr7.empty()); + + std::string llstr8("Hello World", 6, 5); + ensure("std::string(s, n, count)", (!strcmp(llstr8.c_str(), "World")) && (llstr8.size() == 5) && !llstr8.empty()); + + std::string llstr9("Hello World", sizeof("Hello World")-1, 5); // go past end + ensure("std::string(s, n, count) goes past end", (llstr9.size() == 0) && llstr9.empty()); + } + + template<> template<> + void string_index_object_t::test<3>() + { + std::string str("Len=5"); + ensure("isValidIndex failed", LLStringUtil::isValidIndex(str, 0) == TRUE && + LLStringUtil::isValidIndex(str, 5) == TRUE && + LLStringUtil::isValidIndex(str, 6) == FALSE); + + std::string str1; + ensure("isValidIndex failed fo rempty string", LLStringUtil::isValidIndex(str1, 0) == FALSE); + } + + template<> template<> + void string_index_object_t::test<4>() + { + std::string str_val(" Testing the extra whitespaces "); + LLStringUtil::trimHead(str_val); + ensure_equals("1: trimHead failed", str_val, "Testing the extra whitespaces "); + + std::string str_val1("\n\t\r\n Testing the extra whitespaces "); + LLStringUtil::trimHead(str_val1); + ensure_equals("2: trimHead failed", str_val1, "Testing the extra whitespaces "); + } + + template<> template<> + void string_index_object_t::test<5>() + { + std::string str_val(" Testing the extra whitespaces "); + LLStringUtil::trimTail(str_val); + ensure_equals("1: trimTail failed", str_val, " Testing the extra whitespaces"); + + std::string str_val1("\n Testing the extra whitespaces \n\t\r\n "); + LLStringUtil::trimTail(str_val1); + ensure_equals("2: trimTail failed", str_val1, "\n Testing the extra whitespaces"); + } + + + template<> template<> + void string_index_object_t::test<6>() + { + std::string str_val(" \t \r Testing the extra \r\n whitespaces \n \t "); + LLStringUtil::trim(str_val); + ensure_equals("1: trim failed", str_val, "Testing the extra \r\n whitespaces"); + } + + template<> template<> + void string_index_object_t::test<7>() + { + std::string str("Second LindenLabs"); + LLStringUtil::truncate(str, 6); + ensure_equals("1: truncate", str, "Second"); + + // further truncate more than the length + LLStringUtil::truncate(str, 0); + ensure_equals("2: truncate", str, ""); + } + + template<> template<> + void string_index_object_t::test<8>() + { + std::string str_val("SecondLife Source"); + LLStringUtil::toUpper(str_val); + ensure_equals("toUpper failed", str_val, "SECONDLIFE SOURCE"); + } + + template<> template<> + void string_index_object_t::test<9>() + { + std::string str_val("SecondLife Source"); + LLStringUtil::toLower(str_val); + ensure_equals("toLower failed", str_val, "secondlife source"); + } + + template<> template<> + void string_index_object_t::test<10>() + { + std::string str_val("Second"); + ensure("1. isHead failed", LLStringUtil::isHead(str_val, "SecondLife Source") == TRUE); + ensure("2. isHead failed", LLStringUtil::isHead(str_val, " SecondLife Source") == FALSE); + std::string str_val2(""); + ensure("3. isHead failed", LLStringUtil::isHead(str_val2, "") == FALSE); + } + + template<> template<> + void string_index_object_t::test<11>() + { + std::string str_val("Hello.\n\n Lindenlabs. \n This is \na simple test.\n"); + std::string orig_str_val(str_val); + LLStringUtil::addCRLF(str_val); + ensure_equals("addCRLF failed", str_val, "Hello.\r\n\r\n Lindenlabs. \r\n This is \r\na simple test.\r\n"); + LLStringUtil::removeCRLF(str_val); + ensure_equals("removeCRLF failed", str_val, orig_str_val); + } + + template<> template<> + void string_index_object_t::test<12>() + { + std::string str_val("Hello.\n\n\t \t Lindenlabs. \t\t"); + std::string orig_str_val(str_val); + LLStringUtil::replaceTabsWithSpaces(str_val, 1); + ensure_equals("replaceTabsWithSpaces failed", str_val, "Hello.\n\n Lindenlabs. "); + LLStringUtil::replaceTabsWithSpaces(orig_str_val, 0); + ensure_equals("replaceTabsWithSpaces failed for 0", orig_str_val, "Hello.\n\n Lindenlabs. "); + + str_val = "\t\t\t\t"; + LLStringUtil::replaceTabsWithSpaces(str_val, 0); + ensure_equals("replaceTabsWithSpaces failed for all tabs", str_val, ""); + } + + template<> template<> + void string_index_object_t::test<13>() + { + std::string str_val("Hello.\n\n\t\t\r\nLindenlabsX."); + LLStringUtil::replaceNonstandardASCII(str_val, 'X'); + ensure_equals("replaceNonstandardASCII failed", str_val, "Hello.\n\nXXX\nLindenlabsX."); + } + + template<> template<> + void string_index_object_t::test<14>() + { + std::string str_val("Hello.\n\t\r\nABCDEFGHIABABAB"); + LLStringUtil::replaceChar(str_val, 'A', 'X'); + ensure_equals("1: replaceChar failed", str_val, "Hello.\n\t\r\nXBCDEFGHIXBXBXB"); + std::string str_val1("Hello.\n\t\r\nABCDEFGHIABABAB"); + } + + template<> template<> + void string_index_object_t::test<15>() + { + std::string str_val("Hello.\n\r\t"); + ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == TRUE); + + str_val = "ABC "; + ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == FALSE); + } + + template<> template<> + void string_index_object_t::test<16>() + { + std::string str_val("Hello.\n\r\t Again!"); + LLStringUtil::stripNonprintable(str_val); + ensure_equals("stripNonprintable failed", str_val, "Hello. Again!"); + + str_val = "\r\n\t\t"; + LLStringUtil::stripNonprintable(str_val); + ensure_equals("stripNonprintable resulting in empty string failed", str_val, ""); + + str_val = ""; + LLStringUtil::stripNonprintable(str_val); + ensure_equals("stripNonprintable of empty string resulting in empty string failed", str_val, ""); + } + + template<> template<> + void string_index_object_t::test<17>() + { + BOOL value; + std::string str_val("1"); + ensure("convertToBOOL 1 failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "T"; + ensure("convertToBOOL T failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "t"; + ensure("convertToBOOL t failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "TRUE"; + ensure("convertToBOOL TRUE failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "True"; + ensure("convertToBOOL True failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "true"; + ensure("convertToBOOL true failed", LLStringUtil::convertToBOOL(str_val, value) && value); + + str_val = "0"; + ensure("convertToBOOL 0 failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "F"; + ensure("convertToBOOL F failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "f"; + ensure("convertToBOOL f failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "FALSE"; + ensure("convertToBOOL FASLE failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "False"; + ensure("convertToBOOL False failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "false"; + ensure("convertToBOOL false failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + + str_val = "Tblah"; + ensure("convertToBOOL false failed", !LLStringUtil::convertToBOOL(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<18>() + { + U8 value; + std::string str_val("255"); + ensure("1: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 255); + + str_val = "0"; + ensure("2: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 0); + + str_val = "-1"; + ensure("3: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value)); + + str_val = "256"; // bigger than MAX_U8 + ensure("4: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<19>() + { + S8 value; + std::string str_val("127"); + ensure("1: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 127); + + str_val = "0"; + ensure("2: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 0); + + str_val = "-128"; + ensure("3: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == -128); + + str_val = "128"; // bigger than MAX_S8 + ensure("4: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value)); + + str_val = "-129"; + ensure("5: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<20>() + { + S16 value; + std::string str_val("32767"); + ensure("1: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 32767); + + str_val = "0"; + ensure("2: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 0); + + str_val = "-32768"; + ensure("3: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == -32768); + + str_val = "32768"; + ensure("4: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value)); + + str_val = "-32769"; + ensure("5: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<21>() + { + U16 value; + std::string str_val("65535"); //0xFFFF + ensure("1: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 65535); + + str_val = "0"; + ensure("2: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 0); + + str_val = "-1"; + ensure("3: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value)); + + str_val = "65536"; + ensure("4: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<22>() + { + U32 value; + std::string str_val("4294967295"); //0xFFFFFFFF + ensure("1: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 4294967295UL); + + str_val = "0"; + ensure("2: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 0); + + str_val = "4294967296"; + ensure("3: convertToU32 failed", !LLStringUtil::convertToU32(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<23>() + { + S32 value; + std::string str_val("2147483647"); //0x7FFFFFFF + ensure("1: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 2147483647); + + str_val = "0"; + ensure("2: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 0); + + // Avoid "unary minus operator applied to unsigned type" warning on VC++. JC + S32 min_val = -2147483647 - 1; + str_val = "-2147483648"; + ensure("3: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == min_val); + + str_val = "2147483648"; + ensure("4: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value)); + + str_val = "-2147483649"; + ensure("5: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<24>() + { + F32 value; + std::string str_val("2147483647"); //0x7FFFFFFF + ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647); + + str_val = "0"; + ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0); + + /* Need to find max/min F32 values + str_val = "-2147483648"; + ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648); + + str_val = "2147483648"; + ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + + str_val = "-2147483649"; + ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + */ + } + + template<> template<> + void string_index_object_t::test<25>() + { + F64 value; + std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF + ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL); + + str_val = "0"; + ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F); + + /* Need to find max/min F64 values + str_val = "-2147483648"; + ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648); + + str_val = "2147483648"; + ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + + str_val = "-2147483649"; + ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + */ + } + + template<> template<> + void string_index_object_t::test<26>() + { + const char* str1 = NULL; + const char* str2 = NULL; + + ensure("1: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0); + str2 = "A"; + ensure("2: compareStrings failed", LLStringUtil::compareStrings(str1, str2) > 0); + ensure("3: compareStrings failed", LLStringUtil::compareStrings(str2, str1) < 0); + + str1 = "A is smaller than B"; + str2 = "B is greater than A"; + ensure("4: compareStrings failed", LLStringUtil::compareStrings(str1, str2) < 0); + + str2 = "A is smaller than B"; + ensure("5: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0); + } + + template<> template<> + void string_index_object_t::test<27>() + { + const char* str1 = NULL; + const char* str2 = NULL; + + ensure("1: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0); + str2 = "A"; + ensure("2: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) > 0); + ensure("3: compareInsensitive failed", LLStringUtil::compareInsensitive(str2, str1) < 0); + + str1 = "A is equal to a"; + str2 = "a is EQUAL to A"; + ensure("4: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0); + } + + template<> template<> + void string_index_object_t::test<28>() + { + std::string lhs_str("PROgraM12files"); + std::string rhs_str("PROgram12Files"); + ensure("compareDict 1 failed", LLStringUtil::compareDict(lhs_str, rhs_str) < 0); + ensure("precedesDict 1 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == TRUE); + + lhs_str = "PROgram12Files"; + rhs_str = "PROgram12Files"; + ensure("compareDict 2 failed", LLStringUtil::compareDict(lhs_str, rhs_str) == 0); + ensure("precedesDict 2 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == FALSE); + + lhs_str = "PROgram12Files"; + rhs_str = "PROgRAM12FILES"; + ensure("compareDict 3 failed", LLStringUtil::compareDict(lhs_str, rhs_str) > 0); + ensure("precedesDict 3 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == FALSE); + } + + template<> template<> + void string_index_object_t::test<29>() + { + char str1[] = "First String..."; + char str2[100]; + + LLStringUtil::copy(str2, str1, 100); + ensure("LLStringUtil::copy with enough dest length failed", strcmp(str2, str1) == 0); + LLStringUtil::copy(str2, str1, sizeof("First")); + ensure("LLStringUtil::copy with less dest length failed", strcmp(str2, "First") == 0); + } + + template<> template<> + void string_index_object_t::test<30>() + { + std::string str1 = "This is the sentence..."; + std::string str2 = "This is the "; + std::string str3 = "first "; + std::string str4 = "This is the first sentence..."; + std::string str5 = "This is the sentence...first "; + std::string dest; + + dest = str1; + LLStringUtil::copyInto(dest, str3, str2.length()); + ensure("LLStringUtil::copyInto insert failed", dest == str4); + + dest = str1; + LLStringUtil::copyInto(dest, str3, dest.length()); + ensure("LLStringUtil::copyInto append failed", dest == str5); + } + + template<> template<> + void string_index_object_t::test<31>() + { + std::string stripped; + + // Plain US ASCII text, including spaces and punctuation, + // should not be altered. + std::string simple_text = "Hello, world!"; + stripped = LLStringFn::strip_invalid_xml(simple_text); + ensure("Simple text passed unchanged", stripped == simple_text); + + // Control characters should be removed + // except for 0x09, 0x0a, 0x0d + std::string control_chars; + for (char c = 0x01; c < 0x20; c++) + { + control_chars.push_back(c); + } + std::string allowed_control_chars; + allowed_control_chars.push_back( (char)0x09 ); + allowed_control_chars.push_back( (char)0x0a ); + allowed_control_chars.push_back( (char)0x0d ); + + stripped = LLStringFn::strip_invalid_xml(control_chars); + ensure("Only tab, LF, CR control characters allowed", + stripped == allowed_control_chars); + + // UTF-8 should be passed intact, including high byte + // characters. Try Francais (with C squiggle cedilla) + std::string french = "Fran"; + french.push_back( (char)0xC3 ); + french.push_back( (char)0xA7 ); + french += "ais"; + stripped = LLStringFn::strip_invalid_xml( french ); + ensure("UTF-8 high byte text is allowed", french == stripped ); + } + + template<> template<> + void string_index_object_t::test<32>() + { + // Test LLStringUtil::format() string interpolation + LLStringUtil::format_map_t fmt_map; + std::string s; + int subcount; + + fmt_map["[TRICK1]"] = "[A]"; + fmt_map["[A]"] = "a"; + fmt_map["[B]"] = "b"; + fmt_map["[AAA]"] = "aaa"; + fmt_map["[BBB]"] = "bbb"; + fmt_map["[TRICK2]"] = "[A]"; + fmt_map["[EXPLOIT]"] = "!!!!!!!!!!!![EXPLOIT]!!!!!!!!!!!!"; + fmt_map["[KEYLONGER]"] = "short"; + fmt_map["[KEYSHORTER]"] = "Am I not a long string?"; + fmt_map["?"] = "?"; + fmt_map["[DELETE]"] = ""; + fmt_map["[]"] = "[]"; // doesn't do a substitution, but shouldn't crash either + + for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter) + { + // Test when source string is entirely one key + std::string s1 = (std::string)iter->first; + std::string s2 = (std::string)iter->second; + subcount = LLStringUtil::format(s1, fmt_map); + ensure_equals("LLStringUtil::format: Raw interpolation result", s1, s2); + if (s1 == "?" || s1 == "[]") // no interp expected + { + ensure_equals("LLStringUtil::format: Raw interpolation result count", 0, subcount); + } + else + { + ensure_equals("LLStringUtil::format: Raw interpolation result count", 1, subcount); + } + } + + for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter) + { + // Test when source string is one key, duplicated + std::string s1 = (std::string)iter->first; + std::string s2 = (std::string)iter->second; + s = s1 + s1 + s1 + s1; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Rawx4 interpolation result", s, s2 + s2 + s2 + s2); + if (s1 == "?" || s1 == "[]") // no interp expected + { + ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 0, subcount); + } + else + { + ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 4, subcount); + } + } + + // Test when source string has no keys + std::string srcs = "!!!!!!!!!!!!!!!!"; + s = srcs; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: No key test result", s, srcs); + ensure_equals("LLStringUtil::format: No key test result count", 0, subcount); + + // Test when source string has no keys and is empty + std::string srcs3; + s = srcs3; + subcount = LLStringUtil::format(s, fmt_map); + ensure("LLStringUtil::format: No key test3 result", s.empty()); + ensure_equals("LLStringUtil::format: No key test3 result count", 0, subcount); + + // Test a substitution where a key is substituted with blankness + std::string srcs2 = "[DELETE]"; + s = srcs2; + subcount = LLStringUtil::format(s, fmt_map); + ensure("LLStringUtil::format: Delete key test2 result", s.empty()); + ensure_equals("LLStringUtil::format: Delete key test2 result count", 1, subcount); + + // Test an assorted substitution + std::string srcs4 = "[TRICK1][A][B][AAA][BBB][TRICK2][KEYLONGER][KEYSHORTER]?[DELETE]"; + s = srcs4; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Assorted Test1 result", s, "[A]abaaabbb[A]shortAm I not a long string??"); + ensure_equals("LLStringUtil::format: Assorted Test1 result count", 9, subcount); + + // Test an assorted substitution + std::string srcs5 = "[DELETE]?[KEYSHORTER][KEYLONGER][TRICK2][BBB][AAA][B][A][TRICK1]"; + s = srcs5; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "?Am I not a long string?short[A]bbbaaaba[A]"); + ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount); + + // Test an assorted substitution + std::string srcs8 = "foo[DELETE]bar?"; + s = srcs8; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Assorted Test3 result", s, "foobar?"); + ensure_equals("LLStringUtil::format: Assorted Test3 result count", 1, subcount); + } + + template<> template<> + void string_index_object_t::test<33>() + { + // Test LLStringUtil::format() string interpolation + LLStringUtil::format_map_t blank_fmt_map; + std::string s; + int subcount; + + // Test substituting out of a blank format_map + std::string srcs6 = "12345"; + s = srcs6; + subcount = LLStringUtil::format(s, blank_fmt_map); + ensure_equals("LLStringUtil::format: Blankfmt Test1 result", s, "12345"); + ensure_equals("LLStringUtil::format: Blankfmt Test1 result count", 0, subcount); + + // Test substituting a blank string out of a blank format_map + std::string srcs7; + s = srcs7; + subcount = LLStringUtil::format(s, blank_fmt_map); + ensure("LLStringUtil::format: Blankfmt Test2 result", s.empty()); + ensure_equals("LLStringUtil::format: Blankfmt Test2 result count", 0, subcount); + } + + template<> template<> + void string_index_object_t::test<34>() + { + // Test that incorrect LLStringUtil::format() use does not explode. + LLStringUtil::format_map_t nasty_fmt_map; + std::string s; + int subcount; + + nasty_fmt_map[""] = "never used"; // see, this is nasty. + + // Test substituting out of a nasty format_map + std::string srcs6 = "12345"; + s = srcs6; + subcount = LLStringUtil::format(s, nasty_fmt_map); + ensure_equals("LLStringUtil::format: Nastyfmt Test1 result", s, "12345"); + ensure_equals("LLStringUtil::format: Nastyfmt Test1 result count", 0, subcount); + + // Test substituting a blank string out of a nasty format_map + std::string srcs7; + s = srcs7; + subcount = LLStringUtil::format(s, nasty_fmt_map); + ensure("LLStringUtil::format: Nastyfmt Test2 result", s.empty()); + ensure_equals("LLStringUtil::format: Nastyfmt Test2 result count", 0, subcount); + } + + template<> template<> + void string_index_object_t::test<35>() + { + // Make sure startsWith works + std::string string("anybody in there?"); + std::string substr("anybody"); + ensure("startsWith works.", LLStringUtil::startsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<36>() + { + // Make sure startsWith correctly fails + std::string string("anybody in there?"); + std::string substr("there"); + ensure("startsWith fails.", !LLStringUtil::startsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<37>() + { + // startsWith fails on empty strings + std::string value("anybody in there?"); + std::string empty; + ensure("empty string.", !LLStringUtil::startsWith(value, empty)); + ensure("empty substr.", !LLStringUtil::startsWith(empty, value)); + ensure("empty everything.", !LLStringUtil::startsWith(empty, empty)); + } + + template<> template<> + void string_index_object_t::test<38>() + { + // Make sure endsWith works correctly + std::string string("anybody in there?"); + std::string substr("there?"); + ensure("endsWith works.", LLStringUtil::endsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<39>() + { + // Make sure endsWith correctly fails + std::string string("anybody in there?"); + std::string substr("anybody"); + ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr)); + substr = "there"; + ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr)); + substr = "ther?"; + ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<40>() + { + // endsWith fails on empty strings + std::string value("anybody in there?"); + std::string empty; + ensure("empty string.", !LLStringUtil::endsWith(value, empty)); + ensure("empty substr.", !LLStringUtil::endsWith(empty, value)); + ensure("empty everything.", !LLStringUtil::endsWith(empty, empty)); + } +} diff --git a/indra/llcommon/tests/lltreeiterators_test.cpp b/indra/llcommon/tests/lltreeiterators_test.cpp new file mode 100644 index 0000000000..d6d9f68110 --- /dev/null +++ b/indra/llcommon/tests/lltreeiterators_test.cpp @@ -0,0 +1,1222 @@ +/** + * @file lltreeiterators.cpp + * @author Nat Goodspeed + * @date 2008-08-20 + * @brief Test of lltreeiterators.h + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +// Precompiled header +#include "linden_common.h" + +#if LL_WINDOWS +#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored +#endif + +// STL headers +// std headers +#include <iostream> +#include <sstream> +#include <string> +// external library headers +#include <boost/bind.hpp> +#include <boost/range/iterator_range.hpp> +#include <boost/foreach.hpp> + +// associated header +#include "../lltreeiterators.h" +#include "../llpointer.h" + +#include "../test/lltut.h" + +/***************************************************************************** +* tut test group +*****************************************************************************/ +namespace tut +{ + struct iter_data + { + }; + typedef test_group<iter_data> iter_group; + typedef iter_group::object iter_object; + tut::iter_group ig("lltreeiterators"); +} // namespace tut + +/***************************************************************************** +* boost::get_pointer() specialization for LLPointer<> +*****************************************************************************/ +// This specialization of boost::get_pointer() undoubtedly belongs in +// llmemory.h. It's used by boost::bind() so that you can pass an +// LLPointer<Foo> as well as a Foo* to a functor such as +// boost::bind(&Foo::method, _1). +//namespace boost +//{ + template <class NODE> + NODE* get_pointer(const LLPointer<NODE>& ptr) { return ptr.get(); } +//}; + +/***************************************************************************** +* ScopeLabel +*****************************************************************************/ +class ScopeLabel +{ +public: + ScopeLabel(const std::string& label): mLabel(label) + { + std::cout << "Entering " << mLabel << '\n'; + } + ~ScopeLabel() + { + std::cout << "Leaving " << mLabel << '\n'; + } +private: + std::string mLabel; +}; + +/***************************************************************************** +* Cleanup +*****************************************************************************/ +// Yes, we realize this is redundant with auto_ptr and LLPointer and all +// kinds of better mechanisms. But in this particular source file, we need to +// test nodes managed with plain old dumb pointers as well as nodes managed +// with LLPointer, so we introduce this mechanism. +// +// In the general case, when we declare a Cleanup for some pointer, delete the +// pointer when the Cleanup goes out of scope. +template <typename PTRTYPE> +struct Cleanup +{ + Cleanup(const PTRTYPE& ptr): mPtr(ptr) {} + ~Cleanup() + { + delete mPtr; + } + PTRTYPE mPtr; +}; + +// But when the pointer is an LLPointer<something>, Cleanup is a no-op: +// LLPointer will handle the cleanup automagically. +template <typename NODE> +struct Cleanup< LLPointer<NODE> > +{ + Cleanup(const LLPointer<NODE>& ptr) {} + ~Cleanup() {} +}; + +/***************************************************************************** +* Expected +*****************************************************************************/ +// Expected is a base class used to capture the expected results -- a sequence +// of string node names -- from one of our traversals of this example data. +// Its subclasses initialize it with a pair of string iterators. It's not +// strictly necessary to customize Expected to model Boost.Range, it's just +// convenient. +struct Expected +{ + template <typename ITER> + Expected(ITER begin, ITER end): + strings(begin, end) + {} + /*------ The following are to make Expected work with Boost.Range ------*/ + typedef std::vector<std::string> container_type; + typedef container_type::iterator iterator; + typedef container_type::const_iterator const_iterator; + typedef container_type::size_type size_type; + container_type strings; + iterator begin() { return strings.begin(); } + iterator end() { return strings.end(); } + size_type size() { return strings.size(); } + const_iterator begin() const { return strings.begin(); } + const_iterator end() const { return strings.end(); } +}; + +// We have a couple of generic Expected template subclasses. This list of +// strings is used for the "else" case when all specializations fail. +const char* bad_strings[] = { "FAIL" }; + +/***************************************************************************** +* verify() +*****************************************************************************/ +// test function: given (an object modeling) a Boost.Range of tree nodes, +// compare the sequence of visited node names with a range of expected name +// strings. Report success both with std::cout output and a bool return. The +// string desc parameter is to identify the different tests. +template <typename NODERANGE, typename STRINGRANGE> +bool verify(const std::string& desc, NODERANGE noderange, STRINGRANGE expected) +{ + typename boost::range_iterator<NODERANGE>::type + nri = boost::begin(noderange), + nrend = boost::end(noderange); + typename boost::range_iterator<STRINGRANGE>::type + sri = boost::begin(expected), + srend = boost::end(expected); + // We choose to loop over both sequences explicitly rather than using + // std::equal() or std::lexicographical_compare(). The latter tells you + // whether one sequence is *less* than the other -- it doesn't tell you + // equality. std::equal() needs you to verify the sequence lengths ahead + // of time. Anyway, comparing explicitly allows us to report much more + // information about any sequence mismatch. + for ( ; nri != nrend && sri != srend; ++nri, ++sri) + { + if ((*nri)->name() != *sri) + { + std::cout << desc << " mismatch: " + << "expected " << *sri << ", got " << (*nri)->name() << "\n"; + return false; + } + } + if (nri != nrend) + { + std::cout << desc << " produced too many items:\n"; + for ( ; nri != nrend; ++nri) + { + std::cout << " " << (*nri)->name() << '\n'; + } + return false; + } + if (sri != srend) + { + std::cout << desc << " produced too few items, omitting:\n"; + for ( ; sri != srend; ++sri) + { + std::cout << " " << *sri << '\n'; + } + return false; + } +// std::cout << desc << " test passed\n"; + return true; +} + +/***************************************************************************** +* PlainNode: LLLinkIter, non-refcounted +*****************************************************************************/ +class PlainNode +{ +public: + PlainNode(const std::string& name, PlainNode* next=NULL): + mName(name), + mNext(next) + {} + ~PlainNode() + { + delete mNext; + } + std::string name() const { return mName; } + PlainNode* next() const { return mNext; } +public: // if this were 'private', couldn't bind mNext + PlainNode* mNext; +private: + std::string mName; +}; + +namespace tut +{ + template<> template<> + void iter_object::test<1>() + { +// set_test_name("LLLinkedIter -- non-refcounted class"); + PlainNode* last(new PlainNode("c")); + PlainNode* second(new PlainNode("b", last)); + PlainNode* first(new PlainNode("a", second)); + Cleanup<PlainNode*> cleanup(first); + static const char* cseq[] = { "a", "b", "c" }; + Expected seq(boost::begin(cseq), boost::end(cseq)); + std::string desc1("Iterate by public link member"); +// std::cout << desc1 << ":\n"; + // Try instantiating an iterator with NULL. This test is less about + // "did we iterate once?" than "did we avoid blowing up?" + for (LLLinkedIter<PlainNode> pni(NULL, boost::bind(&PlainNode::mNext, _1)), end; + pni != end; ++pni) + { +// std::cout << (*pni)->name() << '\n'; + ensure("LLLinkedIter<PlainNode>(NULL)", false); + } + ensure(desc1, + verify(desc1, + boost::make_iterator_range(LLLinkedIter<PlainNode>(first, + boost::bind(&PlainNode::mNext, _1)), + LLLinkedIter<PlainNode>()), + seq)); + std::string desc2("Iterate by next() method"); +// std::cout << desc2 << ":\n"; +// for (LLLinkedIter<PlainNode> pni(first, boost::bind(&PlainNode::next, _1)); ! (pni == end); ++pni) +// std::cout << (**pni).name() << '\n'; + ensure(desc2, + verify(desc2, + boost::make_iterator_range(LLLinkedIter<PlainNode>(first, + boost::bind(&PlainNode::next, _1)), + LLLinkedIter<PlainNode>()), + seq)); + { +// LLLinkedIter<PlainNode> pni(first, boost::bind(&PlainNode::next, _1)); +// std::cout << "First is " << (*pni++)->name() << '\n'; +// std::cout << "Second is " << (*pni )->name() << '\n'; + } + { + LLLinkedIter<PlainNode> pni(first, boost::bind(&PlainNode::next, _1)); + ensure_equals("first", (*pni++)->name(), "a"); + ensure_equals("second", (*pni )->name(), "b"); + } + } +} // tut + +/***************************************************************************** +* RCNode: LLLinkIter, refcounted +*****************************************************************************/ +class RCNode; +typedef LLPointer<RCNode> RCNodePtr; + +class RCNode: public LLRefCount +{ +public: + RCNode(const std::string& name, const RCNodePtr& next=RCNodePtr()): + mName(name), + mNext(next) + { +// std::cout << "New RCNode(" << mName << ")\n"; + } + RCNode(const RCNode& that): + mName(that.mName), + mNext(that.mNext) + { +// std::cout << "Copy RCNode(" << mName << ")\n"; + } + virtual ~RCNode(); + std::string name() const { return mName; } + RCNodePtr next() const { return mNext; } +public: // if this were 'private', couldn't bind mNext + RCNodePtr mNext; +private: + std::string mName; +}; + +std::ostream& operator<<(std::ostream& out, const RCNode& node) +{ + out << "RCNode(" << node.name() << ')'; + return out; +} + +// This string contains the node name of the last RCNode destroyed. We use it +// to validate that LLLinkedIter<RCNode> in fact contains LLPointer<RCNode>, +// and that therefore an outstanding LLLinkedIter to an instance of a +// refcounted class suffices to keep that instance alive. +std::string last_RCNode_destroyed; + +RCNode::~RCNode() +{ +// std::cout << "Kill " << *this << "\n"; + last_RCNode_destroyed = mName; +} + +namespace tut +{ + template<> template<> + void iter_object::test<2>() + { +// set_test_name("LLLinkedIter -- refcounted class"); + LLLinkedIter<RCNode> rcni, end2; + { +// ScopeLabel label("inner scope"); + RCNodePtr head(new RCNode("x", new RCNode("y", new RCNode("z")))); +// for (rcni = LLLinkedIter<RCNode>(head, boost::bind(&RCNode::mNext, _1)); rcni != end2; ++rcni) +// std::cout << **rcni << '\n'; + rcni = LLLinkedIter<RCNode>(head, boost::bind(&RCNode::next, _1)); + } +// std::cout << "Now the LLLinkedIter<RCNode> is the only remaining reference to RCNode chain\n"; + ensure_equals(last_RCNode_destroyed, ""); + ensure(rcni != end2); + ensure_equals((*rcni)->name(), "x"); + ++rcni; + ensure_equals(last_RCNode_destroyed, "x"); + ensure(rcni != end2); + ensure_equals((*rcni)->name(), "y"); + ++rcni; + ensure_equals(last_RCNode_destroyed, "y"); + ensure(rcni != end2); + ensure_equals((*rcni)->name(), "z"); + ++rcni; + ensure_equals(last_RCNode_destroyed, "z"); + ensure(rcni == end2); + } +} + +/***************************************************************************** +* TreeNode +*****************************************************************************/ +class TreeNode; +typedef LLPointer<TreeNode> TreeNodePtr; + +/** + * TreeNode represents a refcounted tree-node class that hasn't (yet) been + * modified to incorporate LLTreeIter methods. This illustrates how you can + * use tree iterators either standalone, or with free functions. + */ +class TreeNode: public LLRefCount +{ +public: + typedef std::vector<TreeNodePtr> list_type; + typedef list_type::const_iterator child_iterator; + + // To avoid cycles, use a "weak" raw pointer for the parent link + TreeNode(const std::string& name, TreeNode* parent=0): + mParent(parent), + mName(name) + {} + TreeNodePtr newChild(const std::string& name) + { + TreeNodePtr child(new TreeNode(name, this)); + mChildren.push_back(child); + return child; + } + std::string name() const { return mName; } + TreeNodePtr getParent() const { return mParent; } + child_iterator child_begin() const { return mChildren.begin(); } + child_iterator child_end() const { return mChildren.end(); } +private: + std::string mName; + // To avoid cycles, use a "weak" raw pointer for the parent link + TreeNode* mParent; + list_type mChildren; +}; + +/** + * This is an example of a helper function to facilitate iterating from a + * TreeNode up to the root or down from the root (see LLTreeIter::RootIter). + * + * Example: + * @code + * BOOST_FOREACH(TreeNodePtr node, getRootRange<LLTreeIter::UP>(somenode)) + * { + * std::cout << node->name() << '\n'; + * } + * @endcode + */ +template <LLTreeIter::RootIter DISCRIM> +boost::iterator_range< LLTreeRootIter<DISCRIM, TreeNode> > +getRootRange(const TreeNodePtr& node) +{ + typedef LLTreeRootIter<DISCRIM, TreeNode> iter_type; + typedef boost::iterator_range<iter_type> range_type; + return range_type(iter_type(node, boost::bind(&TreeNode::getParent, _1)), + iter_type()); +} + +/** + * This is an example of a helper function to facilitate walking a given + * TreeNode's subtree in any supported order (see LLTreeIter::WalkIter). + * + * Example: + * @code + * BOOST_FOREACH(TreeNodePtr node, getWalkRange<LLTreeIter::DFS_PRE>(root)) + * { + * std::cout << node->name() << '\n'; + * } + * @endcode + */ +template <LLTreeIter::WalkIter DISCRIM> +boost::iterator_range< LLTreeWalkIter<DISCRIM, TreeNode, TreeNode::child_iterator> > +getWalkRange(const TreeNodePtr& node) +{ + typedef LLTreeWalkIter<DISCRIM, TreeNode, TreeNode::child_iterator> iter_type; + typedef boost::iterator_range<iter_type> range_type; + return range_type(iter_type(node, + boost::bind(&TreeNode::child_begin, _1), + boost::bind(&TreeNode::child_end, _1)), + iter_type()); +} + +/***************************************************************************** +* EnhancedTreeNode +*****************************************************************************/ +class EnhancedTreeNode; +typedef LLPointer<EnhancedTreeNode> EnhancedTreeNodePtr; + +/** + * More typically, you enhance the tree-node class itself with template + * methods like the above. This EnhancedTreeNode class illustrates the + * technique. Normally, of course, you'd simply add these methods to TreeNode; + * we put them in a separate class to preserve the undecorated TreeNode class + * to illustrate (and test) the use of plain tree iterators and standalone + * helper functions. + * + * We originally implemented EnhancedTreeNode as a subclass of TreeNode -- but + * because TreeNode stores and manipulates TreeNodePtrs and TreeNode*s, + * reusing its methods required so much ugly downcast logic that we gave up + * and restated the whole class. Bear in mind that logically these aren't two + * separate classes; logically they're two snapshots of the @em same class at + * different moments in time. + */ +class EnhancedTreeNode: public LLRefCount +{ +public: + /*-------------- The following is restated from TreeNode ---------------*/ + typedef std::vector<EnhancedTreeNodePtr> list_type; + typedef list_type::const_iterator child_iterator; + + // To avoid cycles, use a "weak" raw pointer for the parent link + EnhancedTreeNode(const std::string& name, EnhancedTreeNode* parent=0): + mParent(parent), + mName(name) + {} + EnhancedTreeNodePtr newChild(const std::string& name) + { + EnhancedTreeNodePtr child(new EnhancedTreeNode(name, this)); + mChildren.push_back(child); + return child; + } + std::string name() const { return mName; } + EnhancedTreeNodePtr getParent() const { return mParent; } + child_iterator child_begin() const { return mChildren.begin(); } + child_iterator child_end() const { return mChildren.end(); } + +private: + std::string mName; + // To avoid cycles, use a "weak" raw pointer for the parent link + EnhancedTreeNode* mParent; + list_type mChildren; +public: + /*----- End of TreeNode; what follows is new with EnhancedTreeNode -----*/ + + /** + * Because the type of the iterator range returned by getRootRange() + * depends on the discriminator enum value, instead of a simple typedef we + * use a templated struct. Example usage: + * + * @code + * for (EnhancedTreeNode::root_range<LLTreeIter::UP>::type range = + * somenode->getRootRange<LLTreeIter::UP>(); + * range.first != range.second; ++range.first) + * { + * std::cout << (*range.first)->name() << '\n'; + * } + * @endcode + */ + template <LLTreeIter::RootIter DISCRIM> + struct root_range + { + typedef boost::iterator_range< LLTreeRootIter<DISCRIM, EnhancedTreeNode> > type; + }; + + /** + * Helper method for walking up to (or down from) the tree root. See + * LLTreeIter::RootIter. + * + * Example usage: + * @code + * BOOST_FOREACH(EnhancedTreeNodePtr node, somenode->getRootRange<LLTreeIter::UP>()) + * { + * std::cout << node->name() << '\n'; + * } + * @endcode + */ + template <LLTreeIter::RootIter DISCRIM> + typename root_range<DISCRIM>::type getRootRange() const + { + typedef typename root_range<DISCRIM>::type range_type; + typedef typename range_type::iterator iter_type; + return range_type(iter_type(const_cast<EnhancedTreeNode*>(this), + boost::bind(&EnhancedTreeNode::getParent, _1)), + iter_type()); + } + + /** + * Because the type of the iterator range returned by getWalkRange() + * depends on the discriminator enum value, instead of a simple typedef we + * use a templated stuct. Example usage: + * + * @code + * for (EnhancedTreeNode::walk_range<LLTreeIter::DFS_PRE>::type range = + * somenode->getWalkRange<LLTreeIter::DFS_PRE>(); + * range.first != range.second; ++range.first) + * { + * std::cout << (*range.first)->name() << '\n'; + * } + * @endcode + */ + template <LLTreeIter::WalkIter DISCRIM> + struct walk_range + { + typedef boost::iterator_range< LLTreeWalkIter<DISCRIM, + EnhancedTreeNode, + EnhancedTreeNode::child_iterator> > type; + }; + + /** + * Helper method for walking a given node's subtree in any supported + * order (see LLTreeIter::WalkIter). + * + * Example usage: + * @code + * BOOST_FOREACH(EnhancedTreeNodePtr node, somenode->getWalkRange<LLTreeIter::DFS_PRE>()) + * { + * std::cout << node->name() << '\n'; + * } + * @endcode + */ + template <LLTreeIter::WalkIter DISCRIM> + typename walk_range<DISCRIM>::type getWalkRange() const + { + typedef typename walk_range<DISCRIM>::type range_type; + typedef typename range_type::iterator iter_type; + return range_type(iter_type(const_cast<EnhancedTreeNode*>(this), + boost::bind(&EnhancedTreeNode::child_begin, _1), + boost::bind(&EnhancedTreeNode::child_end, _1)), + iter_type()); + } +}; + +/***************************************************************************** +* PlainTree +*****************************************************************************/ +struct PlainTree +{ + PlainTree(const std::string& name, PlainTree* parent=0): + mName(name), + mParent(parent), + mNextSibling(0), + mFirstChild(0) + { + mLastChildLink = &mFirstChild; + } + ~PlainTree() + { + delete mNextSibling; + delete mFirstChild; + } + PlainTree* newChild(const std::string& name) + { + PlainTree* child(new PlainTree(name, this)); + *mLastChildLink = child; + mLastChildLink = &child->mNextSibling; + return child; + } + std::string name() const { return mName; } + + std::string mName; + PlainTree* mParent; + PlainTree* mNextSibling; + PlainTree* mFirstChild; + PlainTree** mLastChildLink; +}; + +// This "classic" tree tracks each node's children with a linked list anchored +// at the parent's mFirstChild and linked through each child's mNextSibling. +// LLTreeDFSIter<> and LLTreeBFSIter<> need functors to return begin()/end() +// iterators over a given node's children. But because this tree's children +// aren't stored in an STL container, we can't just export that container's +// begin()/end(). Instead we'll use LLLinkedIter<> to view the hand-maintained +// linked list as an iterator range. The straightforward way to do that would +// be to add child_begin() and child_end() methods. But let's say (for the +// sake of argument) that this struct is so venerable we don't dare modify it +// even to add new methods. Well, we can use free functions (or functors) too. +LLLinkedIter<PlainTree> PlainTree_child_begin(PlainTree* node) +{ + return LLLinkedIter<PlainTree>(node->mFirstChild, boost::bind(&PlainTree::mNextSibling, _1)); +} + +LLLinkedIter<PlainTree> PlainTree_child_end(PlainTree* node) +{ + return LLLinkedIter<PlainTree>(); +} + +/** + * This is an example of a helper function to facilitate iterating from a + * PlainTree up to the root or down from the root (see LLTreeIter::RootIter). + * Note that we're simply overloading the same getRootRange() helper function + * name we used for TreeNode. + * + * Example: + * @code + * BOOST_FOREACH(PlainTree* node, getRootRange<LLTreeIter::UP>(somenode)) + * { + * std::cout << node->name() << '\n'; + * } + * @endcode + */ +template <LLTreeIter::RootIter DISCRIM> +boost::iterator_range< LLTreeRootIter<DISCRIM, PlainTree> > +getRootRange(PlainTree* node) +{ + typedef LLTreeRootIter<DISCRIM, PlainTree> iter_type; + typedef boost::iterator_range<iter_type> range_type; + return range_type(iter_type(node, boost::bind(&PlainTree::mParent, _1)), + iter_type()); +} + +/** + * This is an example of a helper function to facilitate walking a given + * PlainTree's subtree in any supported order (see LLTreeIter::WalkIter). Note + * that we're simply overloading the same getWalkRange() helper function name + * we used for TreeNode. + * + * Example: + * @code + * BOOST_FOREACH(PlainTree* node, getWalkRange<LLTreeIter::DFS_PRE>(root)) + * { + * std::cout << node->name() << '\n'; + * } + * @endcode + */ +template <LLTreeIter::WalkIter DISCRIM> +boost::iterator_range< LLTreeWalkIter<DISCRIM, PlainTree, LLLinkedIter<PlainTree> > > +getWalkRange(PlainTree* node) +{ + typedef LLTreeWalkIter<DISCRIM, PlainTree, LLLinkedIter<PlainTree> > iter_type; + typedef boost::iterator_range<iter_type> range_type; + return range_type(iter_type(node, + PlainTree_child_begin, + PlainTree_child_end), + iter_type()); +} + +// We could go through the exercise of writing EnhancedPlainTree containing +// root_range, getRootRange(), walk_range and getWalkRange() members -- but we +// won't. See EnhancedTreeNode for examples. + +/***************************************************************************** +* Generic tree test data +*****************************************************************************/ +template <class NODE> +typename LLPtrTo<NODE>::type example_tree() +{ + typedef typename LLPtrTo<NODE>::type NodePtr; + NodePtr root(new NODE("root")); + NodePtr A(root->newChild("A")); + NodePtr A1(A->newChild("A1")); +/* NodePtr A1a*/(A1->newChild("A1a")); +/* NodePtr A1b*/(A1->newChild("A1b")); +/* NodePtr A1c*/(A1->newChild("A1c")); + NodePtr A2(A->newChild("A2")); +/* NodePtr A2a*/(A2->newChild("A2a")); +/* NodePtr A2b*/(A2->newChild("A2b")); +/* NodePtr A2c*/(A2->newChild("A2c")); + NodePtr A3(A->newChild("A3")); +/* NodePtr A3a*/(A3->newChild("A3a")); +/* NodePtr A3b*/(A3->newChild("A3b")); +/* NodePtr A3c*/(A3->newChild("A3c")); + NodePtr B(root->newChild("B")); + NodePtr B1(B->newChild("B1")); +/* NodePtr B1a*/(B1->newChild("B1a")); +/* NodePtr B1b*/(B1->newChild("B1b")); +/* NodePtr B1c*/(B1->newChild("B1c")); + NodePtr B2(B->newChild("B2")); +/* NodePtr B2a*/(B2->newChild("B2a")); +/* NodePtr B2b*/(B2->newChild("B2b")); +/* NodePtr B2c*/(B2->newChild("B2c")); + NodePtr B3(B->newChild("B3")); +/* NodePtr B3a*/(B3->newChild("B3a")); +/* NodePtr B3b*/(B3->newChild("B3b")); +/* NodePtr B3c*/(B3->newChild("B3c")); + NodePtr C(root->newChild("C")); + NodePtr C1(C->newChild("C1")); +/* NodePtr C1a*/(C1->newChild("C1a")); +/* NodePtr C1b*/(C1->newChild("C1b")); +/* NodePtr C1c*/(C1->newChild("C1c")); + NodePtr C2(C->newChild("C2")); +/* NodePtr C2a*/(C2->newChild("C2a")); +/* NodePtr C2b*/(C2->newChild("C2b")); +/* NodePtr C2c*/(C2->newChild("C2c")); + NodePtr C3(C->newChild("C3")); +/* NodePtr C3a*/(C3->newChild("C3a")); +/* NodePtr C3b*/(C3->newChild("C3b")); +/* NodePtr C3c*/(C3->newChild("C3c")); + return root; +} + +// WalkExpected<WalkIter> is the list of string node names we expect from a +// WalkIter traversal of our example_tree() data. +template <LLTreeIter::WalkIter DISCRIM> +struct WalkExpected: public Expected +{ + // Initialize with bad_strings: we don't expect to use this generic case, + // only the specializations. Note that for a classic C-style array we must + // pass a pair of iterators rather than extracting boost::begin() and + // boost::end() within the target constructor: a template ctor accepts + // these classic C-style arrays as char** rather than char*[length]. Oh well. + WalkExpected(): Expected(boost::begin(bad_strings), boost::end(bad_strings)) {} +}; + +// list of string node names we expect from traversing example_tree() in +// DFS_PRE order +const char* dfs_pre_strings[] = +{ + "root", + "A", + "A1", + "A1a", + "A1b", + "A1c", + "A2", + "A2a", + "A2b", + "A2c", + "A3", + "A3a", + "A3b", + "A3c", + "B", + "B1", + "B1a", + "B1b", + "B1c", + "B2", + "B2a", + "B2b", + "B2c", + "B3", + "B3a", + "B3b", + "B3c", + "C", + "C1", + "C1a", + "C1b", + "C1c", + "C2", + "C2a", + "C2b", + "C2c", + "C3", + "C3a", + "C3b", + "C3c" +}; + +// specialize WalkExpected<DFS_PRE> with the expected strings +template <> +struct WalkExpected<LLTreeIter::DFS_PRE>: public Expected +{ + WalkExpected(): Expected(boost::begin(dfs_pre_strings), boost::end(dfs_pre_strings)) {} +}; + +// list of string node names we expect from traversing example_tree() in +// DFS_POST order +const char* dfs_post_strings[] = +{ + "A1a", + "A1b", + "A1c", + "A1", + "A2a", + "A2b", + "A2c", + "A2", + "A3a", + "A3b", + "A3c", + "A3", + "A", + "B1a", + "B1b", + "B1c", + "B1", + "B2a", + "B2b", + "B2c", + "B2", + "B3a", + "B3b", + "B3c", + "B3", + "B", + "C1a", + "C1b", + "C1c", + "C1", + "C2a", + "C2b", + "C2c", + "C2", + "C3a", + "C3b", + "C3c", + "C3", + "C", + "root" +}; + +// specialize WalkExpected<DFS_POST> with the expected strings +template <> +struct WalkExpected<LLTreeIter::DFS_POST>: public Expected +{ + WalkExpected(): Expected(boost::begin(dfs_post_strings), boost::end(dfs_post_strings)) {} +}; + +// list of string node names we expect from traversing example_tree() in BFS order +const char* bfs_strings[] = +{ + "root", + "A", + "B", + "C", + "A1", + "A2", + "A3", + "B1", + "B2", + "B3", + "C1", + "C2", + "C3", + "A1a", + "A1b", + "A1c", + "A2a", + "A2b", + "A2c", + "A3a", + "A3b", + "A3c", + "B1a", + "B1b", + "B1c", + "B2a", + "B2b", + "B2c", + "B3a", + "B3b", + "B3c", + "C1a", + "C1b", + "C1c", + "C2a", + "C2b", + "C2c", + "C3a", + "C3b", + "C3c" +}; + +// specialize WalkExpected<BFS> with the expected strings +template <> +struct WalkExpected<LLTreeIter::BFS>: public Expected +{ + WalkExpected(): Expected(boost::begin(bfs_strings), boost::end(bfs_strings)) {} +}; + +// extract a particular "arbitrary" node from the example_tree() data: the +// second (middle) node at each child level +template <class NODE, typename CHILDITER> +typename LLPtrTo<NODE>::type +get_B2b(const typename LLPtrTo<NODE>::type& root, + const boost::function<CHILDITER(const typename LLPtrTo<NODE>::type&)>& child_begin) +{ + typedef typename LLPtrTo<NODE>::type NodePtr; + CHILDITER Bi(child_begin(root)); + ++Bi; + NodePtr B(*Bi); + CHILDITER B2i(child_begin(B)); + ++B2i; + NodePtr B2(*B2i); + CHILDITER B2bi(child_begin(B2)); + ++B2bi; + NodePtr B2b(*B2bi); + return B2b; +} + +// RootExpected<RootIter> is the list of string node names we expect from a +// RootIter traversal of our example_tree() data. +template <LLTreeIter::RootIter DISCRIM> +struct RootExpected: public Expected +{ + // Initialize with bad_strings: we don't expect to use this generic case, + // only the specializations. + RootExpected(): Expected(boost::begin(bad_strings), boost::end(bad_strings)) {} +}; + +// list of string node names we expect from traversing UP from +// example_tree()'s B2b node +const char* up_from_B2b[] = +{ + "B2b", + "B2", + "B", + "root" +}; + +// specialize RootExpected<UP> with the expected strings +template <> +struct RootExpected<LLTreeIter::UP>: public Expected +{ + RootExpected(): Expected(boost::begin(up_from_B2b), boost::end(up_from_B2b)) {} +}; + +// list of string node names we expect from traversing DOWN to +// example_tree()'s B2b node +const char* down_to_B2b[] = +{ + "root", + "B", + "B2", + "B2b" +}; + +// specialize RootExpected<DOWN> with the expected strings +template <> +struct RootExpected<LLTreeIter::DOWN>: public Expected +{ + RootExpected(): Expected(boost::begin(down_to_B2b), boost::end(down_to_B2b)) {} +}; + +/***************************************************************************** +* Generic tree test functions +*****************************************************************************/ +template<LLTreeIter::RootIter DISCRIM, class NODE, typename PARENTFUNC> +bool LLTreeRootIter_test(const std::string& itername, const std::string& nodename, + const typename LLPtrTo<NODE>::type& node, + PARENTFUNC parentfunc) +{ + std::ostringstream desc; + desc << itername << '<' << nodename << "> from " << node->name(); + if (! verify(desc.str(), + boost::make_iterator_range(LLTreeRootIter<DISCRIM, NODE>(node, parentfunc), + LLTreeRootIter<DISCRIM, NODE>()), + RootExpected<DISCRIM>())) + return false; +// std::cout << desc.str() << '\n'; + // Try instantiating an iterator with NULL (that is, a default-constructed + // node pointer). This test is less about "did we iterate once?" than "did + // we avoid blowing up?" + for (LLTreeRootIter<DISCRIM, NODE> hri = LLTreeRootIter<DISCRIM, NODE>(typename LLPtrTo<NODE>::type(), parentfunc), hrend; + hri != hrend; /* ++hri */) // incrementing is moot, and MSVC complains + { +// std::cout << nodename << '(' << (*hri)->name() << ")\n"; + std::cout << itername << '<' << nodename << ">(NULL)\n"; + return false; + } + return true; +} + +template<class NODE, typename CHILDITER, typename PARENTFUNC, typename CHILDFUNC> +bool LLTreeUpIter_test(const std::string& nodename, PARENTFUNC parentfunc, CHILDFUNC childfunc) +{ + bool success = true; + typedef typename LLPtrTo<NODE>::type ptr_type; + ptr_type root(example_tree<NODE>()); + Cleanup<ptr_type> cleanup(root); + ptr_type B2b(get_B2b<NODE, CHILDITER>(root, childfunc)); + if (! LLTreeRootIter_test<LLTreeIter::UP, NODE>("LLTreeUpIter", nodename, B2b, parentfunc)) + success = false; + if (! LLTreeRootIter_test<LLTreeIter::DOWN, NODE>("LLTreeDownIter", nodename, B2b, parentfunc)) + success = false; + return success; +} + +template <LLTreeIter::WalkIter DISCRIM, class NODE, typename CHILDITER, + typename CHILDBEGINFUNC, typename CHILDENDFUNC> +bool LLTreeWalkIter_test(const std::string& itername, const std::string& nodename, + CHILDBEGINFUNC childbegin, CHILDENDFUNC childend) +{ + typename LLPtrTo<NODE>::type root(example_tree<NODE>()); + Cleanup<typename LLPtrTo<NODE>::type> cleanup(root); + std::ostringstream desc; + desc << itername << '<' << nodename << "> from " << root->name(); + if (! verify(desc.str(), + boost::make_iterator_range(LLTreeWalkIter<DISCRIM, NODE, CHILDITER>(root, + childbegin, + childend), + LLTreeWalkIter<DISCRIM, NODE, CHILDITER>()), + WalkExpected<DISCRIM>())) + return false; + // Try instantiating an iterator with NULL (that is, a default-constructed + // node pointer). This test is less about "did we iterate once?" than "did + // we avoid blowing up?" + for (LLTreeWalkIter<DISCRIM, NODE, CHILDITER> twi = LLTreeWalkIter<DISCRIM, NODE, CHILDITER>(typename LLPtrTo<NODE>::type(), + childbegin, + childend), + twend; + twi != twend; /* ++twi */) // incrementing is moot, and MSVC complains + { + std::cout << itername << '<' << nodename << ">(NULL)\n"; + return false; + } + return true; +} + +template <class NODE, typename CHILDITER, + typename PARENTFUNC, typename CHILDBEGINFUNC, typename CHILDENDFUNC> +bool LLTreeIter_tests(const std::string& nodename, + PARENTFUNC parentfunc, CHILDBEGINFUNC childbegin, CHILDENDFUNC childend) +{ + bool success = true; + if (! LLTreeUpIter_test<NODE, CHILDITER>(nodename, parentfunc, childbegin)) + success = false; +/*==========================================================================*| + LLTreeIter_test<NODE, LLTreeDFSIter<NODE, CHILDITER> >("LLTreeDFSIter", nodename, + childbegin, childend); + LLTreeIter_test<NODE, LLTreeDFSPostIter<NODE, CHILDITER> >("LLTreeDFSPostIter", nodename, + childbegin, childend); + LLTreeIter_test<NODE, LLTreeBFSIter<NODE, CHILDITER> >("LLTreeBFSIter", nodename, + childbegin, childend); +|*==========================================================================*/ + if (! LLTreeWalkIter_test<LLTreeIter::DFS_PRE, NODE, CHILDITER>("LLTreeDFSIter", nodename, + childbegin, childend)) + success = false; + if (! LLTreeWalkIter_test<LLTreeIter::DFS_POST, NODE, CHILDITER>("LLTreeDFSPostIter", nodename, + childbegin, childend)) + success = false; + if (! LLTreeWalkIter_test<LLTreeIter::BFS, NODE, CHILDITER>("LLTreeBFSIter", nodename, + childbegin, childend)) + success = false; + return success; +} + +namespace tut +{ + template<> template<> + void iter_object::test<3>() + { +// set_test_name("LLTreeIter tests"); + ensure(LLTreeIter_tests<TreeNode, TreeNode::child_iterator> + ("TreeNode", + boost::bind(&TreeNode::getParent, _1), + boost::bind(&TreeNode::child_begin, _1), + boost::bind(&TreeNode::child_end, _1))); + ensure(LLTreeIter_tests<PlainTree, LLLinkedIter<PlainTree> > + ("PlainTree", + boost::bind(&PlainTree::mParent, _1), + PlainTree_child_begin, + PlainTree_child_end)); + } + + template<> template<> + void iter_object::test<4>() + { +// set_test_name("getRootRange() tests"); + // This test function illustrates the looping techniques described in the + // comments for the getRootRange() free function, the + // EnhancedTreeNode::root_range template and the + // EnhancedTreeNode::getRootRange() method. Obviously the BOOST_FOREACH() + // forms are more succinct. + TreeNodePtr tnroot(example_tree<TreeNode>()); + TreeNodePtr tnB2b(get_B2b<TreeNode, TreeNode::child_iterator> + (tnroot, boost::bind(&TreeNode::child_begin, _1))); + + std::string desc1("BOOST_FOREACH(TreeNodePr, getRootRange<LLTreeIter::UP>(tnB2b))"); +// std::cout << desc1 << "\n"; + // Although we've commented out the output statement, ensure that the + // loop construct is still valid, as promised by the getRootRange() + // documentation. + BOOST_FOREACH(TreeNodePtr node, getRootRange<LLTreeIter::UP>(tnB2b)) + { +// std::cout << node->name() << '\n'; + } + ensure(desc1, + verify(desc1, getRootRange<LLTreeIter::UP>(tnB2b), RootExpected<LLTreeIter::UP>())); + + EnhancedTreeNodePtr etnroot(example_tree<EnhancedTreeNode>()); + EnhancedTreeNodePtr etnB2b(get_B2b<EnhancedTreeNode, EnhancedTreeNode::child_iterator> + (etnroot, boost::bind(&EnhancedTreeNode::child_begin, _1))); + +// std::cout << "EnhancedTreeNode::root_range<LLTreeIter::DOWN>::type range =\n" +// << " etnB2b->getRootRange<LLTreeIter::DOWN>();\n" +// << "for (EnhancedTreeNode::root_range<LLTreeIter::DOWN>::type::iterator ri = range.begin();\n" +// << " ri != range.end(); ++ri)\n"; + EnhancedTreeNode::root_range<LLTreeIter::DOWN>::type range = + etnB2b->getRootRange<LLTreeIter::DOWN>(); + for (EnhancedTreeNode::root_range<LLTreeIter::DOWN>::type::iterator ri = range.begin(); + ri != range.end(); ++ri) + { +// std::cout << (*ri)->name() << '\n'; + } + + std::string desc2("BOOST_FOREACH(EnhancedTreeNodePtr node, etnB2b->getRootRange<LLTreeIter::UP>())"); +// std::cout << desc2 << '\n'; + BOOST_FOREACH(EnhancedTreeNodePtr node, etnB2b->getRootRange<LLTreeIter::UP>()) + { +// std::cout << node->name() << '\n'; + } + ensure(desc2, + verify(desc2, etnB2b->getRootRange<LLTreeIter::UP>(), RootExpected<LLTreeIter::UP>())); + } + + template<> template<> + void iter_object::test<5>() + { +// set_test_name("getWalkRange() tests"); + // This test function doesn't illustrate the looping permutations for + // getWalkRange(); see getRootRange_tests() for such examples. This + // function simply verifies that they all work. + + // TreeNode, using helper function + TreeNodePtr tnroot(example_tree<TreeNode>()); + std::string desc_tnpre("getWalkRange<LLTreeIter::DFS_PRE>(tnroot)"); + ensure(desc_tnpre, + verify(desc_tnpre, + getWalkRange<LLTreeIter::DFS_PRE>(tnroot), + WalkExpected<LLTreeIter::DFS_PRE>())); + std::string desc_tnpost("getWalkRange<LLTreeIter::DFS_POST>(tnroot)"); + ensure(desc_tnpost, + verify(desc_tnpost, + getWalkRange<LLTreeIter::DFS_POST>(tnroot), + WalkExpected<LLTreeIter::DFS_POST>())); + std::string desc_tnb("getWalkRange<LLTreeIter::BFS>(tnroot)"); + ensure(desc_tnb, + verify(desc_tnb, + getWalkRange<LLTreeIter::BFS>(tnroot), + WalkExpected<LLTreeIter::BFS>())); + + // EnhancedTreeNode, using method + EnhancedTreeNodePtr etnroot(example_tree<EnhancedTreeNode>()); + std::string desc_etnpre("etnroot->getWalkRange<LLTreeIter::DFS_PRE>()"); + ensure(desc_etnpre, + verify(desc_etnpre, + etnroot->getWalkRange<LLTreeIter::DFS_PRE>(), + WalkExpected<LLTreeIter::DFS_PRE>())); + std::string desc_etnpost("etnroot->getWalkRange<LLTreeIter::DFS_POST>()"); + ensure(desc_etnpost, + verify(desc_etnpost, + etnroot->getWalkRange<LLTreeIter::DFS_POST>(), + WalkExpected<LLTreeIter::DFS_POST>())); + std::string desc_etnb("etnroot->getWalkRange<LLTreeIter::BFS>()"); + ensure(desc_etnb, + verify(desc_etnb, + etnroot->getWalkRange<LLTreeIter::BFS>(), + WalkExpected<LLTreeIter::BFS>())); + + // PlainTree, using helper function + PlainTree* ptroot(example_tree<PlainTree>()); + Cleanup<PlainTree*> cleanup(ptroot); + std::string desc_ptpre("getWalkRange<LLTreeIter::DFS_PRE>(ptroot)"); + ensure(desc_ptpre, + verify(desc_ptpre, + getWalkRange<LLTreeIter::DFS_PRE>(ptroot), + WalkExpected<LLTreeIter::DFS_PRE>())); + std::string desc_ptpost("getWalkRange<LLTreeIter::DFS_POST>(ptroot)"); + ensure(desc_ptpost, + verify(desc_ptpost, + getWalkRange<LLTreeIter::DFS_POST>(ptroot), + WalkExpected<LLTreeIter::DFS_POST>())); + std::string desc_ptb("getWalkRange<LLTreeIter::BFS>(ptroot)"); + ensure(desc_ptb, + verify(desc_ptb, + getWalkRange<LLTreeIter::BFS>(ptroot), + WalkExpected<LLTreeIter::BFS>())); + } +} // tut diff --git a/indra/llcommon/tests/lluri_test.cpp b/indra/llcommon/tests/lluri_test.cpp new file mode 100644 index 0000000000..4e5ad0df58 --- /dev/null +++ b/indra/llcommon/tests/lluri_test.cpp @@ -0,0 +1,370 @@ +/** + * @file lluri_tut.cpp + * @brief LLURI unit tests + * @date September 2006 + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../llsd.h" +#include "../lluri.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct URITestData { + void checkParts(const LLURI& u, + const char* expectedScheme, + const char* expectedOpaque, + const char* expectedAuthority, + const char* expectedPath, + const char* expectedQuery = "") + { + ensure_equals("scheme", u.scheme(), expectedScheme); + ensure_equals("opaque", u.opaque(), expectedOpaque); + ensure_equals("authority", u.authority(), expectedAuthority); + ensure_equals("path", u.path(), expectedPath); + ensure_equals("query", u.query(), expectedQuery); + } + + void escapeRoundTrip(const std::string& uri_raw_1) + { + std::string uri_esc_1(LLURI::escape(uri_raw_1)); + std::string uri_raw_2(LLURI::unescape(uri_esc_1)); + ensure_equals("escape/unescape raw", uri_raw_2, uri_raw_1); + std::string uri_esc_2(LLURI::escape(uri_raw_2)); + ensure_equals("escape/unescape escaped", uri_esc_2, uri_esc_1); + } + }; + + typedef test_group<URITestData> URITestGroup; + typedef URITestGroup::object URITestObject; + + URITestGroup uriTestGroup("LLURI"); + + template<> template<> + void URITestObject::test<1>() + { + LLURI u("http://abc.com/def/ghi?x=37&y=hello"); + + ensure_equals("scheme", u.scheme(), "http"); + ensure_equals("authority", u.authority(), "abc.com"); + ensure_equals("path", u.path(), "/def/ghi"); + ensure_equals("query", u.query(), "x=37&y=hello"); + + ensure_equals("host name", u.hostName(), "abc.com"); + ensure_equals("host port", u.hostPort(), 80); + + LLSD query = u.queryMap(); + ensure_equals("query x", query["x"].asInteger(), 37); + ensure_equals("query y", query["y"].asString(), "hello"); + + query = LLURI::queryMap("x=22.23&y=https://lindenlab.com/"); + ensure_equals("query x", query["x"].asReal(), 22.23); + ensure_equals("query y", query["y"].asURI().asString(), "https://lindenlab.com/"); + } + + template<> template<> + void URITestObject::test<2>() + { + // empty string + checkParts(LLURI(""), "", "", "", ""); + } + + template<> template<> + void URITestObject::test<3>() + { + // no scheme + checkParts(LLURI("foo"), "", "foo", "", ""); + checkParts(LLURI("foo%3A"), "", "foo:", "", ""); + } + + template<> template<> + void URITestObject::test<4>() + { + // scheme w/o paths + checkParts(LLURI("mailto:zero@ll.com"), + "mailto", "zero@ll.com", "", ""); + checkParts(LLURI("silly://abc/def?foo"), + "silly", "//abc/def?foo", "", ""); + } + + template<> template<> + void URITestObject::test<5>() + { + // authority section + checkParts(LLURI("http:///"), + "http", "///", "", "/"); + + checkParts(LLURI("http://abc"), + "http", "//abc", "abc", ""); + + checkParts(LLURI("http://a%2Fb/cd"), + "http", "//a/b/cd", "a/b", "/cd"); + + checkParts(LLURI("http://host?"), + "http", "//host?", "host", ""); + } + + template<> template<> + void URITestObject::test<6>() + { + // path section + checkParts(LLURI("http://host/a/b/"), + "http", "//host/a/b/", "host", "/a/b/"); + + checkParts(LLURI("http://host/a%3Fb/"), + "http", "//host/a?b/", "host", "/a?b/"); + + checkParts(LLURI("http://host/a:b/"), + "http", "//host/a:b/", "host", "/a:b/"); + } + + template<> template<> + void URITestObject::test<7>() + { + // query string + checkParts(LLURI("http://host/?"), + "http", "//host/?", "host", "/", ""); + + checkParts(LLURI("http://host/?x"), + "http", "//host/?x", "host", "/", "x"); + + checkParts(LLURI("http://host/??"), + "http", "//host/??", "host", "/", "?"); + + checkParts(LLURI("http://host/?%3F"), + "http", "//host/??", "host", "/", "?"); + } + + template<> template<> + void URITestObject::test<8>() + { + LLSD path; + path.append("x"); + path.append("123"); + checkParts(LLURI::buildHTTP("host", path), + "http", "//host/x/123", "host", "/x/123"); + + LLSD query; + query["123"] = "12"; + query["abcd"] = "abc"; + checkParts(LLURI::buildHTTP("host", path, query), + "http", "//host/x/123?123=12&abcd=abc", + "host", "/x/123", "123=12&abcd=abc"); + } + + template<> template<> + void URITestObject::test<9>() + { + // test unescaped path components + LLSD path; + path.append("x@*//*$&^"); + path.append("123"); + checkParts(LLURI::buildHTTP("host", path), + "http", "//host/x@*//*$&^/123", "host", "/x@*//*$&^/123"); + } + + template<> template<> + void URITestObject::test<10>() + { + // test unescaped query components + LLSD path; + path.append("x"); + path.append("123"); + LLSD query; + query["123"] = "?&*#//"; + query["**@&?//"] = "abc"; + checkParts(LLURI::buildHTTP("host", path, query), + "http", "//host/x/123?**@&?//=abc&123=?&*#//", + "host", "/x/123", "**@&?//=abc&123=?&*#//"); + } + + template<> template<> + void URITestObject::test<11>() + { + // test unescaped host components + LLSD path; + path.append("x"); + path.append("123"); + LLSD query; + query["123"] = "12"; + query["abcd"] = "abc"; + checkParts(LLURI::buildHTTP("hi123*33--}{:portstuffs", path, query), + "http", "//hi123*33--}{:portstuffs/x/123?123=12&abcd=abc", + "hi123*33--}{:portstuffs", "/x/123", "123=12&abcd=abc"); + } + + template<> template<> + void URITestObject::test<12>() + { + // test funky host_port values that are actually prefixes + + checkParts(LLURI::buildHTTP("http://example.com:8080", LLSD()), + "http", "//example.com:8080", + "example.com:8080", ""); + + checkParts(LLURI::buildHTTP("http://example.com:8080/", LLSD()), + "http", "//example.com:8080/", + "example.com:8080", "/"); + + checkParts(LLURI::buildHTTP("http://example.com:8080/a/b", LLSD()), + "http", "//example.com:8080/a/b", + "example.com:8080", "/a/b"); + } + + template<> template<> + void URITestObject::test<13>() + { + const std::string unreserved = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789" + "-._~"; + // test escape + ensure_equals("escaping", LLURI::escape("abcdefg", "abcdef"), "abcdef%67"); + ensure_equals("escaping", LLURI::escape("|/&\\+-_!@", ""), "%7C%2F%26%5C%2B%2D%5F%21%40"); + ensure_equals("escaping as query variable", + LLURI::escape("http://10.0.1.4:12032/agent/god/agent-id/map/layer/?resume=http://station3.ll.com:12032/agent/203ad6df-b522-491d-ba48-4e24eb57aeff/send-postcard", unreserved + ":@!$'()*+,="), + "http:%2F%2F10.0.1.4:12032%2Fagent%2Fgod%2Fagent-id%2Fmap%2Flayer%2F%3Fresume=http:%2F%2Fstation3.ll.com:12032%2Fagent%2F203ad6df-b522-491d-ba48-4e24eb57aeff%2Fsend-postcard"); + // French cedilla (C with squiggle, like in the word Francais) is UTF-8 C3 A7 + +#if LL_WINDOWS +#pragma warning(disable: 4309) +#endif + + std::string cedilla; + cedilla.push_back( (char)0xC3 ); + cedilla.push_back( (char)0xA7 ); + ensure_equals("escape UTF8", LLURI::escape( cedilla, unreserved), "%C3%A7"); + } + + + template<> template<> + void URITestObject::test<14>() + { + // make sure escape and unescape of empty strings return empty + // strings. + std::string uri_esc(LLURI::escape("")); + ensure("escape string empty", uri_esc.empty()); + std::string uri_raw(LLURI::unescape("")); + ensure("unescape string empty", uri_raw.empty()); + } + + template<> template<> + void URITestObject::test<15>() + { + // do some round-trip tests + escapeRoundTrip("http://secondlife.com"); + escapeRoundTrip("http://secondlife.com/url with spaces"); + escapeRoundTrip("http://bad[domain]name.com/"); + escapeRoundTrip("ftp://bill.gates@ms/micro$oft.com/c:\\autoexec.bat"); + escapeRoundTrip(""); + } + + template<> template<> + void URITestObject::test<16>() + { + // Test the default escaping + // yes -- this mangles the url. This is expected behavior + std::string simple("http://secondlife.com"); + ensure_equals( + "simple http", + LLURI::escape(simple), + "http%3A%2F%2Fsecondlife.com"); + ensure_equals( + "needs escape", + LLURI::escape("http://get.secondlife.com/windows viewer"), + "http%3A%2F%2Fget.secondlife.com%2Fwindows%20viewer"); + } + + template<> template<> + void URITestObject::test<17>() + { + // do some round-trip tests with very long strings. + escapeRoundTrip("Welcome to Second Life.We hope you'll have a richly rewarding experience, filled with creativity, self expression and fun.The goals of the Community Standards are simple: treat each other with respect and without harassment, adhere to local standards as indicated by simulator ratings, and refrain from any hate activity which slurs a real-world individual or real-world community. Behavioral Guidelines - The Big Six"); + escapeRoundTrip( + "'asset_data':b(12100){'task_id':ucc706f2d-0b68-68f8-11a4-f1043ff35ca0}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444921\n\ttotal_crc\t323\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.368634403\t0.00781063363\t-0.569040775\n\toldpos\t150.117996\t25.8658009\t8.19664001\n\trotation\t-0.06293071806430816650390625\t-0.6995697021484375\t-0.7002241611480712890625\t0.1277817934751510620117188\n\tchildpos\t-0.00499999989\t-0.0359999985\t0.307999998\n\tchildrot\t-0.515492737293243408203125\t-0.46601200103759765625\t0.529055416584014892578125\t0.4870323240756988525390625\n\tscale" + "\t0.074629\t0.289956\t0.01\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t16\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\tscale_x\t1\n\t\t\tscale_y\t1\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t1\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tf" + "aces\t6\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204" + "\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t-1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061088050622956\n\treztime\t1094866329019785\n\tparceltime\t1133568981980596\n\ttax_rate\t1.00084\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tchild\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n{'task_id':u61fa7364-e151-0597-774c-523312dae31b}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffff" + "ff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444922\n\ttotal_crc\t324\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.367110789\t0.00780026987\t-0.566269755\n\toldpos\t150.115005\t25.8479004\t8.18669987\n\trotation\t0.47332942485809326171875\t-0.380102097988128662109375\t-0.5734078884124755859375\t0.550168216228485107421875\n\tchildpos\t-0.00499999989\t-0.0370000005\t0.305000007\n\tchildrot\t-0.736649334430694580078125\t-0.03042060509324073791503906\t-0.02784589119255542755126953\t0.67501628398895263671875\n\tscale\t0.074629\t0.289956\t0.01\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t" + "0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t16\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\tscale_x\t1\n\t\t\tscale_y\t1\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t1\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t6\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t" + "\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tf54a0c32-3cd1-d49a-5b4f-7b792bebc204\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t" + "\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\tddde1ffc-678b-3cda-1748-513086bdf01b\n\t\tcolors\t0.937255 0.796078 0.494118 1\n\t\tscales\t1\n\t\tscalet\t-1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t0\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061087839248891\n\treztime\t1094866329020800\n\tparceltime\t1133568981981983\n\ttax_rate\t1.00084\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tchild\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n{'task_id':ub8d68643-7dd8-57af-0d24-8790032aed0c}\n{\n\tname\tObject|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreat" + "or_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444923\n\ttotal_crc\t235\n\ttype\t2\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.120029509\t-0.00284469454\t-0.0302077383\n\toldpos\t150.710999\t25.8584995\t8.19172001\n\trotation\t0.145459949970245361328125\t-0.1646589934825897216796875\t0.659558117389678955078125\t-0.718826770782470703125\n\tchildpos\t0\t-0.182999998\t-0.26699999\n\tchildrot\t0.991444766521453857421875\t3.271923924330621957778931e-05\t-0.0002416197530692443251609802\t0.1305266767740249633789062\n\tscale\t0.0382982\t0.205957\t0.368276\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundra" + "dius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t32\n\t\t\tbegin\t0.3\n\t\t\tend\t0.65\n\t\t\tscale_x\t1\n\t\t\tscale_y\t0.05\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t0\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t3\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0" + "\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061087534454174\n\treztime\t1094866329021741\n\tparceltime\t1133568981982889\n\ttax_rate\t1.00326\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tchild\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n{'task_id':ue4b19200-9d33-962f-c8c5-6f" + "25be3a3fd0}\n{\n\tname\tApotheosis_Immolaine_tail|\n\tpermissions 0\n\t{\n\t\tbase_mask\t7fffffff\n\t\towner_mask\t7fffffff\n\t\tgroup_mask\t00000000\n\t\teveryone_mask\t00000000\n\t\tnext_owner_mask\t7fffffff\n\t\tcreator_id\t13fd9595-a47b-4d64-a5fb-6da645f038e0\n\t\towner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tlast_owner_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\t\tgroup_id\t00000000-0000-0000-0000-000000000000\n\t}\n\tlocal_id\t217444924\n\ttotal_crc\t675\n\ttype\t1\n\ttask_valid\t2\n\ttravel_access\t13\n\tdisplayopts\t2\n\tdisplaytype\tv\n\tpos\t-0.34780401\t-0.00968400016\t-0.260098994\n\toldpos\t0\t0\t0\n\trotation\t0.73164522647857666015625\t-0.67541944980621337890625\t-0.07733880728483200073242188\t0.05022468417882919311523438\n\tvelocity\t0\t0\t0\n\tangvel\t0\t0\t0\n\tscale\t0.0382982\t0.32228\t0.383834\n\tsit_offset\t0\t0\t0\n\tcamera_eye_offset\t0\t0\t0\n\tcamera_at_offset\t0\t0\t0\n\tsit_quat\t0\t0\t0\t1\n\tsit_hint\t0\n\tstate\t160\n\tmaterial\t3\n\tsoundid\t00000" + "000-0000-0000-0000-000000000000\n\tsoundgain\t0\n\tsoundradius\t0\n\tsoundflags\t0\n\ttextcolor\t0 0 0 1\n\tselected\t0\n\tselector\t00000000-0000-0000-0000-000000000000\n\tusephysics\t0\n\trotate_x\t1\n\trotate_y\t1\n\trotate_z\t1\n\tphantom\t0\n\tremote_script_access_pin\t0\n\tvolume_detect\t0\n\tblock_grabs\t0\n\tdie_at_edge\t0\n\treturn_at_edge\t0\n\ttemporary\t0\n\tsandbox\t0\n\tsandboxhome\t0\t0\t0\n\tshape 0\n\t{\n\t\tpath 0\n\t\t{\n\t\t\tcurve\t32\n\t\t\tbegin\t0.3\n\t\t\tend\t0.65\n\t\t\tscale_x\t1\n\t\t\tscale_y\t0.05\n\t\t\tshear_x\t0\n\t\t\tshear_y\t0\n\t\t\ttwist\t0\n\t\t\ttwist_begin\t0\n\t\t\tradius_offset\t0\n\t\t\ttaper_x\t0\n\t\t\ttaper_y\t0\n\t\t\trevolutions\t1\n\t\t\tskew\t0\n\t\t}\n\t\tprofile 0\n\t\t{\n\t\t\tcurve\t0\n\t\t\tbegin\t0\n\t\t\tend\t1\n\t\t\thollow\t0\n\t\t}\n\t}\n\tfaces\t3\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1" + ".57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\t{\n\t\timageid\te7150bed-3e3e-c698-eb15-d17b178148af\n\t\tcolors\t0.843137 0.156863 0.156863 1\n\t\tscales\t15\n\t\tscalet\t1\n\t\toffsets\t0\n\t\toffsett\t0\n\t\timagerot\t-1.57084\n\t\tbump\t0\n\t\tfullbright\t0\n\t\tmedia_flags\t0\n\t}\n\tps_next_crc\t1\n\tgpw_bias\t1\n\tip\t0\n\tcomplete\tTRUE\n\tdelay\t50000\n\tnextstart\t0\n\tbirthtime\t1061087463950186\n\treztime\t1094866329022555\n\tparceltime\t1133568981984359\n\tdescription\t(No Description)|\n\ttax_rate\t1.01736\n\tnamevalue\tAttachPt U32 RW S 10\n\tnamevalue\tAttachmentOrientation VEC3 RW DS -3.110088, -0.182018, 1.493795\n\tnamevalue\tAttachmentOffset VEC3 RW DS -0.347804, -0.009684, -0.260099\n\tnamevalue\tAttachItemI" + "D STRING RW SV 20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tscratchpad\t0\n\t{\n\t\n\t}\n\tsale_info\t0\n\t{\n\t\tsale_type\tnot\n\t\tsale_price\t10\n\t}\n\torig_asset_id\t8747acbc-d391-1e59-69f1-41d06830e6c0\n\torig_item_id\t20f36c3a-b44b-9bc7-87f3-018bfdfc8cda\n\tfrom_task_id\t3c115e51-04f4-523c-9fa6-98aff1034730\n\tcorrect_family_id\t00000000-0000-0000-0000-000000000000\n\thas_rezzed\t0\n\tpre_link_base_mask\t7fffffff\n\tlinked \tlinked\n\tdefault_pay_price\t-2\t1\t5\t10\t20\n}\n"); + } + + + template<> template<> + void URITestObject::test<18>() + { + LLURI u("secondlife:///app/login?first_name=Testert4&last_name=Tester&web_login_key=test"); + // if secondlife is the scheme, LLURI should parse /app/login as path, with no authority + ensure_equals("scheme", u.scheme(), "secondlife"); + ensure_equals("authority", u.authority(), ""); + ensure_equals("path", u.path(), "/app/login"); + ensure_equals("pathmap", u.pathArray()[0].asString(), "app"); + ensure_equals("pathmap", u.pathArray()[1].asString(), "login"); + ensure_equals("query", u.query(), "first_name=Testert4&last_name=Tester&web_login_key=test"); + ensure_equals("query map element", u.queryMap()["last_name"].asString(), "Tester"); + + u = LLURI("secondlife://Da Boom/128/128/128"); + // if secondlife is the scheme, LLURI should parse /128/128/128 as path, with Da Boom as authority + ensure_equals("scheme", u.scheme(), "secondlife"); + ensure_equals("authority", u.authority(), "Da Boom"); + ensure_equals("path", u.path(), "/128/128/128"); + ensure_equals("pathmap", u.pathArray()[0].asString(), "128"); + ensure_equals("pathmap", u.pathArray()[1].asString(), "128"); + ensure_equals("pathmap", u.pathArray()[2].asString(), "128"); + ensure_equals("query", u.query(), ""); + } + + template<> template<> + void URITestObject::test<19>() + { + // Parse about: schemes + LLURI u("about:blank?redirect-http-hack=secondlife%3A%2F%2F%2Fapp%2Flogin%3Ffirst_name%3DCallum%26last_name%3DLinden%26location%3Dspecify%26grid%3Dvaak%26region%3D%2FMorris%2F128%2F128%26web_login_key%3Defaa4795-c2aa-4c58-8966-763c27931e78"); + ensure_equals("scheme", u.scheme(), "about"); + ensure_equals("authority", u.authority(), ""); + ensure_equals("path", u.path(), "blank"); + ensure_equals("pathmap", u.pathArray()[0].asString(), "blank"); + 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"); + } +} + + diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 488f3bf78d..9bbc55509d 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -159,7 +159,7 @@ U8* LLImageBase::allocateData(S32 size) size = mWidth * mHeight * mComponents; if (size <= 0) { - llerrs << llformat("LLImageBase::allocateData called with bad dimentions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl; + llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl; } } else if (size <= 0 || (size > 4096*4096*16 && sSizeOverride == FALSE)) diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt index b70548a9ba..e3dd24ad02 100644 --- a/indra/llinventory/CMakeLists.txt +++ b/indra/llinventory/CMakeLists.txt @@ -6,6 +6,7 @@ include(00-Common) include(LLCommon) include(LLMath) include(LLMessage) +include(LLVFS) include(LLXML) include_directories( @@ -54,3 +55,16 @@ set_source_files_properties(${llinventory_HEADER_FILES} list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES}) add_library (llinventory ${llinventory_SOURCE_FILES}) + + + +#add unit tests +INCLUDE(LLAddBuildTest) +SET(llinventory_TEST_SOURCE_FILES + # no real unit tests yet! + ) +LL_ADD_PROJECT_UNIT_TESTS(llinventory "${llinventory_TEST_SOURCE_FILES}") + +#set(TEST_DEBUG on) +set(test_libs llinventory ${LLMESSAGE_LIBRARIES} ${LLVFS_LIBRARIES} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) +LL_ADD_INTEGRATION_TEST(inventorymisc "" "${test_libs}") diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 2808effdc6..ec21ae40e7 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -706,7 +706,6 @@ void LLParcel::packMessage(LLSD& msg) msg["category"] = (U8)mCategory; msg["auth_buyer_id"] = mAuthBuyerID; msg["snapshot_id"] = mSnapshotID; - msg["snapshot_id"] = mSnapshotID; msg["user_location"] = ll_sd_from_vector3(mUserLocation); msg["user_look_at"] = ll_sd_from_vector3(mUserLookAt); msg["landing_type"] = (U8)mLandingType; diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp new file mode 100644 index 0000000000..770594dc9d --- /dev/null +++ b/indra/llinventory/tests/inventorymisc_test.cpp @@ -0,0 +1,514 @@ +/** + * @file inventory.cpp + * @author Phoenix + * @date 2005-11-15 + * @brief Functions for inventory test framework + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llsd.h" + +#include "../llinventory.h" + +#include "../test/lltut.h" + + +#if LL_WINDOWS +// disable unreachable code warnings +#pragma warning(disable: 4702) +#endif + +LLPointer<LLInventoryItem> create_random_inventory_item() +{ + LLUUID item_id; + item_id.generate(); + LLUUID parent_id; + parent_id.generate(); + LLPermissions perm; + LLUUID creator_id; + creator_id.generate(); + LLUUID owner_id; + owner_id.generate(); + LLUUID last_owner_id; + last_owner_id.generate(); + LLUUID group_id; + group_id.generate(); + perm.init(creator_id, owner_id, last_owner_id, group_id); + perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY); + LLUUID asset_id; + asset_id.generate(); + S32 price = rand(); + LLSaleInfo sale_info(LLSaleInfo::FS_COPY, price); + U32 flags = rand(); + S32 creation = time(NULL); + + LLPointer<LLInventoryItem> item = new LLInventoryItem( + item_id, + parent_id, + perm, + asset_id, + LLAssetType::AT_OBJECT, + LLInventoryType::IT_ATTACHMENT, + std::string("Sample Object"), + std::string("Used for Testing"), + sale_info, + flags, + creation); + return item; +} + +LLPointer<LLInventoryCategory> create_random_inventory_cat() +{ + LLUUID item_id; + item_id.generate(); + LLUUID parent_id; + parent_id.generate(); + + LLPointer<LLInventoryCategory> cat = new LLInventoryCategory( + item_id, + parent_id, + LLAssetType::AT_NONE, + std::string("Sample category")); + return cat; +} + +namespace tut +{ + struct inventory_data + { + }; + typedef test_group<inventory_data> inventory_test; + typedef inventory_test::object inventory_object; + tut::inventory_test inv("llinventory"); + +//***class LLInventoryType***// + + + template<> template<> + void inventory_object::test<1>() + { + LLInventoryType::EType retType = LLInventoryType::lookup(std::string("sound")); + ensure("1.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SOUND); + + retType = LLInventoryType::lookup(std::string("snapshot")); + ensure("2.LLInventoryType::lookup(char*) failed", retType == LLInventoryType::IT_SNAPSHOT); + } + + template<> template<> + void inventory_object::test<2>() + { + static std::string retType = LLInventoryType::lookup(LLInventoryType::IT_CALLINGCARD); + ensure("1.LLInventoryType::lookup(EType) failed", (retType == "callcard")); + + retType = LLInventoryType::lookup(LLInventoryType::IT_LANDMARK); + ensure("2.LLInventoryType::lookup(EType) failed", (retType == "landmark")); + + } + + template<> template<> + void inventory_object::test<3>() + { + static std::string retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_CALLINGCARD); + ensure("1.LLInventoryType::lookupHumanReadable(EType) failed", (retType == "calling card")); + + retType = LLInventoryType::lookupHumanReadable(LLInventoryType::IT_LANDMARK); + ensure("2.LLInventoryType::lookupHumanReadable(EType) failed", (retType == "landmark")); + } + + template<> template<> + void inventory_object::test<4>() + { + static LLInventoryType::EType retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_TEXTURE); + ensure("1.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_TEXTURE); + + retType = LLInventoryType::defaultForAssetType(LLAssetType::AT_LANDMARK); + ensure("2.LLInventoryType::defaultForAssetType(LLAssetType EType) failed", retType == LLInventoryType::IT_LANDMARK); + } + +//*****class LLInventoryItem*****// + + template<> template<> + void inventory_object::test<5>() + { + LLPointer<LLInventoryItem> src = create_random_inventory_item(); + LLSD sd = ll_create_sd_from_inventory_item(src); + //llinfos << "sd: " << *sd << llendl; + LLPointer<LLInventoryItem> dst = new LLInventoryItem; + bool successful_parse = dst->fromLLSD(sd); + ensure_equals("0.LLInventoryItem::fromLLSD()", successful_parse, true); + ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID()); + ensure_equals("3.name::getName() failed", dst->getName(), src->getName()); + ensure_equals("4.type::getType() failed", dst->getType(), src->getType()); + + ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions()); + ensure_equals("6.description::getDescription() failed", dst->getDescription(), src->getDescription()); + ensure_equals("7.sale type::getSaleType() failed", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType()); + ensure_equals("8.sale price::getSalePrice() failed", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice()); + ensure_equals("9.asset id::getAssetUUID() failed", dst->getAssetUUID(), src->getAssetUUID()); + ensure_equals("10.inventory type::getInventoryType() failed", dst->getInventoryType(), src->getInventoryType()); + ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src->getFlags()); + ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate()); + + LLUUID new_item_id, new_parent_id; + new_item_id.generate(); + src->setUUID(new_item_id); + + new_parent_id.generate(); + src->setParent(new_parent_id); + + std::string new_name = "LindenLab"; + src->rename(new_name); + + src->setType(LLAssetType::AT_SOUND); + + LLUUID new_asset_id; + new_asset_id.generate(); + + src->setAssetUUID(new_asset_id); + std::string new_desc = "SecondLife Testing"; + src->setDescription(new_desc); + + S32 new_price = rand(); + LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price); + src->setSaleInfo(new_sale_info); + + U32 new_flags = rand(); + S32 new_creation = time(NULL); + + LLPermissions new_perm; + + LLUUID new_creator_id; + new_creator_id.generate(); + + LLUUID new_owner_id; + new_owner_id.generate(); + + LLUUID last_owner_id; + last_owner_id.generate(); + + LLUUID new_group_id; + new_group_id.generate(); + new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id); + new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY); + src->setPermissions(new_perm); + + src->setInventoryType(LLInventoryType::IT_SOUND); + src->setFlags(new_flags); + src->setCreationDate(new_creation); + + sd = ll_create_sd_from_inventory_item(src); + //llinfos << "sd: " << *sd << llendl; + successful_parse = dst->fromLLSD(sd); + ensure_equals("13.item id::getUUID() failed", dst->getUUID(), src->getUUID()); + ensure_equals("14.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID()); + ensure_equals("15.name::getName() failed", dst->getName(), src->getName()); + ensure_equals("16.type::getType() failed", dst->getType(), src->getType()); + + ensure_equals("17.permissions::getPermissions() failed", dst->getPermissions(), src->getPermissions()); + ensure_equals("18.description::getDescription() failed", dst->getDescription(), src->getDescription()); + ensure_equals("19.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src->getSaleInfo().getSaleType()); + ensure_equals("20.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src->getSaleInfo().getSalePrice()); + ensure_equals("21.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src->getAssetUUID()); + ensure_equals("22.inventory type::getInventoryType() failed type", dst->getInventoryType(), src->getInventoryType()); + ensure_equals("23.flags::getFlags() failed", dst->getFlags(), src->getFlags()); + ensure_equals("24.creation::getCreationDate() failed", dst->getCreationDate(), src->getCreationDate()); + + } + + template<> template<> + void inventory_object::test<6>() + { + LLPointer<LLInventoryItem> src = create_random_inventory_item(); + + LLUUID new_item_id, new_parent_id; + new_item_id.generate(); + src->setUUID(new_item_id); + + new_parent_id.generate(); + src->setParent(new_parent_id); + + std::string new_name = "LindenLab"; + src->rename(new_name); + + src->setType(LLAssetType::AT_SOUND); + + LLUUID new_asset_id; + new_asset_id.generate(); + + src->setAssetUUID(new_asset_id); + std::string new_desc = "SecondLife Testing"; + src->setDescription(new_desc); + + S32 new_price = rand(); + LLSaleInfo new_sale_info(LLSaleInfo::FS_COPY, new_price); + src->setSaleInfo(new_sale_info); + + U32 new_flags = rand(); + S32 new_creation = time(NULL); + + LLPermissions new_perm; + + LLUUID new_creator_id; + new_creator_id.generate(); + + LLUUID new_owner_id; + new_owner_id.generate(); + + LLUUID last_owner_id; + last_owner_id.generate(); + + LLUUID new_group_id; + new_group_id.generate(); + new_perm.init(new_creator_id, new_owner_id, last_owner_id, new_group_id); + new_perm.initMasks(PERM_ALL, PERM_ALL, PERM_COPY, PERM_COPY, PERM_MODIFY | PERM_COPY); + src->setPermissions(new_perm); + + src->setInventoryType(LLInventoryType::IT_SOUND); + src->setFlags(new_flags); + src->setCreationDate(new_creation); + + // test a save/load cycle to LLSD and back again + LLSD sd = ll_create_sd_from_inventory_item(src); + LLPointer<LLInventoryItem> dst = new LLInventoryItem; + bool successful_parse = dst->fromLLSD(sd); + ensure_equals("0.LLInventoryItem::fromLLSD()", successful_parse, true); + + LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); + src1->copyItem(src); + + ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src1->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src1->getParentUUID()); + ensure_equals("3.name::getName() failed", dst->getName(), src1->getName()); + ensure_equals("4.type::getType() failed", dst->getType(), src1->getType()); + + ensure_equals("5.permissions::getPermissions() failed", dst->getPermissions(), src1->getPermissions()); + ensure_equals("6.description::getDescription() failed", dst->getDescription(), src1->getDescription()); + ensure_equals("7.sale type::getSaleType() failed type", dst->getSaleInfo().getSaleType(), src1->getSaleInfo().getSaleType()); + ensure_equals("8.sale price::getSalePrice() failed price", dst->getSaleInfo().getSalePrice(), src1->getSaleInfo().getSalePrice()); + ensure_equals("9.asset id::getAssetUUID() failed id", dst->getAssetUUID(), src1->getAssetUUID()); + ensure_equals("10.inventory type::getInventoryType() failed type", dst->getInventoryType(), src1->getInventoryType()); + ensure_equals("11.flags::getFlags() failed", dst->getFlags(), src1->getFlags()); + ensure_equals("12.creation::getCreationDate() failed", dst->getCreationDate(), src1->getCreationDate()); + + // quick test to make sure generateUUID() really works + src1->generateUUID(); + ensure_not_equals("13.item id::generateUUID() failed", src->getUUID(), src1->getUUID()); + } + + template<> template<> + void inventory_object::test<7>() + { + LLFILE* fp = LLFile::fopen("linden_file.dat","w+"); + if(!fp) + { + llerrs << "file could not be opened\n" << llendl; + return; + } + + LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); + src1->exportFile(fp, TRUE); + fclose(fp); + + LLPointer<LLInventoryItem> src2 = new LLInventoryItem(); + fp = LLFile::fopen("linden_file.dat","r+"); + if(!fp) + { + llerrs << "file could not be opened\n" << llendl; + return; + } + + src2->importFile(fp); + fclose(fp); + + ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); + ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions()); + ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); + ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID()); + ensure_equals("6.type::getType() failed", src1->getType(), src2->getType()); + ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType()); + ensure_equals("8.name::getName() failed", src1->getName(), src2->getName()); + ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription()); + ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); + + } + + template<> template<> + void inventory_object::test<8>() + { + + LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); + + std::ostringstream ostream; + src1->exportLegacyStream(ostream, TRUE); + + std::istringstream istream(ostream.str()); + LLPointer<LLInventoryItem> src2 = new LLInventoryItem(); + src2->importLegacyStream(istream); + + ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); + ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions()); + ensure_equals("4.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); + ensure_equals("5.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID()); + ensure_equals("6.type::getType() failed", src1->getType(), src2->getType()); + ensure_equals("7.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType()); + ensure_equals("8.name::getName() failed", src1->getName(), src2->getName()); + ensure_equals("9.description::getDescription() failed", src1->getDescription(), src2->getDescription()); + ensure_equals("10.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); + + + } + + template<> template<> + void inventory_object::test<9>() + { + // Deleted LLInventoryItem::exportFileXML() and LLInventoryItem::importXML() + // because I can't find any non-test code references to it. 2009-05-04 JC + } + + template<> template<> + void inventory_object::test<10>() + { + LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); + U8* bin_bucket = new U8[300]; + S32 bin_bucket_size = src1->packBinaryBucket(bin_bucket, NULL); + + LLPointer<LLInventoryItem> src2 = new LLInventoryItem(); + src2->unpackBinaryBucket(bin_bucket, bin_bucket_size); + + ensure_equals("1.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); + ensure_equals("2.sale type::getSaleType() failed type", src1->getSaleInfo().getSaleType(), src2->getSaleInfo().getSaleType()); + ensure_equals("3.type::getType() failed", src1->getType(), src2->getType()); + ensure_equals("4.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType()); + ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); + ensure_equals("6.description::getDescription() failed", src1->getDescription(), src2->getDescription()); + ensure_equals("7.flags::getFlags() failed", src1->getFlags(), src2->getFlags()); + + } + + template<> template<> + void inventory_object::test<11>() + { + LLPointer<LLInventoryItem> src1 = create_random_inventory_item(); + LLSD retSd = src1->asLLSD(); + LLPointer<LLInventoryItem> src2 = new LLInventoryItem(); + src2->fromLLSD(retSd); + + ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); + ensure_equals("3.permissions::getPermissions() failed", src1->getPermissions(), src2->getPermissions()); + ensure_equals("4.asset id::getAssetUUID() failed id", src1->getAssetUUID(), src2->getAssetUUID()); + ensure_equals("5.type::getType() failed", src1->getType(), src2->getType()); + ensure_equals("6.inventory type::getInventoryType() failed type", src1->getInventoryType(), src2->getInventoryType()); + ensure_equals("7.flags::getFlags() failed", src1->getFlags(), src2->getFlags()); + ensure_equals("8.sale type::getSaleType() failed type", src1->getSaleInfo().getSaleType(), src2->getSaleInfo().getSaleType()); + ensure_equals("9.sale price::getSalePrice() failed price", src1->getSaleInfo().getSalePrice(), src2->getSaleInfo().getSalePrice()); + ensure_equals("10.name::getName() failed", src1->getName(), src2->getName()); + ensure_equals("11.description::getDescription() failed", src1->getDescription(), src2->getDescription()); + ensure_equals("12.creation::getCreationDate() failed", src1->getCreationDate(), src2->getCreationDate()); + } + +//******class LLInventoryCategory*******// + + template<> template<> + void inventory_object::test<12>() + { + LLPointer<LLInventoryCategory> src = create_random_inventory_cat(); + LLSD sd = ll_create_sd_from_inventory_category(src); + LLPointer<LLInventoryCategory> dst = ll_create_category_from_sd(sd); + + ensure_equals("1.item id::getUUID() failed", dst->getUUID(), src->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", dst->getParentUUID(), src->getParentUUID()); + ensure_equals("3.name::getName() failed", dst->getName(), src->getName()); + ensure_equals("4.type::getType() failed", dst->getType(), src->getType()); + ensure_equals("5.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType()); + + src->setPreferredType( LLAssetType::AT_TEXTURE); + sd = ll_create_sd_from_inventory_category(src); + dst = ll_create_category_from_sd(sd); + ensure_equals("6.preferred type::getPreferredType() failed", dst->getPreferredType(), src->getPreferredType()); + + + } + + template<> template<> + void inventory_object::test<13>() + { + LLFILE* fp = LLFile::fopen("linden_file.dat","w"); + if(!fp) + { + llerrs << "file coudnt be opened\n" << llendl; + return; + } + + LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat(); + src1->exportFile(fp, TRUE); + fclose(fp); + + LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory(); + fp = LLFile::fopen("linden_file.dat","r"); + if(!fp) + { + llerrs << "file coudnt be opened\n" << llendl; + return; + } + + src2->importFile(fp); + fclose(fp); + + ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); + ensure_equals("3.type::getType() failed", src1->getType(), src2->getType()); + ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType()); + ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); + } + + template<> template<> + void inventory_object::test<14>() + { + LLPointer<LLInventoryCategory> src1 = create_random_inventory_cat(); + + std::ostringstream ostream; + src1->exportLegacyStream(ostream, TRUE); + + std::istringstream istream(ostream.str()); + LLPointer<LLInventoryCategory> src2 = new LLInventoryCategory(); + src2->importLegacyStream(istream); + + ensure_equals("1.item id::getUUID() failed", src1->getUUID(), src2->getUUID()); + ensure_equals("2.parent::getParentUUID() failed", src1->getParentUUID(), src2->getParentUUID()); + ensure_equals("3.type::getType() failed", src1->getType(), src2->getType()); + ensure_equals("4.preferred type::getPreferredType() failed", src1->getPreferredType(), src2->getPreferredType()); + ensure_equals("5.name::getName() failed", src1->getName(), src2->getName()); + + } +} diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index d27a1467ea..7957c32be2 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -15,6 +15,7 @@ set(llmath_SOURCE_FILES llcamera.cpp llcoordframe.cpp llline.cpp + llmodularmath.cpp llperlin.cpp llquaternion.cpp llrect.cpp @@ -48,6 +49,7 @@ set(llmath_HEADER_FILES llinterp.h llline.h llmath.h + llmodularmath.h lloctree.h llperlin.h llplane.h @@ -83,12 +85,28 @@ list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES}) add_library (llmath ${llmath_SOURCE_FILES}) - +# Add tests include(LLAddBuildTest) +# UNIT TESTS SET(llmath_TEST_SOURCE_FILES - # nat 2009-08-28: found this commented out and considered implementing it - # using LL_ADD_INTEGRATION_TEST, but there's no llvolume_test.cpp source? - # llvolume.cpp + llbboxlocal.cpp + llmodularmath.cpp + llrect.cpp + v2math.cpp + v3color.cpp + v4color.cpp + v4coloru.cpp ) LL_ADD_PROJECT_UNIT_TESTS(llmath "${llmath_TEST_SOURCE_FILES}") +# INTEGRATION TESTS +set(test_libs llmath llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) +# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests. +LL_ADD_INTEGRATION_TEST(llbbox llbbox.cpp "${test_libs}") +LL_ADD_INTEGRATION_TEST(llquaternion llquaternion.cpp "${test_libs}") +LL_ADD_INTEGRATION_TEST(mathmisc "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(m3math "" "${test_libs}") +LL_ADD_INTEGRATION_TEST(v3dmath v3dmath.cpp "${test_libs}") +LL_ADD_INTEGRATION_TEST(v3math v3math.cpp "${test_libs}") +LL_ADD_INTEGRATION_TEST(v4math v4math.cpp "${test_libs}") +LL_ADD_INTEGRATION_TEST(xform xform.cpp "${test_libs}") diff --git a/indra/llmath/llmodularmath.cpp b/indra/llmath/llmodularmath.cpp new file mode 100644 index 0000000000..4a6553ae7c --- /dev/null +++ b/indra/llmath/llmodularmath.cpp @@ -0,0 +1,36 @@ +/** + * @file llmodularmath.cpp + * @brief LLModularMath class implementation + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes. +#include "llmodularmath.h" diff --git a/indra/llmath/llrect.cpp b/indra/llmath/llrect.cpp index cba76dd211..14e094792d 100644 --- a/indra/llmath/llrect.cpp +++ b/indra/llmath/llrect.cpp @@ -1,5 +1,6 @@ /** * @file llrect.cpp + * @brief LLRect class implementation * * $LicenseInfo:firstyear=2001&license=viewergpl$ * @@ -31,4 +32,5 @@ #include "linden_common.h" +// implementation is all in the header, this include dep ensures the unit test is rerun if the implementation changes. #include "llrect.h" diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5cc0a596fd..b8ef92f9a9 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -4273,7 +4273,7 @@ LLFaceID LLVolume::generateFaceMask() } break; default: - llerrs << "Unknown profile!" << llendl + llerrs << "Unknown profile!" << llendl; break; } diff --git a/indra/llmath/m4math.cpp b/indra/llmath/m4math.cpp index 59a0bc2335..d8e7b4aaf9 100644 --- a/indra/llmath/m4math.cpp +++ b/indra/llmath/m4math.cpp @@ -678,32 +678,6 @@ LLVector4 operator*(const LLMatrix4 &a, const LLVector4 &b) } */ -// Operates "to the left" on row-vector a -// -// This used to be in the header file but was not actually inlined in practice. -// When avatar vertex programs are off, this function is a hot spot in profiles -// due to software skinning in LLViewerJointMesh::updateGeometry(). JC -LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b) -{ - // This is better than making a temporary LLVector3. This eliminates an - // unnecessary LLVector3() constructor and also helps the compiler to - // realize that the output floats do not alias the input floats, hence - // eliminating redundant loads of a.mV[0], etc. JC - return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + - a.mV[VY] * b.mMatrix[VY][VX] + - a.mV[VZ] * b.mMatrix[VZ][VX] + - b.mMatrix[VW][VX], - - a.mV[VX] * b.mMatrix[VX][VY] + - a.mV[VY] * b.mMatrix[VY][VY] + - a.mV[VZ] * b.mMatrix[VZ][VY] + - b.mMatrix[VW][VY], - - a.mV[VX] * b.mMatrix[VX][VZ] + - a.mV[VY] * b.mMatrix[VY][VZ] + - a.mV[VZ] * b.mMatrix[VZ][VZ] + - b.mMatrix[VW][VZ]); -} LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b) { diff --git a/indra/llmath/m4math.h b/indra/llmath/m4math.h index 58c9c09d7f..e74b7afe9b 100644 --- a/indra/llmath/m4math.h +++ b/indra/llmath/m4math.h @@ -230,7 +230,7 @@ public: // friend inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b); // Return a * b friend LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b); // Return transform of vector a by matrix b - friend LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b + friend const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b); // Return full transform of a by matrix b friend LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b); // Rotates a but does not translate friend LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b); // Rotates a but does not translate @@ -353,7 +353,31 @@ inline const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b) return a; } -#endif - +// Operates "to the left" on row-vector a +// +// When avatar vertex programs are off, this function is a hot spot in profiles +// due to software skinning in LLViewerJointMesh::updateGeometry(). JC +inline const LLVector3 operator*(const LLVector3 &a, const LLMatrix4 &b) +{ + // This is better than making a temporary LLVector3. This eliminates an + // unnecessary LLVector3() constructor and also helps the compiler to + // realize that the output floats do not alias the input floats, hence + // eliminating redundant loads of a.mV[0], etc. JC + return LLVector3(a.mV[VX] * b.mMatrix[VX][VX] + + a.mV[VY] * b.mMatrix[VY][VX] + + a.mV[VZ] * b.mMatrix[VZ][VX] + + b.mMatrix[VW][VX], + + a.mV[VX] * b.mMatrix[VX][VY] + + a.mV[VY] * b.mMatrix[VY][VY] + + a.mV[VZ] * b.mMatrix[VZ][VY] + + b.mMatrix[VW][VY], + + a.mV[VX] * b.mMatrix[VX][VZ] + + a.mV[VY] * b.mMatrix[VY][VZ] + + a.mV[VZ] * b.mMatrix[VZ][VZ] + + b.mMatrix[VW][VZ]); +} +#endif diff --git a/indra/llmath/tests/llbbox_test.cpp b/indra/llmath/tests/llbbox_test.cpp new file mode 100644 index 0000000000..bc439e4618 --- /dev/null +++ b/indra/llmath/tests/llbbox_test.cpp @@ -0,0 +1,373 @@ +/** + * @file llbbox_tut.cpp + * @author Martin Reddy + * @date 2009-06-25 + * @brief Test for llbbox.cpp. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../test/lltut.h" + +#include "../llbbox.h" + + +#define ANGLE (3.14159265f / 2.0f) +#define APPROX_EQUAL(a, b) dist_vec((a),(b)) < 1e-5 + +namespace tut +{ + struct LLBBoxData + { + }; + + typedef test_group<LLBBoxData> factory; + typedef factory::object object; +} + +namespace +{ + tut::factory llbbox_test_factory("LLBBox"); +} + +namespace tut +{ + template<> template<> + void object::test<1>() + { + // + // test the default constructor + // + + LLBBox bbox1; + + ensure_equals("Default bbox min", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + ensure_equals("Default bbox max", bbox1.getMaxLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + ensure_equals("Default bbox pos agent", bbox1.getPositionAgent(), LLVector3(0.0f, 0.0f, 0.0f)); + ensure_equals("Default bbox rotation", bbox1.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f)); + } + + template<> template<> + void object::test<2>() + { + // + // test the non-default constructor + // + + LLBBox bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), + LLVector3(2.0f, 3.0f, 4.0f), LLVector3(4.0f, 5.0f, 6.0f)); + + ensure_equals("Custom bbox min", bbox2.getMinLocal(), LLVector3(2.0f, 3.0f, 4.0f)); + ensure_equals("Custom bbox max", bbox2.getMaxLocal(), LLVector3(4.0f, 5.0f, 6.0f)); + ensure_equals("Custom bbox pos agent", bbox2.getPositionAgent(), LLVector3(1.0f, 2.0f, 3.0f)); + ensure_equals("Custom bbox rotation", bbox2.getRotation(), LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f)); + } + + template<> template<> + void object::test<3>() + { + // + // test the setMinLocal() method + // + LLBBox bbox2; + bbox2.setMinLocal(LLVector3(3.0f, 3.0f, 3.0f)); + ensure_equals("Custom bbox min (2)", bbox2.getMinLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + } + + template<> template<> + void object::test<4>() + { + // + // test the setMaxLocal() method + // + LLBBox bbox2; + bbox2.setMaxLocal(LLVector3(5.0f, 5.0f, 5.0f)); + ensure_equals("Custom bbox max (2)", bbox2.getMaxLocal(), LLVector3(5.0f, 5.0f, 5.0f)); + } + + template<> template<> + void object::test<5>() + { + // + // test the getCenterLocal() method + // + + ensure_equals("Default bbox local center", LLBBox().getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + + LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), + LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); + + ensure_equals("Custom bbox center local", bbox1.getCenterLocal(), LLVector3(3.0f, 5.0f, 7.0f)); + + LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), + LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + + ensure_equals("Custom bbox center local with rot", bbox2.getCenterLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + } + + template<> template<> + void object::test<6>() + { + // + // test the getCenterAgent() + // + + ensure_equals("Default bbox agent center", LLBBox().getCenterAgent(), LLVector3(0.0f, 0.0f, 0.0f)); + + LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), + LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); + + ensure_equals("Custom bbox center agent", bbox1.getCenterAgent(), LLVector3(4.0f, 7.0f, 10.0f)); + + LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), + LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + + ensure("Custom bbox center agent with rot", APPROX_EQUAL(bbox2.getCenterAgent(), LLVector3(-2.0f, 4.0f, 4.0f))); + } + + template<> template<> + void object::test<7>() + { + // + // test the getExtentLocal() method + // + + ensure_equals("Default bbox local extent", LLBBox().getExtentLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + + LLBBox bbox1(LLVector3(1.0f, 2.0f, 3.0f), LLQuaternion(), + LLVector3(2.0f, 4.0f, 6.0f), LLVector3(4.0f, 6.0f, 8.0f)); + + ensure_equals("Custom bbox extent local", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f)); + + LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(0.0f, 0.0f, 1.0f)), + LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + + ensure_equals("Custom bbox extent local with rot", bbox1.getExtentLocal(), LLVector3(2.0f, 2.0f, 2.0f)); + } + + template<> template<> + void object::test<8>() + { + // + // test the addPointLocal() method + // + + LLBBox bbox1; + bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); + bbox1.addPointLocal(LLVector3(3.0f, 3.0f, 3.0f)); + + ensure_equals("addPointLocal center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); + ensure_equals("addPointLocal center agent (1)", bbox1.getCenterAgent(), LLVector3(2.0f, 2.0f, 2.0f)); + ensure_equals("addPointLocal min (1)", bbox1.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); + ensure_equals("addPointLocal max (1)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + + bbox1.addPointLocal(LLVector3(0.0f, 0.0f, 0.0f)); + bbox1.addPointLocal(LLVector3(1.0f, 1.0f, 1.0f)); + bbox1.addPointLocal(LLVector3(2.0f, 2.0f, 2.0f)); + + ensure_equals("addPointLocal center local (2)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); + ensure_equals("addPointLocal min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + ensure_equals("addPointLocal max (2)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + } + + template<> template<> + void object::test<9>() + { + // + // test the addBBoxLocal() method + // + + LLBBox bbox1; + bbox1.addBBoxLocal(LLBBox(LLVector3(), LLQuaternion(), + LLVector3(0.0f, 0.0f, 0.0f), LLVector3(3.0f, 3.0f, 3.0f))); + + ensure_equals("addPointLocal center local (3)", bbox1.getCenterLocal(), LLVector3(1.5f, 1.5f, 1.5f)); + ensure_equals("addPointLocal min (3)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + ensure_equals("addPointLocal max (3)", bbox1.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + + bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), + LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); + + ensure_equals("addPointLocal center local (4)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 5.0f)); + ensure_equals("addPointLocal center agent (4)", bbox1.getCenterAgent(), LLVector3(5.0f, 5.0f, 5.0f)); + ensure_equals("addPointLocal min (4)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + ensure_equals("addPointLocal max (4)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f)); + } + + template<> template<> + void object::test<10>() + { + // + // test the addPointAgent() method + // + + LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), + LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + + bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); + bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); + + ensure_equals("addPointAgent center local (1)", bbox1.getCenterLocal(), LLVector3(2.0f, 2.0f, -2.0f)); + ensure_equals("addPointAgent center agent (1)", bbox1.getCenterAgent(), LLVector3(3.0f, 3.0f, 7.0f)); + ensure_equals("addPointAgent min (1)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); + ensure_equals("addPointAgent max (1)", bbox1.getMaxLocal(), LLVector3(4.0f, 4.0f, 0.0f)); + } + + template<> template<> + void object::test<11>() + { + // + // test the addBBoxAgent() method + // + + LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(1.0, 0.0, 0.0, 1.0), + LLVector3(2.0f, 2.0f, 2.0f), LLVector3(4.0f, 4.0f, 4.0f)); + + bbox1.addPointAgent(LLVector3(1.0f, 1.0f, 1.0f)); + bbox1.addPointAgent(LLVector3(3.0f, 3.0f, 3.0f)); + + bbox1.addBBoxLocal(LLBBox(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), + LLVector3(5.0f, 5.0f, 5.0f), LLVector3(10.0f, 10.0f, 10.0f))); + + ensure_equals("addPointAgent center local (2)", bbox1.getCenterLocal(), LLVector3(5.0f, 5.0f, 3.0f)); + ensure_equals("addPointAgent center agent (2)", bbox1.getCenterAgent(), LLVector3(6.0f, -10.0f, 8.0f)); + ensure_equals("addPointAgent min (2)", bbox1.getMinLocal(), LLVector3(0.0f, 0.0f, -4.0f)); + ensure_equals("addPointAgent max (2)", bbox1.getMaxLocal(), LLVector3(10.0f, 10.0f, 10.0f)); + } + + template<> template<> + void object::test<12>() + { + // + // test the expand() method + // + + LLBBox bbox1; + bbox1.expand(0.0); + + ensure_equals("Zero-expanded Default BBox center", bbox1.getCenterLocal(), LLVector3(0.0f, 0.0f, 0.0f)); + + LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), + LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + bbox2.expand(0.0); + + ensure_equals("Zero-expanded center local", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); + ensure_equals("Zero-expanded center agent", bbox2.getCenterAgent(), LLVector3(3.0f, 3.0f, 3.0f)); + ensure_equals("Zero-expanded min", bbox2.getMinLocal(), LLVector3(1.0f, 1.0f, 1.0f)); + ensure_equals("Zero-expanded max", bbox2.getMaxLocal(), LLVector3(3.0f, 3.0f, 3.0f)); + + bbox2.expand(0.5); + + ensure_equals("Positive-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); + ensure_equals("Positive-expanded min", bbox2.getMinLocal(), LLVector3(0.5f, 0.5f, 0.5f)); + ensure_equals("Positive-expanded max", bbox2.getMaxLocal(), LLVector3(3.5f, 3.5f, 3.5f)); + + bbox2.expand(-1.0); + + ensure_equals("Negative-expanded center", bbox2.getCenterLocal(), LLVector3(2.0f, 2.0f, 2.0f)); + ensure_equals("Negative-expanded min", bbox2.getMinLocal(), LLVector3(1.5f, 1.5f, 1.5f)); + ensure_equals("Negative-expanded max", bbox2.getMaxLocal(), LLVector3(2.5f, 2.5f, 2.5f)); + } + + template<> template<> + void object::test<13>() + { + // + // test the localToAgent() method + // + + LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), + LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + + ensure_equals("localToAgent(1,2,3)", bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, 3.0f, 4.0f)); + + LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), + LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + + ensure("localToAgent(1,2,3) rot", APPROX_EQUAL(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(2.0f, -2.0f, 3.0f))); + } + + template<> template<> + void object::test<14>() + { + // + // test the agentToLocal() method + // + + LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), + LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + + ensure_equals("agentToLocal(1,2,3)", bbox1.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 1.0f, 2.0f)); + ensure_equals("agentToLocal(localToAgent)", bbox1.agentToLocal(bbox1.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), + LLVector3(1.0f, 2.0f, 3.0f)); + + LLBBox bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(ANGLE, LLVector3(1.0f, 0.0f, 0.0f)), + LLVector3(1.0f, 1.0f, 1.0f), LLVector3(3.0f, 3.0f, 3.0f)); + + ensure("agentToLocal(1,2,3) rot", APPROX_EQUAL(bbox2.agentToLocal(LLVector3(1.0f, 2.0f, 3.0f)), LLVector3(0.0f, 2.0f, -1.0f))); + ensure("agentToLocal(localToAgent) rot", APPROX_EQUAL(bbox2.agentToLocal(bbox2.localToAgent(LLVector3(1.0f, 2.0f, 3.0f))), + LLVector3(1.0f, 2.0f, 3.0f))); + } + + template<> template<> + void object::test<15>() + { + // + // test the containsPointLocal() method + // + + LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), + LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); + + ensure("containsPointLocal(0,0,0)", bbox1.containsPointLocal(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); + ensure("containsPointLocal(1,2,3)", bbox1.containsPointLocal(LLVector3(1.0f, 2.0f, 3.0f)) == TRUE); + ensure("containsPointLocal(0.999,2,3)", bbox1.containsPointLocal(LLVector3(0.999f, 2.0f, 3.0f)) == FALSE); + ensure("containsPointLocal(3,4,5)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.0f)) == TRUE); + ensure("containsPointLocal(3,4,5.001)", bbox1.containsPointLocal(LLVector3(3.0f, 4.0f, 5.001f)) == FALSE); + } + + template<> template<> + void object::test<16>() + { + // + // test the containsPointAgent() method + // + + LLBBox bbox1(LLVector3(1.0f, 1.0f, 1.0f), LLQuaternion(), + LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); + + ensure("containsPointAgent(0,0,0)", bbox1.containsPointAgent(LLVector3(0.0f, 0.0f, 0.0f)) == FALSE); + ensure("containsPointAgent(2,3,4)", bbox1.containsPointAgent(LLVector3(2.0f, 3.0f, 4.0f)) == TRUE); + ensure("containsPointAgent(2,2.999,4)", bbox1.containsPointAgent(LLVector3(2.0f, 2.999f, 4.0f)) == FALSE); + ensure("containsPointAgent(4,5,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.0f, 6.0f)) == TRUE); + ensure("containsPointAgent(4,5.001,6)", bbox1.containsPointAgent(LLVector3(4.0f, 5.001f, 6.0f)) == FALSE); + } +} + diff --git a/indra/llmath/tests/llbboxlocal_test.cpp b/indra/llmath/tests/llbboxlocal_test.cpp new file mode 100644 index 0000000000..91a303201b --- /dev/null +++ b/indra/llmath/tests/llbboxlocal_test.cpp @@ -0,0 +1,238 @@ +/** + * @file llbboxlocal_tut.cpp + * @author Martin Reddy + * @date 2009-06-25 + * @brief Test for llbboxlocal.cpp. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" +#include "../llbboxlocal.h" + +namespace tut +{ + struct LLBBoxLocalData + { + }; + + typedef test_group<LLBBoxLocalData> factory; + typedef factory::object object; +} + +namespace +{ + tut::factory llbboxlocal_test_factory("LLBBoxLocal"); +} + +namespace tut +{ + template<> template<> + void object::test<1>() + { + // + // test the default constructor + // + + LLBBoxLocal bbox1; + + ensure_equals("Default bbox min", bbox1.getMin(), LLVector3(0.0f, 0.0f, 0.0f)); + ensure_equals("Default bbox max", bbox1.getMax(), LLVector3(0.0f, 0.0f, 0.0f)); + } + + template<> template<> + void object::test<2>() + { + // + // test the non-default constructor + // + + LLBBoxLocal bbox2(LLVector3(-1.0f, -2.0f, 0.0f), LLVector3(1.0f, 2.0f, 3.0f)); + + ensure_equals("Custom bbox min", bbox2.getMin(), LLVector3(-1.0f, -2.0f, 0.0f)); + ensure_equals("Custom bbox max", bbox2.getMax(), LLVector3(1.0f, 2.0f, 3.0f)); + } + + template<> template<> + void object::test<3>() + { + // + // test the setMin() + // + // N.B. no validation is currently performed to ensure that the min + // and max vectors are actually the min/max values. + // + + LLBBoxLocal bbox2; + bbox2.setMin(LLVector3(1.0f, 2.0f, 3.0f)); + + ensure_equals("Custom bbox min (2)", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); + } + + template<> template<> + void object::test<4>() + { + // + // test the setMax() + // + // N.B. no validation is currently performed to ensure that the min + // and max vectors are actually the min/max values. + // + + LLBBoxLocal bbox2; + bbox2.setMax(LLVector3(10.0f, 20.0f, 30.0f)); + + ensure_equals("Custom bbox max (2)", bbox2.getMax(), LLVector3(10.0f, 20.0f, 30.0f)); + } + + template<> template<> + void object::test<5>() + { + // + // test the getCenter() method + // + + ensure_equals("Default bbox center", LLBBoxLocal().getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); + + LLBBoxLocal bbox1(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f)); + + ensure_equals("Custom bbox center", bbox1.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); + + LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); + + ensure_equals("Invalid bbox center", bbox2.getCenter(), LLVector3(-0.5f, -0.5f, -0.5f)); + } + + template<> template<> + void object::test<6>() + { + // + // test the getExtent() method + // + + LLBBoxLocal bbox2(LLVector3(0.0f, 0.0f, 0.0f), LLVector3(-1.0f, -1.0f, -1.0f)); + + ensure_equals("Default bbox extent", LLBBoxLocal().getExtent(), LLVector3(0.0f, 0.0f, 0.0f)); + + LLBBoxLocal bbox3(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(1.0f, 2.0f, 0.0f)); + + ensure_equals("Custom bbox extent", bbox3.getExtent(), LLVector3(2.0f, 3.0f, 1.0f)); + } + + template<> template<> + void object::test<7>() + { + // + // test the addPoint() method + // + // N.B. if you create an empty bbox and then add points, + // the vector (0, 0, 0) will always be part of the bbox. + // (Fixing this would require adding a bool to the class size). + // + + LLBBoxLocal bbox1; + bbox1.addPoint(LLVector3(-1.0f, -2.0f, -3.0f)); + bbox1.addPoint(LLVector3(3.0f, 4.0f, 5.0f)); + + ensure_equals("Custom BBox center (1)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); + ensure_equals("Custom BBox min (1)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); + ensure_equals("Custom BBox max (1)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); + + bbox1.addPoint(LLVector3(0.0f, 0.0f, 0.0f)); + bbox1.addPoint(LLVector3(1.0f, 2.0f, 3.0f)); + bbox1.addPoint(LLVector3(2.0f, 2.0f, 2.0f)); + + ensure_equals("Custom BBox center (2)", bbox1.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); + ensure_equals("Custom BBox min (2)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); + ensure_equals("Custom BBox max (2)", bbox1.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); + + bbox1.addPoint(LLVector3(5.0f, 5.0f, 5.0f)); + + ensure_equals("Custom BBox center (3)", bbox1.getCenter(), LLVector3(2.0f, 1.5f, 1.0f)); + ensure_equals("Custom BBox min (3)", bbox1.getMin(), LLVector3(-1.0f, -2.0f, -3.0f)); + ensure_equals("Custom BBox max (3)", bbox1.getMax(), LLVector3(5.0f, 5.0f, 5.0f)); + } + + template<> template<> + void object::test<8>() + { + // + // test the addBBox() methods + // + // N.B. if you create an empty bbox and then add points, + // the vector (0, 0, 0) will always be part of the bbox. + // (Fixing this would require adding a bool to the class size). + // + + LLBBoxLocal bbox2(LLVector3(1.0f, 1.0f, 1.0f), LLVector3(2.0f, 2.0f, 2.0f)); + bbox2.addBBox(LLBBoxLocal(LLVector3(1.5f, 1.5f, 1.5f), LLVector3(3.0f, 3.0f, 3.0f))); + + ensure_equals("Custom BBox center (4)", bbox2.getCenter(), LLVector3(2.0f, 2.0f, 2.0f)); + ensure_equals("Custom BBox min (4)", bbox2.getMin(), LLVector3(1.0f, 1.0f, 1.0f)); + ensure_equals("Custom BBox max (4)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); + + bbox2.addBBox(LLBBoxLocal(LLVector3(-1.0f, -1.0f, -1.0f), LLVector3(0.0f, 0.0f, 0.0f))); + + ensure_equals("Custom BBox center (5)", bbox2.getCenter(), LLVector3(1.0f, 1.0f, 1.0f)); + ensure_equals("Custom BBox min (5)", bbox2.getMin(), LLVector3(-1.0f, -1.0f, -1.0f)); + ensure_equals("Custom BBox max (5)", bbox2.getMax(), LLVector3(3.0f, 3.0f, 3.0f)); + } + + template<> template<> + void object::test<9>() + { + // + // test the expand() method + // + + LLBBoxLocal bbox1; + bbox1.expand(0.0f); + + ensure_equals("Zero-expanded Default BBox center", bbox1.getCenter(), LLVector3(0.0f, 0.0f, 0.0f)); + + LLBBoxLocal bbox2(LLVector3(1.0f, 2.0f, 3.0f), LLVector3(3.0f, 4.0f, 5.0f)); + bbox2.expand(0.0f); + + ensure_equals("Zero-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); + ensure_equals("Zero-expanded BBox min", bbox2.getMin(), LLVector3(1.0f, 2.0f, 3.0f)); + ensure_equals("Zero-expanded BBox max", bbox2.getMax(), LLVector3(3.0f, 4.0f, 5.0f)); + + bbox2.expand(0.5f); + + ensure_equals("Positive-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); + ensure_equals("Positive-expanded BBox min", bbox2.getMin(), LLVector3(0.5f, 1.5f, 2.5f)); + ensure_equals("Positive-expanded BBox max", bbox2.getMax(), LLVector3(3.5f, 4.5f, 5.5f)); + + bbox2.expand(-1.0f); + + ensure_equals("Negative-expanded BBox center", bbox2.getCenter(), LLVector3(2.0f, 3.0f, 4.0f)); + ensure_equals("Negative-expanded BBox min", bbox2.getMin(), LLVector3(1.5f, 2.5f, 3.5f)); + ensure_equals("Negative-expanded BBox max", bbox2.getMax(), LLVector3(2.5f, 3.5f, 4.5f)); + } +} diff --git a/indra/llmath/tests/llmodularmath_test.cpp b/indra/llmath/tests/llmodularmath_test.cpp new file mode 100644 index 0000000000..a998a95618 --- /dev/null +++ b/indra/llmath/tests/llmodularmath_test.cpp @@ -0,0 +1,82 @@ +/** + * @file modularmath_tut.cpp + * @author babbage + * @date 2008-09 + * @brief llmodularmath tests + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../llmodularmath.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct modularmath_data + { + }; + typedef test_group<modularmath_data> modularmath_test; + typedef modularmath_test::object modularmath_object; + tut::modularmath_test modularmath_testcase("modularmath"); + + template<> template<> + void modularmath_object::test<1>() + { + // lhs < rhs + const U32 lhs = 0x000001; + const U32 rhs = 0xFFFFFF; + const U32 width = 24; + U32 result = LLModularMath::subtract<width>(lhs, rhs); + ensure_equals("diff(0x000001, 0xFFFFFF, 24)", result, 2); + } + + template<> template<> + void modularmath_object::test<2>() + { + // lhs > rhs + const U32 lhs = 0x000002; + const U32 rhs = 0x000001; + const U32 width = 24; + U32 result = LLModularMath::subtract<width>(lhs, rhs); + ensure_equals("diff(0x000002, 0x000001, 24)", result, 1); + } + + template<> template<> + void modularmath_object::test<3>() + { + // lhs == rhs + const U32 lhs = 0xABCDEF; + const U32 rhs = 0xABCDEF; + const U32 width = 24; + U32 result = LLModularMath::subtract<width>(lhs, rhs); + ensure_equals("diff(0xABCDEF, 0xABCDEF, 24)", result, 0); + } +} diff --git a/indra/llmath/tests/llquaternion_test.cpp b/indra/llmath/tests/llquaternion_test.cpp new file mode 100644 index 0000000000..bfa475d91b --- /dev/null +++ b/indra/llmath/tests/llquaternion_test.cpp @@ -0,0 +1,666 @@ +/** + * @file llquaternion_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief Test cases of llquaternion.h + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../llquaternion.h" +#include "../v4math.h" +#include "../v3math.h" +#include "../v3dmath.h" +#include "../m4math.h" +#include "../m3math.h" + +namespace tut +{ + struct llquat_test + { + }; + typedef test_group<llquat_test> llquat_test_t; + typedef llquat_test_t::object llquat_test_object_t; + tut::llquat_test_t tut_llquat_test("llquat"); + + //test case for LLQuaternion::LLQuaternion(void) fn. + template<> template<> + void llquat_test_object_t::test<1>() + { + LLQuaternion llquat; + ensure("LLQuaternion::LLQuaternion() failed", 0.f == llquat.mQ[0] && + 0.f == llquat.mQ[1] && + 0.f == llquat.mQ[2] && + 1.f == llquat.mQ[3]); + } + + //test case for explicit LLQuaternion(const LLMatrix4 &mat) fn. + template<> template<> + void llquat_test_object_t::test<2>() + { + LLMatrix4 llmat; + LLVector4 vector1(2.0f, 1.0f, 3.0f, 6.0f); + LLVector4 vector2(5.0f, 6.0f, 0.0f, 1.0f); + LLVector4 vector3(2.0f, 1.0f, 2.0f, 9.0f); + LLVector4 vector4(3.0f, 8.0f, 1.0f, 5.0f); + + llmat.initRows(vector1, vector2, vector3, vector4); + ensure("explicit LLQuaternion(const LLMatrix4 &mat) failed", 2.0f == llmat.mMatrix[0][0] && + 1.0f == llmat.mMatrix[0][1] && + 3.0f == llmat.mMatrix[0][2] && + 6.0f == llmat.mMatrix[0][3] && + 5.0f == llmat.mMatrix[1][0] && + 6.0f == llmat.mMatrix[1][1] && + 0.0f == llmat.mMatrix[1][2] && + 1.0f == llmat.mMatrix[1][3] && + 2.0f == llmat.mMatrix[2][0] && + 1.0f == llmat.mMatrix[2][1] && + 2.0f == llmat.mMatrix[2][2] && + 9.0f == llmat.mMatrix[2][3] && + 3.0f == llmat.mMatrix[3][0] && + 8.0f == llmat.mMatrix[3][1] && + 1.0f == llmat.mMatrix[3][2] && + 5.0f == llmat.mMatrix[3][3]); + } + + template<> template<> + void llquat_test_object_t::test<3>() + { + LLMatrix3 llmat; + + LLVector3 vect1(3.4028234660000000f , 234.56f, 4234.442234f); + LLVector3 vect2(741.434f, 23.00034f, 6567.223423f); + LLVector3 vect3(566.003034f, 12.98705f, 234.764423f); + llmat.setRows(vect1, vect2, vect3); + + ensure("LLMatrix3::setRows fn failed.", 3.4028234660000000f == llmat.mMatrix[0][0] && + 234.56f == llmat.mMatrix[0][1] && + 4234.442234f == llmat.mMatrix[0][2] && + 741.434f == llmat.mMatrix[1][0] && + 23.00034f == llmat.mMatrix[1][1] && + 6567.223423f == llmat.mMatrix[1][2] && + 566.003034f == llmat.mMatrix[2][0] && + 12.98705f == llmat.mMatrix[2][1] && + 234.764423f == llmat.mMatrix[2][2]); + } + + //test case for LLQuaternion(F32 x, F32 y, F32 z, F32 w), setQuatInit() and normQuat() fns. + template<> template<> + void llquat_test_object_t::test<4>() + { + F32 x_val = 3.0f; + F32 y_val = 2.0f; + F32 z_val = 6.0f; + F32 w_val = 1.0f; + + LLQuaternion res_quat; + res_quat.setQuatInit(x_val, y_val, z_val, w_val); + res_quat.normQuat(); + + ensure("LLQuaternion::normQuat() fn failed", + is_approx_equal(0.42426407f, res_quat.mQ[0]) && + is_approx_equal(0.28284273f, res_quat.mQ[1]) && + is_approx_equal(0.84852815f, res_quat.mQ[2]) && + is_approx_equal(0.14142136f, res_quat.mQ[3])); + + x_val = 0.0f; + y_val = 0.0f; + z_val = 0.0f; + w_val = 0.0f; + + res_quat.setQuatInit(x_val, y_val, z_val, w_val); + res_quat.normQuat(); + + ensure("LLQuaternion::normQuat() fn. failed.", + is_approx_equal(0.0f, res_quat.mQ[0]) && + is_approx_equal(0.0f, res_quat.mQ[1]) && + is_approx_equal(0.0f, res_quat.mQ[2]) && + is_approx_equal(1.0f, res_quat.mQ[3])); + + + ensure("LLQuaternion::normQuat() fn. failed.", + is_approx_equal(0.0f, res_quat.mQ[0]) && + is_approx_equal(0.0f, res_quat.mQ[1]) && + is_approx_equal(0.0f, res_quat.mQ[2]) && + is_approx_equal(1.0f, res_quat.mQ[3])); + } + + //test case for conjQuat() and transQuat() fns. + template<> template<> + void llquat_test_object_t::test<5>() + { + F32 x_val = 3.0f; + F32 y_val = 2.0f; + F32 z_val = 6.0f; + F32 w_val = 1.0f; + + LLQuaternion res_quat; + LLQuaternion result, result1; + result1 = result = res_quat.setQuatInit(x_val, y_val, z_val, w_val); + + result.conjQuat(); + result1.transQuat(); + + ensure("LLQuaternion::conjQuat and LLQuaternion::transQuat failed ", + is_approx_equal(result1.mQ[0], result.mQ[0]) && + is_approx_equal(result1.mQ[1], result.mQ[1]) && + is_approx_equal(result1.mQ[2], result.mQ[2])); + + } + + //test case for dot(const LLQuaternion &a, const LLQuaternion &b) fn. + template<> template<> + void llquat_test_object_t::test<6>() + { + LLQuaternion quat1(3.0f, 2.0f, 6.0f, 0.0f), quat2(1.0f, 1.0f, 1.0f, 1.0f); + ensure("1. The two values are different", llround(12.000000f, 2) == llround(dot(quat1, quat2), 2)); + + LLQuaternion quat0(3.0f, 9.334f, 34.5f, 23.0f), quat(34.5f, 23.23f, 2.0f, 45.5f); + ensure("2. The two values are different", llround(1435.828807f, 2) == llround(dot(quat0, quat), 2)); + } + + //test case for LLQuaternion &LLQuaternion::constrain(F32 radians) fn. + template<> template<> + void llquat_test_object_t::test<7>() + { + F32 radian = 60.0f; + LLQuaternion quat(3.0f, 2.0f, 6.0f, 0.0f); + LLQuaternion quat1; + quat1 = quat.constrain(radian); + ensure("1. LLQuaternion::constrain(F32 radians) failed", + is_approx_equal_fraction(-0.423442f, quat1.mQ[0], 8) && + is_approx_equal_fraction(-0.282295f, quat1.mQ[1], 8) && + is_approx_equal_fraction(-0.846884f, quat1.mQ[2], 8) && + is_approx_equal_fraction(0.154251f, quat1.mQ[3], 8)); + + + radian = 30.0f; + LLQuaternion quat0(37.50f, 12.0f, 86.023f, 40.32f); + quat1 = quat0.constrain(radian); + + ensure("2. LLQuaternion::constrain(F32 radians) failed", + is_approx_equal_fraction(37.500000f, quat1.mQ[0], 8) && + is_approx_equal_fraction(12.0000f, quat1.mQ[1], 8) && + is_approx_equal_fraction(86.0230f, quat1.mQ[2], 8) && + is_approx_equal_fraction(40.320000f, quat1.mQ[3], 8)); + } + + template<> template<> + void llquat_test_object_t::test<8>() + { + F32 value1 = 15.0f; + LLQuaternion quat1(1.0f, 2.0f, 4.0f, 1.0f); + LLQuaternion quat2(4.0f, 3.0f, 6.5f, 9.7f); + LLQuaternion res_lerp, res_slerp, res_nlerp; + + //test case for lerp(F32 t, const LLQuaternion &q) fn. + res_lerp = lerp(value1, quat1); + ensure("1. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed", + is_approx_equal_fraction(0.181355f, res_lerp.mQ[0], 16) && + is_approx_equal_fraction(0.362711f, res_lerp.mQ[1], 16) && + is_approx_equal_fraction(0.725423f, res_lerp.mQ[2], 16) && + is_approx_equal_fraction(0.556158f, res_lerp.mQ[3], 16)); + + //test case for lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) fn. + res_lerp = lerp(value1, quat1, quat2); + ensure("2. LLQuaternion lerp(F32 t, const LLQuaternion &p, const LLQuaternion &q) failed", + is_approx_equal_fraction(0.314306f, res_lerp.mQ[0], 16) && + is_approx_equal_fraction(0.116156f, res_lerp.mQ[1], 16) && + is_approx_equal_fraction(0.283559f, res_lerp.mQ[2], 16) && + is_approx_equal_fraction(0.898506f, res_lerp.mQ[3], 16)); + + //test case for slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b ) fn. + res_slerp = slerp(value1, quat1, quat2); + ensure("3. LLQuaternion slerp( F32 u, const LLQuaternion &a, const LLQuaternion &b) failed", + is_approx_equal_fraction(46.000f, res_slerp.mQ[0], 16) && + is_approx_equal_fraction(17.00f, res_slerp.mQ[1], 16) && + is_approx_equal_fraction(41.5f, res_slerp.mQ[2], 16) && + is_approx_equal_fraction(131.5f, res_slerp.mQ[3], 16)); + + //test case for nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) fn. + res_nlerp = nlerp(value1, quat1, quat2); + ensure("4. LLQuaternion nlerp(F32 t, const LLQuaternion &a, const LLQuaternion &b) failed", + is_approx_equal_fraction(0.314306f, res_nlerp.mQ[0], 16) && + is_approx_equal_fraction(0.116157f, res_nlerp.mQ[1], 16) && + is_approx_equal_fraction(0.283559f, res_nlerp.mQ[2], 16) && + is_approx_equal_fraction(0.898506f, res_nlerp.mQ[3], 16)); + + //test case for nlerp(F32 t, const LLQuaternion &q) fn. + res_slerp = slerp(value1, quat1); + ensure("5. LLQuaternion slerp(F32 t, const LLQuaternion &q) failed", + is_approx_equal_fraction(1.0f, res_slerp.mQ[0], 16) && + is_approx_equal_fraction(2.0f, res_slerp.mQ[1], 16) && + is_approx_equal_fraction(4.0000f, res_slerp.mQ[2], 16) && + is_approx_equal_fraction(1.000f, res_slerp.mQ[3], 16)); + + LLQuaternion quat3(2.0f, 1.0f, 5.5f, 10.5f); + LLQuaternion res_nlerp1; + value1 = 100.0f; + res_nlerp1 = nlerp(value1, quat3); + ensure("6. LLQuaternion nlerp(F32 t, const LLQuaternion &q) failed", + is_approx_equal_fraction(0.268245f, res_nlerp1.mQ[0], 16) && is_approx_equal_fraction(0.134122f, res_nlerp1.mQ[1], 2) && + is_approx_equal_fraction(0.737673f, res_nlerp1.mQ[2], 16) && + is_approx_equal_fraction(0.604892f, res_nlerp1.mQ[3], 16)); + + //test case for lerp(F32 t, const LLQuaternion &q) fn. + res_lerp = lerp(value1, quat2); + ensure("7. LLQuaternion lerp(F32 t, const LLQuaternion &q) failed", + is_approx_equal_fraction(0.404867f, res_lerp.mQ[0], 16) && + is_approx_equal_fraction(0.303650f, res_lerp.mQ[1], 16) && + is_approx_equal_fraction(0.657909f, res_lerp.mQ[2], 16) && + is_approx_equal_fraction(0.557704f, res_lerp.mQ[3], 16)); + + } + + template<> template<> + void llquat_test_object_t::test<9>() + { + //test case for LLQuaternion operator*(const LLQuaternion &a, const LLQuaternion &b) fn + LLQuaternion quat1(1.0f, 2.5f, 3.5f, 5.5f); + LLQuaternion quat2(4.0f, 3.0f, 5.0f, 1.0f); + LLQuaternion result = quat1 * quat2; + ensure("1. LLQuaternion Operator* failed", (21.0f == result.mQ[0]) && + (10.0f == result.mQ[1]) && + (38.0f == result.mQ[2]) && + (-23.5f == result.mQ[3])); + + LLQuaternion quat3(2341.340f, 2352.345f, 233.25f, 7645.5f); + LLQuaternion quat4(674.067f, 893.0897f, 578.0f, 231.0f); + result = quat3 * quat4; + ensure("2. LLQuaternion Operator* failed", (4543086.5f == result.mQ[0]) && + (8567578.0f == result.mQ[1]) && + (3967591.25f == result.mQ[2]) && + is_approx_equal(-2047783.25f, result.mQ[3])); + + //inline LLQuaternion operator+(const LLQuaternion &a, const LLQuaternion &b)fn. + result = quat1 + quat2; + ensure("3. LLQuaternion operator+ failed", (5.0f == result.mQ[0]) && + (5.5f == result.mQ[1]) && + (8.5f == result.mQ[2]) && + (6.5f == result.mQ[3])); + + result = quat3 + quat4; + ensure( + "4. LLQuaternion operator+ failed", + is_approx_equal(3015.407227f, result.mQ[0]) && + is_approx_equal(3245.434570f, result.mQ[1]) && + (811.25f == result.mQ[2]) && + (7876.5f == result.mQ[3])); + + //inline LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) fn + result = quat1 - quat2; + ensure( + "5. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed", + (-3.0f == result.mQ[0]) && + (-0.5f == result.mQ[1]) && + (-1.5f == result.mQ[2]) && + (4.5f == result.mQ[3])); + + result = quat3 - quat4; + ensure( + "6. LLQuaternion operator-(const LLQuaternion &a, const LLQuaternion &b) failed", + is_approx_equal(1667.273071f, result.mQ[0]) && + is_approx_equal(1459.255249f, result.mQ[1]) && + (-344.75f == result.mQ[2]) && + (7414.50f == result.mQ[3])); + } + + //test case for LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) fn. + template<> template<> + void llquat_test_object_t::test<10>() + { + LLVector4 vect(12.0f, 5.0f, 60.0f, 75.1f); + LLQuaternion quat(2323.034f, 23.5f, 673.23f, 57667.5f); + LLVector4 result = vect * quat; + ensure( + "1. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed", + is_approx_equal(39928406016.0f, result.mV[0]) && + // gcc on x86 actually gives us more precision than we were expecting, verified with -ffloat-store - we forgive this + (1457802240.0f >= result.mV[1]) && // gcc+x86+linux + (1457800960.0f <= result.mV[1]) && // elsewhere + is_approx_equal(200580612096.0f, result.mV[2]) && + (75.099998f == result.mV[3])); + + LLVector4 vect1(22.0f, 45.0f, 40.0f, 78.1f); + LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); + result = vect1 * quat1; + ensure( + "2. LLVector4 operator*(const LLVector4 &a, const LLQuaternion &rot) failed", + is_approx_equal(-58153.5390f, result.mV[0]) && + (183787.8125f == result.mV[1]) && + (116864.164063f == result.mV[2]) && + (78.099998f == result.mV[3])); + } + + //test case for LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) fn. + template<> template<> + void llquat_test_object_t::test<11>() + { + LLVector3 vect(12.0f, 5.0f, 60.0f); + LLQuaternion quat(23.5f, 6.5f, 3.23f, 56.5f); + LLVector3 result = vect * quat; + ensure( + "1. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed", + is_approx_equal(97182.953125f,result.mV[0]) && + is_approx_equal(-135405.640625f, result.mV[1]) && + is_approx_equal(162986.140f, result.mV[2])); + + LLVector3 vect1(5.0f, 40.0f, 78.1f); + LLQuaternion quat1(2.034f, 45.5f, 37.23f, 7.5f); + result = vect1 * quat1; + ensure( + "2. LLVector3 operator*(const LLVector3 &a, const LLQuaternion &rot) failed", + is_approx_equal(33217.703f, result.mV[0]) && + is_approx_equal(295383.8125f, result.mV[1]) && + is_approx_equal(84718.140f, result.mV[2])); + } + + //test case for LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) fn. + template<> template<> + void llquat_test_object_t::test<12>() + { + LLVector3d vect(-2.0f, 5.0f, -6.0f); + LLQuaternion quat(-3.5f, 4.5f, 3.5f, 6.5f); + LLVector3d result = vect * quat; + ensure( + "1. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed ", + (-633.0f == result.mdV[0]) && + (-300.0f == result.mdV[1]) && + (-36.0f == result.mdV[2])); + + LLVector3d vect1(5.0f, -4.5f, 8.21f); + LLQuaternion quat1(2.0f, 4.5f, -7.2f, 9.5f); + result = vect1 * quat1; + ensure( + "2. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed", + is_approx_equal_fraction(-120.29f, (F32) result.mdV[0], 8) && + is_approx_equal_fraction(-1683.958f, (F32) result.mdV[1], 8) && + is_approx_equal_fraction(516.56f, (F32) result.mdV[2], 8)); + + LLVector3d vect2(2.0f, 3.5f, 1.1f); + LLQuaternion quat2(1.0f, 4.0f, 2.0f, 5.0f); + result = vect2 * quat2; + ensure( + "3. LLVector3d operator*(const LLVector3d &a, const LLQuaternion &rot) failed", + is_approx_equal_fraction(18.400001f, (F32) result.mdV[0], 8) && + is_approx_equal_fraction(188.6f, (F32) result.mdV[1], 8) && + is_approx_equal_fraction(32.20f, (F32) result.mdV[2], 8)); + } + + //test case for inline LLQuaternion operator-(const LLQuaternion &a) fn. + template<> template<> + void llquat_test_object_t::test<13>() + { + LLQuaternion quat(23.5f, 34.5f, 16723.4f, 324.7f); + LLQuaternion result = -quat; + ensure( + "1. LLQuaternion operator-(const LLQuaternion &a) failed", + (-23.5f == result.mQ[0]) && + (-34.5f == result.mQ[1]) && + (-16723.4f == result.mQ[2]) && + (-324.7f == result.mQ[3])); + + LLQuaternion quat1(-3.5f, -34.5f, -16.4f, -154.7f); + result = -quat1; + ensure( + "2. LLQuaternion operator-(const LLQuaternion &a) failed.", + (3.5f == result.mQ[0]) && + (34.5f == result.mQ[1]) && + (16.4f == result.mQ[2]) && + (154.7f == result.mQ[3])); + } + + //test case for inline LLQuaternion operator*(F32 a, const LLQuaternion &q) and + //inline LLQuaternion operator*(F32 a, const LLQuaternion &q) fns. + template<> template<> + void llquat_test_object_t::test<14>() + { + LLQuaternion quat_value(9.0f, 8.0f, 7.0f, 6.0f); + F32 a =3.5f; + LLQuaternion result = a * quat_value; + LLQuaternion result1 = quat_value * a; + + ensure( + "1. LLQuaternion operator* failed", + (result.mQ[0] == result1.mQ[0]) && + (result.mQ[1] == result1.mQ[1]) && + (result.mQ[2] == result1.mQ[2]) && + (result.mQ[3] == result1.mQ[3])); + + + LLQuaternion quat_val(9454.0f, 43568.3450f, 456343247.0343f, 2346.03434f); + a =-3324.3445f; + result = a * quat_val; + result1 = quat_val * a; + + ensure( + "2. LLQuaternion operator* failed", + (result.mQ[0] == result1.mQ[0]) && + (result.mQ[1] == result1.mQ[1]) && + (result.mQ[2] == result1.mQ[2]) && + (result.mQ[3] == result1.mQ[3])); + } + + template<> template<> + void llquat_test_object_t::test<15>() + { + // test cases for inline LLQuaternion operator~(const LLQuaternion &a) + LLQuaternion quat_val(2323.634f, -43535.4f, 3455.88f, -32232.45f); + LLQuaternion result = ~quat_val; + ensure( + "1. LLQuaternion operator~(const LLQuaternion &a) failed ", + (-2323.634f == result.mQ[0]) && + (43535.4f == result.mQ[1]) && + (-3455.88f == result.mQ[2]) && + (-32232.45f == result.mQ[3])); + + //test case for inline bool LLQuaternion::operator==(const LLQuaternion &b) const + LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); + LLQuaternion quat_val2(2323.634f, -43535.4f, 3455.88f, -32232.45f); + ensure( + "2. LLQuaternion::operator==(const LLQuaternion &b) failed", + quat_val1 == quat_val2); + } + + template<> template<> + void llquat_test_object_t::test<16>() + { + //test case for inline bool LLQuaternion::operator!=(const LLQuaternion &b) const + LLQuaternion quat_val1(2323.634f, -43535.4f, 3455.88f, -32232.45f); + LLQuaternion quat_val2(0, -43535.4f, 3455.88f, -32232.45f); + ensure("LLQuaternion::operator!=(const LLQuaternion &b) failed", quat_val1 != quat_val2); + } + + template<> template<> + void llquat_test_object_t::test<17>() + { + //test case for LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) + F32 x = 2.0f; + F32 y = 1.0f; + F32 z = 3.0f; + + LLQuaternion result = mayaQ(x, y, z, LLQuaternion::XYZ); + ensure( + "1. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", + is_approx_equal_fraction(0.0172174f, result.mQ[0], 16) && + is_approx_equal_fraction(0.009179f, result.mQ[1], 16) && + is_approx_equal_fraction(0.026020f, result.mQ[2], 16) && + is_approx_equal_fraction(0.999471f, result.mQ[3], 16)); + + LLQuaternion result1 = mayaQ(x, y, z, LLQuaternion::YZX); + ensure( + "2. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XYZ", + is_approx_equal_fraction(0.017217f, result1.mQ[0], 16) && + is_approx_equal_fraction(0.008265f, result1.mQ[1], 16) && + is_approx_equal_fraction(0.026324f, result1.mQ[2], 16) && + is_approx_equal_fraction(0.999471f, result1.mQ[3], 16)); + + LLQuaternion result2 = mayaQ(x, y, z, LLQuaternion::ZXY); + ensure( + "3. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZXY", + is_approx_equal_fraction(0.017674f, result2.mQ[0], 16) && + is_approx_equal_fraction(0.008265f, result2.mQ[1], 16) && + is_approx_equal_fraction(0.026020f, result2.mQ[2], 16) && + is_approx_equal_fraction(0.999471f, result2.mQ[3], 16)); + + LLQuaternion result3 = mayaQ(x, y, z, LLQuaternion::XZY); + ensure( + "4. TLLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for XZY", + is_approx_equal_fraction(0.017674f, result3.mQ[0], 16) && + is_approx_equal_fraction(0.009179f, result3.mQ[1], 16) && + is_approx_equal_fraction(0.026020f, result3.mQ[2], 16) && + is_approx_equal_fraction(0.999463f, result3.mQ[3], 16)); + + LLQuaternion result4 = mayaQ(x, y, z, LLQuaternion::YXZ); + ensure( + "5. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for YXZ", + is_approx_equal_fraction(0.017217f, result4.mQ[0], 16) && + is_approx_equal_fraction(0.009179f, result4.mQ[1], 16) && + is_approx_equal_fraction(0.026324f, result4.mQ[2], 16) && + is_approx_equal_fraction(0.999463f, result4.mQ[3], 16)); + + LLQuaternion result5 = mayaQ(x, y, z, LLQuaternion::ZYX); + ensure( + "6. LLQuaternion mayaQ(F32 xRot, F32 yRot, F32 zRot, LLQuaternion::Order order) failed for ZYX", + is_approx_equal_fraction(0.017674f, result5.mQ[0], 16) && + is_approx_equal_fraction(0.008265f, result5.mQ[1], 16) && + is_approx_equal_fraction(0.026324f, result5.mQ[2], 16) && + is_approx_equal_fraction(0.999463f, result5.mQ[3], 16)); + } + + template<> template<> + void llquat_test_object_t::test<18>() + { + // test case for friend std::ostream& operator<<(std::ostream &s, const LLQuaternion &a) fn + LLQuaternion a(1.0f, 1.0f, 1.0f, 1.0f); + std::ostringstream result_value; + result_value << a; + ensure_equals("1. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }"); + + LLQuaternion b(-31.034f, 231.2340f, 3451.344320f, -341.0f); + std::ostringstream result_value1; + result_value1 << b; + ensure_equals("2. Operator << failed", result_value1.str(), "{ -31.034, 231.234, 3451.34, -341 }"); + + LLQuaternion c(1.0f, 2.2f, 3.3f, 4.4f); + result_value << c; + ensure_equals("3. Operator << failed", result_value.str(), "{ 1, 1, 1, 1 }{ 1, 2.2, 3.3, 4.4 }"); + + } + + template<> template<> + void llquat_test_object_t::test<19>() + { + //test case for const char *OrderToString( const LLQuaternion::Order order ) fn + const char* result = OrderToString(LLQuaternion::XYZ); + ensure("1. OrderToString failed for XYZ", (0 == strcmp("XYZ", result))); + + result = OrderToString(LLQuaternion::YZX); + ensure("2. OrderToString failed for YZX", (0 == strcmp("YZX", result))); + + result = OrderToString(LLQuaternion::ZXY); + ensure( + "3. OrderToString failed for ZXY", + (0 == strcmp("ZXY", result)) && + (0 != strcmp("XYZ", result)) && + (0 != strcmp("YXZ", result)) && + (0 != strcmp("ZYX", result)) && + (0 != strcmp("XYZ", result))); + + result = OrderToString(LLQuaternion::XZY); + ensure("4. OrderToString failed for XZY", (0 == strcmp("XZY", result))); + + result = OrderToString(LLQuaternion::ZYX); + ensure("5. OrderToString failed for ZYX", (0 == strcmp("ZYX", result))); + + result = OrderToString(LLQuaternion::YXZ); + ensure("6.OrderToString failed for YXZ", (0 == strcmp("YXZ", result))); + } + + template<> template<> + void llquat_test_object_t::test<20>() + { + //test case for LLQuaternion::Order StringToOrder( const char *str ) fn + int result = StringToOrder("XYZ"); + ensure("1. LLQuaternion::Order StringToOrder(const char *str ) failed for XYZ", 0 == result); + + result = StringToOrder("YZX"); + ensure("2. LLQuaternion::Order StringToOrder(const char *str) failed for YZX", 1 == result); + + result = StringToOrder("ZXY"); + ensure("3. LLQuaternion::Order StringToOrder(const char *str) failed for ZXY", 2 == result); + + result = StringToOrder("XZY"); + ensure("4. LLQuaternion::Order StringToOrder(const char *str) failed for XZY", 3 == result); + + result = StringToOrder("YXZ"); + ensure("5. LLQuaternion::Order StringToOrder(const char *str) failed for YXZ", 4 == result); + + result = StringToOrder("ZYX"); + ensure("6. LLQuaternion::Order StringToOrder(const char *str) failed for ZYX", 5 == result); + + } + + template<> template<> + void llquat_test_object_t::test<21>() + { + //void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const fn + F32 angle_value = 90.0f; + LLVector3 vect(12.0f, 4.0f, 1.0f); + LLQuaternion llquat(angle_value, vect); + llquat.getAngleAxis(&angle_value, vect); + ensure( + "LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) failed", + is_approx_equal_fraction(2.035406f, angle_value, 16) && + is_approx_equal_fraction(0.315244f, vect.mV[1], 16) && + is_approx_equal_fraction(0.078811f, vect.mV[2], 16) && + is_approx_equal_fraction(0.945733f, vect.mV[0], 16)); + } + + template<> template<> + void llquat_test_object_t::test<22>() + { + //test case for void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const fn + F32 roll = -12.0f; + F32 pitch = -22.43f; + F32 yaw = 11.0f; + + LLQuaternion llquat; + llquat.getEulerAngles(&roll, &pitch, &yaw); + ensure( + "LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) failed", + is_approx_equal(0.000f, llquat.mQ[0]) && + is_approx_equal(0.000f, llquat.mQ[1]) && + is_approx_equal(0.000f, llquat.mQ[2]) && + is_approx_equal(1.000f, llquat.mQ[3])); + } + +} diff --git a/indra/llmath/tests/llrect_test.cpp b/indra/llmath/tests/llrect_test.cpp new file mode 100644 index 0000000000..26a1163b5f --- /dev/null +++ b/indra/llmath/tests/llrect_test.cpp @@ -0,0 +1,532 @@ +/** + * @file llrect_tut.cpp + * @author Martin Reddy + * @date 2009-06-25 + * @brief Test for llrect.cpp. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" +#include "../llrect.h" + +namespace tut +{ + struct LLRectData + { + }; + + typedef test_group<LLRectData> factory; + typedef factory::object object; +} + +namespace +{ + tut::factory llrect_test_factory("LLRect"); +} + +namespace tut +{ + template<> template<> + void object::test<1>() + { + // + // test the LLRect default constructor + // + + LLSD zero; + zero.append(0); zero.append(0); zero.append(0); zero.append(0); + + // default constructor + LLRect rect1; + ensure_equals("Empty rect", rect1.getValue(), zero); + ensure_equals("Empty rect left", rect1.mLeft, 0); + ensure_equals("Empty rect top", rect1.mTop, 0); + ensure_equals("Empty rect right", rect1.mRight, 0); + ensure_equals("Empty rect bottom", rect1.mBottom, 0); + ensure_equals("Empty rect width", rect1.getWidth(), 0); + ensure_equals("Empty rect height", rect1.getHeight(), 0); + ensure_equals("Empty rect centerx", rect1.getCenterX(), 0); + ensure_equals("Empty rect centery", rect1.getCenterY(), 0); + } + + template<> template<> + void object::test<2>() + { + // + // test the LLRectf default constructor + // + + LLSD zerof; + zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); zerof.append(0.0f); + + LLRectf rect2; + ensure_equals("Empty rectf", rect2.getValue(), zerof); + ensure_equals("Empty rectf left", rect2.mLeft, 0.0f); + ensure_equals("Empty rectf top", rect2.mTop, 0.0f); + ensure_equals("Empty rectf right", rect2.mRight, 0.0f); + ensure_equals("Empty rectf bottom", rect2.mBottom, 0.0f); + ensure_equals("Empty rectf width", rect2.getWidth(), 0.0f); + ensure_equals("Empty rectf height", rect2.getHeight(), 0.0f); + ensure_equals("Empty rectf centerx", rect2.getCenterX(), 0.0f); + ensure_equals("Empty rectf centery", rect2.getCenterY(), 0.0f); + } + + template<> template<> + void object::test<3>() + { + // + // test the LLRect constructor from another LLRect + // + + LLRect rect3(LLRect(1, 6, 7, 2)); + ensure_equals("Default rect left", rect3.mLeft, 1); + ensure_equals("Default rect top", rect3.mTop, 6); + ensure_equals("Default rect right", rect3.mRight, 7); + ensure_equals("Default rect bottom", rect3.mBottom, 2); + ensure_equals("Default rect width", rect3.getWidth(), 6); + ensure_equals("Default rect height", rect3.getHeight(), 4); + ensure_equals("Default rect centerx", rect3.getCenterX(), 4); + ensure_equals("Default rect centery", rect3.getCenterY(), 4); + } + + template<> template<> + void object::test<4>() + { + // + // test the LLRectf four-float constructor + // + + LLRectf rect4(1.0f, 5.0f, 6.0f, 2.0f); + ensure_equals("Default rectf left", rect4.mLeft, 1.0f); + ensure_equals("Default rectf top", rect4.mTop, 5.0f); + ensure_equals("Default rectf right", rect4.mRight, 6.0f); + ensure_equals("Default rectf bottom", rect4.mBottom, 2.0f); + ensure_equals("Default rectf width", rect4.getWidth(), 5.0f); + ensure_equals("Default rectf height", rect4.getHeight(), 3.0f); + ensure_equals("Default rectf centerx", rect4.getCenterX(), 3.5f); + ensure_equals("Default rectf centery", rect4.getCenterY(), 3.5f); + } + + template<> template<> + void object::test<5>() + { + // + // test the LLRectf LLSD constructor + // + + LLSD array; + array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); + LLRectf rect5(array); + ensure_equals("LLSD rectf left", rect5.mLeft, -1.0f); + ensure_equals("LLSD rectf top", rect5.mTop, 0.0f); + ensure_equals("LLSD rectf right", rect5.mRight, 0.0f); + ensure_equals("LLSD rectf bottom", rect5.mBottom, -1.0f); + ensure_equals("LLSD rectf width", rect5.getWidth(), 1.0f); + ensure_equals("LLSD rectf height", rect5.getHeight(), 1.0f); + ensure_equals("LLSD rectf centerx", rect5.getCenterX(), -0.5f); + ensure_equals("LLSD rectf centery", rect5.getCenterY(), -0.5f); + } + + template<> template<> + void object::test<6>() + { + // + // test directly setting the member variables for dimensions + // + + LLRectf rectf; + + rectf.mLeft = -1.0f; + rectf.mTop = 1.0f; + rectf.mRight = 1.0f; + rectf.mBottom = -1.0f; + ensure_equals("Member-set rectf left", rectf.mLeft, -1.0f); + ensure_equals("Member-set rectf top", rectf.mTop, 1.0f); + ensure_equals("Member-set rectf right", rectf.mRight, 1.0f); + ensure_equals("Member-set rectf bottom", rectf.mBottom, -1.0f); + ensure_equals("Member-set rectf width", rectf.getWidth(), 2.0f); + ensure_equals("Member-set rectf height", rectf.getHeight(), 2.0f); + ensure_equals("Member-set rectf centerx", rectf.getCenterX(), 0.0f); + ensure_equals("Member-set rectf centery", rectf.getCenterY(), 0.0f); + } + + template<> template<> + void object::test<7>() + { + // + // test the setValue() method + // + + LLRectf rectf; + + LLSD array; + array.append(-1.0f); array.append(0.0f); array.append(0.0f); array.append(-1.0f); + rectf.setValue(array); + ensure_equals("setValue() rectf left", rectf.mLeft, -1.0f); + ensure_equals("setValue() rectf top", rectf.mTop, 0.0f); + ensure_equals("setValue() rectf right", rectf.mRight, 0.0f); + ensure_equals("setValue() rectf bottom", rectf.mBottom, -1.0f); + ensure_equals("setValue() rectf width", rectf.getWidth(), 1.0f); + ensure_equals("setValue() rectf height", rectf.getHeight(), 1.0f); + ensure_equals("setValue() rectf centerx", rectf.getCenterX(), -0.5f); + ensure_equals("setValue() rectf centery", rectf.getCenterY(), -0.5f); + } + + template<> template<> + void object::test<8>() + { + // + // test the set() method + // + + LLRect rect; + + rect.set(10, 90, 70, 10); + ensure_equals("set() rectf left", rect.mLeft, 10); + ensure_equals("set() rectf top", rect.mTop, 90); + ensure_equals("set() rectf right", rect.mRight, 70); + ensure_equals("set() rectf bottom", rect.mBottom, 10); + ensure_equals("set() rectf width", rect.getWidth(), 60); + ensure_equals("set() rectf height", rect.getHeight(), 80); + ensure_equals("set() rectf centerx", rect.getCenterX(), 40); + ensure_equals("set() rectf centery", rect.getCenterY(), 50); + } + + template<> template<> + void object::test<9>() + { + // + // test the setOriginAndSize() method + // + + LLRectf rectf; + + rectf.setOriginAndSize(0.0f, 0.0f, 2.0f, 1.0f); + ensure_equals("setOriginAndSize() rectf left", rectf.mLeft, 0.0f); + ensure_equals("setOriginAndSize() rectf top", rectf.mTop, 1.0f); + ensure_equals("setOriginAndSize() rectf right", rectf.mRight, 2.0f); + ensure_equals("setOriginAndSize() rectf bottom", rectf.mBottom, 0.0f); + ensure_equals("setOriginAndSize() rectf width", rectf.getWidth(), 2.0f); + ensure_equals("setOriginAndSize() rectf height", rectf.getHeight(), 1.0f); + ensure_equals("setOriginAndSize() rectf centerx", rectf.getCenterX(), 1.0f); + ensure_equals("setOriginAndSize() rectf centery", rectf.getCenterY(), 0.5f); + } + + template<> template<> + void object::test<10>() + { + // + // test the setLeftTopAndSize() method + // + + LLRectf rectf; + + rectf.setLeftTopAndSize(0.0f, 0.0f, 2.0f, 1.0f); + ensure_equals("setLeftTopAndSize() rectf left", rectf.mLeft, 0.0f); + ensure_equals("setLeftTopAndSize() rectf top", rectf.mTop, 0.0f); + ensure_equals("setLeftTopAndSize() rectf right", rectf.mRight, 2.0f); + ensure_equals("setLeftTopAndSize() rectf bottom", rectf.mBottom, -1.0f); + ensure_equals("setLeftTopAndSize() rectf width", rectf.getWidth(), 2.0f); + ensure_equals("setLeftTopAndSize() rectf height", rectf.getHeight(), 1.0f); + ensure_equals("setLeftTopAndSize() rectf centerx", rectf.getCenterX(), 1.0f); + ensure_equals("setLeftTopAndSize() rectf centery", rectf.getCenterY(), -0.5f); + } + + template<> template<> + void object::test<11>() + { + // + // test the setCenterAndSize() method + // + + LLRectf rectf; + + rectf.setCenterAndSize(0.0f, 0.0f, 2.0f, 1.0f); + ensure_equals("setCenterAndSize() rectf left", rectf.mLeft, -1.0f); + ensure_equals("setCenterAndSize() rectf top", rectf.mTop, 0.5f); + ensure_equals("setCenterAndSize() rectf right", rectf.mRight, 1.0f); + ensure_equals("setCenterAndSize() rectf bottom", rectf.mBottom, -0.5f); + ensure_equals("setCenterAndSize() rectf width", rectf.getWidth(), 2.0f); + ensure_equals("setCenterAndSize() rectf height", rectf.getHeight(), 1.0f); + ensure_equals("setCenterAndSize() rectf centerx", rectf.getCenterX(), 0.0f); + ensure_equals("setCenterAndSize() rectf centery", rectf.getCenterY(), 0.0f); + } + + template<> template<> + void object::test<12>() + { + // + // test the validity checking method + // + + LLRectf rectf; + + rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); + ensure("BBox is valid", rectf.isValid()); + + rectf.mLeft = 2.0f; + ensure("BBox is not valid", ! rectf.isValid()); + + rectf.makeValid(); + ensure("BBox forced valid", rectf.isValid()); + + rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); + ensure("BBox(0,0,0,0) is valid", rectf.isValid()); + } + + template<> template<> + void object::test<13>() + { + // + // test the null checking methods + // + + LLRectf rectf; + + rectf.set(-1.0f, 1.0f, 1.0f, -1.0f); + ensure("BBox is not Null", ! rectf.isEmpty()); + ensure("BBox notNull", rectf.notEmpty()); + + rectf.mLeft = 2.0f; + rectf.makeValid(); + ensure("BBox is now Null", rectf.isEmpty()); + + rectf.set(-1.0f, -1.0f, -1.0f, -1.0f); + ensure("BBox(0,0,0,0) is Null", rectf.isEmpty()); + } + + template<> template<> + void object::test<14>() + { + // + // test the (in)equality operators + // + + LLRectf rect1, rect2; + + rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect2.set(-1.0f, 0.9f, 1.0f, -1.0f); + + ensure("rect1 == rect2 (false)", ! (rect1 == rect2)); + ensure("rect1 != rect2 (true)", rect1 != rect2); + + ensure("rect1 == rect1 (true)", rect1 == rect1); + ensure("rect1 != rect1 (false)", ! (rect1 != rect1)); + } + + template<> template<> + void object::test<15>() + { + // + // test the copy constructor + // + + LLRectf rect1, rect2(rect1); + + ensure("rect1 == rect2 (true)", rect1 == rect2); + ensure("rect1 != rect2 (false)", ! (rect1 != rect2)); + } + + template<> template<> + void object::test<16>() + { + // + // test the translate() method + // + + LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); + LLRectf rect2(rect1); + + rect1.translate(0.0f, 0.0f); + + ensure("translate(0, 0)", rect1 == rect2); + + rect1.translate(100.0f, 100.0f); + rect1.translate(-100.0f, -100.0f); + + ensure("translate(100, 100) + translate(-100, -100)", rect1 == rect2); + + rect1.translate(10.0f, 0.0f); + rect2.set(9.0f, 1.0f, 11.0f, -1.0f); + ensure("translate(10, 0)", rect1 == rect2); + + rect1.translate(0.0f, 10.0f); + rect2.set(9.0f, 11.0f, 11.0f, 9.0f); + ensure("translate(0, 10)", rect1 == rect2); + + rect1.translate(-10.0f, -10.0f); + rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); + ensure("translate(-10, -10)", rect1 == rect2); + } + + template<> template<> + void object::test<17>() + { + // + // test the stretch() method + // + + LLRectf rect1(-1.0f, 1.0f, 1.0f, -1.0f); + LLRectf rect2(rect1); + + rect1.stretch(0.0f); + ensure("stretch(0)", rect1 == rect2); + + rect1.stretch(0.0f, 0.0f); + ensure("stretch(0, 0)", rect1 == rect2); + + rect1.stretch(10.0f); + rect1.stretch(-10.0f); + ensure("stretch(10) + stretch(-10)", rect1 == rect2); + + rect1.stretch(2.0f, 1.0f); + rect2.set(-3.0f, 2.0f, 3.0f, -2.0f); + ensure("stretch(2, 1)", rect1 == rect2); + } + + + template<> template<> + void object::test<18>() + { + // + // test the unionWith() method + // + + LLRectf rect1, rect2, rect3; + + rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect3 = rect1; + rect3.unionWith(rect2); + ensure_equals("union with self", rect3, rect1); + + rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); + rect3 = rect1; + rect3.unionWith(rect2); + ensure_equals("union - overlap", rect3, LLRectf(-2.0f, 2.0f, 1.0f, -1.0f)); + + rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect2.set(5.0f, 10.0f, 10.0f, 5.0f); + rect3 = rect1; + rect3.unionWith(rect2); + ensure_equals("union - no overlap", rect3, LLRectf(-1.0f, 10.0f, 10.0f, -1.0f)); + } + + template<> template<> + void object::test<19>() + { + // + // test the intersectWith() methods + // + + LLRectf rect1, rect2, rect3; + + rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect2.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect3 = rect1; + rect3.intersectWith(rect2); + ensure_equals("intersect with self", rect3, rect1); + + rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect2.set(-2.0f, 2.0f, 0.0f, 0.0f); + rect3 = rect1; + rect3.intersectWith(rect2); + ensure_equals("intersect - overlap", rect3, LLRectf(-1.0f, 1.0f, 0.0f, 0.0f)); + + rect1.set(-1.0f, 1.0f, 1.0f, -1.0f); + rect2.set(5.0f, 10.0f, 10.0f, 5.0f); + rect3 = rect1; + rect3.intersectWith(rect2); + ensure("intersect - no overlap", rect3.isEmpty()); + } + + template<> template<> + void object::test<20>() + { + // + // test the pointInRect() method + // + + LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); + + ensure("(0,0) not in rect", rect.pointInRect(0.0f, 0.0f) == FALSE); + ensure("(2,2) in rect", rect.pointInRect(2.0f, 2.0f) == TRUE); + ensure("(1,1) in rect", rect.pointInRect(1.0f, 1.0f) == TRUE); + ensure("(3,3) not in rect", rect.pointInRect(3.0f, 3.0f) == FALSE); + ensure("(2.999,2.999) in rect", rect.pointInRect(2.999f, 2.999f) == TRUE); + ensure("(2.999,3.0) not in rect", rect.pointInRect(2.999f, 3.0f) == FALSE); + ensure("(3.0,2.999) not in rect", rect.pointInRect(3.0f, 2.999f) == FALSE); + } + + template<> template<> + void object::test<21>() + { + // + // test the localPointInRect() method + // + + LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); + + ensure("(0,0) in local rect", rect.localPointInRect(0.0f, 0.0f) == TRUE); + ensure("(-0.0001,-0.0001) not in local rect", rect.localPointInRect(-0.0001f, -0.001f) == FALSE); + ensure("(1,1) in local rect", rect.localPointInRect(1.0f, 1.0f) == TRUE); + ensure("(2,2) not in local rect", rect.localPointInRect(2.0f, 2.0f) == FALSE); + ensure("(1.999,1.999) in local rect", rect.localPointInRect(1.999f, 1.999f) == TRUE); + ensure("(1.999,2.0) not in local rect", rect.localPointInRect(1.999f, 2.0f) == FALSE); + ensure("(2.0,1.999) not in local rect", rect.localPointInRect(2.0f, 1.999f) == FALSE); + } + + template<> template<> + void object::test<22>() + { + // + // test the clampPointToRect() method + // + + LLRectf rect(1.0f, 3.0f, 3.0f, 1.0f); + F32 x, y; + + x = 2.0f; y = 2.0f; + rect.clampPointToRect(x, y); + ensure_equals("clamp x-coord within rect", x, 2.0f); + ensure_equals("clamp y-coord within rect", y, 2.0f); + + x = -100.0f; y = 100.0f; + rect.clampPointToRect(x, y); + ensure_equals("clamp x-coord outside rect", x, 1.0f); + ensure_equals("clamp y-coord outside rect", y, 3.0f); + + x = 3.0f; y = 1.0f; + rect.clampPointToRect(x, y); + ensure_equals("clamp x-coord edge rect", x, 3.0f); + ensure_equals("clamp y-coord edge rect", y, 1.0f); + } +} diff --git a/indra/llmath/tests/m3math_test.cpp b/indra/llmath/tests/m3math_test.cpp new file mode 100644 index 0000000000..83ca5768df --- /dev/null +++ b/indra/llmath/tests/m3math_test.cpp @@ -0,0 +1,327 @@ +/** + * @file m3math_test.cpp + * @author Adroit + * @date 2007-03 + * @brief Test cases of m3math.h + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../m3math.h" +#include "../v3math.h" +#include "../v4math.h" +#include "../m4math.h" +#include "../llquaternion.h" +#include "../v3dmath.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct m3math_test + { + }; + typedef test_group<m3math_test> m3math_test_t; + typedef m3math_test_t::object m3math_test_object_t; + tut::m3math_test_t tut_m3math_test("m3math_test"); + + //test case for setIdentity() fn. + template<> template<> + void m3math_test_object_t::test<1>() + { + LLMatrix3 llmat3_obj; + llmat3_obj.setIdentity(); + ensure("LLMatrix3::setIdentity failed", 1.f == llmat3_obj.mMatrix[0][0] && + 0.f == llmat3_obj.mMatrix[0][1] && + 0.f == llmat3_obj.mMatrix[0][2] && + 0.f == llmat3_obj.mMatrix[1][0] && + 1.f == llmat3_obj.mMatrix[1][1] && + 0.f == llmat3_obj.mMatrix[1][2] && + 0.f == llmat3_obj.mMatrix[2][0] && + 0.f == llmat3_obj.mMatrix[2][1] && + 1.f == llmat3_obj.mMatrix[2][2]); + } + + //test case for LLMatrix3& setZero() fn. + template<> template<> + void m3math_test_object_t::test<2>() + { + LLMatrix3 llmat3_obj(30, 1, 2, 3); + llmat3_obj.setZero(); + + ensure("LLMatrix3::setZero failed", 0.f == llmat3_obj.setZero().mMatrix[0][0] && + 0.f == llmat3_obj.setZero().mMatrix[0][1] && + 0.f == llmat3_obj.setZero().mMatrix[0][2] && + 0.f == llmat3_obj.setZero().mMatrix[1][0] && + 0.f == llmat3_obj.setZero().mMatrix[1][1] && + 0.f == llmat3_obj.setZero().mMatrix[1][2] && + 0.f == llmat3_obj.setZero().mMatrix[2][0] && + 0.f == llmat3_obj.setZero().mMatrix[2][1] && + 0.f == llmat3_obj.setZero().mMatrix[2][2]); + } + + //test case for setRows(const LLVector3 &x_axis, const LLVector3 &y_axis, const LLVector3 &z_axis) fns. + template<> template<> + void m3math_test_object_t::test<3>() + { + LLMatrix3 llmat3_obj; + LLVector3 vect1(2, 1, 4); + LLVector3 vect2(3, 5, 7); + LLVector3 vect3(6, 9, 7); + llmat3_obj.setRows(vect1, vect2, vect3); + ensure("LLVector3::setRows failed ", 2 == llmat3_obj.mMatrix[0][0] && + 1 == llmat3_obj.mMatrix[0][1] && + 4 == llmat3_obj.mMatrix[0][2] && + 3 == llmat3_obj.mMatrix[1][0] && + 5 == llmat3_obj.mMatrix[1][1] && + 7 == llmat3_obj.mMatrix[1][2] && + 6 == llmat3_obj.mMatrix[2][0] && + 9 == llmat3_obj.mMatrix[2][1] && + 7 == llmat3_obj.mMatrix[2][2]); + } + + //test case for getFwdRow(), getLeftRow(), getUpRow() fns. + template<> template<> + void m3math_test_object_t::test<4>() + { + LLMatrix3 llmat3_obj; + LLVector3 vect1(2, 1, 4); + LLVector3 vect2(3, 5, 7); + LLVector3 vect3(6, 9, 7); + llmat3_obj.setRows(vect1, vect2, vect3); + + ensure("LLVector3::getFwdRow failed ", vect1 == llmat3_obj.getFwdRow()); + ensure("LLVector3::getLeftRow failed ", vect2 == llmat3_obj.getLeftRow()); + ensure("LLVector3::getUpRow failed ", vect3 == llmat3_obj.getUpRow()); + } + + //test case for operator*(const LLMatrix3 &a, const LLMatrix3 &b) + template<> template<> + void m3math_test_object_t::test<5>() + { + LLMatrix3 llmat_obj1; + LLMatrix3 llmat_obj2; + LLMatrix3 llmat_obj3; + + LLVector3 llvec1(1, 3, 5); + LLVector3 llvec2(3, 6, 1); + LLVector3 llvec3(4, 6, 9); + + LLVector3 llvec4(1, 1, 5); + LLVector3 llvec5(3, 6, 8); + LLVector3 llvec6(8, 6, 2); + + LLVector3 llvec7(0, 0, 0); + LLVector3 llvec8(0, 0, 0); + LLVector3 llvec9(0, 0, 0); + + llmat_obj1.setRows(llvec1, llvec2, llvec3); + llmat_obj2.setRows(llvec4, llvec5, llvec6); + llmat_obj3.setRows(llvec7, llvec8, llvec9); + llmat_obj3 = llmat_obj1 * llmat_obj2; + ensure("LLMatrix3::operator*(const LLMatrix3 &a, const LLMatrix3 &b) failed", + 50 == llmat_obj3.mMatrix[0][0] && + 49 == llmat_obj3.mMatrix[0][1] && + 39 == llmat_obj3.mMatrix[0][2] && + 29 == llmat_obj3.mMatrix[1][0] && + 45 == llmat_obj3.mMatrix[1][1] && + 65 == llmat_obj3.mMatrix[1][2] && + 94 == llmat_obj3.mMatrix[2][0] && + 94 == llmat_obj3.mMatrix[2][1] && + 86 == llmat_obj3.mMatrix[2][2]); + } + + + //test case for operator*(const LLVector3 &a, const LLMatrix3 &b) + template<> template<> + void m3math_test_object_t::test<6>() + { + + LLMatrix3 llmat_obj1; + + LLVector3 llvec(1, 3, 5); + LLVector3 res_vec(0, 0, 0); + LLVector3 llvec1(1, 3, 5); + LLVector3 llvec2(3, 6, 1); + LLVector3 llvec3(4, 6, 9); + + llmat_obj1.setRows(llvec1, llvec2, llvec3); + res_vec = llvec * llmat_obj1; + + LLVector3 expected_result(30, 51, 53); + + ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", res_vec == expected_result); + } + + //test case for operator*(const LLVector3d &a, const LLMatrix3 &b) + template<> template<> + void m3math_test_object_t::test<7>() + { + LLMatrix3 llmat_obj1; + LLVector3d llvec3d1; + LLVector3d llvec3d2(0, 3, 4); + + LLVector3 llvec1(1, 3, 5); + LLVector3 llvec2(3, 2, 1); + LLVector3 llvec3(4, 6, 0); + + llmat_obj1.setRows(llvec1, llvec2, llvec3); + llvec3d1 = llvec3d2 * llmat_obj1; + + LLVector3d expected_result(25, 30, 3); + + ensure("LLMatrix3::operator*(const LLVector3 &a, const LLMatrix3 &b) failed", llvec3d1 == expected_result); + } + + // test case for operator==(const LLMatrix3 &a, const LLMatrix3 &b) + template<> template<> + void m3math_test_object_t::test<8>() + { + LLMatrix3 llmat_obj1; + LLMatrix3 llmat_obj2; + + LLVector3 llvec1(1, 3, 5); + LLVector3 llvec2(3, 6, 1); + LLVector3 llvec3(4, 6, 9); + + llmat_obj1.setRows(llvec1, llvec2, llvec3); + llmat_obj2.setRows(llvec1, llvec2, llvec3); + ensure("LLMatrix3::operator==(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 == llmat_obj2); + + llmat_obj2.setRows(llvec2, llvec2, llvec3); + ensure("LLMatrix3::operator!=(const LLMatrix3 &a, const LLMatrix3 &b) failed", llmat_obj1 != llmat_obj2); + } + + //test case for quaternion() fn. + template<> template<> + void m3math_test_object_t::test<9>() + { + LLMatrix3 llmat_obj1; + LLQuaternion llmat_quat; + + LLVector3 llmat1(2.0f, 1.0f, 6.0f); + LLVector3 llmat2(1.0f, 1.0f, 3.0f); + LLVector3 llmat3(1.0f, 7.0f, 5.0f); + + llmat_obj1.setRows(llmat1, llmat2, llmat3); + llmat_quat = llmat_obj1.quaternion(); + ensure("LLMatrix3::quaternion failed ", is_approx_equal(-0.66666669f, llmat_quat.mQ[0]) && + is_approx_equal(-0.83333337f, llmat_quat.mQ[1]) && + is_approx_equal(0.0f, llmat_quat.mQ[2]) && + is_approx_equal(1.5f, llmat_quat.mQ[3])); + } + + //test case for transpose() fn. + template<> template<> + void m3math_test_object_t::test<10>() + { + LLMatrix3 llmat_obj; + + LLVector3 llvec1(1, 2, 3); + LLVector3 llvec2(3, 2, 1); + LLVector3 llvec3(2, 2, 2); + + llmat_obj.setRows(llvec1, llvec2, llvec3); + llmat_obj.transpose(); + + LLVector3 resllvec1(1, 3, 2); + LLVector3 resllvec2(2, 2, 2); + LLVector3 resllvec3(3, 1, 2); + LLMatrix3 expectedllmat_obj; + expectedllmat_obj.setRows(resllvec1, resllvec2, resllvec3); + + ensure("LLMatrix3::transpose failed ", llmat_obj == expectedllmat_obj); + } + + //test case for determinant() fn. + template<> template<> + void m3math_test_object_t::test<11>() + { + LLMatrix3 llmat_obj1; + + LLVector3 llvec1(1, 2, 3); + LLVector3 llvec2(3, 2, 1); + LLVector3 llvec3(2, 2, 2); + llmat_obj1.setRows(llvec1, llvec2, llvec3); + ensure("LLMatrix3::determinant failed ", 0.0f == llmat_obj1.determinant()); + } + + //test case for orthogonalize() fn. + template<> template<> + void m3math_test_object_t::test<12>() + { + LLMatrix3 llmat_obj; + + LLVector3 llvec1(1, 4, 3); + LLVector3 llvec2(1, 2, 0); + LLVector3 llvec3(2, 4, 2); + + llmat_obj.setRows(llvec1, llvec2, llvec3); + llmat_obj.orthogonalize(); + + skip("Grr, LLMatrix3::orthogonalize test is failing. Has it ever worked?"); + ensure("LLMatrix3::orthogonalize failed ", + is_approx_equal(0.19611613f, llmat_obj.mMatrix[0][0]) && + is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) && + is_approx_equal(0.58834839f, llmat_obj.mMatrix[0][2]) && + is_approx_equal(0.47628206f, llmat_obj.mMatrix[1][0]) && + is_approx_equal(0.44826555f, llmat_obj.mMatrix[1][1]) && + is_approx_equal(-0.75644791f, llmat_obj.mMatrix[1][2]) && + is_approx_equal(-0.85714287f, llmat_obj.mMatrix[2][0]) && + is_approx_equal(0.42857143f, llmat_obj.mMatrix[2][1]) && + is_approx_equal(-0.28571427f, llmat_obj.mMatrix[2][2])); + } + + //test case for adjointTranspose() fn. + template<> template<> + void m3math_test_object_t::test<13>() + { + LLMatrix3 llmat_obj; + + LLVector3 llvec1(3, 2, 1); + LLVector3 llvec2(6, 2, 1); + LLVector3 llvec3(3, 6, 8); + + llmat_obj.setRows(llvec1, llvec2, llvec3); + llmat_obj.adjointTranspose(); + + ensure("LLMatrix3::adjointTranspose failed ", 10 == llmat_obj.mMatrix[0][0] && + -45 == llmat_obj.mMatrix[1][0] && + 30 == llmat_obj.mMatrix[2][0] && + -10 == llmat_obj.mMatrix[0][1] && + 21 == llmat_obj.mMatrix[1][1] && + -12 == llmat_obj.mMatrix[2][1] && + 0 == llmat_obj.mMatrix[0][2] && + 3 == llmat_obj.mMatrix[1][2] && + -6 == llmat_obj.mMatrix[2][2]); + } + + /* TBD: Need to add test cases for getEulerAngles() and setRot() functions */ +} diff --git a/indra/llmath/tests/mathmisc_test.cpp b/indra/llmath/tests/mathmisc_test.cpp new file mode 100644 index 0000000000..ea42f6e001 --- /dev/null +++ b/indra/llmath/tests/mathmisc_test.cpp @@ -0,0 +1,727 @@ +/** + * @file math.cpp + * @author Phoenix + * @date 2005-09-26 + * @brief Tests for the llmath library. + * + * $LicenseInfo:firstyear=2005&license=viewergpl$ + * + * Copyright (c) 2005-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "llcrc.h" +#include "llrand.h" +#include "lluuid.h" + +#include "../llline.h" +#include "../llmath.h" +#include "../llsphere.h" +#include "../v3math.h" + +namespace tut +{ + struct math_data + { + }; + typedef test_group<math_data> math_test; + typedef math_test::object math_object; + tut::math_test tm("basic_linden_math"); + + template<> template<> + void math_object::test<1>() + { + S32 val = 89543; + val = llabs(val); + ensure("integer absolute value 1", (89543 == val)); + val = -500; + val = llabs(val); + ensure("integer absolute value 2", (500 == val)); + } + + template<> template<> + void math_object::test<2>() + { + F32 val = -2583.4f; + val = llabs(val); + ensure("float absolute value 1", (2583.4f == val)); + val = 430903.f; + val = llabs(val); + ensure("float absolute value 2", (430903.f == val)); + } + + template<> template<> + void math_object::test<3>() + { + F64 val = 387439393.987329839; + val = llabs(val); + ensure("double absolute value 1", (387439393.987329839 == val)); + val = -8937843.9394878; + val = llabs(val); + ensure("double absolute value 2", (8937843.9394878 == val)); + } + + template<> template<> + void math_object::test<4>() + { + F32 val = 430903.9f; + S32 val1 = lltrunc(val); + ensure("float truncate value 1", (430903 == val1)); + val = -2303.9f; + val1 = lltrunc(val); + ensure("float truncate value 2", (-2303 == val1)); + } + + template<> template<> + void math_object::test<5>() + { + F64 val = 387439393.987329839 ; + S32 val1 = lltrunc(val); + ensure("float truncate value 1", (387439393 == val1)); + val = -387439393.987329839; + val1 = lltrunc(val); + ensure("float truncate value 2", (-387439393 == val1)); + } + + template<> template<> + void math_object::test<6>() + { + F32 val = 430903.2f; + S32 val1 = llfloor(val); + ensure("float llfloor value 1", (430903 == val1)); + val = -430903.9f; + val1 = llfloor(val); + ensure("float llfloor value 2", (-430904 == val1)); + } + + template<> template<> + void math_object::test<7>() + { + F32 val = 430903.2f; + S32 val1 = llceil(val); + ensure("float llceil value 1", (430904 == val1)); + val = -430903.9f; + val1 = llceil(val); + ensure("float llceil value 2", (-430903 == val1)); + } + + template<> template<> + void math_object::test<8>() + { + F32 val = 430903.2f; + S32 val1 = llround(val); + ensure("float llround value 1", (430903 == val1)); + val = -430903.9f; + val1 = llround(val); + ensure("float llround value 2", (-430904 == val1)); + } + + template<> template<> + void math_object::test<9>() + { + F32 val = 430905.2654f, nearest = 100.f; + val = llround(val, nearest); + ensure("float llround value 1", (430900 == val)); + val = -430905.2654f, nearest = 10.f; + val = llround(val, nearest); + ensure("float llround value 1", (-430910 == val)); + } + + template<> template<> + void math_object::test<10>() + { + F64 val = 430905.2654, nearest = 100.0; + val = llround(val, nearest); + ensure("double llround value 1", (430900 == val)); + val = -430905.2654, nearest = 10.0; + val = llround(val, nearest); + ensure("double llround value 1", (-430910.00000 == val)); + } + + template<> template<> + void math_object::test<11>() + { + const F32 F_PI = 3.1415926535897932384626433832795f; + F32 angle = 3506.f; + angle = llsimple_angle(angle); + ensure("llsimple_angle value 1", (angle <=F_PI && angle >= -F_PI)); + angle = -431.f; + angle = llsimple_angle(angle); + ensure("llsimple_angle value 1", (angle <=F_PI && angle >= -F_PI)); + } +} + +namespace tut +{ + struct uuid_data + { + LLUUID id; + }; + typedef test_group<uuid_data> uuid_test; + typedef uuid_test::object uuid_object; + tut::uuid_test tu("uuid"); + + template<> template<> + void uuid_object::test<1>() + { + ensure("uuid null", id.isNull()); + id.generate(); + ensure("generate not null", id.notNull()); + id.setNull(); + ensure("set null", id.isNull()); + } + + template<> template<> + void uuid_object::test<2>() + { + id.generate(); + LLUUID a(id); + ensure_equals("copy equal", id, a); + a.generate(); + ensure_not_equals("generate not equal", id, a); + a = id; + ensure_equals("assignment equal", id, a); + } + + template<> template<> + void uuid_object::test<3>() + { + id.generate(); + LLUUID copy(id); + LLUUID mask; + mask.generate(); + copy ^= mask; + ensure_not_equals("mask not equal", id, copy); + copy ^= mask; + ensure_equals("mask back", id, copy); + } + + template<> template<> + void uuid_object::test<4>() + { + id.generate(); + std::string id_str = id.asString(); + LLUUID copy(id_str.c_str()); + ensure_equals("string serialization", id, copy); + } + +} + +namespace tut +{ + struct crc_data + { + }; + typedef test_group<crc_data> crc_test; + typedef crc_test::object crc_object; + tut::crc_test tc("crc"); + + template<> template<> + void crc_object::test<1>() + { + /* Test buffer update and individual char update */ + const char TEST_BUFFER[] = "hello &#$)$&Nd0"; + LLCRC c1, c2; + c1.update((U8*)TEST_BUFFER, sizeof(TEST_BUFFER) - 1); + char* rh = (char*)TEST_BUFFER; + while(*rh != '\0') + { + c2.update(*rh); + ++rh; + } + ensure_equals("crc update 1", c1.getCRC(), c2.getCRC()); + } + + template<> template<> + void crc_object::test<2>() + { + /* Test mixing of buffer and individual char update */ + const char TEST_BUFFER1[] = "Split Buffer one $^%$%#@$"; + const char TEST_BUFFER2[] = "Split Buffer two )(8723#5dsds"; + LLCRC c1, c2; + c1.update((U8*)TEST_BUFFER1, sizeof(TEST_BUFFER1) - 1); + char* rh = (char*)TEST_BUFFER2; + while(*rh != '\0') + { + c1.update(*rh); + ++rh; + } + + rh = (char*)TEST_BUFFER1; + while(*rh != '\0') + { + c2.update(*rh); + ++rh; + } + c2.update((U8*)TEST_BUFFER2, sizeof(TEST_BUFFER2) - 1); + + ensure_equals("crc update 2", c1.getCRC(), c2.getCRC()); + } +} + +namespace tut +{ + struct sphere_data + { + }; + typedef test_group<sphere_data> sphere_test; + typedef sphere_test::object sphere_object; + tut::sphere_test tsphere("LLSphere"); + + template<> template<> + void sphere_object::test<1>() + { + // test LLSphere::contains() and ::overlaps() + S32 number_of_tests = 10; + for (S32 test = 0; test < number_of_tests; ++test) + { + LLVector3 first_center(1.f, 1.f, 1.f); + F32 first_radius = 3.f; + LLSphere first_sphere( first_center, first_radius ); + + F32 half_millimeter = 0.0005f; + LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); + direction.normalize(); + + F32 distance = ll_frand(first_radius - 2.f * half_millimeter); + LLVector3 second_center = first_center + distance * direction; + F32 second_radius = first_radius - distance - half_millimeter; + LLSphere second_sphere( second_center, second_radius ); + ensure("first sphere should contain the second", first_sphere.contains(second_sphere)); + ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); + + distance = first_radius + ll_frand(first_radius); + second_center = first_center + distance * direction; + second_radius = distance - first_radius + half_millimeter; + second_sphere.set( second_center, second_radius ); + ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); + ensure("first sphere should overlap the second", first_sphere.overlaps(second_sphere)); + + distance = first_radius + ll_frand(first_radius) + half_millimeter; + second_center = first_center + distance * direction; + second_radius = distance - first_radius - half_millimeter; + second_sphere.set( second_center, second_radius ); + ensure("first sphere should NOT contain the second", !first_sphere.contains(second_sphere)); + ensure("first sphere should NOT overlap the second", !first_sphere.overlaps(second_sphere)); + } + } + + template<> template<> + void sphere_object::test<2>() + { + // test LLSphere::getBoundingSphere() + S32 number_of_tests = 100; + S32 number_of_spheres = 10; + F32 sphere_center_range = 32.f; + F32 sphere_radius_range = 5.f; + + for (S32 test = 0; test < number_of_tests; ++test) + { + // gegnerate a bunch of random sphere + std::vector< LLSphere > sphere_list; + for (S32 sphere_count=0; sphere_count < number_of_spheres; ++sphere_count) + { + LLVector3 direction( ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f, ll_frand(2.f) - 1.f); + direction.normalize(); + F32 distance = ll_frand(sphere_center_range); + LLVector3 center = distance * direction; + F32 radius = ll_frand(sphere_radius_range); + LLSphere sphere( center, radius ); + sphere_list.push_back(sphere); + } + + // compute the bounding sphere + LLSphere bounding_sphere = LLSphere::getBoundingSphere(sphere_list); + + // make sure all spheres are inside the bounding sphere + { + std::vector< LLSphere >::const_iterator sphere_itr; + for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) + { + ensure("sphere should be contained by the bounding sphere", bounding_sphere.contains(*sphere_itr)); + } + } + + // TODO -- improve LLSphere::getBoundingSphere() to the point where + // we can reduce the 'expansion' in the two tests below to about + // 2 mm or less + + F32 expansion = 0.005f; + // move all spheres out a little bit + // and count how many are NOT contained + { + std::vector< LLVector3 > uncontained_directions; + std::vector< LLSphere >::iterator sphere_itr; + for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) + { + LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); + direction.normalize(); + + sphere_itr->setCenter( sphere_itr->getCenter() + expansion * direction ); + if (! bounding_sphere.contains( *sphere_itr ) ) + { + uncontained_directions.push_back(direction); + } + } + ensure("when moving spheres out there should be at least two uncontained spheres", + uncontained_directions.size() > 1); + + /* TODO -- when the bounding sphere algorithm is improved we can open up this test + * at the moment it occasionally fails when the sphere collection is tight and small + * (2 meters or less) + if (2 == uncontained_directions.size() ) + { + // if there were only two uncontained spheres then + // the two directions should be nearly opposite + F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; + ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); + } + */ + } + + // compute the new bounding sphere + bounding_sphere = LLSphere::getBoundingSphere(sphere_list); + + // increase the size of all spheres a little bit + // and count how many are NOT contained + { + std::vector< LLVector3 > uncontained_directions; + std::vector< LLSphere >::iterator sphere_itr; + for (sphere_itr = sphere_list.begin(); sphere_itr != sphere_list.end(); ++sphere_itr) + { + LLVector3 direction = sphere_itr->getCenter() - bounding_sphere.getCenter(); + direction.normalize(); + + sphere_itr->setRadius( sphere_itr->getRadius() + expansion ); + if (! bounding_sphere.contains( *sphere_itr ) ) + { + uncontained_directions.push_back(direction); + } + } + ensure("when boosting sphere radii there should be at least two uncontained spheres", + uncontained_directions.size() > 1); + + /* TODO -- when the bounding sphere algorithm is improved we can open up this test + * at the moment it occasionally fails when the sphere collection is tight and small + * (2 meters or less) + if (2 == uncontained_directions.size() ) + { + // if there were only two uncontained spheres then + // the two directions should be nearly opposite + F32 dir_dot = uncontained_directions[0] * uncontained_directions[1]; + ensure("two uncontained spheres should lie opposite the bounding center", dir_dot < -0.95f); + } + */ + } + } + } +} + +namespace tut +{ + F32 SMALL_RADIUS = 1.0f; + F32 MEDIUM_RADIUS = 5.0f; + F32 LARGE_RADIUS = 10.0f; + + struct line_data + { + }; + typedef test_group<line_data> line_test; + typedef line_test::object line_object; + tut::line_test tline("LLLine"); + + template<> template<> + void line_object::test<1>() + { + // this is a test for LLLine::intersects(point) which returns TRUE + // if the line passes within some tolerance of point + + // these tests will have some floating point error, + // so we need to specify how much error is ok + F32 allowable_relative_error = 0.00001f; + S32 number_of_tests = 100; + for (S32 test = 0; test < number_of_tests; ++test) + { + // generate some random point to be on the line + LLVector3 point_on_line( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + point_on_line.normalize(); + point_on_line *= ll_frand(LARGE_RADIUS); + + // generate some random point to "intersect" + LLVector3 random_direction ( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + random_direction.normalize(); + + LLVector3 random_offset( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + random_offset.normalize(); + random_offset *= ll_frand(SMALL_RADIUS); + + LLVector3 point = point_on_line + MEDIUM_RADIUS * random_direction + + random_offset; + + // compute the axis of approach (a unit vector between the points) + LLVector3 axis_of_approach = point - point_on_line; + axis_of_approach.normalize(); + + // compute the direction of the the first line (perp to axis_of_approach) + LLVector3 first_dir( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + first_dir.normalize(); + F32 dot = first_dir * axis_of_approach; + first_dir -= dot * axis_of_approach; // subtract component parallel to axis + first_dir.normalize(); + + // construct the line + LLVector3 another_point_on_line = point_on_line + ll_frand(LARGE_RADIUS) * first_dir; + LLLine line(another_point_on_line, point_on_line); + + // test that the intersection point is within MEDIUM_RADIUS + SMALL_RADIUS + F32 test_radius = MEDIUM_RADIUS + SMALL_RADIUS; + test_radius += (LARGE_RADIUS * allowable_relative_error); + ensure("line should pass near intersection point", line.intersects(point, test_radius)); + + test_radius = allowable_relative_error * (point - point_on_line).length(); + ensure("line should intersect point used to define it", line.intersects(point_on_line, test_radius)); + } + } + + template<> template<> + void line_object::test<2>() + { + /* + These tests fail intermittently on all platforms - see DEV-16600 + Commenting this out until dev has time to investigate. + + // this is a test for LLLine::nearestApproach(LLLIne) method + // which computes the point on a line nearest another line + + // these tests will have some floating point error, + // so we need to specify how much error is ok + // TODO -- make nearestApproach() algorithm more accurate so + // we can tighten the allowable_error. Most tests are tighter + // than one milimeter, however when doing randomized testing + // you can walk into inaccurate cases. + F32 allowable_relative_error = 0.001f; + S32 number_of_tests = 100; + for (S32 test = 0; test < number_of_tests; ++test) + { + // generate two points to be our known nearest approaches + LLVector3 some_point( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + some_point.normalize(); + some_point *= ll_frand(LARGE_RADIUS); + + LLVector3 another_point( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + another_point.normalize(); + another_point *= ll_frand(LARGE_RADIUS); + + // compute the axis of approach (a unit vector between the points) + LLVector3 axis_of_approach = another_point - some_point; + axis_of_approach.normalize(); + + // compute the direction of the the first line (perp to axis_of_approach) + LLVector3 first_dir( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + F32 dot = first_dir * axis_of_approach; + first_dir -= dot * axis_of_approach; // subtract component parallel to axis + first_dir.normalize(); // normalize + + // compute the direction of the the second line + LLVector3 second_dir( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + dot = second_dir * axis_of_approach; + second_dir -= dot * axis_of_approach; + second_dir.normalize(); + + // make sure the lines aren't too parallel, + dot = fabsf(first_dir * second_dir); + if (dot > 0.99f) + { + // skip this test, we're not interested in testing + // the intractible cases + continue; + } + + // construct the lines + LLVector3 first_point = some_point + ll_frand(LARGE_RADIUS) * first_dir; + LLLine first_line(first_point, some_point); + + LLVector3 second_point = another_point + ll_frand(LARGE_RADIUS) * second_dir; + LLLine second_line(second_point, another_point); + + // compute the points of nearest approach + LLVector3 some_computed_point = first_line.nearestApproach(second_line); + LLVector3 another_computed_point = second_line.nearestApproach(first_line); + + // compute the error + F32 first_error = (some_point - some_computed_point).length(); + F32 scale = llmax((some_point - another_point).length(), some_point.length()); + scale = llmax(scale, another_point.length()); + scale = llmax(scale, 1.f); + F32 first_relative_error = first_error / scale; + + F32 second_error = (another_point - another_computed_point).length(); + F32 second_relative_error = second_error / scale; + + //if (first_relative_error > allowable_relative_error) + //{ + // std::cout << "first_error = " << first_error + // << " first_relative_error = " << first_relative_error + // << " scale = " << scale + // << " dir_dot = " << (first_dir * second_dir) + // << std::endl; + //} + //if (second_relative_error > allowable_relative_error) + //{ + // std::cout << "second_error = " << second_error + // << " second_relative_error = " << second_relative_error + // << " scale = " << scale + // << " dist = " << (some_point - another_point).length() + // << " dir_dot = " << (first_dir * second_dir) + // << std::endl; + //} + + // test that the errors are small + + ensure("first line should accurately compute its closest approach", + first_relative_error <= allowable_relative_error); + ensure("second line should accurately compute its closest approach", + second_relative_error <= allowable_relative_error); + } + */ + } + + F32 ALMOST_PARALLEL = 0.99f; + template<> template<> + void line_object::test<3>() + { + // this is a test for LLLine::getIntersectionBetweenTwoPlanes() method + + // first some known tests + LLLine xy_plane(LLVector3(0.f, 0.f, 2.f), LLVector3(0.f, 0.f, 3.f)); + LLLine yz_plane(LLVector3(2.f, 0.f, 0.f), LLVector3(3.f, 0.f, 0.f)); + LLLine zx_plane(LLVector3(0.f, 2.f, 0.f), LLVector3(0.f, 3.f, 0.f)); + + LLLine x_line; + LLLine y_line; + LLLine z_line; + + bool x_success = LLLine::getIntersectionBetweenTwoPlanes(x_line, xy_plane, zx_plane); + bool y_success = LLLine::getIntersectionBetweenTwoPlanes(y_line, yz_plane, xy_plane); + bool z_success = LLLine::getIntersectionBetweenTwoPlanes(z_line, zx_plane, yz_plane); + + ensure("xy and zx planes should intersect", x_success); + ensure("yz and xy planes should intersect", y_success); + ensure("zx and yz planes should intersect", z_success); + + LLVector3 direction = x_line.getDirection(); + ensure("x_line should be parallel to x_axis", fabs(direction.mV[VX]) == 1.f + && 0.f == direction.mV[VY] + && 0.f == direction.mV[VZ] ); + direction = y_line.getDirection(); + ensure("y_line should be parallel to y_axis", 0.f == direction.mV[VX] + && fabs(direction.mV[VY]) == 1.f + && 0.f == direction.mV[VZ] ); + direction = z_line.getDirection(); + ensure("z_line should be parallel to z_axis", 0.f == direction.mV[VX] + && 0.f == direction.mV[VY] + && fabs(direction.mV[VZ]) == 1.f ); + + // next some random tests + F32 allowable_relative_error = 0.0001f; + S32 number_of_tests = 20; + for (S32 test = 0; test < number_of_tests; ++test) + { + // generate the known line + LLVector3 some_point( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + some_point.normalize(); + some_point *= ll_frand(LARGE_RADIUS); + LLVector3 another_point( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + another_point.normalize(); + another_point *= ll_frand(LARGE_RADIUS); + LLLine known_intersection(some_point, another_point); + + // compute a plane that intersect the line + LLVector3 point_on_plane( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + point_on_plane.normalize(); + point_on_plane *= ll_frand(LARGE_RADIUS); + LLVector3 plane_normal = (point_on_plane - some_point) % known_intersection.getDirection(); + plane_normal.normalize(); + LLLine first_plane(point_on_plane, point_on_plane + plane_normal); + + // compute a different plane that intersect the line + LLVector3 point_on_different_plane( ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f, + ll_frand(2.f) - 1.f); + point_on_different_plane.normalize(); + point_on_different_plane *= ll_frand(LARGE_RADIUS); + LLVector3 different_plane_normal = (point_on_different_plane - another_point) % known_intersection.getDirection(); + different_plane_normal.normalize(); + LLLine second_plane(point_on_different_plane, point_on_different_plane + different_plane_normal); + + if (fabs(plane_normal * different_plane_normal) > ALMOST_PARALLEL) + { + // the two planes are approximately parallel, so we won't test this case + continue; + } + + LLLine measured_intersection; + bool success = LLLine::getIntersectionBetweenTwoPlanes( + measured_intersection, + first_plane, + second_plane); + + ensure("plane intersection should succeed", success); + + F32 dot = fabs(known_intersection.getDirection() * measured_intersection.getDirection()); + ensure("measured intersection should be parallel to known intersection", + dot > ALMOST_PARALLEL); + + ensure("measured intersection should pass near known point", + measured_intersection.intersects(some_point, LARGE_RADIUS * allowable_relative_error)); + } + } +} + diff --git a/indra/llmath/tests/v2math_test.cpp b/indra/llmath/tests/v2math_test.cpp new file mode 100644 index 0000000000..456faf7c0c --- /dev/null +++ b/indra/llmath/tests/v2math_test.cpp @@ -0,0 +1,454 @@ +/** + * @file v2math_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief v2math test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../v2math.h" + + +namespace tut +{ + struct v2math_data + { + }; + typedef test_group<v2math_data> v2math_test; + typedef v2math_test::object v2math_object; + tut::v2math_test v2math_testcase("v2math"); + + template<> template<> + void v2math_object::test<1>() + { + LLVector2 vec2; + ensure("LLVector2:Fail to initialize ", (0.f == vec2.mV[VX] && 0.f == vec2.mV[VY])); + + F32 x =2.0f, y = 3.2f ; + LLVector2 vec3(x,y); + ensure("LLVector2(F32 x, F32 y):Fail to initialize ", (x == vec3.mV[VX]) && (y == vec3.mV[VY])); + + const F32 vec[2] = {3.2f, 4.5f}; + LLVector2 vec4(vec); + ensure("LLVector2(const F32 *vec):Fail to initialize ", (vec[0] == vec4.mV[VX]) && (vec[1] == vec4.mV[VY])); + + vec4.clearVec(); + ensure("clearVec():Fail to clean the values ", (0.f == vec4.mV[VX] && 0.f == vec4.mV[VY])); + + vec3.zeroVec(); + ensure("zeroVec():Fail to fill the zero ", (0.f == vec3.mV[VX] && 0.f == vec3.mV[VY])); + } + + template<> template<> + void v2math_object::test<2>() + { + F32 x = 123.356f, y = 2387.453f; + LLVector2 vec2,vec3; + vec2.setVec(x, y); + ensure("1:setVec: Fail ", (x == vec2.mV[VX]) && (y == vec2.mV[VY])); + + vec3.setVec(vec2); + ensure("2:setVec: Fail " ,(vec2 == vec3)); + + vec3.zeroVec(); + const F32 vec[2] = {3.24653f, 457653.4f}; + vec3.setVec(vec); + ensure("3:setVec: Fail ", (vec[0] == vec3.mV[VX]) && (vec[1] == vec3.mV[VY])); + } + + template<> template<> + void v2math_object::test<3>() + { + F32 x = 2.2345f, y = 3.5678f ; + LLVector2 vec2(x,y); + ensure("magVecSquared:Fail ", is_approx_equal(vec2.magVecSquared(), (x*x + y*y))); + ensure("magVec:Fail ", is_approx_equal(vec2.magVec(), fsqrtf(x*x + y*y))); + } + + template<> template<> + void v2math_object::test<4>() + { + F32 x =-2.0f, y = -3.0f ; + LLVector2 vec2(x,y); + ensure_equals("abs():Fail", vec2.abs(), TRUE); + ensure("abs() x", is_approx_equal(vec2.mV[VX], 2.f)); + ensure("abs() y", is_approx_equal(vec2.mV[VY], 3.f)); + + ensure("isNull():Fail ", FALSE == vec2.isNull()); //Returns TRUE if vector has a _very_small_ length + + x =.00000001f, y = .000001001f; + vec2.setVec(x, y); + ensure("isNull(): Fail ", TRUE == vec2.isNull()); + } + + template<> template<> + void v2math_object::test<5>() + { + F32 x =1.f, y = 2.f; + LLVector2 vec2(x, y), vec3; + vec3 = vec3.scaleVec(vec2); + ensure("scaleVec: Fail ", vec3.mV[VX] == 0. && vec3.mV[VY] == 0.); + ensure("isExactlyZero(): Fail", TRUE == vec3.isExactlyZero()); + + vec3.setVec(2.f, 1.f); + vec3 = vec3.scaleVec(vec2); + ensure("scaleVec: Fail ", (2.f == vec3.mV[VX]) && (2.f == vec3.mV[VY])); + ensure("isExactlyZero():Fail", FALSE == vec3.isExactlyZero()); + } + + template<> template<> + void v2math_object::test<6>() + { + F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; + F32 val1, val2; + LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; + vec4 = vec2 + vec3 ; + val1 = x1+x2; + val2 = y1+y2; + ensure("1:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); + + vec2.clearVec(); + vec3.clearVec(); + x1 = -.235f, y1 = -24.32f, x2 = -2.3f, y2 = 1.f; + vec2.setVec(x1, y1); + vec3.setVec(x2, y2); + vec4 = vec2 + vec3; + val1 = x1+x2; + val2 = y1+y2; + ensure("2:operator+ failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); + } + + template<> template<> + void v2math_object::test<7>() + { + F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; + F32 val1, val2; + LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; + vec4 = vec2 - vec3 ; + val1 = x1-x2; + val2 = y1-y2; + ensure("1:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); + + vec2.clearVec(); + vec3.clearVec(); + vec4.clearVec(); + x1 = -.235f, y1 = -24.32f, x2 = -2.3f, y2 = 1.f; + vec2.setVec(x1, y1); + vec3.setVec(x2, y2); + vec4 = vec2 - vec3; + val1 = x1-x2; + val2 = y1-y2; + ensure("2:operator- failed",(val1 == vec4.mV[VX]) && ((val2 == vec4.mV[VY]))); + } + + template<> template<> + void v2math_object::test<8>() + { + F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; + F32 val1, val2; + LLVector2 vec2(x1, y1), vec3(x2, y2); + val1 = vec2 * vec3; + val2 = x1*x2 + y1*y2; + ensure("1:operator* failed",(val1 == val2)); + + vec3.clearVec(); + F32 mulVal = 4.332f; + vec3 = vec2 * mulVal; + val1 = x1*mulVal; + val2 = y1*mulVal; + ensure("2:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY])); + + vec3.clearVec(); + vec3 = mulVal * vec2; + ensure("3:operator* failed",(val1 == vec3.mV[VX]) && (val2 == vec3.mV[VY])); + } + + template<> template<> + void v2math_object::test<9>() + { + F32 x1 =1.f, y1 = 2.f, div = 3.2f; + F32 val1, val2; + LLVector2 vec2(x1, y1), vec3; + vec3 = vec2 / div; + val1 = x1 / div; + val2 = y1 / div; + ensure("1:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY])); + + vec3.clearVec(); + x1 = -.235f, y1 = -24.32f, div = -2.2f; + vec2.setVec(x1, y1); + vec3 = vec2 / div; + val1 = x1 / div; + val2 = y1 / div; + ensure("2:operator/ failed", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY])); + } + + template<> template<> + void v2math_object::test<10>() + { + F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; + F32 val1, val2; + LLVector2 vec2(x1, y1), vec3(x2, y2), vec4; + vec4 = vec2 % vec3; + val1 = x1*y2 - x2*y1; + val2 = y1*x2 - y2*x1; + ensure("1:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY])); + + vec2.clearVec(); + vec3.clearVec(); + vec4.clearVec(); + x1 = -.235f, y1 = -24.32f, x2 = -2.3f, y2 = 1.f; + vec2.setVec(x1, y1); + vec3.setVec(x2, y2); + vec4 = vec2 % vec3; + val1 = x1*y2 - x2*y1; + val2 = y1*x2 - y2*x1; + ensure("2:operator% failed",(val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY])); + } + template<> template<> + void v2math_object::test<11>() + { + F32 x1 =1.f, y1 = 2.f; + LLVector2 vec2(x1, y1), vec3(x1, y1); + ensure("1:operator== failed",(vec2 == vec3)); + + vec2.clearVec(); + vec3.clearVec(); + x1 = -.235f, y1 = -24.32f; + vec2.setVec(x1, y1); + vec3.setVec(vec2); + ensure("2:operator== failed",(vec2 == vec3)); + } + + template<> template<> + void v2math_object::test<12>() + { + F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; + LLVector2 vec2(x1, y1), vec3(x2, y2); + ensure("1:operator!= failed",(vec2 != vec3)); + + vec2.clearVec(); + vec3.clearVec(); + vec2.setVec(x1, y1); + vec3.setVec(vec2); + ensure("2:operator!= failed", (FALSE == (vec2 != vec3))); + } + template<> template<> + void v2math_object::test<13>() + { + F32 x1 = 1.f, y1 = 2.f,x2 = 2.332f, y2 = -1.23f; + F32 val1, val2; + LLVector2 vec2(x1, y1), vec3(x2, y2); + vec2 +=vec3; + val1 = x1+x2; + val2 = y1+y2; + ensure("1:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + + vec2.setVec(x1, y1); + vec2 -=vec3; + val1 = x1-x2; + val2 = y1-y2; + ensure("2:operator-= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + + vec2.clearVec(); + vec3.clearVec(); + x1 = -21.000466f, y1 = 2.98382f,x2 = 0.332f, y2 = -01.23f; + vec2.setVec(x1, y1); + vec3.setVec(x2, y2); + vec2 +=vec3; + val1 = x1+x2; + val2 = y1+y2; + ensure("3:operator+= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + + vec2.setVec(x1, y1); + vec2 -=vec3; + val1 = x1-x2; + val2 = y1-y2; + ensure("4:operator-= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); + } + + template<> template<> + void v2math_object::test<14>() + { + F32 x1 =1.f, y1 = 2.f; + F32 val1, val2, mulVal = 4.332f; + LLVector2 vec2(x1, y1); + vec2 /=mulVal; + val1 = x1 / mulVal; + val2 = y1 / mulVal; + ensure("1:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); + + vec2.clearVec(); + x1 = .213f, y1 = -2.34f, mulVal = -.23f; + vec2.setVec(x1, y1); + vec2 /=mulVal; + val1 = x1 / mulVal; + val2 = y1 / mulVal; + ensure("2:operator/= failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY])); + } + + template<> template<> + void v2math_object::test<15>() + { + F32 x1 =1.f, y1 = 2.f; + F32 val1, val2, mulVal = 4.332f; + LLVector2 vec2(x1, y1); + vec2 *=mulVal; + val1 = x1*mulVal; + val2 = y1*mulVal; + ensure("1:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + + vec2.clearVec(); + x1 = .213f, y1 = -2.34f, mulVal = -.23f; + vec2.setVec(x1, y1); + vec2 *=mulVal; + val1 = x1*mulVal; + val2 = y1*mulVal; + ensure("2:operator*= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + } + + template<> template<> + void v2math_object::test<16>() + { + F32 x1 =1.f, y1 = 2.f, x2 = -2.3f, y2 = 1.11f; + F32 val1, val2; + LLVector2 vec2(x1, y1), vec3(x2, y2); + vec2 %= vec3; + val1 = x1*y2 - x2*y1; + val2 = y1*x2 - y2*x1; + ensure("1:operator%= failed",(val1 == vec2.mV[VX]) && (val2 == vec2.mV[VY])); + } + + template<> template<> + void v2math_object::test<17>() + { + F32 x1 =1.f, y1 = 2.f; + LLVector2 vec2(x1, y1),vec3; + vec3 = -vec2; + ensure("1:operator- failed",(-vec3 == vec2)); + } + + template<> template<> + void v2math_object::test<18>() + { + F32 x1 =1.f, y1 = 2.f; + std::ostringstream stream1, stream2; + LLVector2 vec2(x1, y1),vec3; + stream1 << vec2; + vec3.setVec(x1, y1); + stream2 << vec3; + ensure("1:operator << failed",(stream1.str() == stream2.str())); + } + + template<> template<> + void v2math_object::test<19>() + { + F32 x1 =1.0f, y1 = 2.0f, x2 = -.32f, y2 = .2234f; + LLVector2 vec2(x1, y1),vec3(x2, y2); + ensure("1:operator < failed",(vec3 < vec2)); + + x1 = 1.0f, y1 = 2.0f, x2 = 1.0f, y2 = 3.2234f; + vec2.setVec(x1, y1); + vec3.setVec(x2, y2); + ensure("2:operator < failed", (FALSE == (vec3 < vec2))); + } + + template<> template<> + void v2math_object::test<20>() + { + F32 x1 =1.0f, y1 = 2.0f; + LLVector2 vec2(x1, y1); + ensure("1:operator [] failed",( x1 == vec2[0])); + ensure("2:operator [] failed",( y1 == vec2[1])); + + vec2.clearVec(); + x1 = 23.0f, y1 = -.2361f; + vec2.setVec(x1, y1); + F32 ref1 = vec2[0]; + ensure("3:operator [] failed", ( ref1 == x1)); + F32 ref2 = vec2[1]; + ensure("4:operator [] failed", ( ref2 == y1)); + } + + template<> template<> + void v2math_object::test<21>() + { + F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f; + F32 val1, val2; + LLVector2 vec2(x1, y1),vec3(x2, y2); + val1 = dist_vec_squared2D(vec2, vec3); + val2 = (x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); + ensure_equals("dist_vec_squared2D values are not equal",val2, val1); + + val1 = dist_vec_squared(vec2, vec3); + ensure_equals("dist_vec_squared values are not equal",val2, val1); + + val1 = dist_vec(vec2, vec3); + val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2)); + ensure_equals("dist_vec values are not equal",val2, val1); + } + + template<> template<> + void v2math_object::test<22>() + { + F32 x1 =1.f, y1 = 2.f, x2 = -.32f, y2 = .2234f,fVal = .0121f; + F32 val1, val2; + LLVector2 vec2(x1, y1),vec3(x2, y2); + LLVector2 vec4 = lerp(vec2, vec3, fVal); + val1 = x1 + (x2 - x1) * fVal; + val2 = y1 + (y2 - y1) * fVal; + ensure("lerp values are not equal", ((val1 == vec4.mV[VX]) && (val2 == vec4.mV[VY]))); + } + + template<> template<> + void v2math_object::test<23>() + { + F32 x1 =1.f, y1 = 2.f; + F32 val1, val2; + LLVector2 vec2(x1, y1); + + F32 vecMag = vec2.normVec(); + F32 mag = fsqrtf(x1*x1 + y1*y1); + + F32 oomag = 1.f / mag; + val1 = x1 * oomag; + val2 = y1 * oomag; + + ensure("normVec failed", is_approx_equal(val1, vec2.mV[VX]) && is_approx_equal(val2, vec2.mV[VY]) && is_approx_equal(vecMag, mag)); + + x1 =.00000001f, y1 = 0.f; + + vec2.setVec(x1, y1); + vecMag = vec2.normVec(); + ensure("normVec failed should be 0.", 0. == vec2.mV[VX] && 0. == vec2.mV[VY] && vecMag == 0.); + } +} diff --git a/indra/llmath/tests/v3color_test.cpp b/indra/llmath/tests/v3color_test.cpp new file mode 100644 index 0000000000..bb6e234fd6 --- /dev/null +++ b/indra/llmath/tests/v3color_test.cpp @@ -0,0 +1,315 @@ +/** + * @file v3color_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v3color test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../v3color.h" + + +namespace tut +{ + struct v3color_data + { + }; + typedef test_group<v3color_data> v3color_test; + typedef v3color_test::object v3color_object; + tut::v3color_test v3color_testcase("v3color"); + + template<> template<> + void v3color_object::test<1>() + { + LLColor3 llcolor3; + ensure("1:LLColor3:Fail to default-initialize ", (0.0f == llcolor3.mV[0]) && (0.0f == llcolor3.mV[1]) && (0.0f == llcolor3.mV[2])); + F32 r = 2.0f, g = 3.2f, b = 1.f; + F32 v1,v2,v3; + LLColor3 llcolor3a(r,g,b); + ensure("2:LLColor3:Fail to initialize " ,(2.0f == llcolor3a.mV[0]) && (3.2f == llcolor3a.mV[1]) && (1.f == llcolor3a.mV[2])); + + const F32 vec[3] = {2.0f, 3.2f,1.f}; + LLColor3 llcolor3b(vec); + ensure("3:LLColor3:Fail to initialize " ,(2.0f == llcolor3b.mV[0]) && (3.2f == llcolor3b.mV[1]) && (1.f == llcolor3b.mV[2])); + const char* str = "561122"; + LLColor3 llcolor3c(str); + v1 = (F32)86.0f/255.0f; // 0x56 = 86 + v2 = (F32)17.0f/255.0f; // 0x11 = 17 + v3 = (F32)34.0f/255.f; // 0x22 = 34 + ensure("4:LLColor3:Fail to initialize " , is_approx_equal(v1, llcolor3c.mV[0]) && is_approx_equal(v2, llcolor3c.mV[1]) && is_approx_equal(v3, llcolor3c.mV[2])); + } + + template<> template<> + void v3color_object::test<2>() + { + LLColor3 llcolor3; + llcolor3.setToBlack(); + ensure("setToBlack:Fail to set black ", ((llcolor3.mV[0] == 0.f) && (llcolor3.mV[1] == 0.f) && (llcolor3.mV[2] == 0.f))); + llcolor3.setToWhite(); + ensure("setToWhite:Fail to set white ", ((llcolor3.mV[0] == 1.f) && (llcolor3.mV[1] == 1.f) && (llcolor3.mV[2] == 1.f))); + } + + template<> template<> + void v3color_object::test<3>() + { + F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; + LLColor3 llcolor3, llcolor3a; + llcolor3.setVec(r,g,b); + ensure("1:setVec(r,g,b) Fail ",((r == llcolor3.mV[0]) && (g == llcolor3.mV[1]) && (b == llcolor3.mV[2]))); + llcolor3a.setVec(llcolor3); + ensure_equals("2:setVec(LLColor3) Fail ", llcolor3,llcolor3a); + F32 vec[3] = {1.2324f, 2.45634f, .234563f}; + llcolor3.setToBlack(); + llcolor3.setVec(vec); + ensure("3:setVec(F32*) Fail ",((vec[0] == llcolor3.mV[0]) && (vec[1] == llcolor3.mV[1]) && (vec[2] == llcolor3.mV[2]))); + } + + template<> template<> + void v3color_object::test<4>() + { + F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; + LLColor3 llcolor3(r,g,b); + ensure("magVecSquared:Fail ", is_approx_equal(llcolor3.magVecSquared(), (r*r + g*g + b*b))); + ensure("magVec:Fail ", is_approx_equal(llcolor3.magVec(), fsqrtf(r*r + g*g + b*b))); + } + + template<> template<> + void v3color_object::test<5>() + { + F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; + F32 val1, val2,val3; + LLColor3 llcolor3(r,g,b); + F32 vecMag = llcolor3.normVec(); + F32 mag = fsqrtf(r*r + g*g + b*b); + F32 oomag = 1.f / mag; + val1 = r * oomag; + val2 = g * oomag; + val3 = b * oomag; + ensure("1:normVec failed ", (is_approx_equal(val1, llcolor3.mV[0]) && is_approx_equal(val2, llcolor3.mV[1]) && is_approx_equal(val3, llcolor3.mV[2]) && is_approx_equal(vecMag, mag))); + r = .000000000f, g = 0.f, b = 0.0f; + llcolor3.setVec(r,g,b); + vecMag = llcolor3.normVec(); + ensure("2:normVec failed should be 0. ", (0. == llcolor3.mV[0] && 0. == llcolor3.mV[1] && 0. == llcolor3.mV[2] && vecMag == 0.)); + } + + template<> template<> + void v3color_object::test<6>() + { + F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; + std::ostringstream stream1, stream2; + LLColor3 llcolor3(r,g,b),llcolor3a; + stream1 << llcolor3; + llcolor3a.setVec(r,g,b); + stream2 << llcolor3a; + ensure("operator << failed ", (stream1.str() == stream2.str())); + } + + template<> template<> + void v3color_object::test<7>() + { + F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; + LLColor3 llcolor3(r,g,b),llcolor3a; + llcolor3a = llcolor3; + ensure("operator == failed ", (llcolor3a == llcolor3)); + } + + template<> template<> + void v3color_object::test<8>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; + llcolor3b = llcolor3 + llcolor3a ; + ensure("1:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); + r1 = -.235f, g1 = -24.32f, b1 = 2.13f, r2 = -2.3f, g2 = 1.f, b2 = 34.21f; + llcolor3.setVec(r1,g1,b1); + llcolor3a.setVec(r2,g2,b2); + llcolor3b = llcolor3 + llcolor3a; + ensure("2:operator+ failed",is_approx_equal(r1+r2 ,llcolor3b.mV[0]) && is_approx_equal(g1+g2,llcolor3b.mV[1])&& is_approx_equal(b1+b2,llcolor3b.mV[2])); + } + + template<> template<> + void v3color_object::test<9>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; + llcolor3b = llcolor3 - llcolor3a ; + ensure("1:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); + r1 = -.235f, g1 = -24.32f, b1 = 2.13f, r2 = -2.3f, g2 = 1.f, b2 = 34.21f; + llcolor3.setVec(r1,g1,b1); + llcolor3a.setVec(r2,g2,b2); + llcolor3b = llcolor3 - llcolor3a; + ensure("2:operator- failed",is_approx_equal(r1-r2 ,llcolor3b.mV[0]) && is_approx_equal(g1-g2,llcolor3b.mV[1])&& is_approx_equal(b1-b2,llcolor3b.mV[2])); + } + + template<> template<> + void v3color_object::test<10>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2),llcolor3b; + llcolor3b = llcolor3 * llcolor3a; + ensure("1:operator* failed",is_approx_equal(r1*r2 ,llcolor3b.mV[0]) && is_approx_equal(g1*g2,llcolor3b.mV[1])&& is_approx_equal(b1*b2,llcolor3b.mV[2])); + llcolor3a.setToBlack(); + F32 mulVal = 4.332f; + llcolor3a = llcolor3 * mulVal; + ensure("2:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); + llcolor3a.setToBlack(); + llcolor3a = mulVal * llcolor3; + ensure("3:operator* failed",is_approx_equal(r1*mulVal ,llcolor3a.mV[0]) && is_approx_equal(g1*mulVal,llcolor3a.mV[1])&& is_approx_equal(b1*mulVal,llcolor3a.mV[2])); + } + + template<> template<> + void v3color_object::test<11>() + { + F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; + LLColor3 llcolor3(r,g,b),llcolor3a; + llcolor3a = -llcolor3; + ensure("operator- failed ", (-llcolor3a == llcolor3)); + } + + template<> template<> + void v3color_object::test<12>() + { + F32 r = 2.3436212f, g = 1231.f, b = 4.7849321232f; + LLColor3 llcolor3(r,g,b),llcolor3a(r,g,b); + ensure_equals("1:operator== failed",llcolor3a,llcolor3); + r = 13.3436212f, g = -11.f, b = .7849321232f; + llcolor3.setVec(r,g,b); + llcolor3a.setVec(r,g,b); + ensure_equals("2:operator== failed",llcolor3a,llcolor3); + } + + template<> template<> + void v3color_object::test<13>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); + ensure("1:operator!= failed",(llcolor3 != llcolor3a)); + llcolor3.setToBlack(); + llcolor3a.setVec(llcolor3); + ensure("2:operator!= failed", ( FALSE == (llcolor3a != llcolor3))); + } + + template<> template<> + void v3color_object::test<14>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); + llcolor3a += llcolor3; + ensure("1:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); + llcolor3.setVec(r1,g1,b1); + llcolor3a.setVec(r2,g2,b2); + llcolor3a += llcolor3; + ensure("2:operator+= failed",is_approx_equal(r1+r2 ,llcolor3a.mV[0]) && is_approx_equal(g1+g2,llcolor3a.mV[1])&& is_approx_equal(b1+b2,llcolor3a.mV[2])); + } + + template<> template<> + void v3color_object::test<15>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); + llcolor3a -= llcolor3; + ensure("1:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); + ensure("2:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); + ensure("3:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); + llcolor3.setVec(r1,g1,b1); + llcolor3a.setVec(r2,g2,b2); + llcolor3a -= llcolor3; + ensure("4:operator-= failed", is_approx_equal(r2-r1, llcolor3a.mV[0])); + ensure("5:operator-= failed", is_approx_equal(g2-g1, llcolor3a.mV[1])); + ensure("6:operator-= failed", is_approx_equal(b2-b1, llcolor3a.mV[2])); + } + + template<> template<> + void v3color_object::test<16>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); + llcolor3a *= llcolor3; + ensure("1:operator*= failed",is_approx_equal(r1*r2 ,llcolor3a.mV[0]) && is_approx_equal(g1*g2,llcolor3a.mV[1])&& is_approx_equal(b1*b2,llcolor3a.mV[2])); + F32 mulVal = 4.332f; + llcolor3 *=mulVal; + ensure("2:operator*= failed",is_approx_equal(r1*mulVal ,llcolor3.mV[0]) && is_approx_equal(g1*mulVal,llcolor3.mV[1])&& is_approx_equal(b1*mulVal,llcolor3.mV[2])); + } + + template<> template<> + void v3color_object::test<17>() + { + F32 r = 2.3436212f, g = -1231.f, b = .7849321232f; + LLColor3 llcolor3(r,g,b); + llcolor3.clamp(); + ensure("1:clamp:Fail to clamp " ,(1.0f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (b == llcolor3.mV[2])); + r = -2.3436212f, g = -1231.f, b = 67.7849321232f; + llcolor3.setVec(r,g,b); + llcolor3.clamp(); + ensure("2:clamp:Fail to clamp " ,(0.f == llcolor3.mV[0]) && (0.f == llcolor3.mV[1]) && (1.f == llcolor3.mV[2])); + } + + template<> template<> + void v3color_object::test<18>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + F32 val = 2.3f,val1,val2,val3; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); + val1 = r1 + (r2 - r1)* val; + val2 = g1 + (g2 - g1)* val; + val3 = b1 + (b2 - b1)* val; + LLColor3 llcolor3b = lerp(llcolor3,llcolor3a,val); + ensure("lerp failed ", ((val1 ==llcolor3b.mV[0])&& (val2 ==llcolor3b.mV[1]) && (val3 ==llcolor3b.mV[2]))); + } + + template<> template<> + void v3color_object::test<19>() + { + F32 r1 =1.f, g1 = 2.f,b1 = 1.2f, r2 = -2.3f, g2 = 1.11f, b2 = 1234.234f; + LLColor3 llcolor3(r1,g1,b1),llcolor3a(r2,g2,b2); + F32 val = distVec(llcolor3,llcolor3a); + ensure("distVec failed ", is_approx_equal(fsqrtf((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val)); + + F32 val1 = distVec_squared(llcolor3,llcolor3a); + ensure("distVec_squared failed ", is_approx_equal(((r1-r2)*(r1-r2) + (g1-g2)*(g1-g2) + (b1-b2)*(b1-b2)) ,val1)); + } + + template<> template<> + void v3color_object::test<20>() + { + F32 r1 = 1.02223f, g1 = 22222.212f, b1 = 122222.00002f; + LLColor3 llcolor31(r1,g1,b1); + + LLSD sd = llcolor31.getValue(); + LLColor3 llcolor32; + llcolor32.setValue(sd); + ensure_equals("LLColor3::setValue/getValue failed", llcolor31, llcolor32); + + LLColor3 llcolor33(sd); + ensure_equals("LLColor3(LLSD) failed", llcolor31, llcolor33); + } +} diff --git a/indra/llmath/tests/v3dmath_test.cpp b/indra/llmath/tests/v3dmath_test.cpp new file mode 100644 index 0000000000..780495e53d --- /dev/null +++ b/indra/llmath/tests/v3dmath_test.cpp @@ -0,0 +1,532 @@ +/** + * @file v3dmath_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v3dmath test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llsd.h" +#include "../test/lltut.h" + +#include "../llquaternion.h" +#include "../m3math.h" +#include "../v4math.h" +#include "../v3dmath.h" +#include "../v3dmath.h" + +namespace tut +{ + struct v3dmath_data + { + }; + typedef test_group<v3dmath_data> v3dmath_test; + typedef v3dmath_test::object v3dmath_object; + tut::v3dmath_test v3dmath_testcase("v3dmath"); + + template<> template<> + void v3dmath_object::test<1>() + { + LLVector3d vec3D; + ensure("1:LLVector3d:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); + F64 x = 2.32f, y = 1.212f, z = -.12f; + LLVector3d vec3Da(x,y,z); + ensure("2:LLVector3d:Fail to initialize ", ((2.32f == vec3Da.mdV[VX]) && (1.212f == vec3Da.mdV[VY]) && (-.12f == vec3Da.mdV[VZ]))); + const F64 vec[3] = {1.2f ,3.2f, -4.2f}; + LLVector3d vec3Db(vec); + ensure("3:LLVector3d:Fail to initialize ", ((1.2f == vec3Db.mdV[VX]) && (3.2f == vec3Db.mdV[VY]) && (-4.2f == vec3Db.mdV[VZ]))); + LLVector3 vec3((F32)x,(F32)y,(F32)z); + LLVector3d vec3Dc(vec3); + ensure_equals("4:LLVector3d Fail to initialize",vec3Da,vec3Dc); + } + + template<> template<> + void v3dmath_object::test<2>() + { + S32 a = -235; + LLSD llsd(a); + LLVector3d vec3d(llsd); + LLSD sd = vec3d.getValue(); + LLVector3d vec3da(sd); + ensure("1:getValue:Fail ", (vec3d == vec3da)); + } + + template<> template<> + void v3dmath_object::test<3>() + { + F64 a = 232345521.411132; + LLSD llsd(a); + LLVector3d vec3d; + vec3d.setValue(llsd); + LLSD sd = vec3d.getValue(); + LLVector3d vec3da(sd); + ensure("1:setValue:Fail to initialize ", (vec3d == vec3da)); + } + + template<> template<> + void v3dmath_object::test<4>() + { + F64 a[3] = {222231.43222, 12345.2343, -434343.33222}; + LLSD llsd; + llsd[0] = a[0]; + llsd[1] = a[1]; + llsd[2] = a[2]; + LLVector3d vec3D; + vec3D = (LLVector3d)llsd; + ensure("1:operator=:Fail to initialize ", ((llsd[0].asReal()== vec3D.mdV[VX]) && (llsd[1].asReal() == vec3D.mdV[VY]) && (llsd[2].asReal() == vec3D.mdV[VZ]))); + } + + template<> template<> + void v3dmath_object::test<5>() + { + F64 x = 2.32f, y = 1.212f, z = -.12f; + LLVector3d vec3D(x,y,z); + vec3D.clearVec(); + ensure("1:clearVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); + vec3D.setVec(x,y,z); + ensure("2:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); + vec3D.zeroVec(); + ensure("3:zeroVec:Fail to initialize ", ((0 == vec3D.mdV[VX]) && (0 == vec3D.mdV[VY]) && (0 == vec3D.mdV[VZ]))); + vec3D.clearVec(); + LLVector3 vec3((F32)x,(F32)y,(F32)z); + vec3D.setVec(vec3); + ensure("4:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); + vec3D.clearVec(); + const F64 vec[3] = {x,y,z}; + vec3D.setVec(vec); + ensure("5:setVec:Fail to initialize ", ((x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (z == vec3D.mdV[VZ]))); + LLVector3d vec3Da; + vec3Da.setVec(vec3D); + ensure_equals("6:setVec: Fail to initialize", vec3D, vec3Da); + } + + template<> template<> + void v3dmath_object::test<6>() + { + F64 x = -2.32, y = 1.212, z = -.12; + LLVector3d vec3D(x,y,z); + vec3D.abs(); + ensure("1:abs:Fail ", ((-x == vec3D.mdV[VX]) && (y == vec3D.mdV[VY]) && (-z == vec3D.mdV[VZ]))); + ensure("2:isNull():Fail ", (FALSE == vec3D.isNull())); + vec3D.clearVec(); + x =.00000001, y = .000001001, z = .000001001; + vec3D.setVec(x,y,z); + ensure("3:isNull():Fail ", (TRUE == vec3D.isNull())); + ensure("4:isExactlyZero():Fail ", (FALSE == vec3D.isExactlyZero())); + x =.0000000, y = .00000000, z = .00000000; + vec3D.setVec(x,y,z); + ensure("5:isExactlyZero():Fail ", (TRUE == vec3D.isExactlyZero())); + } + + template<> template<> + void v3dmath_object::test<7>() + { + F64 x = -2.32, y = 1.212, z = -.12; + LLVector3d vec3D(x,y,z); + + ensure("1:operator [] failed",( x == vec3D[0])); + ensure("2:operator [] failed",( y == vec3D[1])); + ensure("3:operator [] failed",( z == vec3D[2])); + vec3D.clearVec(); + x = 23.23, y = -.2361, z = 3.25; + vec3D.setVec(x,y,z); + F64 &ref1 = vec3D[0]; + ensure("4:operator [] failed",( ref1 == vec3D[0])); + F64 &ref2 = vec3D[1]; + ensure("5:operator [] failed",( ref2 == vec3D[1])); + F64 &ref3 = vec3D[2]; + ensure("6:operator [] failed",( ref3 == vec3D[2])); + } + + template<> template<> + void v3dmath_object::test<8>() + { + F32 x = 1.f, y = 2.f, z = -1.f; + LLVector4 vec4(x,y,z); + LLVector3d vec3D; + vec3D = vec4; + ensure("1:operator=:Fail to initialize ", ((vec4.mV[VX] == vec3D.mdV[VX]) && (vec4.mV[VY] == vec3D.mdV[VY]) && (vec4.mV[VZ] == vec3D.mdV[VZ]))); + } + + template<> template<> + void v3dmath_object::test<9>() + { + F64 x1 = 1.78787878, y1 = 232322.2121, z1 = -12121.121212; + F64 x2 = 1.2, y2 = 2.5, z2 = 1.; + LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; + vec3Db = vec3Da+ vec3D; + ensure("1:operator+:Fail to initialize ", ((x1+x2 == vec3Db.mdV[VX]) && (y1+y2 == vec3Db.mdV[VY]) && (z1+z2 == vec3Db.mdV[VZ]))); + x1 = -2.45, y1 = 2.1, z1 = 3.0; + vec3D.clearVec(); + vec3Da.clearVec(); + vec3D.setVec(x1,y1,z1); + vec3Da += vec3D; + ensure_equals("2:operator+=: Fail to initialize", vec3Da,vec3D); + vec3Da += vec3D; + ensure("3:operator+=:Fail to initialize ", ((2*x1 == vec3Da.mdV[VX]) && (2*y1 == vec3Da.mdV[VY]) && (2*z1 == vec3Da.mdV[VZ]))); + } + + template<> template<> + void v3dmath_object::test<10>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1; + F64 x2 = 1.2, y2 = 2.5, z2 = 1.; + LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2),vec3Db; + vec3Db = vec3Da - vec3D; + ensure("1:operator-:Fail to initialize ", ((x2-x1 == vec3Db.mdV[VX]) && (y2-y1 == vec3Db.mdV[VY]) && (z2-z1 == vec3Db.mdV[VZ]))); + x1 = -2.45, y1 = 2.1, z1 = 3.0; + vec3D.clearVec(); + vec3Da.clearVec(); + vec3D.setVec(x1,y1,z1); + vec3Da -=vec3D; + ensure("2:operator-=:Fail to initialize ", ((2.45 == vec3Da.mdV[VX]) && (-2.1 == vec3Da.mdV[VY]) && (-3.0 == vec3Da.mdV[VZ]))); + vec3Da -= vec3D; + ensure("3:operator-=:Fail to initialize ", ((-2*x1 == vec3Da.mdV[VX]) && (-2*y1 == vec3Da.mdV[VY]) && (-2*z1 == vec3Da.mdV[VZ]))); + } + template<> template<> + void v3dmath_object::test<11>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1; + F64 x2 = 1.2, y2 = 2.5, z2 = 1.; + LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2); + F64 res = vec3D * vec3Da; + ensure_approximately_equals( + "1:operator* failed", + res, + (x1*x2 + y1*y2 + z1*z2), + 8); + vec3Da.clearVec(); + F64 mulVal = 4.2; + vec3Da = vec3D * mulVal; + ensure_approximately_equals( + "2a:operator* failed", + vec3Da.mdV[VX], + x1*mulVal, + 8); + ensure_approximately_equals( + "2b:operator* failed", + vec3Da.mdV[VY], + y1*mulVal, + 8); + ensure_approximately_equals( + "2c:operator* failed", + vec3Da.mdV[VZ], + z1*mulVal, + 8); + vec3Da.clearVec(); + vec3Da = mulVal * vec3D; + ensure_approximately_equals( + "3a:operator* failed", + vec3Da.mdV[VX], + x1*mulVal, + 8); + ensure_approximately_equals( + "3b:operator* failed", + vec3Da.mdV[VY], + y1*mulVal, + 8); + ensure_approximately_equals( + "3c:operator* failed", + vec3Da.mdV[VZ], + z1*mulVal, + 8); + vec3D *= mulVal; + ensure_approximately_equals( + "4a:operator*= failed", + vec3D.mdV[VX], + x1*mulVal, + 8); + ensure_approximately_equals( + "4b:operator*= failed", + vec3D.mdV[VY], + y1*mulVal, + 8); + ensure_approximately_equals( + "4c:operator*= failed", + vec3D.mdV[VZ], + z1*mulVal, + 8); + } + + template<> template<> + void v3dmath_object::test<12>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1; + F64 x2 = 1.2, y2 = 2.5, z2 = 1.; + F64 val1, val2, val3; + LLVector3d vec3D(x1,y1,z1),vec3Da(x2,y2,z2), vec3Db; + vec3Db = vec3D % vec3Da; + val1 = y1*z2 - y2*z1; + val2 = z1*x2 -z2*x1; + val3 = x1*y2-x2*y1; + ensure("1:operator% failed",(val1 == vec3Db.mdV[VX]) && (val2 == vec3Db.mdV[VY]) && (val3 == vec3Db.mdV[VZ])); + vec3D %= vec3Da; + ensure("2:operator%= failed", + is_approx_equal(vec3D.mdV[VX],vec3Db.mdV[VX]) && + is_approx_equal(vec3D.mdV[VY],vec3Db.mdV[VY]) && + is_approx_equal(vec3D.mdV[VZ],vec3Db.mdV[VZ]) ); + } + + template<> template<> + void v3dmath_object::test<13>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1,div = 4.2; + F64 t = 1.f / div; + LLVector3d vec3D(x1,y1,z1), vec3Da; + vec3Da = vec3D/div; + ensure_approximately_equals( + "1a:operator/ failed", + vec3Da.mdV[VX], + x1*t, + 8); + ensure_approximately_equals( + "1b:operator/ failed", + vec3Da.mdV[VY], + y1*t, + 8); + ensure_approximately_equals( + "1c:operator/ failed", + vec3Da.mdV[VZ], + z1*t, + 8); + x1 = 1.23, y1 = 4., z1 = -2.32; + vec3D.clearVec(); + vec3Da.clearVec(); + vec3D.setVec(x1,y1,z1); + vec3Da = vec3D/div; + ensure_approximately_equals( + "2a:operator/ failed", + vec3Da.mdV[VX], + x1*t, + 8); + ensure_approximately_equals( + "2b:operator/ failed", + vec3Da.mdV[VY], + y1*t, + 8); + ensure_approximately_equals( + "2c:operator/ failed", + vec3Da.mdV[VZ], + z1*t, + 8); + vec3D /= div; + ensure_approximately_equals( + "3a:operator/= failed", + vec3D.mdV[VX], + x1*t, + 8); + ensure_approximately_equals( + "3b:operator/= failed", + vec3D.mdV[VY], + y1*t, + 8); + ensure_approximately_equals( + "3c:operator/= failed", + vec3D.mdV[VZ], + z1*t, + 8); + } + + template<> template<> + void v3dmath_object::test<14>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1; + LLVector3d vec3D(x1,y1,z1), vec3Da; + ensure("1:operator!= failed",(TRUE == (vec3D !=vec3Da))); + vec3Da = vec3D; + ensure("2:operator== failed",(vec3D ==vec3Da)); + vec3D.clearVec(); + vec3Da.clearVec(); + x1 = .211, y1 = 21.111, z1 = 23.22; + vec3D.setVec(x1,y1,z1); + vec3Da.setVec(x1,y1,z1); + ensure("3:operator== failed",(vec3D ==vec3Da)); + ensure("4:operator!= failed",(FALSE == (vec3D !=vec3Da))); + } + + template<> template<> + void v3dmath_object::test<15>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1; + LLVector3d vec3D(x1,y1,z1), vec3Da; + std::ostringstream stream1, stream2; + stream1 << vec3D; + vec3Da.setVec(x1,y1,z1); + stream2 << vec3Da; + ensure("1:operator << failed",(stream1.str() == stream2.str())); + } + + template<> template<> + void v3dmath_object::test<16>() + { + F64 x1 = 1.23, y1 = 2.0, z1 = 4.; + std::string buf("1.23 2. 4"); + LLVector3d vec3D, vec3Da(x1,y1,z1); + LLVector3d::parseVector3d(buf, &vec3D); + ensure_equals("1:parseVector3d: failed " , vec3D, vec3Da); + } + + template<> template<> + void v3dmath_object::test<17>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1; + LLVector3d vec3D(x1,y1,z1), vec3Da; + vec3Da = -vec3D; + ensure("1:operator- failed", (vec3D == - vec3Da)); + } + + template<> template<> + void v3dmath_object::test<18>() + { + F64 x = 1., y = 2., z = -1.1; + LLVector3d vec3D(x,y,z); + F64 res = (x*x + y*y + z*z) - vec3D.magVecSquared(); + ensure("1:magVecSquared:Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO))); + res = fsqrtf(x*x + y*y + z*z) - vec3D.magVec(); + ensure("2:magVec: Fail ", ((-F_APPROXIMATELY_ZERO <= res)&& (res <=F_APPROXIMATELY_ZERO))); + } + + template<> template<> + void v3dmath_object::test<19>() + { + F64 x = 1., y = 2., z = -1.1; + LLVector3d vec3D(x,y,z); + F64 mag = vec3D.normVec(); + mag = 1.f/ mag; + ensure_approximately_equals( + "1a:normVec: Fail ", + vec3D.mdV[VX], + x * mag, + 8); + ensure_approximately_equals( + "1b:normVec: Fail ", + vec3D.mdV[VY], + y * mag, + 8); + ensure_approximately_equals( + "1c:normVec: Fail ", + vec3D.mdV[VZ], + z * mag, + 8); + x = 0.000000001, y = 0.000000001, z = 0.000000001; + vec3D.clearVec(); + vec3D.setVec(x,y,z); + mag = vec3D.normVec(); + ensure_approximately_equals( + "2a:normVec: Fail ", + vec3D.mdV[VX], + x * mag, + 8); + ensure_approximately_equals( + "2b:normVec: Fail ", + vec3D.mdV[VY], + y * mag, + 8); + ensure_approximately_equals( + "2c:normVec: Fail ", + vec3D.mdV[VZ], + z * mag, + 8); + } + + template<> template<> + void v3dmath_object::test<20>() + { + F64 x1 = 1111.232222; + F64 y1 = 2222222222.22; + F64 z1 = 422222222222.0; + std::string buf("1111.232222 2222222222.22 422222222222"); + LLVector3d vec3Da, vec3Db(x1,y1,z1); + LLVector3d::parseVector3d(buf, &vec3Da); + ensure_equals("1:parseVector3 failed", vec3Da, vec3Db); + } + + template<> template<> + void v3dmath_object::test<21>() + { + F64 x1 = 1., y1 = 2., z1 = -1.1; + F64 x2 = 1.2, y2 = 2.5, z2 = 1.; + F64 val = 2.3f,val1,val2,val3; + val1 = x1 + (x2 - x1)* val; + val2 = y1 + (y2 - y1)* val; + val3 = z1 + (z2 - z1)* val; + LLVector3d vec3Da(x1,y1,z1),vec3Db(x2,y2,z2); + LLVector3d vec3d = lerp(vec3Da,vec3Db,val); + ensure("1:lerp failed", ((val1 ==vec3d.mdV[VX])&& (val2 ==vec3d.mdV[VY]) && (val3 ==vec3d.mdV[VZ]))); + } + + template<> template<> + void v3dmath_object::test<22>() + { + F64 x = 2.32, y = 1.212, z = -.12; + F64 min = 0.0001, max = 3.0; + LLVector3d vec3d(x,y,z); + ensure("1:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); + x = 0.000001f, z = 5.3f; + vec3d.setVec(x,y,z); + ensure("2:clamp:Fail ", (TRUE == (vec3d.clamp(min, max)))); + } + + template<> template<> + void v3dmath_object::test<23>() + { + F64 x = 10., y = 20., z = -15.; + F64 epsilon = .23425; + LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); + ensure("1:are_parallel: Fail ", (TRUE == are_parallel(vec3Da,vec3Db,epsilon))); + F64 x1 = -12., y1 = -20., z1 = -100.; + vec3Db.clearVec(); + vec3Db.setVec(x1,y1,z1); + ensure("2:are_parallel: Fail ", (FALSE == are_parallel(vec3Da,vec3Db,epsilon))); + } + + template<> template<> + void v3dmath_object::test<24>() + { +#if LL_WINDOWS && _MSC_VER < 1400 + skip("This fails on VS2003!"); +#else + F64 x = 10., y = 20., z = -15.; + F64 angle1, angle2; + LLVector3d vec3Da(x,y,z), vec3Db(x,y,z); + angle1 = angle_between(vec3Da, vec3Db); + ensure("1:angle_between: Fail ", (0 == angle1)); + F64 x1 = -1., y1 = -20., z1 = -1.; + vec3Da.clearVec(); + vec3Da.setVec(x1,y1,z1); + angle2 = angle_between(vec3Da, vec3Db); + vec3Db.normVec(); + vec3Da.normVec(); + F64 angle = vec3Db*vec3Da; + angle = acos(angle); + ensure("2:angle_between: Fail ", (angle == angle2)); +#endif + } +} diff --git a/indra/llmath/tests/v3math_test.cpp b/indra/llmath/tests/v3math_test.cpp new file mode 100644 index 0000000000..14159974a3 --- /dev/null +++ b/indra/llmath/tests/v3math_test.cpp @@ -0,0 +1,573 @@ +/** + * @file v3math_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief v3math test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" +#include "llsd.h" + +#include "../llquaternion.h" +#include "../llquantize.h" +#include "../v3dmath.h" +#include "../m3math.h" +#include "../v4math.h" +#include "../v3math.h" + + +namespace tut +{ + struct v3math_data + { + }; + typedef test_group<v3math_data> v3math_test; + typedef v3math_test::object v3math_object; + tut::v3math_test v3math_testcase("v3math"); + + template<> template<> + void v3math_object::test<1>() + { + LLVector3 vec3; + ensure("1:LLVector3:Fail to initialize ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); + F32 x = 2.32f, y = 1.212f, z = -.12f; + LLVector3 vec3a(x,y,z); + ensure("2:LLVector3:Fail to initialize ", ((2.32f == vec3a.mV[VX]) && (1.212f == vec3a.mV[VY]) && (-.12f == vec3a.mV[VZ]))); + const F32 vec[3] = {1.2f ,3.2f, -4.2f}; + LLVector3 vec3b(vec); + ensure("3:LLVector3:Fail to initialize ", ((1.2f == vec3b.mV[VX]) && (3.2f == vec3b.mV[VY]) && (-4.2f == vec3b.mV[VZ]))); + } + + template<> template<> + void v3math_object::test<2>() + { + F32 x = 2.32f, y = 1.212f, z = -.12f; + LLVector3 vec3(x,y,z); + LLVector3d vector3d(vec3); + LLVector3 vec3a(vector3d); + ensure("1:LLVector3:Fail to initialize ", vec3 == vec3a); + LLVector4 vector4(vec3); + LLVector3 vec3b(vector4); + ensure("2:LLVector3:Fail to initialize ", vec3 == vec3b); + } + + template<> template<> + void v3math_object::test<3>() + { + S32 a = 231; + LLSD llsd(a); + LLVector3 vec3(llsd); + LLSD sd = vec3.getValue(); + LLVector3 vec3a(sd); + ensure("1:LLVector3:Fail to initialize ", (vec3 == vec3a)); + } + + template<> template<> + void v3math_object::test<4>() + { + S32 a = 231; + LLSD llsd(a); + LLVector3 vec3(llsd),vec3a; + vec3a = vec3; + ensure("1:Operator= Fail to initialize " ,(vec3 == vec3a)); + } + + template<> template<> + void v3math_object::test<5>() + { + F32 x = 2.32f, y = 1.212f, z = -.12f; + LLVector3 vec3(x,y,z); + ensure("1:isFinite= Fail to initialize ", (TRUE == vec3.isFinite()));//need more test cases: + vec3.clearVec(); + ensure("2:clearVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); + vec3.setVec(x,y,z); + ensure("3:setVec:Fail to set values ", ((2.32f == vec3.mV[VX]) && (1.212f == vec3.mV[VY]) && (-.12f == vec3.mV[VZ]))); + vec3.zeroVec(); + ensure("4:zeroVec:Fail to set values ", ((0.f == vec3.mV[VX]) && (0.f == vec3.mV[VY]) && (0.f == vec3.mV[VZ]))); + } + + template<> template<> + void v3math_object::test<6>() + { + F32 x = 2.32f, y = 1.212f, z = -.12f; + LLVector3 vec3(x,y,z),vec3a; + vec3.abs(); + ensure("1:abs:Fail ", ((x == vec3.mV[VX]) && (y == vec3.mV[VY]) && (-z == vec3.mV[VZ]))); + vec3a.setVec(vec3); + ensure("2:setVec:Fail to initialize ", (vec3a == vec3)); + const F32 vec[3] = {1.2f ,3.2f, -4.2f}; + vec3.clearVec(); + vec3.setVec(vec); + ensure("3:setVec:Fail to initialize ", ((1.2f == vec3.mV[VX]) && (3.2f == vec3.mV[VY]) && (-4.2f == vec3.mV[VZ]))); + vec3a.clearVec(); + LLVector3d vector3d(vec3); + vec3a.setVec(vector3d); + ensure("4:setVec:Fail to initialize ", (vec3 == vec3a)); + LLVector4 vector4(vec3); + vec3a.clearVec(); + vec3a.setVec(vector4); + ensure("5:setVec:Fail to initialize ", (vec3 == vec3a)); + } + + template<> template<> + void v3math_object::test<7>() + { + F32 x = 2.32f, y = 3.212f, z = -.12f; + F32 min = 0.0001f, max = 3.0f; + LLVector3 vec3(x,y,z); + ensure("1:clamp:Fail ", TRUE == vec3.clamp(min, max) && x == vec3.mV[VX] && max == vec3.mV[VY] && min == vec3.mV[VZ]); + x = 1.f, y = 2.2f, z = 2.8f; + vec3.setVec(x,y,z); + ensure("2:clamp:Fail ", FALSE == vec3.clamp(min, max)); + } + + template<> template<> + void v3math_object::test<8>() + { + F32 x = 2.32f, y = 1.212f, z = -.12f; + LLVector3 vec3(x,y,z); + ensure("1:magVecSquared:Fail ", is_approx_equal(vec3.magVecSquared(), (x*x + y*y + z*z))); + ensure("2:magVec:Fail ", is_approx_equal(vec3.magVec(), fsqrtf(x*x + y*y + z*z))); + } + + template<> template<> + void v3math_object::test<9>() + { + F32 x =-2.0f, y = -3.0f, z = 1.23f ; + LLVector3 vec3(x,y,z); + ensure("1:abs():Fail ", (TRUE == vec3.abs())); + ensure("2:isNull():Fail", (FALSE == vec3.isNull())); //Returns TRUE if vector has a _very_small_ length + x =.00000001f, y = .000001001f, z = .000001001f; + vec3.setVec(x,y,z); + ensure("3:isNull(): Fail ", (TRUE == vec3.isNull())); + } + + template<> template<> + void v3math_object::test<10>() + { + F32 x =-2.0f, y = -3.0f, z = 1.f ; + LLVector3 vec3(x,y,z),vec3a; + ensure("1:isExactlyZero():Fail ", (TRUE == vec3a.isExactlyZero())); + vec3a = vec3a.scaleVec(vec3); + ensure("2:scaleVec: Fail ", vec3a.mV[VX] == 0.f && vec3a.mV[VY] == 0.f && vec3a.mV[VZ] == 0.f); + vec3a.setVec(x,y,z); + vec3a = vec3a.scaleVec(vec3); + ensure("3:scaleVec: Fail ", ((4 == vec3a.mV[VX]) && (9 == vec3a.mV[VY]) &&(1 == vec3a.mV[VZ]))); + ensure("4:isExactlyZero():Fail ", (FALSE == vec3.isExactlyZero())); + } + + template<> template<> + void v3math_object::test<11>() + { + F32 x =20.0f, y = 30.0f, z = 15.f ; + F32 angle = 100.f; + LLVector3 vec3(x,y,z),vec3a(1.f,2.f,3.f); + vec3a = vec3a.rotVec(angle, vec3); + LLVector3 vec3b(1.f,2.f,3.f); + vec3b = vec3b.rotVec(angle, vec3); + ensure_equals("rotVec():Fail" ,vec3b,vec3a); + } + + template<> template<> + void v3math_object::test<12>() + { + F32 x =-2.0f, y = -3.0f, z = 1.f ; + LLVector3 vec3(x,y,z); + ensure("1:operator [] failed",( x == vec3[0])); + ensure("2:operator [] failed",( y == vec3[1])); + ensure("3:operator [] failed",( z == vec3[2])); + + vec3.clearVec(); + x = 23.f, y = -.2361f, z = 3.25; + vec3.setVec(x,y,z); + F32 &ref1 = vec3[0]; + ensure("4:operator [] failed",( ref1 == vec3[0])); + F32 &ref2 = vec3[1]; + ensure("5:operator [] failed",( ref2 == vec3[1])); + F32 &ref3 = vec3[2]; + ensure("6:operator [] failed",( ref3 == vec3[2])); + } + + template<> template<> + void v3math_object::test<13>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; + F32 val1, val2, val3; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; + vec3b = vec3 + vec3a ; + val1 = x1+x2; + val2 = y1+y2; + val3 = z1+z2; + ensure("1:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + + vec3.clearVec(); + vec3a.clearVec(); + vec3b.clearVec(); + x1 = -.235f, y1 = -24.32f,z1 = 2.13f, x2 = -2.3f, y2 = 1.f, z2 = 34.21f; + vec3.setVec(x1,y1,z1); + vec3a.setVec(x2,y2,z2); + vec3b = vec3 + vec3a; + val1 = x1+x2; + val2 = y1+y2; + val3 = z1+z2; + ensure("2:operator+ failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + } + + template<> template<> + void v3math_object::test<14>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; + F32 val1, val2, val3; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; + vec3b = vec3 - vec3a ; + val1 = x1-x2; + val2 = y1-y2; + val3 = z1-z2; + ensure("1:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + + vec3.clearVec(); + vec3a.clearVec(); + vec3b.clearVec(); + x1 = -.235f, y1 = -24.32f,z1 = 2.13f, x2 = -2.3f, y2 = 1.f, z2 = 34.21f; + vec3.setVec(x1,y1,z1); + vec3a.setVec(x2,y2,z2); + vec3b = vec3 - vec3a; + val1 = x1-x2; + val2 = y1-y2; + val3 = z1-z2; + ensure("2:operator- failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + } + + template<> template<> + void v3math_object::test<15>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; + F32 val1, val2, val3; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); + val1 = vec3 * vec3a; + val2 = x1*x2 + y1*y2 + z1*z2; + ensure_equals("1:operator* failed",val1,val2); + + vec3a.clearVec(); + F32 mulVal = 4.332f; + vec3a = vec3 * mulVal; + val1 = x1*mulVal; + val2 = y1*mulVal; + val3 = z1*mulVal; + ensure("2:operator* failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); + vec3a.clearVec(); + vec3a = mulVal * vec3; + ensure("3:operator* failed ", (val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); + } + + template<> template<> + void v3math_object::test<16>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; + F32 val1, val2, val3; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2), vec3b; + vec3b = vec3 % vec3a ; + val1 = y1*z2 - y2*z1; + val2 = z1*x2 -z2*x1; + val3 = x1*y2-x2*y1; + ensure("1:operator% failed",(val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + + vec3.clearVec(); + vec3a.clearVec(); + vec3b.clearVec(); + x1 =112.f, y1 = 22.3f,z1 = 1.2f, x2 = -2.3f, y2 = 341.11f, z2 = 1234.234f; + vec3.setVec(x1,y1,z1); + vec3a.setVec(x2,y2,z2); + vec3b = vec3 % vec3a ; + val1 = y1*z2 - y2*z1; + val2 = z1*x2 -z2*x1; + val3 = x1*y2-x2*y1; + ensure("2:operator% failed ", (val1 == vec3b.mV[VX]) && (val2 == vec3b.mV[VY]) && (val3 == vec3b.mV[VZ])); + } + + template<> template<> + void v3math_object::test<17>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; + F32 t = 1.f / div, val1, val2, val3; + LLVector3 vec3(x1,y1,z1), vec3a; + vec3a = vec3 / div; + val1 = x1 * t; + val2 = y1 * t; + val3 = z1 *t; + ensure("1:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ])); + + vec3a.clearVec(); + x1 = -.235f, y1 = -24.32f, z1 = .342f, div = -2.2f; + t = 1.f / div; + vec3.setVec(x1,y1,z1); + vec3a = vec3 / div; + val1 = x1 * t; + val2 = y1 * t; + val3 = z1 *t; + ensure("2:operator/ failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ])); + } + + template<> template<> + void v3math_object::test<18>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; + LLVector3 vec3(x1,y1,z1), vec3a(x1,y1,z1); + ensure("1:operator== failed",(vec3 == vec3a)); + + vec3a.clearVec(); + x1 = -.235f, y1 = -24.32f, z1 = .342f; + vec3.clearVec(); + vec3a.clearVec(); + vec3.setVec(x1,y1,z1); + vec3a.setVec(x1,y1,z1); + ensure("2:operator== failed ", (vec3 == vec3a)); + } + + template<> template<> + void v3math_object::test<19>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.234f,z2 = 11.2f;; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); + ensure("1:operator!= failed",(vec3a != vec3)); + + vec3.clearVec(); + vec3.clearVec(); + vec3a.setVec(vec3); + ensure("2:operator!= failed", ( FALSE == (vec3a != vec3))); + } + + template<> template<> + void v3math_object::test<20>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); + vec3a += vec3; + F32 val1, val2, val3; + val1 = x1+x2; + val2 = y1+y2; + val3 = z1+z2; + ensure("1:operator+= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); + } + + template<> template<> + void v3math_object::test<21>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 =112.f, y2 = 2.2f,z2 = 11.2f;; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); + vec3a -= vec3; + F32 val1, val2, val3; + val1 = x2-x1; + val2 = y2-y1; + val3 = z2-z1; + ensure("1:operator-= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); + } + + template<> template<> + void v3math_object::test<22>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; + F32 val1,val2,val3; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); + vec3a *= vec3; + val1 = x1*x2; + val2 = y1*y2; + val3 = z1*z2; + ensure("1:operator*= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY])&& (val3 == vec3a.mV[VZ])); + + F32 mulVal = 4.332f; + vec3 *=mulVal; + val1 = x1*mulVal; + val2 = y1*mulVal; + val3 = z1*mulVal; + ensure("2:operator*= failed ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); + } + + template<> template<> + void v3math_object::test<23>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, x2 = -2.3f, y2 = 1.11f, z2 = 1234.234f; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2),vec3b; + vec3b = vec3a % vec3; + vec3a %= vec3; + ensure_equals("1:operator%= failed",vec3a,vec3b); + } + + template<> template<> + void v3math_object::test<24>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f, div = 3.2f; + F32 t = 1.f / div, val1, val2, val3; + LLVector3 vec3a(x1,y1,z1); + vec3a /= div; + val1 = x1 * t; + val2 = y1 * t; + val3 = z1 *t; + ensure("1:operator/= failed",(val1 == vec3a.mV[VX]) && (val2 == vec3a.mV[VY]) && (val3 == vec3a.mV[VZ])); + } + + template<> template<> + void v3math_object::test<25>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; + LLVector3 vec3(x1,y1,z1), vec3a; + vec3a = -vec3; + ensure("1:operator- failed",(-vec3a == vec3)); + } + + template<> template<> + void v3math_object::test<26>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 1.2f; + std::ostringstream stream1, stream2; + LLVector3 vec3(x1,y1,z1), vec3a; + stream1 << vec3; + vec3a.setVec(x1,y1,z1); + stream2 << vec3a; + ensure("1:operator << failed",(stream1.str() == stream2.str())); + } + + template<> template<> + void v3math_object::test<27>() + { + F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; + LLVector3 vec3(x1,y1,z1), vec3a(x2,y2,z2); + ensure("1:operator< failed", (TRUE == (vec3 < vec3a))); + x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 2.f, z2 = 1234.234f; + vec3.setVec(x1,y1,z1); + vec3a.setVec(x2,y2,z2); + ensure("2:operator< failed ", (TRUE == (vec3 < vec3a))); + x1 =2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, + vec3.setVec(x1,y1,z1); + vec3a.setVec(x2,y2,z2); + ensure("3:operator< failed ", (FALSE == (vec3 < vec3a))); + } + + template<> template<> + void v3math_object::test<28>() + { + F32 x1 =1.23f, y1 = 2.f,z1 = 4.f; + std::string buf("1.23 2. 4"); + LLVector3 vec3, vec3a(x1,y1,z1); + LLVector3::parseVector3(buf, &vec3); + ensure_equals("1:parseVector3 failed", vec3, vec3a); + } + + template<> template<> + void v3math_object::test<29>() + { + F32 x1 =1.f, y1 = 2.f,z1 = 4.f; + LLVector3 vec3(x1,y1,z1),vec3a,vec3b; + vec3a.setVec(1,1,1); + vec3a.scaleVec(vec3); + ensure_equals("1:scaleVec failed", vec3, vec3a); + vec3a.clearVec(); + vec3a.setVec(x1,y1,z1); + vec3a.scaleVec(vec3); + ensure("2:scaleVec failed", ((1.f ==vec3a.mV[VX])&& (4.f ==vec3a.mV[VY]) && (16.f ==vec3a.mV[VZ]))); + } + + template<> template<> + void v3math_object::test<30>() + { + F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.11f, z2 = 1234.234f; + F32 val = 2.3f,val1,val2,val3; + val1 = x1 + (x2 - x1)* val; + val2 = y1 + (y2 - y1)* val; + val3 = z1 + (z2 - z1)* val; + LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); + LLVector3 vec3b = lerp(vec3,vec3a,val); + ensure("1:lerp failed", ((val1 ==vec3b.mV[VX])&& (val2 ==vec3b.mV[VY]) && (val3 ==vec3b.mV[VZ]))); + } + + template<> template<> + void v3math_object::test<31>() + { + F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; + F32 val1,val2; + LLVector3 vec3(x1,y1,z1),vec3a(x2,y2,z2); + val1 = dist_vec(vec3,vec3a); + val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); + ensure_equals("1:dist_vec: Fail ",val2, val1); + val1 = dist_vec_squared(vec3,vec3a); + val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); + ensure_equals("2:dist_vec_squared: Fail ",val2, val1); + val1 = dist_vec_squared2D(vec3, vec3a); + val2 =(x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2); + ensure_equals("3:dist_vec_squared2D: Fail ",val2, val1); + } + + template<> template<> + void v3math_object::test<32>() + { + F32 x =12.3524f, y = -342.f,z = 4.126341f; + LLVector3 vec3(x,y,z); + F32 mag = vec3.normVec(); + mag = 1.f/ mag; + F32 val1 = x* mag, val2 = y* mag, val3 = z* mag; + ensure("1:normVec: Fail ", is_approx_equal(val1, vec3.mV[VX]) && is_approx_equal(val2, vec3.mV[VY]) && is_approx_equal(val3, vec3.mV[VZ])); + x = 0.000000001f, y = 0.f, z = 0.f; + vec3.clearVec(); + vec3.setVec(x,y,z); + mag = vec3.normVec(); + val1 = x* mag, val2 = y* mag, val3 = z* mag; + ensure("2:normVec: Fail ", (mag == 0.) && (0. == vec3.mV[VX]) && (0. == vec3.mV[VY])&& (0. == vec3.mV[VZ])); + } + + template<> template<> + void v3math_object::test<33>() + { + F32 x = -202.23412f, y = 123.2312f, z = -89.f; + LLVector3 vec(x,y,z); + vec.snap(2); + ensure("1:snap: Fail ", is_approx_equal(-202.23f, vec.mV[VX]) && is_approx_equal(123.23f, vec.mV[VY]) && is_approx_equal(-89.f, vec.mV[VZ])); + } + + template<> template<> + void v3math_object::test<34>() + { + F32 x = 10.f, y = 20.f, z = -15.f; + F32 x1, y1, z1; + F32 lowerxy = 0.f, upperxy = 1.0f, lowerz = -1.0f, upperz = 1.f; + LLVector3 vec3(x,y,z); + vec3.quantize16(lowerxy,upperxy,lowerz,upperz); + x1 = U16_to_F32(F32_to_U16(x, lowerxy, upperxy), lowerxy, upperxy); + y1 = U16_to_F32(F32_to_U16(y, lowerxy, upperxy), lowerxy, upperxy); + z1 = U16_to_F32(F32_to_U16(z, lowerz, upperz), lowerz, upperz); + ensure("1:quantize16: Fail ", is_approx_equal(x1, vec3.mV[VX]) && is_approx_equal(y1, vec3.mV[VY]) && is_approx_equal(z1, vec3.mV[VZ])); + LLVector3 vec3a(x,y,z); + vec3a.quantize8(lowerxy,upperxy,lowerz,upperz); + x1 = U8_to_F32(F32_to_U8(x, lowerxy, upperxy), lowerxy, upperxy); + y1 = U8_to_F32(F32_to_U8(y, lowerxy, upperxy), lowerxy, upperxy); + z1 = U8_to_F32(F32_to_U8(z, lowerz, upperz), lowerz, upperz); + ensure("2:quantize8: Fail ", is_approx_equal(x1, vec3a.mV[VX]) && is_approx_equal(y1, vec3a.mV[VY]) && is_approx_equal(z1, vec3a.mV[VZ])); + } +} diff --git a/indra/llmath/tests/v4color_test.cpp b/indra/llmath/tests/v4color_test.cpp new file mode 100644 index 0000000000..cebb026ce6 --- /dev/null +++ b/indra/llmath/tests/v4color_test.cpp @@ -0,0 +1,365 @@ +/** + * @file v4color_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v4color test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../v4coloru.h" +#include "llsd.h" +#include "../v3color.h" +#include "../v4color.h" + + +namespace tut +{ + struct v4color_data + { + }; + typedef test_group<v4color_data> v4color_test; + typedef v4color_test::object v4color_object; + tut::v4color_test v4color_testcase("v4color"); + + template<> template<> + void v4color_object::test<1>() + { + LLColor4 llcolor4; + ensure("1:LLColor4:Fail to initialize ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); + + F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; + LLColor4 llcolor4a(r,g,b); + ensure("2:LLColor4:Fail to initialize ", ((r == llcolor4a.mV[VX]) && (g == llcolor4a.mV[VY]) && (b == llcolor4a.mV[VZ])&& (1.0f == llcolor4a.mV[VW]))); + + LLColor4 llcolor4b(r,g,b,a); + ensure("3:LLColor4:Fail to initialize ", ((r == llcolor4b.mV[VX]) && (g == llcolor4b.mV[VY]) && (b == llcolor4b.mV[VZ])&& (a == llcolor4b.mV[VW]))); + + const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; + LLColor4 llcolor4c(vec); + ensure("4:LLColor4:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW]))); + + LLColor3 llcolor3(-2.23f,1.01f,42.3f); + F32 val = -.1f; + LLColor4 llcolor4d(llcolor3,val); + ensure("5:LLColor4:Fail to initialize ", ((llcolor3.mV[VX] == llcolor4d.mV[VX]) && (llcolor3.mV[VY] == llcolor4d.mV[VY]) && (llcolor3.mV[VZ] == llcolor4d.mV[VZ])&& (val == llcolor4d.mV[VW]))); + + LLSD sd = llcolor4d.getValue(); + LLColor4 llcolor4e(sd); + ensure_equals("6:LLColor4:(LLSD) failed ", llcolor4d, llcolor4e); + + U8 r1 = 0xF2, g1 = 0xFA, b1 = 0xBF; + LLColor4U color4u(r1,g1,b1); + LLColor4 llcolor4g(color4u); + const F32 SCALE = 1.f/255.f; + F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; + ensure("7:LLColor4:Fail to initialize ", ((r2 == llcolor4g.mV[VX]) && (g2 == llcolor4g.mV[VY]) && (b2 == llcolor4g.mV[VZ]))); + } + + template<> template<> + void v4color_object::test<2>() + { + LLColor4 llcolor(1.0, 2.0, 3.0, 4.0); + LLSD llsd = llcolor.getValue(); + LLColor4 llcolor4(llsd), llcolor4a; + llcolor4a.setValue(llsd); + ensure("setValue: failed", (llcolor4 == llcolor4a)); + LLSD sd = llcolor4a.getValue(); + LLColor4 llcolor4b(sd); + ensure("getValue: Failed ", (llcolor4b == llcolor4a)); + } + + template<> template<> + void v4color_object::test<3>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0xAF; + LLColor4 llcolor4(r,g,b,a); + llcolor4.setToBlack(); + ensure("setToBlack:Fail to set the black ", ((0 == llcolor4.mV[VX]) && (0 == llcolor4.mV[VY]) && (0 == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); + + llcolor4.setToWhite(); + ensure("setToWhite:Fail to set the white ", ((1.f == llcolor4.mV[VX]) && (1.f == llcolor4.mV[VY]) && (1.f == llcolor4.mV[VZ])&& (1.0f == llcolor4.mV[VW]))); + } + + template<> template<> + void v4color_object::test<4>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF, a = 0xAF; + LLColor4 llcolor4; + llcolor4.setVec(r,g,b); + ensure("1:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (1.f == llcolor4.mV[VW]))); + + llcolor4.setVec(r,g,b,a); + ensure("2:setVec:Fail to set the values ", ((r == llcolor4.mV[VX]) && (g == llcolor4.mV[VY]) && (b == llcolor4.mV[VZ])&& (a == llcolor4.mV[VW]))); + + LLColor4 llcolor4a; + llcolor4a.setVec(llcolor4); + ensure_equals("3:setVec:Fail to set the values ", llcolor4a,llcolor4); + + LLColor3 llcolor3(-2.23f,1.01f,42.3f); + llcolor4a.setVec(llcolor3); + ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]))); + + F32 val = -.33f; + llcolor4a.setVec(llcolor3,val); + ensure("4:setVec:Fail to set the values ", ((llcolor3.mV[VX] == llcolor4a.mV[VX]) && (llcolor3.mV[VY] == llcolor4a.mV[VY]) && (llcolor3.mV[VZ] == llcolor4a.mV[VZ]) && (val == llcolor4a.mV[VW]))); + + const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; + LLColor4 llcolor4c; + llcolor4c.setVec(vec); + ensure("5:setVec:Fail to initialize ", ((vec[0] == llcolor4c.mV[VX]) && (vec[1] == llcolor4c.mV[VY]) && (vec[2] == llcolor4c.mV[VZ])&& (vec[3] == llcolor4c.mV[VW]))); + + U8 r1 = 0xF2, g1 = 0xFA, b1= 0xBF; + LLColor4U color4u(r1,g1,b1); + llcolor4.setVec(color4u); + const F32 SCALE = 1.f/255.f; + F32 r2 = r1*SCALE, g2 = g1* SCALE, b2 = b1* SCALE; + ensure("6:setVec:Fail to initialize ", ((r2 == llcolor4.mV[VX]) && (g2 == llcolor4.mV[VY]) && (b2 == llcolor4.mV[VZ]))); + } + + template<> template<> + void v4color_object::test<5>() + { + F32 alpha = 0xAF; + LLColor4 llcolor4; + llcolor4.setAlpha(alpha); + ensure("setAlpha:Fail to initialize ", (alpha == llcolor4.mV[VW])); + } + + template<> template<> + void v4color_object::test<6>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF; + LLColor4 llcolor4(r,g,b); + ensure("magVecSquared:Fail ", is_approx_equal(llcolor4.magVecSquared(), (r*r + g*g + b*b))); + ensure("magVec:Fail ", is_approx_equal(llcolor4.magVec(), fsqrtf(r*r + g*g + b*b))); + } + + template<> template<> + void v4color_object::test<7>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF; + LLColor4 llcolor4(r,g,b); + F32 vecMag = llcolor4.normVec(); + F32 mag = fsqrtf(r*r + g*g + b*b); + F32 oomag = 1.f / mag; + F32 val1 = r * oomag, val2 = g * oomag, val3 = b * oomag; + ensure("1:normVec failed ", (is_approx_equal(val1, llcolor4.mV[0]) && is_approx_equal(val2, llcolor4.mV[1]) && is_approx_equal(val3, llcolor4.mV[2]) && is_approx_equal(vecMag, mag))); + } + + template<> template<> + void v4color_object::test<8>() + { + LLColor4 llcolor4; + ensure("1:isOpaque failed ",(1 == llcolor4.isOpaque())); + F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 1.f; + llcolor4.setVec(r,g,b,a); + ensure("2:isOpaque failed ",(1 == llcolor4.isOpaque())); + a = 2.f; + llcolor4.setVec(r,g,b,a); + ensure("3:isOpaque failed ",(0 == llcolor4.isOpaque())); + } + + template<> template<> + void v4color_object::test<9>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF; + LLColor4 llcolor4(r,g,b); + ensure("1:operator [] failed",( r == llcolor4[0])); + ensure("2:operator [] failed",( g == llcolor4[1])); + ensure("3:operator [] failed",( b == llcolor4[2])); + + r = 0xA20, g = 0xFBFF, b = 0xFFF; + llcolor4.setVec(r,g,b); + F32 &ref1 = llcolor4[0]; + ensure("4:operator [] failed",( ref1 == llcolor4[0])); + F32 &ref2 = llcolor4[1]; + ensure("5:operator [] failed",( ref2 == llcolor4[1])); + F32 &ref3 = llcolor4[2]; + ensure("6:operator [] failed",( ref3 == llcolor4[2])); + } + + template<> template<> + void v4color_object::test<10>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF; + LLColor3 llcolor3(r,g,b); + LLColor4 llcolor4a,llcolor4b; + llcolor4a = llcolor3; + ensure("Operator=:Fail to initialize ", ((llcolor3.mV[0] == llcolor4a.mV[VX]) && (llcolor3.mV[1] == llcolor4a.mV[VY]) && (llcolor3.mV[2] == llcolor4a.mV[VZ]))); + LLSD sd = llcolor4a.getValue(); + llcolor4b = LLColor4(sd); + ensure_equals("Operator= LLSD:Fail ", llcolor4a, llcolor4b); + } + + template<> template<> + void v4color_object::test<11>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF; + std::ostringstream stream1, stream2; + LLColor4 llcolor4a(r,g,b),llcolor4b; + stream1 << llcolor4a; + llcolor4b.setVec(r,g,b); + stream2 << llcolor4b; + ensure("operator << failed ", (stream1.str() == stream2.str())); + } + + template<> template<> + void v4color_object::test<12>() + { + F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; + F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; + LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; + llcolor4c = llcolor4b + llcolor4a; + ensure("operator+:Fail to Add the values ", (is_approx_equal(r1+r2,llcolor4c.mV[VX]) && is_approx_equal(g1+g2,llcolor4c.mV[VY]) && is_approx_equal(b1+b2,llcolor4c.mV[VZ]))); + + llcolor4b += llcolor4a; + ensure("operator+=:Fail to Add the values ", (is_approx_equal(r1+r2,llcolor4b.mV[VX]) && is_approx_equal(g1+g2,llcolor4b.mV[VY]) && is_approx_equal(b1+b2,llcolor4b.mV[VZ]))); + } + + template<> template<> + void v4color_object::test<13>() + { + F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; + F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; + LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; + llcolor4c = llcolor4a - llcolor4b; + ensure("operator-:Fail to subtract the values ", (is_approx_equal(r1-r2,llcolor4c.mV[VX]) && is_approx_equal(g1-g2,llcolor4c.mV[VY]) && is_approx_equal(b1-b2,llcolor4c.mV[VZ]))); + + llcolor4a -= llcolor4b; + ensure("operator-=:Fail to subtract the values ", (is_approx_equal(r1-r2,llcolor4a.mV[VX]) && is_approx_equal(g1-g2,llcolor4a.mV[VY]) && is_approx_equal(b1-b2,llcolor4a.mV[VZ]))); + } + + template<> template<> + void v4color_object::test<14>() + { + F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF; + F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; + LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; + llcolor4c = llcolor4a * llcolor4b; + ensure("1:operator*:Fail to multiply the values", (is_approx_equal(r1*r2,llcolor4c.mV[VX]) && is_approx_equal(g1*g2,llcolor4c.mV[VY]) && is_approx_equal(b1*b2,llcolor4c.mV[VZ]))); + + F32 mulVal = 3.33f; + llcolor4c = llcolor4a * mulVal; + ensure("2:operator*:Fail ", (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); + llcolor4c = mulVal * llcolor4a; + ensure("3:operator*:Fail to multiply the values", (is_approx_equal(r1*mulVal,llcolor4c.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4c.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4c.mV[VZ]))); + + llcolor4a *= mulVal; + ensure("4:operator*=:Fail to multiply the values ", (is_approx_equal(r1*mulVal,llcolor4a.mV[VX]) && is_approx_equal(g1*mulVal,llcolor4a.mV[VY]) && is_approx_equal(b1*mulVal,llcolor4a.mV[VZ]))); + + LLColor4 llcolor4d(r1,g1,b1),llcolor4e(r2,g2,b2); + llcolor4e *= llcolor4d; + ensure("5:operator*=:Fail to multiply the values ", (is_approx_equal(r1*r2,llcolor4e.mV[VX]) && is_approx_equal(g1*g2,llcolor4e.mV[VY]) && is_approx_equal(b1*b2,llcolor4e.mV[VZ]))); + } + + template<> template<> + void v4color_object::test<15>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; + F32 div = 12.345f; + LLColor4 llcolor4a(r,g,b,a),llcolor4b; + llcolor4b = llcolor4a % div;//chnage only alpha value nor r,g,b; + ensure("1operator%:Fail ", (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); + + llcolor4b = div % llcolor4a; + ensure("2operator%:Fail ", (is_approx_equal(r,llcolor4b.mV[VX]) && is_approx_equal(g,llcolor4b.mV[VY]) && is_approx_equal(b,llcolor4b.mV[VZ])&& is_approx_equal(div*a,llcolor4b.mV[VW]))); + + llcolor4a %= div; + ensure("operator%=:Fail ", (is_approx_equal(a*div,llcolor4a.mV[VW]))); + } + + template<> template<> + void v4color_object::test<16>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF,a = 0x30; + LLColor4 llcolor4a(r,g,b,a),llcolor4b; + llcolor4b = llcolor4a; + ensure("1:operator== failed to ensure the equality ", (llcolor4b == llcolor4a)); + F32 r1 = 0x2, g1 = 0xFF, b1 = 0xFA; + LLColor3 llcolor3(r1,g1,b1); + llcolor4b = llcolor3; + ensure("2:operator== failed to ensure the equality ", (llcolor4b == llcolor3)); + ensure("2:operator!= failed to ensure the equality ", (llcolor4a != llcolor3)); + } + + template<> template<> + void v4color_object::test<17>() + { + F32 r = 0x20, g = 0xFFFF, b = 0xFF; + LLColor4 llcolor4a(r,g,b),llcolor4b; + LLColor3 llcolor3 = vec4to3(llcolor4a); + ensure("vec4to3:Fail to convert vec4 to vec3 ", (is_approx_equal(llcolor3.mV[VX],llcolor4a.mV[VX]) && is_approx_equal(llcolor3.mV[VY],llcolor4a.mV[VY]) && is_approx_equal(llcolor3.mV[VZ],llcolor4a.mV[VZ]))); + llcolor4b = vec3to4(llcolor3); + ensure_equals("vec3to4:Fail to convert vec3 to vec4 ", llcolor4b, llcolor4a); + } + + template<> template<> + void v4color_object::test<18>() + { + F32 r1 = 0x20, g1 = 0xFFFF, b1 = 0xFF, val = 0x20; + F32 r2 = 0xABF, g2 = 0xFB, b2 = 0xFFF; + LLColor4 llcolor4a(r1,g1,b1),llcolor4b(r2,g2,b2),llcolor4c; + llcolor4c = lerp(llcolor4a,llcolor4b,val); + ensure("lerp:Fail ", (is_approx_equal(r1 + (r2 - r1)* val,llcolor4c.mV[VX]) && is_approx_equal(g1 + (g2 - g1)* val,llcolor4c.mV[VY]) && is_approx_equal(b1 + (b2 - b1)* val,llcolor4c.mV[VZ]))); + } + + template<> template<> + void v4color_object::test<19>() + { + F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; + LLColor4 llcolor4a(r,g,b,a),llcolor4b; + std::string color("red"); + LLColor4::parseColor(color, &llcolor4b); + ensure_equals("1:parseColor() failed to parse the color value ", llcolor4b, LLColor4::red); + + color = "12.0, -2.3, 1.32, 5.0"; + LLColor4::parseColor(color, &llcolor4b); + llcolor4a = llcolor4a * (1.f / 255.f); + ensure_equals("2:parseColor() failed to parse the color value ", llcolor4a,llcolor4b); + + color = "yellow5"; + llcolor4a.setVec(r,g,b); + LLColor4::parseColor(color, &llcolor4a); + ensure_equals("3:parseColor() failed to parse the color value ", llcolor4a, LLColor4::yellow5); + } + + template<> template<> + void v4color_object::test<20>() + { + F32 r = 12.0f, g = -2.3f, b = 1.32f, a = 5.0f; + LLColor4 llcolor4a(r,g,b,a),llcolor4b; + std::string color("12.0, -2.3, 1.32, 5.0"); + LLColor4::parseColor4(color, &llcolor4b); + ensure_equals("parseColor4() failed to parse the color value ", llcolor4a, llcolor4b); + } +} diff --git a/indra/llmath/tests/v4coloru_test.cpp b/indra/llmath/tests/v4coloru_test.cpp new file mode 100644 index 0000000000..00515893da --- /dev/null +++ b/indra/llmath/tests/v4coloru_test.cpp @@ -0,0 +1,342 @@ +/** + * @file v4coloru_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v4coloru test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "llsd.h" + +#include "../v4coloru.h" + + +namespace tut +{ + struct v4coloru_data + { + }; + typedef test_group<v4coloru_data> v4coloru_test; + typedef v4coloru_test::object v4coloru_object; + tut::v4coloru_test v4coloru_testcase("v4coloru"); + + template<> template<> + void v4coloru_object::test<1>() + { + LLColor4U llcolor4u; + ensure("1:LLColor4u:Fail to initialize ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + + U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; + LLColor4U llcolor4u1(r,g,b); + ensure("2:LLColor4u:Fail to initialize ", ((r == llcolor4u1.mV[VX]) && (g == llcolor4u1.mV[VY]) && (b == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); + + LLColor4U llcolor4u2(r,g,b,a); + ensure("3:LLColor4u:Fail to initialize ", ((r == llcolor4u2.mV[VX]) && (g == llcolor4u2.mV[VY]) && (b == llcolor4u2.mV[VZ])&& (a == llcolor4u2.mV[VW]))); + + const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; + LLColor4U llcolor4u3(vec); + ensure("4:LLColor4u:Fail to initialize ", ((vec[0] == llcolor4u3.mV[VX]) && (vec[1] == llcolor4u3.mV[VY]) && (vec[2] == llcolor4u3.mV[VZ])&& (vec[3] == llcolor4u3.mV[VW]))); + + LLSD sd = llcolor4u3.getValue(); + LLColor4U llcolor4u4(sd); + ensure_equals("5:LLColor4u (LLSD) Failed ", llcolor4u4, llcolor4u3); + } + + template<> template<> + void v4coloru_object::test<2>() + { + LLColor4U llcolor4ua(1, 2, 3, 4); + LLSD sd = llcolor4ua.getValue(); + LLColor4U llcolor4u; + llcolor4u.setValue(sd); + ensure_equals("setValue(LLSD)/getValue Failed ", llcolor4u, llcolor4ua); + } + + template<> template<> + void v4coloru_object::test<3>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; + LLColor4U llcolor4u(r,g,b,a); + llcolor4u.setToBlack(); + ensure("setToBlack:Fail to set black ", ((0 == llcolor4u.mV[VX]) && (0 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + + llcolor4u.setToWhite(); + ensure("setToWhite:Fail to white ", ((255 == llcolor4u.mV[VX]) && (255 == llcolor4u.mV[VY]) && (255 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + } + + template<> template<> + void v4coloru_object::test<4>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; + LLColor4U llcolor4ua(r,g,b,a); + LLSD sd = llcolor4ua.getValue(); + LLColor4U llcolor4u = (LLColor4U)sd; + ensure_equals("Operator=(LLSD) Failed ", llcolor4u, llcolor4ua); + } + + template<> template<> + void v4coloru_object::test<5>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF, a = 0x23; + LLColor4U llcolor4u; + llcolor4u.setVec(r,g,b,a); + ensure("1:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (a == llcolor4u.mV[VW]))); + + llcolor4u.setToBlack(); + llcolor4u.setVec(r,g,b); + ensure("2:setVec:Fail to set the values ", ((r == llcolor4u.mV[VX]) && (g == llcolor4u.mV[VY]) && (b == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + + LLColor4U llcolor4u1; + llcolor4u1.setVec(llcolor4u); + ensure_equals("3:setVec:Fail to set the values ", llcolor4u1,llcolor4u); + + const U8 vec[4] = {0x12,0xFF,0xAF,0x23}; + LLColor4U llcolor4u2; + llcolor4u2.setVec(vec); + ensure("4:setVec:Fail to set the values ", ((vec[0] == llcolor4u2.mV[VX]) && (vec[1] == llcolor4u2.mV[VY]) && (vec[2] == llcolor4u2.mV[VZ])&& (vec[3] == llcolor4u2.mV[VW]))); + } + + template<> template<> + void v4coloru_object::test<6>() + { + U8 alpha = 0x12; + LLColor4U llcolor4u; + llcolor4u.setAlpha(alpha); + ensure("setAlpha:Fail to set alpha value ", (alpha == llcolor4u.mV[VW])); + } + + template<> template<> + void v4coloru_object::test<7>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF; + LLColor4U llcolor4u(r,g,b); + ensure("magVecSquared:Fail ", is_approx_equal(llcolor4u.magVecSquared(), (F32)(r*r + g*g + b*b))); + ensure("magVec:Fail ", is_approx_equal(llcolor4u.magVec(), fsqrtf(r*r + g*g + b*b))); + } + + template<> template<> + void v4coloru_object::test<8>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF; + std::ostringstream stream1, stream2; + LLColor4U llcolor4u1(r,g,b),llcolor4u2; + stream1 << llcolor4u1; + llcolor4u2.setVec(r,g,b); + stream2 << llcolor4u2; + ensure("operator << failed ", (stream1.str() == stream2.str())); + } + + template<> template<> + void v4coloru_object::test<9>() + { + U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; + U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; + LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; + llcolor4u3 = llcolor4u1 + llcolor4u2; + ensure_equals( + "1a.operator+:Fail to Add the values ", + llcolor4u3.mV[VX], + (U8)(r1+r2)); + ensure_equals( + "1b.operator+:Fail to Add the values ", + llcolor4u3.mV[VY], + (U8)(g1+g2)); + ensure_equals( + "1c.operator+:Fail to Add the values ", + llcolor4u3.mV[VZ], + (U8)(b1+b2)); + + llcolor4u2 += llcolor4u1; + ensure_equals( + "2a.operator+=:Fail to Add the values ", + llcolor4u2.mV[VX], + (U8)(r1+r2)); + ensure_equals( + "2b.operator+=:Fail to Add the values ", + llcolor4u2.mV[VY], + (U8)(g1+g2)); + ensure_equals( + "2c.operator+=:Fail to Add the values ", + llcolor4u2.mV[VZ], + (U8)(b1+b2)); + } + + template<> template<> + void v4coloru_object::test<10>() + { + U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; + U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; + LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; + llcolor4u3 = llcolor4u1 - llcolor4u2; + ensure_equals( + "1a. operator-:Fail to Add the values ", + llcolor4u3.mV[VX], + (U8)(r1-r2)); + ensure_equals( + "1b. operator-:Fail to Add the values ", + llcolor4u3.mV[VY], + (U8)(g1-g2)); + ensure_equals( + "1c. operator-:Fail to Add the values ", + llcolor4u3.mV[VZ], + (U8)(b1-b2)); + + llcolor4u1 -= llcolor4u2; + ensure_equals( + "2a. operator-=:Fail to Add the values ", + llcolor4u1.mV[VX], + (U8)(r1-r2)); + ensure_equals( + "2b. operator-=:Fail to Add the values ", + llcolor4u1.mV[VY], + (U8)(g1-g2)); + ensure_equals( + "2c. operator-=:Fail to Add the values ", + llcolor4u1.mV[VZ], + (U8)(b1-b2)); + } + + template<> template<> + void v4coloru_object::test<11>() + { + U8 r1 = 0x12, g1 = 0xFF, b1 = 0xAF; + U8 r2 = 0x1C, g2 = 0x9A, b2 = 0x1B; + LLColor4U llcolor4u1(r1,g1,b1), llcolor4u2(r2,g2,b2),llcolor4u3; + llcolor4u3 = llcolor4u1 * llcolor4u2; + ensure_equals( + "1a. operator*:Fail to multiply the values", + llcolor4u3.mV[VX], + (U8)(r1*r2)); + ensure_equals( + "1b. operator*:Fail to multiply the values", + llcolor4u3.mV[VY], + (U8)(g1*g2)); + ensure_equals( + "1c. operator*:Fail to multiply the values", + llcolor4u3.mV[VZ], + (U8)(b1*b2)); + + U8 mulVal = 123; + llcolor4u1 *= mulVal; + ensure_equals( + "2a. operator*=:Fail to multiply the values", + llcolor4u1.mV[VX], + (U8)(r1*mulVal)); + ensure_equals( + "2b. operator*=:Fail to multiply the values", + llcolor4u1.mV[VY], + (U8)(g1*mulVal)); + ensure_equals( + "2c. operator*=:Fail to multiply the values", + llcolor4u1.mV[VZ], + (U8)(b1*mulVal)); + } + + template<> template<> + void v4coloru_object::test<12>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF; + LLColor4U llcolor4u(r,g,b),llcolor4u1; + llcolor4u1 = llcolor4u; + ensure("operator== failed to ensure the equality ", (llcolor4u1 == llcolor4u)); + llcolor4u1.setToBlack(); + ensure("operator!= failed to ensure the equality ", (llcolor4u1 != llcolor4u)); + } + + template<> template<> + void v4coloru_object::test<13>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; + LLColor4U llcolor4u(r,g,b,a); + U8 modVal = 45; + llcolor4u %= modVal; + ensure_equals("operator%=:Fail ", llcolor4u.mV[VW], (U8)(a * modVal)); + } + + template<> template<> + void v4coloru_object::test<14>() + { + U8 r = 0x12, g = 0xFF, b = 0xAF, a = 12; + LLColor4U llcolor4u1(r,g,b,a); + std::string color("12, 23, 132, 50"); + LLColor4U::parseColor4U(color, &llcolor4u1); + ensure("parseColor4U() failed to parse the color value ", ((12 == llcolor4u1.mV[VX]) && (23 == llcolor4u1.mV[VY]) && (132 == llcolor4u1.mV[VZ])&& (50 == llcolor4u1.mV[VW]))); + + color = "12, 23, 132"; + ensure("2:parseColor4U() failed to parse the color value ", (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); + + color = "12"; + ensure("2:parseColor4U() failed to parse the color value ", (FALSE == LLColor4U::parseColor4U(color, &llcolor4u1))); + } + + template<> template<> + void v4coloru_object::test<15>() + { + U8 r = 12, g = 123, b = 3, a = 2; + LLColor4U llcolor4u(r,g,b,a),llcolor4u1; + const F32 fVal = 3.f; + llcolor4u1 = llcolor4u.multAll(fVal); + ensure("multAll:Fail to multiply ", (((U8)llround(r * fVal) == llcolor4u1.mV[VX]) && (U8)llround(g * fVal) == llcolor4u1.mV[VY] + && ((U8)llround(b * fVal) == llcolor4u1.mV[VZ])&& ((U8)llround(a * fVal) == llcolor4u1.mV[VW]))); + } + + template<> template<> + void v4coloru_object::test<16>() + { + U8 r1 = 12, g1 = 123, b1 = 3, a1 = 2; + U8 r2 = 23, g2 = 230, b2 = 124, a2 = 255; + LLColor4U llcolor4u(r1,g1,b1,a1),llcolor4u1(r2,g2,b2,a2); + llcolor4u1 = llcolor4u1.addClampMax(llcolor4u); + ensure("1:addClampMax():Fail to add the value ", ((r1+r2 == llcolor4u1.mV[VX]) && (255 == llcolor4u1.mV[VY]) && (b1+b2 == llcolor4u1.mV[VZ])&& (255 == llcolor4u1.mV[VW]))); + + r1 = 132, g1 = 3, b1 = 3, a1 = 2; + r2 = 123, g2 = 230, b2 = 154, a2 = 25; + LLColor4U llcolor4u2(r1,g1,b1,a1),llcolor4u3(r2,g2,b2,a2); + llcolor4u3 = llcolor4u3.addClampMax(llcolor4u2); + ensure("2:addClampMax():Fail to add the value ", ((255 == llcolor4u3.mV[VX]) && (g1+g2 == llcolor4u3.mV[VY]) && (b1+b2 == llcolor4u3.mV[VZ])&& (a1+a2 == llcolor4u3.mV[VW]))); + } + + template<> template<> + void v4coloru_object::test<17>() + { + F32 r = 23.f, g = 12.32f, b = -12.3f; + LLColor3 color3(r,g,b); + LLColor4U llcolor4u; + llcolor4u.setVecScaleClamp(color3); + const S32 MAX_COLOR = 255; + F32 color_scale_factor = MAX_COLOR/r; + S32 r2 = llround(r * color_scale_factor); + S32 g2 = llround(g * color_scale_factor); + ensure("setVecScaleClamp():Fail to add the value ", ((r2 == llcolor4u.mV[VX]) && (g2 == llcolor4u.mV[VY]) && (0 == llcolor4u.mV[VZ])&& (255 == llcolor4u.mV[VW]))); + } +} diff --git a/indra/llmath/tests/v4math_test.cpp b/indra/llmath/tests/v4math_test.cpp new file mode 100644 index 0000000000..e020038ae5 --- /dev/null +++ b/indra/llmath/tests/v4math_test.cpp @@ -0,0 +1,388 @@ +/** + * @file v4math_tut.cpp + * @author Adroit + * @date 2007-03 + * @brief v4math test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" +#include "llsd.h" + +#include "../llquaternion.h" +#include "../m4math.h" +#include "../v4math.h" + +namespace tut +{ + struct v4math_data + { + }; + typedef test_group<v4math_data> v4math_test; + typedef v4math_test::object v4math_object; + tut::v4math_test v4math_testcase("v4math"); + + template<> template<> + void v4math_object::test<1>() + { + LLVector4 vec4; + ensure("1:LLVector4:Fail to initialize " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); + F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; + LLVector4 vec4a(x,y,z); + ensure("2:LLVector4:Fail to initialize " ,((x == vec4a.mV[VX]) && (y == vec4a.mV[VY]) && (z == vec4a.mV[VZ])&& (1.0f == vec4a.mV[VW]))); + LLVector4 vec4b(x,y,z,w); + ensure("3:LLVector4:Fail to initialize " ,((x == vec4b.mV[VX]) && (y == vec4b.mV[VY]) && (z == vec4b.mV[VZ])&& (w == vec4b.mV[VW]))); + const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; + LLVector4 vec4c(vec); + ensure("4:LLVector4:Fail to initialize " ,((vec[0] == vec4c.mV[VX]) && (vec[1] == vec4c.mV[VY]) && (vec[2] == vec4c.mV[VZ])&& (vec[3] == vec4c.mV[VW]))); + LLVector3 vec3(-2.23f,1.01f,42.3f); + LLVector4 vec4d(vec3); + ensure("5:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4d.mV[VX]) && (vec3.mV[VY] == vec4d.mV[VY]) && (vec3.mV[VZ] == vec4d.mV[VZ])&& (1.f == vec4d.mV[VW]))); + F32 w1 = -.234f; + LLVector4 vec4e(vec3,w1); + ensure("6:LLVector4:Fail to initialize " ,((vec3.mV[VX] == vec4e.mV[VX]) && (vec3.mV[VY] == vec4e.mV[VY]) && (vec3.mV[VZ] == vec4e.mV[VZ])&& (w1 == vec4e.mV[VW]))); + } + + template<> template<> + void v4math_object::test<2>() + { + F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; + LLVector4 vec4; + vec4.setVec(x,y,z); + ensure("1:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); + vec4.clearVec(); + ensure("2:clearVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (1.0f == vec4.mV[VW]))); + vec4.setVec(x,y,z,w); + ensure("3:setVec:Fail to initialize " ,((x == vec4.mV[VX]) && (y == vec4.mV[VY]) && (z == vec4.mV[VZ])&& (w == vec4.mV[VW]))); + vec4.zeroVec(); + ensure("4:zeroVec:Fail " ,((0 == vec4.mV[VX]) && (0 == vec4.mV[VY]) && (0 == vec4.mV[VZ])&& (0 == vec4.mV[VW]))); + LLVector3 vec3(-2.23f,1.01f,42.3f); + vec4.clearVec(); + vec4.setVec(vec3); + ensure("5:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (1.f == vec4.mV[VW]))); + F32 w1 = -.234f; + vec4.zeroVec(); + vec4.setVec(vec3,w1); + ensure("6:setVec:Fail to initialize " ,((vec3.mV[VX] == vec4.mV[VX]) && (vec3.mV[VY] == vec4.mV[VY]) && (vec3.mV[VZ] == vec4.mV[VZ])&& (w1 == vec4.mV[VW]))); + const F32 vec[4] = {.112f ,23.2f, -4.2f, -.0001f}; + LLVector4 vec4a; + vec4a.setVec(vec); + ensure("7:setVec:Fail to initialize " ,((vec[0] == vec4a.mV[VX]) && (vec[1] == vec4a.mV[VY]) && (vec[2] == vec4a.mV[VZ])&& (vec[3] == vec4a.mV[VW]))); + } + + template<> template<> + void v4math_object::test<3>() + { + F32 x = 10.f, y = -2.3f, z = -.023f; + LLVector4 vec4(x,y,z); + ensure("magVec:Fail ", is_approx_equal(vec4.magVec(), fsqrtf(x*x + y*y + z*z))); + ensure("magVecSquared:Fail ", is_approx_equal(vec4.magVecSquared(), (x*x + y*y + z*z))); + } + + template<> template<> + void v4math_object::test<4>() + { + F32 x = 10.f, y = -2.3f, z = -.023f; + LLVector4 vec4(x,y,z); + F32 mag = vec4.normVec(); + mag = 1.f/ mag; + ensure("1:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); + x = 0.000000001f, y = 0.000000001f, z = 0.000000001f; + vec4.clearVec(); + vec4.setVec(x,y,z); + mag = vec4.normVec(); + ensure("2:normVec: Fail " ,is_approx_equal(mag*x,vec4.mV[VX]) && is_approx_equal(mag*y, vec4.mV[VY])&& is_approx_equal(mag*z, vec4.mV[VZ])); + } + + template<> template<> + void v4math_object::test<5>() + { + F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; + LLVector4 vec4(x,y,z,w); + vec4.abs(); + ensure("abs:Fail " ,((x == vec4.mV[VX]) && (-y == vec4.mV[VY]) && (-z == vec4.mV[VZ])&& (-w == vec4.mV[VW]))); + vec4.clearVec(); + ensure("isExactlyClear:Fail " ,(TRUE == vec4.isExactlyClear())); + vec4.zeroVec(); + ensure("isExactlyZero:Fail " ,(TRUE == vec4.isExactlyZero())); + } + + template<> template<> + void v4math_object::test<6>() + { + F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; + LLVector4 vec4(x,y,z,w),vec4a; + vec4a = vec4.scaleVec(vec4); + ensure("scaleVec:Fail " ,(is_approx_equal(x*x, vec4a.mV[VX]) && is_approx_equal(y*y, vec4a.mV[VY]) && is_approx_equal(z*z, vec4a.mV[VZ])&& is_approx_equal(w*w, vec4a.mV[VW]))); + } + + template<> template<> + void v4math_object::test<7>() + { + F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; + LLVector4 vec4(x,y,z,w); + ensure("1:operator [] failed " ,( x == vec4[0])); + ensure("2:operator [] failed " ,( y == vec4[1])); + ensure("3:operator [] failed " ,( z == vec4[2])); + ensure("4:operator [] failed " ,( w == vec4[3])); + x = 23.f, y = -.2361f, z = 3.25; + vec4.setVec(x,y,z); + F32 &ref1 = vec4[0]; + ensure("5:operator [] failed " ,( ref1 == vec4[0])); + F32 &ref2 = vec4[1]; + ensure("6:operator [] failed " ,( ref2 == vec4[1])); + F32 &ref3 = vec4[2]; + ensure("7:operator [] failed " ,( ref3 == vec4[2])); + F32 &ref4 = vec4[3]; + ensure("8:operator [] failed " ,( ref4 == vec4[3])); + } + + template<> template<> + void v4math_object::test<8>() + { + F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; + const F32 val[16] = { + 1.f, 2.f, 3.f, 0.f, + .34f, .1f, -.5f, 0.f, + 2.f, 1.23f, 1.234f, 0.f, + .89f, 0.f, 0.f, 0.f + }; + LLMatrix4 mat(val); + LLVector4 vec4(x,y,z,w),vec4a; + vec4.rotVec(mat); + vec4a.setVec(x,y,z,w); + vec4a.rotVec(mat); + ensure_equals("1:rotVec: Fail " ,vec4a, vec4); + F32 a = 2.32f, b = -23.2f, c = -34.1112f, d = 1.010112f; + LLQuaternion q(a,b,c,d); + LLVector4 vec4b(a,b,c,d),vec4c; + vec4b.rotVec(q); + vec4c.setVec(a, b, c, d); + vec4c.rotVec(q); + ensure_equals("2:rotVec: Fail " ,vec4b, vec4c); + } + + template<> template<> + void v4math_object::test<9>() + { + F32 x = 10.f, y = -2.3f, z = -.023f, w = -2.0f; + LLVector4 vec4(x,y,z,w),vec4a;; + std::ostringstream stream1, stream2; + stream1 << vec4; + vec4a.setVec(x,y,z,w); + stream2 << vec4a; + ensure("operator << failed",(stream1.str() == stream2.str())); + } + + template<> template<> + void v4math_object::test<10>() + { + F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; + F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; + LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; + vec4b = vec4a + vec4; + ensure("1:operator+:Fail to initialize " ,(is_approx_equal(x1+x2,vec4b.mV[VX]) && is_approx_equal(y1+y2,vec4b.mV[VY]) && is_approx_equal(z1+z2,vec4b.mV[VZ]))); + x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; + vec4.clearVec(); + vec4a.clearVec(); + vec4.setVec(x1,y1,z1); + vec4a +=vec4; + ensure_equals("2:operator+=: Fail to initialize", vec4a,vec4); + vec4a += vec4; + ensure("3:operator+=:Fail to initialize " ,(is_approx_equal(2*x1,vec4a.mV[VX]) && is_approx_equal(2*y1,vec4a.mV[VY]) && is_approx_equal(2*z1,vec4a.mV[VZ]))); + } + template<> template<> + void v4math_object::test<11>() + { + F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f, w1 = .23f; + F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f, w2 = 1.3f; + LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2),vec4b; + vec4b = vec4a - vec4; + ensure("1:operator-:Fail to initialize " ,(is_approx_equal(x2-x1,vec4b.mV[VX]) && is_approx_equal(y2-y1,vec4b.mV[VY]) && is_approx_equal(z2-z1,vec4b.mV[VZ]))); + x1 = -2.45f, y1 = 2.1f, z1 = 3.0f; + vec4.clearVec(); + vec4a.clearVec(); + vec4.setVec(x1,y1,z1); + vec4a -=vec4; + ensure_equals("2:operator-=: Fail to initialize" , vec4a,-vec4); + vec4a -=vec4; + ensure("3:operator-=:Fail to initialize " ,(is_approx_equal(-2*x1,vec4a.mV[VX]) && is_approx_equal(-2*y1,vec4a.mV[VY]) && is_approx_equal(-2*z1,vec4a.mV[VZ]))); + } + + template<> template<> + void v4math_object::test<12>() + { + F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; + F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; + LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); + F32 res = vec4 * vec4a; + ensure("1:operator* failed " ,is_approx_equal(res, x1*x2 + y1*y2 + z1*z2)); + vec4a.clearVec(); + F32 mulVal = 4.2f; + vec4a = vec4 * mulVal; + ensure("2:operator* failed " ,is_approx_equal(x1*mulVal,vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); + vec4a.clearVec(); + vec4a = mulVal * vec4 ; + ensure("3:operator* failed " ,is_approx_equal(x1*mulVal, vec4a.mV[VX]) && is_approx_equal(y1*mulVal, vec4a.mV[VY])&& is_approx_equal(z1*mulVal, vec4a.mV[VZ])); + vec4 *= mulVal; + ensure("4:operator*= failed " ,is_approx_equal(x1*mulVal, vec4.mV[VX]) && is_approx_equal(y1*mulVal, vec4.mV[VY])&& is_approx_equal(z1*mulVal, vec4.mV[VZ])); + } + + template<> template<> + void v4math_object::test<13>() + { + F32 x1 = 1.f, y1 = 2.f, z1 = -1.1f; + F32 x2 = 1.2f, y2 = 2.5f, z2 = 1.f; + LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2),vec4b; + vec4b = vec4 % vec4a; + ensure("1:operator% failed " ,is_approx_equal(y1*z2 - y2*z1, vec4b.mV[VX]) && is_approx_equal(z1*x2 -z2*x1, vec4b.mV[VY]) && is_approx_equal(x1*y2-x2*y1, vec4b.mV[VZ])); + vec4 %= vec4a; + ensure_equals("operator%= failed " ,vec4,vec4b); + } + + template<> template<> + void v4math_object::test<14>() + { + F32 x = 1.f, y = 2.f, z = -1.1f,div = 4.2f; + F32 t = 1.f / div; + LLVector4 vec4(x,y,z), vec4a; + vec4a = vec4/div; + ensure("1:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); + x = 1.23f, y = 4.f, z = -2.32f; + vec4.clearVec(); + vec4a.clearVec(); + vec4.setVec(x,y,z); + vec4a = vec4/div; + ensure("2:operator/ failed " ,is_approx_equal(x*t, vec4a.mV[VX]) && is_approx_equal(y*t, vec4a.mV[VY])&& is_approx_equal(z*t, vec4a.mV[VZ])); + vec4 /= div; + ensure("3:operator/ failed " ,is_approx_equal(x*t, vec4.mV[VX]) && is_approx_equal(y*t, vec4.mV[VY])&& is_approx_equal(z*t, vec4.mV[VZ])); + } + + template<> template<> + void v4math_object::test<15>() + { + F32 x = 1.f, y = 2.f, z = -1.1f; + LLVector4 vec4(x,y,z), vec4a; + ensure("operator!= failed " ,(vec4 != vec4a)); + vec4a = vec4; + ensure("operator== failed " ,(vec4 ==vec4a)); + } + + template<> template<> + void v4math_object::test<16>() + { + F32 x = 1.f, y = 2.f, z = -1.1f; + LLVector4 vec4(x,y,z), vec4a; + vec4a = - vec4; + ensure("operator- failed " , (vec4 == - vec4a)); + } + + template<> template<> + void v4math_object::test<17>() + { + F32 x = 1.f, y = 2.f, z = -1.1f,epsilon = .23425f; + LLVector4 vec4(x,y,z), vec4a(x,y,z); + ensure("1:are_parallel: Fail " ,(TRUE == are_parallel(vec4a,vec4,epsilon))); + x = 21.f, y = 12.f, z = -123.1f; + vec4a.clearVec(); + vec4a.setVec(x,y,z); + ensure("2:are_parallel: Fail " ,(FALSE == are_parallel(vec4a,vec4,epsilon))); + } + + template<> template<> + void v4math_object::test<18>() + { + F32 x = 1.f, y = 2.f, z = -1.1f; + F32 angle1, angle2; + LLVector4 vec4(x,y,z), vec4a(x,y,z); + angle1 = angle_between(vec4, vec4a); + vec4.normVec(); + vec4a.normVec(); + angle2 = acos(vec4 * vec4a); + ensure_approximately_equals("1:angle_between: Fail " ,angle1,angle2,8); + F32 x1 = 21.f, y1 = 2.23f, z1 = -1.1f; + LLVector4 vec4b(x,y,z), vec4c(x1,y1,z1); + angle1 = angle_between(vec4b, vec4c); + vec4b.normVec(); + vec4c.normVec(); + angle2 = acos(vec4b * vec4c); + ensure_approximately_equals("2:angle_between: Fail " ,angle1,angle2,8); + } + + template<> template<> + void v4math_object::test<19>() + { + F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, x2 = 1.3f, y2 = 1.f, z2 = 1.f; + F32 val1,val2; + LLVector4 vec4(x1,y1,z1),vec4a(x2,y2,z2); + val1 = dist_vec(vec4,vec4a); + val2 = fsqrtf((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); + ensure_equals("dist_vec: Fail ",val2, val1); + val1 = dist_vec_squared(vec4,vec4a); + val2 =((x1 - x2)*(x1 - x2) + (y1 - y2)* (y1 - y2) + (z1 - z2)* (z1 -z2)); + ensure_equals("dist_vec_squared: Fail ",val2, val1); + } + + template<> template<> + void v4math_object::test<20>() + { + F32 x1 =-2.3f, y1 = 2.f,z1 = 1.2f, w1 = -.23f, x2 = 1.3f, y2 = 1.f, z2 = 1.f,w2 = .12f; + F32 val = 2.3f,val1,val2,val3,val4; + LLVector4 vec4(x1,y1,z1,w1),vec4a(x2,y2,z2,w2); + val1 = x1 + (x2 - x1)* val; + val2 = y1 + (y2 - y1)* val; + val3 = z1 + (z2 - z1)* val; + val4 = w1 + (w2 - w1)* val; + LLVector4 vec4b = lerp(vec4,vec4a,val); + ensure("lerp failed", ((val1 ==vec4b.mV[VX])&& (val2 ==vec4b.mV[VY]) && (val3 ==vec4b.mV[VZ])&& (val4 ==vec4b.mV[VW]))); + } + + template<> template<> + void v4math_object::test<21>() + { + F32 x = 1.f, y = 2.f, z = -1.1f; + LLVector4 vec4(x,y,z); + LLVector3 vec3 = vec4to3(vec4); + ensure("vec4to3 failed", ((x == vec3.mV[VX])&& (y == vec3.mV[VY]) && (z == vec3.mV[VZ]))); + LLVector4 vec4a = vec3to4(vec3); + ensure_equals("vec3to4 failed",vec4a,vec4); + } + + template<> template<> + void v4math_object::test<22>() + { + F32 x = 1.f, y = 2.f, z = -1.1f; + LLVector4 vec4(x,y,z); + LLSD llsd = vec4.getValue(); + LLVector3 vec3(llsd); + LLVector4 vec4a = vec3to4(vec3); + ensure_equals("getValue failed",vec4a,vec4); + } +} diff --git a/indra/llmath/tests/xform_test.cpp b/indra/llmath/tests/xform_test.cpp new file mode 100644 index 0000000000..81116a58f0 --- /dev/null +++ b/indra/llmath/tests/xform_test.cpp @@ -0,0 +1,251 @@ +/** + * @file xform_tut.cpp + * @author Adroit + * @date March 2007 + * @brief Test cases for LLXform + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../xform.h" + +namespace tut +{ + struct xform_test + { + }; + typedef test_group<xform_test> xform_test_t; + typedef xform_test_t::object xform_test_object_t; + tut::xform_test_t tut_xform_test("xform_test"); + + //test case for init(), getParent(), getRotation(), getPositionW(), getWorldRotation() fns. + template<> template<> + void xform_test_object_t::test<1>() + { + LLXform xform_obj; + LLVector3 emptyVec(0.f,0.f,0.f); + LLVector3 initialScaleVec(1.f,1.f,1.f); + + ensure("LLXform empty constructor failed: ", !xform_obj.getParent() && !xform_obj.isChanged() && + xform_obj.getPosition() == emptyVec && + (xform_obj.getRotation()).isIdentity() && + xform_obj.getScale() == initialScaleVec && + xform_obj.getPositionW() == emptyVec && + (xform_obj.getWorldRotation()).isIdentity() && + !xform_obj.getScaleChildOffset()); + } + + // test cases for + // setScale(const LLVector3& scale) + // setScale(const F32 x, const F32 y, const F32 z) + // setRotation(const F32 x, const F32 y, const F32 z) + // setPosition(const F32 x, const F32 y, const F32 z) + // getLocalMat4(LLMatrix4 &mat) + template<> template<> + void xform_test_object_t::test<2>() + { + LLMatrix4 llmat4; + LLXform xform_obj; + + F32 x = 3.6f; + F32 y = 5.5f; + F32 z = 4.2f; + F32 w = 0.f; + F32 posz = z + 2.122f; + LLVector3 vec(x, y, z); + xform_obj.setScale(x, y, z); + xform_obj.setPosition(x, y, posz); + ensure("setScale failed: ", xform_obj.getScale() == vec); + + vec.setVec(x, y, posz); + ensure("getPosition failed: ", xform_obj.getPosition() == vec); + + x = x * 2.f; + y = y + 2.3f; + z = posz * 4.f; + vec.setVec(x, y, z); + xform_obj.setPositionX(x); + xform_obj.setPositionY(y); + xform_obj.setPositionZ(z); + ensure("setPositionX/Y/Z failed: ", xform_obj.getPosition() == vec); + + xform_obj.setScaleChildOffset(TRUE); + ensure("setScaleChildOffset failed: ", xform_obj.getScaleChildOffset()); + + vec.setVec(x, y, z); + + xform_obj.addPosition(vec); + vec += vec; + ensure("addPosition failed: ", xform_obj.getPosition() == vec); + + xform_obj.setScale(vec); + ensure("setScale vector failed: ", xform_obj.getScale() == vec); + + LLQuaternion quat(x, y, z, w); + xform_obj.setRotation(quat); + ensure("setRotation quat failed: ", xform_obj.getRotation() == quat); + + xform_obj.setRotation(x, y, z, w); + ensure("getRotation 2 failed: ", xform_obj.getRotation() == quat); + + xform_obj.setRotation(x, y, z); + quat.setQuat(x,y,z); + ensure("setRotation xyz failed: ", xform_obj.getRotation() == quat); + + // LLXform::setRotation(const F32 x, const F32 y, const F32 z) + // Does normalization + // LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) + // Simply copies the individual values - does not do any normalization. + // Is that the expected behavior? + } + + // test cases for inline BOOL setParent(LLXform *parent) and getParent() fn. + template<> template<> + void xform_test_object_t::test<3>() + { + LLXform xform_obj; + LLXform par; + LLXform grandpar; + xform_obj.setParent(&par); + par.setParent(&grandpar); + ensure("setParent/getParent failed: ", &par == xform_obj.getParent()); + ensure("getRoot failed: ", &grandpar == xform_obj.getRoot()); + ensure("isRoot failed: ", grandpar.isRoot() && !par.isRoot() && !xform_obj.isRoot()); + ensure("isRootEdit failed: ", grandpar.isRootEdit() && !par.isRootEdit() && !xform_obj.isRootEdit()); + } + + template<> template<> + void xform_test_object_t::test<4>() + { + LLXform xform_obj; + xform_obj.setChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); + ensure("setChanged/isChanged failed: ", xform_obj.isChanged()); + + xform_obj.clearChanged(LLXform::TRANSLATED | LLXform::ROTATED | LLXform::SCALED); + ensure("clearChanged failed: ", !xform_obj.isChanged()); + + LLVector3 llvect3(12.4f, -5.6f, 0.34f); + xform_obj.setScale(llvect3); + ensure("setScale did not set SCALED flag: ", xform_obj.isChanged(LLXform::SCALED)); + xform_obj.setPosition(1.2f, 2.3f, 3.4f); + ensure("setScale did not set TRANSLATED flag: ", xform_obj.isChanged(LLXform::TRANSLATED)); + ensure("TRANSLATED reset SCALED flag: ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::SCALED)); + xform_obj.clearChanged(LLXform::SCALED); + ensure("reset SCALED failed: ", !xform_obj.isChanged(LLXform::SCALED)); + xform_obj.setRotation(1, 2, 3, 4); + ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::TRANSLATED | LLXform::ROTATED)); + xform_obj.setScale(llvect3); + ensure("ROTATION flag not set ", xform_obj.isChanged(LLXform::MOVED)); + } + + //to test init() and getWorldMatrix() fns. + template<> template<> + void xform_test_object_t::test<5>() + { + LLXformMatrix formMatrix_obj; + formMatrix_obj.init(); + LLMatrix4 mat4_obj; + + ensure("1. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[0][0]); + ensure("2. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][1]); + ensure("3. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][2]); + ensure("4. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[0][3]); + ensure("5. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][0]); + ensure("6. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[1][1]); + ensure("7. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][2]); + ensure("8. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[1][3]); + ensure("9. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][0]); + ensure("10. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][1]); + ensure("11. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[2][2]); + ensure("12. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[2][3]); + ensure("13. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][0]); + ensure("14. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][1]); + ensure("15. The value is not NULL", 0.f == formMatrix_obj.getWorldMatrix().mMatrix[3][2]); + ensure("16. The value is not NULL", 1.f == formMatrix_obj.getWorldMatrix().mMatrix[3][3]); + } + + //to test mMin.clearVec() and mMax.clearVec() fns + template<> template<> + void xform_test_object_t::test<6>() + { + LLXformMatrix formMatrix_obj; + formMatrix_obj.init(); + LLVector3 llmin_vec3; + LLVector3 llmax_vec3; + formMatrix_obj.getMinMax(llmin_vec3, llmax_vec3); + ensure("1. The value is not NULL", 0.f == llmin_vec3.mV[0]); + ensure("2. The value is not NULL", 0.f == llmin_vec3.mV[1]); + ensure("3. The value is not NULL", 0.f == llmin_vec3.mV[2]); + ensure("4. The value is not NULL", 0.f == llmin_vec3.mV[0]); + ensure("5. The value is not NULL", 0.f == llmin_vec3.mV[1]); + ensure("6. The value is not NULL", 0.f == llmin_vec3.mV[2]); + } + + //test case of update() fn. + template<> template<> + void xform_test_object_t::test<7>() + { + LLXformMatrix formMatrix_obj; + + LLXformMatrix parent; + LLVector3 llvecpos(1.0, 2.0, 3.0); + LLVector3 llvecpospar(10.0, 20.0, 30.0); + formMatrix_obj.setPosition(llvecpos); + parent.setPosition(llvecpospar); + + LLVector3 llvecparentscale(1.0, 2.0, 0); + parent.setScaleChildOffset(TRUE); + parent.setScale(llvecparentscale); + + LLQuaternion quat(1, 2, 3, 4); + LLQuaternion quatparent(5, 6, 7, 8); + formMatrix_obj.setRotation(quat); + parent.setRotation(quatparent); + formMatrix_obj.setParent(&parent); + + parent.update(); + formMatrix_obj.update(); + + LLVector3 worldPos = llvecpos; + worldPos.scaleVec(llvecparentscale); + worldPos *= quatparent; + worldPos += llvecpospar; + + LLQuaternion worldRot = quat * quatparent; + + ensure("getWorldPosition failed: ", formMatrix_obj.getWorldPosition() == worldPos); + ensure("getWorldRotation failed: ", formMatrix_obj.getWorldRotation() == worldRot); + + ensure("getWorldPosition for parent failed: ", parent.getWorldPosition() == llvecpospar); + ensure("getWorldRotation for parent failed: ", parent.getWorldRotation() == quatparent); + } +} + diff --git a/indra/llmath/v3color.cpp b/indra/llmath/v3color.cpp index e76607a91f..b4cd410076 100644 --- a/indra/llmath/v3color.cpp +++ b/indra/llmath/v3color.cpp @@ -56,9 +56,7 @@ LLColor3::LLColor3(const LLVector4 &a) LLColor3::LLColor3(const LLSD &sd) { - mV[0] = (F32) sd[0].asReal(); - mV[1] = (F32) sd[1].asReal(); - mV[2] = (F32) sd[2].asReal(); + setValue(sd); } const LLColor3& LLColor3::operator=(const LLColor4 &a) diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index f392ac448b..63683ed496 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -185,14 +185,6 @@ void LLVector3::snap(S32 sig_digits) mV[VZ] = snap_to_sig_figs(mV[VZ], sig_digits); } - -std::ostream& operator<<(std::ostream& s, const LLVector3 &a) -{ - s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }"; - return s; -} - - const LLVector3& LLVector3::rotVec(const LLMatrix3 &mat) { *this = *this * mat; diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h index 06a4f5c542..73738cffd2 100644 --- a/indra/llmath/v3math.h +++ b/indra/llmath/v3math.h @@ -556,4 +556,10 @@ inline BOOL are_parallel(const LLVector3 &a, const LLVector3 &b, F32 epsilon) return FALSE; } +inline std::ostream& operator<<(std::ostream& s, const LLVector3 &a) +{ + s << "{ " << a.mV[VX] << ", " << a.mV[VY] << ", " << a.mV[VZ] << " }"; + return s; +} + #endif diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 3eceda7901..81c7534d01 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -208,43 +208,43 @@ list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES}) add_library (llmessage ${llmessage_SOURCE_FILES}) target_link_libraries( - llmessage - ${CURL_LIBRARIES} - ${CARES_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${CRYPTO_LIBRARIES} - ${XMLRPCEPI_LIBRARIES} - ) + llmessage + ${CURL_LIBRARIES} + ${CARES_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CRYPTO_LIBRARIES} + ${XMLRPCEPI_LIBRARIES} + ) + +# tests -IF (NOT LINUX AND VIEWER) - # When building the viewer the tests links against the shared objects. - # These can not be found when we try to run the tests, so we had to disable them, for the viewer build. - # TODO: Can someone with viewer knowledge figure out how to make these find the correct so. - SET(llmessage_TEST_SOURCE_FILES - # llhttpclientadapter.cpp - lltrustedmessageservice.cpp - lltemplatemessagedispatcher.cpp +SET(llmessage_TEST_SOURCE_FILES + # llhttpclientadapter.cpp + llmime.cpp + llnamevalue.cpp + lltrustedmessageservice.cpp + lltemplatemessagedispatcher.cpp llregionpresenceverifier.cpp - ) + ) +LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}") # set(TEST_DEBUG on) - set(test_libs - ${LLMESSAGE_LIBRARIES} - ${WINDOWS_LIBRARIES} - ${LLVFS_LIBRARIES} - ${LLMATH_LIBRARIES} - ${LLCOMMON_LIBRARIES} +set(test_libs + ${LLMESSAGE_LIBRARIES} + ${WINDOWS_LIBRARIES} + ${LLVFS_LIBRARIES} + ${LLMATH_LIBRARIES} + ${LLCOMMON_LIBRARIES} ${GOOGLEMOCK_LIBRARIES} - ) - - LL_ADD_INTEGRATION_TEST( - llsdmessage - "llsdmessage.cpp" - "${test_libs}" - ${PYTHON_EXECUTABLE} - "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py" - ) - - LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}") -ENDIF (NOT LINUX AND VIEWER) + ) + +LL_ADD_INTEGRATION_TEST( + llsdmessage + "llsdmessage.cpp" + "${test_libs}" + ${PYTHON_EXECUTABLE} + "${CMAKE_CURRENT_SOURCE_DIR}/tests/test_llsdmessage_peer.py" + ) + +LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}") diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp index e6419807ff..6400310c46 100644 --- a/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -728,9 +728,9 @@ static S32 buildBlock(U8* buffer, S32 buffer_size, const LLMessageBlock* templat // out gracefully from this function. XXXTBD llerrs << "buildBlock failed. " << "Attempted to pack " - << result + mvci.getSize() + << (result + mvci.getSize()) << " bytes into a buffer with size " - << buffer_size << "." << llendl + << buffer_size << "." << llendl; } } } diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index 8c9eb7ed42..6682575ca5 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -678,12 +678,7 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender // default to 0s. U32 size = mvci.getSize(); - std::vector<U8> data(size); - if(size) - { - // Nonsense test to get past GCC 4.3.1 bug with -O3 - memset(&(data[0]), 0, size); - } + std::vector<U8> data(size, 0); cur_data_block->addData(mvci.getName(), &(data[0]), size, mvci.getType()); } diff --git a/indra/llmessage/tests/llhost_test.cpp b/indra/llmessage/tests/llhost_test.cpp new file mode 100644 index 0000000000..5dc9ce42ee --- /dev/null +++ b/indra/llmessage/tests/llhost_test.cpp @@ -0,0 +1,247 @@ +/** + * @file llhost_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief llhost test cases. + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../llhost.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct host_data + { + }; + typedef test_group<host_data> host_test; + typedef host_test::object host_object; + tut::host_test host_testcase("llhost"); + + + template<> template<> + void host_object::test<1>() + { + LLHost host; + ensure("IP address is not NULL", (0 == host.getAddress()) && (0 == host.getPort()) && !host.isOk()); + } + template<> template<> + void host_object::test<2>() + { + U32 ip_addr = 0xc098017d; + U32 port = 8080; + LLHost host(ip_addr, port); + ensure("IP address is invalid", ip_addr == host.getAddress()); + ensure("Port Number is invalid", port == host.getPort()); + ensure("IP address and port number both should be ok", host.isOk()); + } + + template<> template<> + void host_object::test<3>() + { + const char* str = "192.168.1.1"; + U32 port = 8080; + LLHost host(str, port); + ensure("IP address could not be processed", (host.getAddress() == ip_string_to_u32(str))); + ensure("Port Number is invalid", (port == host.getPort())); + } + + template<> template<> + void host_object::test<4>() + { + U32 ip = ip_string_to_u32("192.168.1.1"); + U32 port = 22; + U64 ip_port = (((U64) ip) << 32) | port; + LLHost host(ip_port); + ensure("IP address is invalid", ip == host.getAddress()); + ensure("Port Number is invalid", port == host.getPort()); + } + + template<> template<> + void host_object::test<5>() + { + std::string ip_port_string = "192.168.1.1:8080"; + U32 ip = ip_string_to_u32("192.168.1.1"); + U32 port = 8080; + + LLHost host(ip_port_string); + ensure("IP address from IP:port is invalid", ip == host.getAddress()); + ensure("Port Number from from IP:port is invalid", port == host.getPort()); + } + + template<> template<> + void host_object::test<6>() + { + U32 ip = 0xc098017d, port = 8080; + LLHost host; + host.set(ip,port); + ensure("IP address is invalid", (ip == host.getAddress())); + ensure("Port Number is invalid", (port == host.getPort())); + } + + template<> template<> + void host_object::test<7>() + { + const char* str = "192.168.1.1"; + U32 port = 8080, ip; + LLHost host; + host.set(str,port); + ip = ip_string_to_u32(str); + ensure("IP address is invalid", (ip == host.getAddress())); + ensure("Port Number is invalid", (port == host.getPort())); + + str = "64.233.187.99"; + ip = ip_string_to_u32(str); + host.setAddress(str); + ensure("IP address is invalid", (ip == host.getAddress())); + + ip = 0xc098017b; + host.setAddress(ip); + ensure("IP address is invalid", (ip == host.getAddress())); + // should still use the old port + ensure("Port Number is invalid", (port == host.getPort())); + + port = 8084; + host.setPort(port); + ensure("Port Number is invalid", (port == host.getPort())); + // should still use the old address + ensure("IP address is invalid", (ip == host.getAddress())); + } + + template<> template<> + void host_object::test<8>() + { + const std::string str("192.168.1.1"); + U32 port = 8080; + LLHost host; + host.set(str,port); + + std::string ip_string = host.getIPString(); + ensure("Function Failed", (ip_string == str)); + + std::string ip_string_port = host.getIPandPort(); + ensure("Function Failed", (ip_string_port == "192.168.1.1:8080")); + } + + +// getHostName() and setHostByName + template<> template<> + void host_object::test<9>() + { + std::string hostStr = "google.com"; + LLHost host; + host.setHostByName(hostStr); + + // reverse DNS will likely result in appending of some + // sub-domain to the main hostname. so look for + // the main domain name and not do the exact compare + + std::string hostname = host.getHostName(); + ensure("getHostName failed", hostname.find(hostStr) != std::string::npos); + } + +// setHostByName for dotted IP + template<> template<> + void host_object::test<10>() + { + std::string hostStr = "64.233.167.99"; + LLHost host; + host.setHostByName(hostStr); + ensure("SetHostByName for dotted IP Address failed", host.getAddress() == ip_string_to_u32(hostStr.c_str())); + } + + template<> template<> + void host_object::test<11>() + { + LLHost host1(0xc098017d, 8080); + LLHost host2 = host1; + ensure("Both IP addresses are not same", (host1.getAddress() == host2.getAddress())); + ensure("Both port numbers are not same", (host1.getPort() == host2.getPort())); + } + + template<> template<> + void host_object::test<12>() + { + LLHost host1("192.168.1.1", 8080); + std::string str1 = "192.168.1.1:8080"; + std::ostringstream stream; + stream << host1; + ensure("Operator << failed", ( stream.str()== str1)); + + // There is no istream >> llhost operator. + //std::istringstream is(stream.str()); + //LLHost host2; + //is >> host2; + //ensure("Operator >> failed. Not compatible with <<", host1 == host2); + } + + // operators ==, !=, < + template<> template<> + void host_object::test<13>() + { + U32 ip_addr = 0xc098017d; + U32 port = 8080; + LLHost host1(ip_addr, port); + LLHost host2(ip_addr, port); + ensure("operator== failed", host1 == host2); + + // change port + host2.setPort(7070); + ensure("operator!= failed", host1 != host2); + + // set port back to 8080 and change IP address now + host2.setPort(8080); + host2.setAddress(ip_addr+10); + ensure("operator!= failed", host1 != host2); + + ensure("operator< failed", host1 < host2); + + // set IP address back to same value and change port + host2.setAddress(ip_addr); + host2.setPort(host1.getPort() + 10); + ensure("operator< failed", host1 < host2); + } + + // invalid ip address string + template<> template<> + void host_object::test<14>() + { + LLHost host1("10.0.1.2", 6143); + ensure("10.0.1.2 should be a valid address", host1.isOk()); + + LLHost host2("booger-brains", 6143); + ensure("booger-brains should be an invalid ip addess", !host2.isOk()); + + LLHost host3("255.255.255.255", 6143); + ensure("255.255.255.255 should be valid broadcast address", host3.isOk()); + } +} diff --git a/indra/llmessage/tests/llmime_test.cpp b/indra/llmessage/tests/llmime_test.cpp new file mode 100644 index 0000000000..62a84d34c0 --- /dev/null +++ b/indra/llmessage/tests/llmime_test.cpp @@ -0,0 +1,451 @@ +/** + * @file llmime_tut.cpp + * @author Phoenix + * @date 2006-12-24 + * @brief BRIEF_DESC of llmime_tut.cpp + * + * $LicenseInfo:firstyear=2006&license=viewergpl$ + * + * Copyright (c) 2006-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llsdserialize.h" + +#include "../llmime.h" + +#include "../test/lltut.h" + +namespace tut +{ + struct mime_index + { + }; + typedef test_group<mime_index> mime_index_t; + typedef mime_index_t::object mime_index_object_t; + tut::mime_index_t tut_mime_index("mime_index"); + + template<> template<> + void mime_index_object_t::test<1>() + { + LLMimeIndex mime; + ensure("no headers", mime.headers().isUndefined()); + ensure_equals("invalid offset", mime.offset(), -1); + ensure_equals("invalid content length", mime.contentLength(), -1); + ensure("no content type", mime.contentType().empty()); + ensure("not multipart", !mime.isMultipart()); + ensure_equals("no attachments", mime.subPartCount(), 0); + } + + template<> template<> + void mime_index_object_t::test<2>() + { + const S32 CONTENT_LENGTH = 6000; + const S32 CONTENT_OFFSET = 100; + const std::string CONTENT_TYPE = std::string("image/j2c"); + LLSD headers; + headers["Content-Length"] = CONTENT_LENGTH; + headers["Content-Type"] = CONTENT_TYPE; + LLMimeIndex mime(headers, CONTENT_OFFSET); + ensure("headers are map", mime.headers().isMap()); + ensure_equals("offset", mime.offset(), CONTENT_OFFSET); + ensure_equals("content length", mime.contentLength(), CONTENT_LENGTH); + ensure_equals("type is image/j2c", mime.contentType(), CONTENT_TYPE); + ensure("not multipart", !mime.isMultipart()); + ensure_equals("no attachments", mime.subPartCount(), 0); + } + + template<> template<> + void mime_index_object_t::test<3>() + { + const S32 MULTI_CONTENT_LENGTH = 8000; + const S32 MULTI_CONTENT_OFFSET = 100; + const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed"); + LLSD headers; + headers["Content-Length"] = MULTI_CONTENT_LENGTH; + headers["Content-Type"] = MULTI_CONTENT_TYPE; + LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET); + llinfos << "headers: " << LLSDOStreamer<LLSDNotationFormatter>(headers) + << llendl; + + + const S32 META_CONTENT_LENGTH = 700; + const S32 META_CONTENT_OFFSET = 69; + const std::string META_CONTENT_TYPE = std::string( + "text/llsd+xml"); + headers = LLSD::emptyMap(); + headers["Content-Length"] = META_CONTENT_LENGTH; + headers["Content-Type"] = META_CONTENT_TYPE; + LLMimeIndex meta(headers, META_CONTENT_OFFSET); + mime.attachSubPart(meta); + + const S32 IMAGE_CONTENT_LENGTH = 6000; + const S32 IMAGE_CONTENT_OFFSET = 200; + const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c"); + headers = LLSD::emptyMap(); + headers["Content-Length"] = IMAGE_CONTENT_LENGTH; + headers["Content-Type"] = IMAGE_CONTENT_TYPE; + LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET); + mime.attachSubPart(image); + + // make sure we have a valid multi-part + ensure("is multipart", mime.isMultipart()); + ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET); + ensure_equals( + "multi content length", + mime.contentLength(), + MULTI_CONTENT_LENGTH); + ensure_equals("two attachments", mime.subPartCount(), 2); + + // make sure ranged gets do the right thing with out of bounds + // sub-parts. + LLMimeIndex invalid_child(mime.subPart(-1)); + ensure("no headers", invalid_child.headers().isUndefined()); + ensure_equals("invalid offset", invalid_child.offset(), -1); + ensure_equals( + "invalid content length", invalid_child.contentLength(), -1); + ensure("no content type", invalid_child.contentType().empty()); + ensure("not multipart", !invalid_child.isMultipart()); + ensure_equals("no attachments", invalid_child.subPartCount(), 0); + + invalid_child = mime.subPart(2); + ensure("no headers", invalid_child.headers().isUndefined()); + ensure_equals("invalid offset", invalid_child.offset(), -1); + ensure_equals( + "invalid content length", invalid_child.contentLength(), -1); + ensure("no content type", invalid_child.contentType().empty()); + ensure("not multipart", !invalid_child.isMultipart()); + ensure_equals("no attachments", invalid_child.subPartCount(), 0); + } + + template<> template<> + void mime_index_object_t::test<4>() + { + const S32 MULTI_CONTENT_LENGTH = 8000; + const S32 MULTI_CONTENT_OFFSET = 100; + const std::string MULTI_CONTENT_TYPE = std::string("multipart/mixed"); + LLSD headers; + headers["Content-Length"] = MULTI_CONTENT_LENGTH; + headers["Content-Type"] = MULTI_CONTENT_TYPE; + LLMimeIndex mime(headers, MULTI_CONTENT_OFFSET); + + const S32 META_CONTENT_LENGTH = 700; + const S32 META_CONTENT_OFFSET = 69; + const std::string META_CONTENT_TYPE = std::string( + "application/llsd+xml"); + headers = LLSD::emptyMap(); + headers["Content-Length"] = META_CONTENT_LENGTH; + headers["Content-Type"] = META_CONTENT_TYPE; + LLMimeIndex meta(headers, META_CONTENT_OFFSET); + mime.attachSubPart(meta); + + const S32 IMAGE_CONTENT_LENGTH = 6000; + const S32 IMAGE_CONTENT_OFFSET = 200; + const std::string IMAGE_CONTENT_TYPE = std::string("image/j2c"); + headers = LLSD::emptyMap(); + headers["Content-Length"] = IMAGE_CONTENT_LENGTH; + headers["Content-Type"] = IMAGE_CONTENT_TYPE; + LLMimeIndex image(headers, IMAGE_CONTENT_OFFSET); + mime.attachSubPart(image); + + // check what we have + ensure("is multipart", mime.isMultipart()); + ensure_equals("multi offset", mime.offset(), MULTI_CONTENT_OFFSET); + ensure_equals( + "multi content length", + mime.contentLength(), + MULTI_CONTENT_LENGTH); + ensure_equals("two attachments", mime.subPartCount(), 2); + + LLMimeIndex actual_meta = mime.subPart(0); + ensure_equals( + "meta type", actual_meta.contentType(), META_CONTENT_TYPE); + ensure_equals( + "meta offset", actual_meta.offset(), META_CONTENT_OFFSET); + ensure_equals( + "meta content length", + actual_meta.contentLength(), + META_CONTENT_LENGTH); + + LLMimeIndex actual_image = mime.subPart(1); + ensure_equals( + "image type", actual_image.contentType(), IMAGE_CONTENT_TYPE); + ensure_equals( + "image offset", actual_image.offset(), IMAGE_CONTENT_OFFSET); + ensure_equals( + "image content length", + actual_image.contentLength(), + IMAGE_CONTENT_LENGTH); + } + +/* + template<> template<> + void mime_index_object_t::test<5>() + { + } + template<> template<> + void mime_index_object_t::test<6>() + { + } + template<> template<> + void mime_index_object_t::test<7>() + { + } + template<> template<> + void mime_index_object_t::test<8>() + { + } + template<> template<> + void mime_index_object_t::test<>() + { + } +*/ +} + + +namespace tut +{ + struct mime_parse + { + }; + typedef test_group<mime_parse> mime_parse_t; + typedef mime_parse_t::object mime_parse_object_t; + tut::mime_parse_t tut_mime_parse("mime_parse"); + + template<> template<> + void mime_parse_object_t::test<1>() + { + // parse one mime object + const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n"); + std::stringstream istr; + istr.str(SERIALIZED_MIME); + LLMimeIndex mime; + LLMimeParser parser; + bool ok = parser.parseIndex(istr, mime); + ensure("Parse successful.", ok); + ensure_equals("content type", mime.contentType(), "text/plain"); + ensure_equals("content length", mime.contentLength(), 200); + ensure_equals("offset", mime.offset(), 49); + } + + template<> template<> + void mime_parse_object_t::test<2>() + { + // make sure we only parse one. + const std::string SERIALIZED_MIME("Content-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\nContent-Length: 200\r\nContent-Type: text/plain\r\n\r\naaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccc\r\n\r\n"); + std::stringstream istr; + istr.str(SERIALIZED_MIME); + LLMimeIndex mime; + LLMimeParser parser; + bool ok = parser.parseIndex(istr, mime); + ensure("Parse successful.", ok); + ensure("not multipart.", !mime.isMultipart()); + ensure_equals("content type", mime.contentType(), "text/plain"); + ensure_equals("content length", mime.contentLength(), 200); + ensure_equals("offset", mime.offset(), 49); + } + + template<> template<> + void mime_parse_object_t::test<3>() + { + // test multi-part and lack of content length for some of it. + /* +Content-Type: multipart/mixed; boundary="segment"rnContent-Length: 148rnrn--segmentrnContent-Type: text/plainrnrnsome datarnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn + */ + const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=\"segment\"\r\nContent-Length: 150\r\n\r\n--segment\r\nContent-Type: text/plain\r\n\r\nsome data\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n"); + std::stringstream istr; + istr.str(SERIALIZED_MIME); + LLMimeIndex mime; + LLMimeParser parser; + bool ok = parser.parseIndex(istr, mime); + ensure("Parse successful.", ok); + ensure("is multipart.", mime.isMultipart()); + ensure_equals("sub-part count", mime.subPartCount(), 2); + ensure_equals("content length", mime.contentLength(), 150); + ensure_equals("data offset for multipart", mime.offset(), 74); + + LLMimeIndex mime_plain(mime.subPart(0)); + ensure_equals( + "first part type", + mime_plain.contentType(), + "text/plain"); + ensure_equals( + "first part content length not known.", + mime_plain.contentLength(), + -1); + ensure_equals("first part offset", mime_plain.offset(), 113); + + LLMimeIndex mime_xml(mime.subPart(1)); + ensure_equals( + "second part type", + mime_xml.contentType(), + "text/xml; charset=UTF-8"); + ensure_equals( + "second part content length", + mime_xml.contentLength(), + 22); + ensure_equals("second part offset", mime_xml.offset(), 198); + } + + template<> template<> + void mime_parse_object_t::test<4>() + { + // test multi-part, unquoted separator, and premature eof conditions + /* +Content-Type: multipart/mixed; boundary=segmentrnContent-Length: 220rnrn--segmentrnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--segmentrnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn */ + const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n"); + std::stringstream istr; + istr.str(SERIALIZED_MIME); + LLMimeIndex mime; + LLMimeParser parser; + bool ok = parser.parseIndex(istr, mime); + ensure("Parse successful.", ok); + ensure("is multipart.", mime.isMultipart()); + ensure_equals("sub-part count", mime.subPartCount(), 2); + ensure_equals("content length", mime.contentLength(), 220); + ensure_equals("data offset for multipart", mime.offset(), 72); + + LLMimeIndex mime_plain(mime.subPart(0)); + ensure_equals( + "first part type", + mime_plain.contentType(), + "text/plain"); + ensure_equals( + "first part content length", + mime_plain.contentLength(), + 55); + ensure_equals("first part offset", mime_plain.offset(), 131); + + LLMimeIndex mime_xml(mime.subPart(1)); + ensure_equals( + "second part type", + mime_xml.contentType(), + "text/xml; charset=UTF-8"); + ensure_equals( + "second part content length", + mime_xml.contentLength(), + 22); + ensure_equals("second part offset", mime_xml.offset(), 262); + } + + template<> template<> + void mime_parse_object_t::test<5>() + { + // test multi-part with multiple params + const std::string SERIALIZED_MIME("Content-Type: multipart/mixed; boundary=segment; comment=\"testing multiple params.\"\r\nContent-Length: 220\r\n\r\n--segment\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--segment\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n"); + std::stringstream istr; + istr.str(SERIALIZED_MIME); + LLMimeIndex mime; + LLMimeParser parser; + bool ok = parser.parseIndex(istr, mime); + ensure("Parse successful.", ok); + ensure("is multipart.", mime.isMultipart()); + ensure_equals("sub-part count", mime.subPartCount(), 2); + ensure_equals("content length", mime.contentLength(), 220); + + LLMimeIndex mime_plain(mime.subPart(0)); + ensure_equals( + "first part type", + mime_plain.contentType(), + "text/plain"); + ensure_equals( + "first part content length", + mime_plain.contentLength(), + 55); + + LLMimeIndex mime_xml(mime.subPart(1)); + ensure_equals( + "second part type", + mime_xml.contentType(), + "text/xml; charset=UTF-8"); + ensure_equals( + "second part content length", + mime_xml.contentLength(), + 22); + } + + template<> template<> + void mime_parse_object_t::test<6>() + { + // test multi-part with no specified boundary and eof +/* +Content-Type: multipart/relatedrnContent-Length: 220rnrn--rnContent-Type: text/plainrnContent-Length: 55rnrnhow are you today?rnI do not know. I guess I am:n'fine'rnrn--rnContent-Type: text/xml; charset=UTF-8rnContent-Length: 22rnrn<llsd><undef /></llsd>rnrn +*/ + const std::string SERIALIZED_MIME("Content-Type: multipart/related\r\nContent-Length: 500\r\n\r\n--\r\nContent-Type: text/plain\r\nContent-Length: 55\r\n\r\nhow are you today?\r\nI do not know. I guess I am:\n'fine'\r\n\r\n--\r\nContent-Type: text/xml; charset=UTF-8\r\nContent-Length: 22\r\n\r\n<llsd><undef /></llsd>\r\n\r\n"); + std::stringstream istr; + istr.str(SERIALIZED_MIME); + LLMimeIndex mime; + LLMimeParser parser; + bool ok = parser.parseIndex(istr, mime); + ensure("Parse successful.", ok); + ensure("is multipart.", mime.isMultipart()); + ensure_equals("sub-part count", mime.subPartCount(), 2); + ensure_equals("content length", mime.contentLength(), 500); + ensure_equals("data offset for multipart", mime.offset(), 56); + + LLMimeIndex mime_plain(mime.subPart(0)); + ensure_equals( + "first part type", + mime_plain.contentType(), + "text/plain"); + ensure_equals( + "first part content length", + mime_plain.contentLength(), + 55); + ensure_equals("first part offset", mime_plain.offset(), 108); + + LLMimeIndex mime_xml(mime.subPart(1)); + ensure_equals( + "second part type", + mime_xml.contentType(), + "text/xml; charset=UTF-8"); + ensure_equals( + "second part content length", + mime_xml.contentLength(), + 22); + ensure_equals("second part offset", mime_xml.offset(), 232); + } + +/* + template<> template<> + void mime_parse_object_t::test<>() + { + } + template<> template<> + void mime_parse_object_t::test<>() + { + } + template<> template<> + void mime_parse_object_t::test<>() + { + } + template<> template<> + void mime_parse_object_t::test<>() + { + } +*/ +} diff --git a/indra/llmessage/tests/llnamevalue_test.cpp b/indra/llmessage/tests/llnamevalue_test.cpp new file mode 100644 index 0000000000..3146e7f979 --- /dev/null +++ b/indra/llmessage/tests/llnamevalue_test.cpp @@ -0,0 +1,412 @@ +/** + * @file llnamevalue_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief LLNameValue unit test + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llsdserialize.h" + +#include "../llnamevalue.h" + +#include "../test/lltut.h" + + +#if LL_WINDOWS +// disable unreachable code warnings +#pragma warning(disable: 4702) +#endif + +namespace tut +{ + struct namevalue_test + { + namevalue_test() + { + } + }; + typedef test_group<namevalue_test> namevalue_t; + typedef namevalue_t::object namevalue_object_t; + tut::namevalue_t tut_namevalue("namevalue_test"); + + + template<> template<> + void namevalue_object_t::test<1>() + { + // LLNameValue() + LLNameValue nValue; + ensure("mName should have been NULL", nValue.mName == NULL); + ensure("getTypeEnum failed",nValue.getTypeEnum() == NVT_NULL); + ensure("getClassEnum failed",nValue.getClassEnum() == NVC_NULL); + ensure("getSendtoEnum failed",nValue.getSendtoEnum() == NVS_NULL); + + LLNameValue nValue1(" SecondLife ASSET RW SIM 232324343"); + + } + + // LLNameValue(const char* data); + // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, const char* nvsendto, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<2>() + { + LLNameValue nValue(" SecondLife ASSET RW S 232324343"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); + ensure("sendToData or sendToViewer failed", !nValue.sendToData() && !nValue.sendToViewer()); + + LLNameValue nValue1("\n\r SecondLife_1 STRING READ_WRITE SIM 232324343"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife_1"))); + ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); + ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); + ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); + ensure("1. sendToData or sendToViewer failed", !nValue1.sendToData() && !nValue1.sendToViewer()); + + LLNameValue nValue2("SecondLife", "23.5", "F32", "R", "DS"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_DATA_SIM); + ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); + ensure("2. sendToData or sendToViewer failed", nValue2.sendToData() && !nValue2.sendToViewer()); + + LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY", "SIM_SPACE"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_DATA_SIM); + ensure("3. getS32 failed", *nValue3.getS32() == -43456787); + ensure("sendToData or sendToViewer failed", nValue3.sendToData() && !nValue3.sendToViewer()); + + LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW", "SV"); + LLVector3 llvec4(1.0, 2.0, 3.0); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM_VIEWER); + ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); + ensure("4. sendToData or sendToViewer failed", !nValue4.sendToData() && nValue4.sendToViewer()); + + LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW", "SIM_VIEWER"); + LLVector3 llvec5(-1.0f, 2.4f, 3); + ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); + ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); + ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM_VIEWER); + ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); + ensure("5. sendToData or sendToViewer failed", !nValue5.sendToData() && nValue5.sendToViewer()); + + LLNameValue nValue6("SecondLife", "89764323", "U32", "RW", "DSV"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + ensure("6. getU32 failed", *nValue6.getU32() == 89764323); + ensure("6. sendToData or sendToViewer failed", nValue6.sendToData() && nValue6.sendToViewer()); + + LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW", "SIM_SPACE_VIEWER"); + U64 u64_7 = U64L(89764323323232); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_DATA_SIM_VIEWER); + ensure("7. getU32 failed", *nValue7.getU64() == u64_7); + ensure("7. sendToData or sendToViewer failed", nValue7.sendToData() && nValue7.sendToViewer()); + } + + // LLNameValue(const char* name, const char* data, const char* type, const char* nvclass, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<3>() + { + LLNameValue nValue("SecondLife", "232324343", "ASSET", "READ_WRITE"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_ASSET); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + ensure("getString failed", (0==strcmp(nValue.getAsset(),"232324343"))); + + LLNameValue nValue1("SecondLife", "232324343", "STRING", "READ_WRITE"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); + ensure("1. getTypeEnum failed", nValue1.getTypeEnum() == NVT_STRING); + ensure("1. getClassEnum failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum failed", nValue1.getSendtoEnum() == NVS_SIM); + ensure("1. getString failed", (0==strcmp(nValue1.getString(),"232324343"))); + + LLNameValue nValue2("SecondLife", "23.5", "F32", "R"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); + ensure("2. getF32 failed", *nValue2.getF32() == 23.5f); + + LLNameValue nValue3("SecondLife", "-43456787", "S32", "READ_ONLY"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); + ensure("3. getS32 failed", *nValue3.getS32() == -43456787); + + LLNameValue nValue4("SecondLife", "<1.0, 2.0, 3.0>", "VEC3", "RW"); + LLVector3 llvec4(1.0, 2.0, 3.0); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); + ensure("4. getVec3 failed", *nValue4.getVec3() == llvec4); + + LLNameValue nValue5("SecondLife", "-1.0, 2.4, 3", "VEC3", "RW"); + LLVector3 llvec5(-1.0f, 2.4f, 3); + ensure("5. getTypeEnum failed", nValue5.getTypeEnum() == NVT_VEC3); + ensure("5. getClassEnum failed", nValue5.getClassEnum() == NVC_READ_WRITE); + ensure("5. getSendtoEnum failed", nValue5.getSendtoEnum() == NVS_SIM); + ensure("5. getVec3 failed", *nValue5.getVec3() == llvec5); + + LLNameValue nValue6("SecondLife", "89764323", "U32", "RW"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); + ensure("6. getU32 failed", *nValue6.getU32() == 89764323); + + LLNameValue nValue7("SecondLife", "89764323323232", "U64", "RW"); + U64 u64_7 = U64L(89764323323232); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); + ensure("7. getU32 failed", *nValue7.getU64() == u64_7); + } + + // LLNameValue(const char* name, const char* type, const char* nvclass, + // TNameValueCallback nvcb = NULL, void** user_data = NULL); + template<> template<> + void namevalue_object_t::test<4>() + { + LLNameValue nValue("SecondLife", "STRING", "READ_WRITE"); + ensure("mName not set correctly", (0 == strcmp(nValue.mName,"SecondLife"))); + ensure("getTypeEnum failed", nValue.getTypeEnum() == NVT_STRING); + ensure("getClassEnum failed", nValue.getClassEnum() == NVC_READ_WRITE); + ensure("getSendtoEnum failed", nValue.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue1("SecondLife", "ASSET", "READ_WRITE"); + ensure("1. mName not set correctly", (0 == strcmp(nValue1.mName,"SecondLife"))); + ensure("1. getTypeEnum for RW failed", nValue1.getTypeEnum() == NVT_ASSET); + ensure("1. getClassEnum for RW failed", nValue1.getClassEnum() == NVC_READ_WRITE); + ensure("1. getSendtoEnum for RW failed", nValue1.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue2("SecondLife", "F32", "READ_ONLY"); + ensure("2. getTypeEnum failed", nValue2.getTypeEnum() == NVT_F32); + ensure("2. getClassEnum failed", nValue2.getClassEnum() == NVC_READ_ONLY); + ensure("2. getSendtoEnum failed", nValue2.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue3("SecondLife", "S32", "READ_ONLY"); + ensure("3. getTypeEnum failed", nValue3.getTypeEnum() == NVT_S32); + ensure("3. getClassEnum failed", nValue3.getClassEnum() == NVC_READ_ONLY); + ensure("3. getSendtoEnum failed", nValue3.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue4("SecondLife", "VEC3", "READ_WRITE"); + ensure("4. getTypeEnum failed", nValue4.getTypeEnum() == NVT_VEC3); + ensure("4. getClassEnum failed", nValue4.getClassEnum() == NVC_READ_WRITE); + ensure("4. getSendtoEnum failed", nValue4.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue6("SecondLife", "U32", "READ_WRITE"); + ensure("6. getTypeEnum failed", nValue6.getTypeEnum() == NVT_U32); + ensure("6. getClassEnum failed", nValue6.getClassEnum() == NVC_READ_WRITE); + ensure("6. getSendtoEnum failed", nValue6.getSendtoEnum() == NVS_SIM); + + LLNameValue nValue7("SecondLife", "U64", "READ_WRITE"); + ensure("7. getTypeEnum failed", nValue7.getTypeEnum() == NVT_U64); + ensure("7. getClassEnum failed", nValue7.getClassEnum() == NVC_READ_WRITE); + ensure("7. getSendtoEnum failed", nValue7.getSendtoEnum() == NVS_SIM); + } + + template<> template<> + void namevalue_object_t::test<5>() + { + LLNameValue nValue("SecondLife", "This is a test", "STRING", "RW", "SIM"); + + ensure("getString failed", (0 == strcmp(nValue.getString(),"This is a test"))); + } + + template<> template<> + void namevalue_object_t::test<6>() + { + LLNameValue nValue("SecondLife", "This is a test", "ASSET", "RW", "S"); + ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + } + + template<> template<> + void namevalue_object_t::test<7>() + { + LLNameValue nValue("SecondLife", "555555", "F32", "RW", "SIM"); + + ensure("getF32 failed",*nValue.getF32() == 555555.f); + } + + template<> template<> + void namevalue_object_t::test<8>() + { + LLNameValue nValue("SecondLife", "-5555", "S32", "RW", "SIM"); + + ensure("getS32 failed", *nValue.getS32() == -5555); + + S32 sVal = 0x7FFFFFFF; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + + sVal = -0x7FFFFFFF; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + + sVal = 0; + nValue.setS32(sVal); + ensure("getS32 failed", *nValue.getS32() == sVal); + } + + template<> template<> + void namevalue_object_t::test<9>() + { + LLNameValue nValue("SecondLife", "<-3, 2, 1>", "VEC3", "RW", "SIM"); + LLVector3 vecExpected(-3, 2, 1); + LLVector3 vec; + nValue.getVec3(vec); + ensure("getVec3 failed", vec == vecExpected); + } + + template<> template<> + void namevalue_object_t::test<10>() + { + LLNameValue nValue("SecondLife", "12345678", "U32", "RW", "SIM"); + + ensure("getU32 failed",*nValue.getU32() == 12345678); + + U32 val = 0xFFFFFFFF; + nValue.setU32(val); + ensure("U32 max", *nValue.getU32() == val); + + val = 0; + nValue.setU32(val); + ensure("U32 min", *nValue.getU32() == val); + } + + template<> template<> + void namevalue_object_t::test<11>() + { + //skip_fail("incomplete support for U64."); + LLNameValue nValue("SecondLife", "44444444444", "U64", "RW", "SIM"); + + ensure("getU64 failed",*nValue.getU64() == U64L(44444444444)); + + // there is no LLNameValue::setU64() + } + + + template<> template<> + void namevalue_object_t::test<12>() + { + //skip_fail("incomplete support for U64."); + LLNameValue nValue("SecondLife U64 RW DSV 44444444444"); + std::string ret_str = nValue.printNameValue(); + + ensure_equals("1:printNameValue failed",ret_str,"SecondLife U64 RW DSV 44444444444"); + + LLNameValue nValue1(ret_str.c_str()); + ensure_equals("Serialization of printNameValue failed", *nValue.getU64(), *nValue1.getU64()); + } + + template<> template<> + void namevalue_object_t::test<13>() + { + LLNameValue nValue("SecondLife STRING RW DSV 44444444444"); + std::string ret_str = nValue.printData(); + ensure_equals("1:printData failed",ret_str,"44444444444"); + + LLNameValue nValue1("SecondLife S32 RW DSV 44444"); + ret_str = nValue1.printData(); + ensure_equals("2:printData failed",ret_str,"44444"); + } + + template<> template<> + void namevalue_object_t::test<14>() + { + LLNameValue nValue("SecodLife STRING RW SIM 22222"); + std::ostringstream stream1,stream2,stream3, stream4, stream5; + stream1 << nValue; + ensure_equals("STRING << failed",stream1.str(),"22222"); + + LLNameValue nValue1("SecodLife F32 RW SIM 22222"); + stream2 << nValue1; + ensure_equals("F32 << failed",stream2.str(),"22222"); + + LLNameValue nValue2("SecodLife S32 RW SIM 22222"); + stream3<< nValue2; + ensure_equals("S32 << failed",stream3.str(),"22222"); + + LLNameValue nValue3("SecodLife U32 RW SIM 122222"); + stream4<< nValue3; + ensure_equals("U32 << failed",stream4.str(),"122222"); + + // I don't think we use U64 name value pairs. JC + //skip_fail("incomplete support for U64."); + //LLNameValue nValue4("SecodLife U64 RW SIM 22222"); + //stream5<< nValue4; + //ensure("U64 << failed",0 == strcmp((stream5.str()).c_str(),"22222")); + } + + template<> template<> + void namevalue_object_t::test<15>() + { + LLNameValue nValue("SecondLife", "This is a test", "ASSET", "R", "S"); + + ensure("getAsset failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + // this should not have updated as it is read only. + nValue.setAsset("New Value should not be updated"); + ensure("setAsset on ReadOnly failed", (0 == strcmp(nValue.getAsset(),"This is a test"))); + + LLNameValue nValue1("SecondLife", "1234", "U32", "R", "S"); + // this should not have updated as it is read only. + nValue1.setU32(4567); + ensure("setU32 on ReadOnly failed", *nValue1.getU32() == 1234); + + LLNameValue nValue2("SecondLife", "1234", "S32", "R", "S"); + // this should not have updated as it is read only. + nValue2.setS32(4567); + ensure("setS32 on ReadOnly failed", *nValue2.getS32() == 1234); + + LLNameValue nValue3("SecondLife", "1234", "F32", "R", "S"); + // this should not have updated as it is read only. + nValue3.setF32(4567); + ensure("setF32 on ReadOnly failed", *nValue3.getF32() == 1234); + + LLNameValue nValue4("SecondLife", "<1,2,3>", "VEC3", "R", "S"); + // this should not have updated as it is read only. + LLVector3 vec(4,5,6); + nValue3.setVec3(vec); + LLVector3 vec1(1,2,3); + ensure("setVec3 on ReadOnly failed", *nValue4.getVec3() == vec1); + + // cant test for U64 as no set64 exists nor any operators support U64 type + } +} diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index aac650bec9..5c13df9f81 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -9,6 +9,7 @@ include(LLCommon) include(LLImage) include(LLMath) include(LLRender) +include(LLVFS) include(LLWindow) include(LLXML) include(LLVFS) @@ -19,6 +20,7 @@ include_directories( ${LLIMAGE_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLRENDER_INCLUDE_DIRS} + ${LLVFS_INCLUDE_DIRS} ${LLWINDOW_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} ${LLVFS_INCLUDE_DIRS} diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index 754d90c854..08a96b4e31 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -106,7 +106,7 @@ void LLCubeMap::initGL() } else { - llwarns << "Using cube map without extension!" << llendl + llwarns << "Using cube map without extension!" << llendl; } } diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 44e997340e..786dc64452 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -98,9 +98,7 @@ LLFontGlyphInfo::LLFontGlyphInfo(U32 index) mWidth(0), // In pixels mHeight(0), // In pixels mXAdvance(0.f), // In pixels - mYAdvance(0.f), // In pixels - mIsRendered(FALSE), - mMetricsValid(FALSE) + mYAdvance(0.f) // In pixels { } @@ -199,7 +197,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v if (!mIsFallback) { // Add the default glyph - addGlyph(0, 0); + addGlyphFromFont(this, 0, 0); } mName = filename; @@ -251,57 +249,10 @@ F32 LLFontFreetype::getXAdvance(llwchar wch) const if (mFTFace == NULL) return 0.0; - //llassert(!mIsFallback); - U32 glyph_index; - // Return existing info only if it is current LLFontGlyphInfo* gi = getGlyphInfo(wch); - if (gi && gi->mMetricsValid) - { - return gi->mXAdvance; - } - - const LLFontFreetype* fontp = this; - - // Initialize char to glyph map - glyph_index = FT_Get_Char_Index(mFTFace, wch); - if (glyph_index == 0) - { - font_vector_t::const_iterator iter; - for(iter = mFallbackFonts.begin(); (iter != mFallbackFonts.end()) && (glyph_index == 0); iter++) - { - glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch); - if(glyph_index) - { - fontp = *iter; - } - } - } - - if (glyph_index) + if (gi) { - // This font has this glyph - fontp->renderGlyph(glyph_index); - - // Create the entry if it's not there - char_glyph_info_map_t::iterator iter2 = mCharGlyphInfoMap.find(wch); - if (iter2 == mCharGlyphInfoMap.end()) - { - gi = new LLFontGlyphInfo(glyph_index); - insertGlyphInfo(wch, gi); - } - else - { - gi = iter2->second; - } - - gi->mWidth = fontp->mFTFace->glyph->bitmap.width; - gi->mHeight = fontp->mFTFace->glyph->bitmap.rows; - - // Convert these from 26.6 units to float pixels. - gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; - gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; - gi->mMetricsValid = TRUE; return gi->mXAdvance; } else @@ -323,10 +274,10 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const return 0.0; //llassert(!mIsFallback); - LLFontGlyphInfo* left_glyph_info = get_if_there(mCharGlyphInfoMap, char_left, (LLFontGlyphInfo*)NULL); + LLFontGlyphInfo* left_glyph_info = getGlyphInfo(char_left);; U32 left_glyph = left_glyph_info ? left_glyph_info->mGlyphIndex : 0; // Kern this puppy. - LLFontGlyphInfo* right_glyph_info = get_if_there(mCharGlyphInfoMap, char_right, (LLFontGlyphInfo*)NULL); + LLFontGlyphInfo* right_glyph_info = getGlyphInfo(char_right); U32 right_glyph = right_glyph_info ? right_glyph_info->mGlyphIndex : 0; FT_Vector delta; @@ -339,18 +290,10 @@ F32 LLFontFreetype::getXKerning(llwchar char_left, llwchar char_right) const BOOL LLFontFreetype::hasGlyph(llwchar wch) const { llassert(!mIsFallback); - const LLFontGlyphInfo* gi = getGlyphInfo(wch); - if (gi && gi->mIsRendered) - { - return TRUE; - } - else - { - return FALSE; - } + return(mCharGlyphInfoMap.find(wch) != mCharGlyphInfoMap.end()); } -BOOL LLFontFreetype::addChar(llwchar wch) const +LLFontGlyphInfo* LLFontFreetype::addGlyph(llwchar wch) const { if (mFTFace == NULL) return FALSE; @@ -364,37 +307,30 @@ BOOL LLFontFreetype::addChar(llwchar wch) const glyph_index = FT_Get_Char_Index(mFTFace, wch); if (glyph_index == 0) { - //llinfos << "Trying to add glyph from fallback font!" << llendl + //llinfos << "Trying to add glyph from fallback font!" << llendl; font_vector_t::const_iterator iter; for(iter = mFallbackFonts.begin(); iter != mFallbackFonts.end(); iter++) { glyph_index = FT_Get_Char_Index((*iter)->mFTFace, wch); if (glyph_index) { - addGlyphFromFont(*iter, wch, glyph_index); - return TRUE; + return addGlyphFromFont(*iter, wch, glyph_index); } } } char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.find(wch); - if (iter == mCharGlyphInfoMap.end() || !(iter->second->mIsRendered)) + if (iter == mCharGlyphInfoMap.end()) { - BOOL result = addGlyph(wch, glyph_index); - return result; + return addGlyphFromFont(this, wch, glyph_index); } - return FALSE; -} - -BOOL LLFontFreetype::addGlyph(llwchar wch, U32 glyph_index) const -{ - return addGlyphFromFont(this, wch, glyph_index); + return NULL; } -BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const +LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const { if (mFTFace == NULL) - return FALSE; + return NULL; llassert(!mIsFallback); fontp->renderGlyph(glyph_index); @@ -417,8 +353,6 @@ BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, // Convert these from 26.6 units to float pixels. gi->mXAdvance = fontp->mFTFace->glyph->advance.x / 64.f; gi->mYAdvance = fontp->mFTFace->glyph->advance.y / 64.f; - gi->mIsRendered = TRUE; - gi->mMetricsValid = TRUE; insertGlyphInfo(wch, gi); @@ -489,7 +423,11 @@ BOOL LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, // omit it from the font-image. } - return TRUE; + LLImageGL *image_gl = mFontBitmapCachep->getImageGL(bitmap_num); + LLImageRaw *image_raw = mFontBitmapCachep->getImageRaw(bitmap_num); + image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); + + return gi; } LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const @@ -499,7 +437,11 @@ LLFontGlyphInfo* LLFontFreetype::getGlyphInfo(llwchar wch) const { return iter->second; } - return NULL; + else + { + // this glyph doesn't yet exist, so render it and return the result + return addGlyph(wch); + } } void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const @@ -534,11 +476,10 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) { resetBitmapCache(); + loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback); if (!mIsFallback) { // This is the head of the list - need to rebuild ourself and all fallbacks. - loadFace(mName, mPointSize, vert_dpi ,horz_dpi, mFontBitmapCachep->getNumComponents(), mIsFallback); - if (mFallbackFonts.empty()) { llwarns << "LLFontGL::reset(), no fallback fonts present" << llendl; @@ -557,19 +498,12 @@ void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi) void LLFontFreetype::resetBitmapCache() { - // Iterate through glyphs and clear the mIsRendered flag - for (char_glyph_info_map_t::iterator iter = mCharGlyphInfoMap.begin(); - iter != mCharGlyphInfoMap.end(); ++iter) - { - iter->second->mIsRendered = FALSE; - //FIXME: this is only strictly necessary when resetting the entire font, - //not just flushing the bitmap - iter->second->mMetricsValid = FALSE; - } + for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer()); + mCharGlyphInfoMap.clear(); mFontBitmapCachep->reset(); // Add the empty glyph - addGlyph(0, 0); + addGlyphFromFont(this, 0, 0); } void LLFontFreetype::destroyGL() @@ -577,21 +511,11 @@ void LLFontFreetype::destroyGL() mFontBitmapCachep->destroyGL(); } -BOOL LLFontFreetype::getIsFallback() const -{ - return mIsFallback; -} - const std::string &LLFontFreetype::getName() const { return mName; } -F32 LLFontFreetype::getPointSize() const -{ - return mPointSize; -} - const LLPointer<LLFontBitmapCache> LLFontFreetype::getFontBitmapCache() const { return mFontBitmapCachep; diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 5adaab3a88..1325b4995b 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -70,10 +70,8 @@ public: S32 mHeight; // In pixels F32 mXAdvance; // In pixels F32 mYAdvance; // In pixels - BOOL mMetricsValid; // We have up-to-date metrics for this glyph // Information for actually rendering - BOOL mIsRendered; // We actually have rendered this glyph S32 mXBitmapOffset; // Offset to the origin in the bitmap S32 mYBitmapOffset; // Offset to the origin in the bitmap S32 mXBearing; // Distance from baseline to left in pixels @@ -133,34 +131,27 @@ public: F32 getXAdvance(llwchar wc) const; F32 getXKerning(llwchar char_left, llwchar char_right) const; // Get the kerning between the two characters - BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character - BOOL addChar(llwchar wch) const; // Add a new character to the font if necessary - BOOL addGlyph(llwchar wch, U32 glyph_index) const; // Add a new glyph to the existing font - BOOL addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) - LLFontGlyphInfo* getGlyphInfo(llwchar wch) const; - void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; - void renderGlyph(U32 glyph_index) const; - void reset(F32 vert_dpi, F32 horz_dpi); - void resetBitmapCache(); void destroyGL(); - BOOL getIsFallback() const; - const std::string& getName() const; - F32 getPointSize() const; - const LLPointer<LLFontBitmapCache> getFontBitmapCache() const; void setStyle(U8 style); U8 getStyle() const; private: + void resetBitmapCache(); void setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 width, U32 height, U8 *data, S32 stride = 0) const; + BOOL hasGlyph(llwchar wch) const; // Has a glyph for this character + LLFontGlyphInfo* addGlyph(llwchar wch) const; // Add a new character to the font if necessary + LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) + void renderGlyph(U32 glyph_index) const; + void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; std::string mName; diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index f7bab3de67..c9163d2890 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -44,6 +44,7 @@ #include "llstl.h" #include "v4color.h" #include "lltexture.h" +#include "lldir.h" // Third party library includes #include <boost/tokenizer.hpp> @@ -251,11 +252,6 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons { llwchar wch = wstr[i]; - if (!mFontFreetype->hasGlyph(wch)) - { - addChar(wch); - } - const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); if (!fgi) { @@ -298,10 +294,6 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons if (next_char && (next_char < LAST_CHARACTER)) { // Kern this puppy. - if (!mFontFreetype->hasGlyph(next_char)) - { - addChar(next_char); - } cur_x += mFontFreetype->getXKerning(wch, next_char); } @@ -441,15 +433,22 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars F32 cur_x = 0; const S32 max_index = begin_offset + max_chars; - for (S32 i = begin_offset; i < max_index; i++) + + F32 width_padding = 0.f; + for (S32 i = begin_offset; i < max_index && wchars[i] != 0; i++) { llwchar wch = wchars[i]; - if (wch == 0) - { - break; // done - } - cur_x += mFontFreetype->getXAdvance(wch); + const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); + + F32 advance = mFontFreetype->getXAdvance(wch); + + // for the last character we want to measure the greater of its width and xadvance values + // so keep track of the difference between these values for the each character we measure + // so we can fix things up at the end + width_padding = llmax(0.f, (F32)fgi->mWidth - advance); + + cur_x += advance; llwchar next_char = wchars[i+1]; if (((i + 1) < begin_offset + max_chars) @@ -463,6 +462,9 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars cur_x = (F32)llfloor(cur_x + 0.5f); } + // add in extra pixels for last character's width past its xadvance + cur_x += width_padding; + return cur_x / sScaleX; } @@ -662,25 +664,6 @@ S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 t return llmin(max_chars, pos - begin_offset); } -BOOL LLFontGL::addChar(llwchar wch) const -{ - if (!mFontFreetype->addChar(wch)) - { - return FALSE; - } - - stop_glerror(); - - LLFontGlyphInfo *glyph_info = mFontFreetype->getGlyphInfo(wch); - U32 bitmap_num = glyph_info->mBitmapNum; - - const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache(); - LLImageGL *image_gl = font_bitmap_cache->getImageGL(bitmap_num); - LLImageRaw *image_raw = font_bitmap_cache->getImageRaw(bitmap_num); - image_gl->setSubImage(image_raw, 0, 0, image_gl->getWidth(), image_gl->getHeight()); - return TRUE; -} - const LLFontDescriptor& LLFontGL::getFontDesc() const { return mFontDescriptor; diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index ad84b6d641..a278d88287 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -131,8 +131,6 @@ public: // Returns the index of the character closest to pixel position x (ignoring text to the right of max_pixels and max_chars) S32 charFromPixelOffset(const llwchar* wchars, S32 char_offset, F32 x, F32 max_pixels=F32_MAX, S32 max_chars = S32_MAX, BOOL round = TRUE) const; - BOOL addChar(const llwchar wch) const; - const LLFontDescriptor& getFontDesc() const; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index c7178a5552..f33ae7d8f0 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -53,8 +53,6 @@ # include "GL/glxext.h" //# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p)) # define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddress((const GLubyte*)(p)) -// the X headers define 'Status'. Undefine to avoid confusion. -#undef Status // The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly // This header is distributed with SL. You'll find it in linden/libraries/include/GL/ @@ -277,8 +275,6 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT; // Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol // is considered 'legacy' but works on more machines. # define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p)) -// Whee, the X headers define 'Status'. Undefine to avoid confusion. -#undef Status #endif // LL_LINUX && !LL_MESA_HEADLESS #if LL_LINUX && defined(WINGDIAPI) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index dd64d753c7..e5fea5b995 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -428,7 +428,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents) // Check if dimensions are a power of two! if (!checkSize(width,height)) { - llerrs << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; + llerrs << llformat("Texture has non power of two dimension: %dx%d",width,height) << llendl; } if (mTexName) diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 219c2ee254..f28fca35c5 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -52,6 +52,7 @@ #include "llrender.h" #include "lluictrlfactory.h" #include "llhelp.h" +#include "lldockablefloater.h" static LLDefaultChildRegistry::Register<LLButton> r("button"); @@ -1057,6 +1058,20 @@ void LLButton::setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) } // static +void LLButton::setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname) +{ + LLButton* button = dynamic_cast<LLButton*>(ctrl); + if (!button) + return; + // Get the visibility control name for the floater + std::string vis_control_name = LLFloaterReg::declareVisibilityControl(sdname.asString()); + // Set the button control value (toggle state) to the floater visibility control (Sets the value as well) + button->setControlVariable(LLUI::sSettingGroups["floater"]->getControl(vis_control_name)); + // Set the clicked callback to toggle the floater + button->setClickedCallback(boost::bind(&LLDockableFloater::toggleInstance, sdname)); +} + +// static void LLButton::showHelp(LLUICtrl* ctrl, const LLSD& sdname) { // search back through the button's parents for a panel diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 73ba457d34..7ca520b935 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -232,6 +232,7 @@ public: static void onHeldDown(void *userdata); // to be called by gIdleCallbacks static void toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname); static void setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname); + static void setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname); static void showHelp(LLUICtrl* ctrl, const LLSD& sdname); void setForcePressedState(BOOL b) { mForcePressedState = b; } diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp index c512ef25be..228d0e701f 100644 --- a/indra/llui/lldockablefloater.cpp +++ b/indra/llui/lldockablefloater.cpp @@ -33,24 +33,36 @@ #include "linden_common.h" #include "lldockablefloater.h" +#include "llfloaterreg.h" //static LLHandle<LLFloater> LLDockableFloater::sInstanceHandle; +//static +void LLDockableFloater::init(LLDockableFloater* thiz) +{ + thiz->setDocked(thiz->mDockControl.get() != NULL + && thiz->mDockControl.get()->isDockVisible()); + thiz->resetInstance(); + + // all dockable floaters should have close, dock and minimize buttons + thiz->setCanClose(TRUE); + thiz->setCanDock(true); + thiz->setCanMinimize(TRUE); +} + LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, const LLSD& key, const Params& params) : LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(true) { - setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible()); - resetInstance(); + init(this); } LLDockableFloater::LLDockableFloater(LLDockControl* dockControl, bool uniqueDocking, const LLSD& key, const Params& params) : LLFloater(key, params), mDockControl(dockControl), mUniqueDocking(uniqueDocking) { - setDocked(mDockControl.get() != NULL && mDockControl.get()->isDockVisible()); - resetInstance(); + init(this); } LLDockableFloater::~LLDockableFloater() @@ -64,6 +76,33 @@ BOOL LLDockableFloater::postBuild() return LLView::postBuild(); } +//static +void LLDockableFloater::toggleInstance(const LLSD& sdname) +{ + LLSD key; + std::string name = sdname.asString(); + + LLDockableFloater* instance = + dynamic_cast<LLDockableFloater*> (LLFloaterReg::findInstance(name)); + // if floater closed or docked + if (instance == NULL || instance != NULL && instance->isDocked()) + { + LLFloaterReg::toggleInstance(name, key); + // restore button toggle state + if (instance != NULL) + { + instance->storeVisibilityControl(); + } + } + // if floater undocked + else if (instance != NULL) + { + instance->setMinimized(FALSE); + instance->setVisible(TRUE); + instance->setFocus(TRUE); + } +} + void LLDockableFloater::resetInstance() { if (mUniqueDocking && sInstanceHandle.get() != this) @@ -91,6 +130,17 @@ void LLDockableFloater::setVisible(BOOL visible) LLFloater::setVisible(visible); } +void LLDockableFloater::setMinimized(BOOL minimize) +{ + if(minimize && isDocked()) + { + setVisible(FALSE); + } + setCanDock(!minimize); + + LLFloater::setMinimized(minimize); +} + void LLDockableFloater::onDockHidden() { setCanDock(FALSE); diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h index 7d91d007ee..499ce9ae8d 100644 --- a/indra/llui/lldockablefloater.h +++ b/indra/llui/lldockablefloater.h @@ -44,6 +44,8 @@ class LLDockableFloater : public LLFloater { static const U32 UNDOCK_LEAP_HEIGHT = 12; + + static void init(LLDockableFloater* thiz); public: LOG_CLASS(LLDockableFloater); LLDockableFloater(LLDockControl* dockControl, const LLSD& key, @@ -54,6 +56,8 @@ public: static LLHandle<LLFloater> getInstanceHandle() { return sInstanceHandle; } + static void toggleInstance(const LLSD& sdname); + /** * If descendant class overrides postBuild() in order to perform specific * construction then it must still invoke its superclass' implementation. @@ -68,6 +72,12 @@ public: */ /*virtual*/ void setVisible(BOOL visible); + /** + * If descendant class overrides setMinimized() then it must still invoke its + * superclass' implementation. + */ + /*virtual*/ void setMinimized(BOOL minimize); + virtual void onDockHidden(); virtual void onDockShown(); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 66defbbf0a..647c816fdf 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -916,6 +916,9 @@ void LLFloater::setMinimized(BOOL minimize) if (minimize) { + // minimized flag should be turned on before release focus + mMinimized = TRUE; + mExpandedRect = getRect(); // If the floater has been dragged while minimized in the @@ -977,8 +980,6 @@ void LLFloater::setMinimized(BOOL minimize) } } - mMinimized = TRUE; - // Reshape *after* setting mMinimized reshape( minimized_width, floater_header_size, TRUE); } @@ -1432,7 +1433,18 @@ void LLFloater::onClickHelp( LLFloater* self ) { if (self && LLUI::sHelpImpl) { - LLUI::sHelpImpl->showTopic(self->getHelpTopic()); + // get the help topic for this floater + std::string help_topic = self->getHelpTopic(); + + // but use a more specific help topic for the currently + // displayed tab inside of this floater, if present + LLPanel *curtab = self->childGetVisibleTabWithHelp(); + if (curtab) + { + help_topic = curtab->getHelpTopic(); + } + + LLUI::sHelpImpl->showTopic(help_topic); } } @@ -2554,10 +2566,10 @@ void LLFloater::initFromParams(const LLFloater::Params& p) LLFastTimer::DeclareTimer POST_BUILD("Floater Post Build"); -void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) +bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node) { Params params(LLUICtrlFactory::getDefaultParams<LLFloater>()); - LLXUIParser::instance().readXUI(node, params); + LLXUIParser::instance().readXUI(node, params); // *TODO: Error checking if (output_node) { @@ -2603,5 +2615,7 @@ void LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr o gFloaterView->adjustToFitScreen(this, FALSE); // Floaters loaded from XML should all fit on screen moveResizeHandlesToFront(); + + return true; // *TODO: Error checking } diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 466d060068..cbe374252f 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -146,7 +146,7 @@ public: static void setupParamsForExport(Params& p, LLView* parent); void initFromParams(const LLFloater::Params& p); - void initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); + bool initFloaterXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node = NULL); /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false); /*virtual*/ BOOL canSnapTo(const LLView* other_view); diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp index 8617ba940e..8e56951dbf 100644 --- a/indra/llui/llfloaterreg.cpp +++ b/indra/llui/llfloaterreg.cpp @@ -124,8 +124,13 @@ LLFloater* LLFloaterReg::getInstance(const std::string& name, const LLSD& key) res = build_func(key); - LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL); - + bool success = LLUICtrlFactory::getInstance()->buildFloater(res, xui_file, NULL); + if (!success) + { + llwarns << "Failed to buid floater type: '" << name << "'." << llendl; + return NULL; + } + // Note: key should eventually be a non optional LLFloater arg; for now, set mKey to be safe res->mKey = key; res->setInstanceName(name); diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 693ea5bb45..e053477d58 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -148,6 +148,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mBgImage( p.background_image ), mBgImageDisabled( p.background_image_disabled ), mBgImageFocused( p.background_image_focused ), + mHaveHistory(FALSE), mReplaceNewlinesWithSpaces( TRUE ), mLabel(p.label), mCursorColor(p.cursor_color()), @@ -164,13 +165,8 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p) mTripleClickTimer.reset(); setText(p.default_text()); - // line history support: - // - initialize line history list - mLineHistory.insert( mLineHistory.end(), "" ); - // - disable line history by default - mHaveHistory = FALSE; - // - reset current history line pointer - mCurrentHistoryLine = 0; + // Initialize current history line iterator + mCurrentHistoryLine = mLineHistory.begin(); LLRect border_rect(getLocalRect()); // adjust for gl line drawing glitch @@ -278,16 +274,31 @@ void LLLineEditor::updateHistory() // reset current history line number. // Be sure only to remember lines that are not empty and that are // different from the last on the list. - if( mHaveHistory && mText.length() && ( mLineHistory.empty() || getText() != mLineHistory.back() ) ) + if( mHaveHistory && getLength() ) { - // discard possible empty line at the end of the history - // inserted by setText() - if( !mLineHistory.back().length() ) + if( !mLineHistory.empty() ) { - mLineHistory.pop_back(); + // When not empty, last line of history should always be blank. + if( mLineHistory.back().empty() ) + { + // discard the empty line + mLineHistory.pop_back(); + } + else + { + LL_WARNS("") << "Last line of history was not blank." << LL_ENDL; + } + } + + // Add text to history, ignoring duplicates + if( mLineHistory.empty() || getText() != mLineHistory.back() ) + { + mLineHistory.push_back( getText() ); } - mLineHistory.insert( mLineHistory.end(), getText() ); - mCurrentHistoryLine = mLineHistory.size() - 1; + + // Restore the blank line and set mCurrentHistoryLine to point at it + mLineHistory.push_back( "" ); + mCurrentHistoryLine = mLineHistory.end() - 1; } } @@ -357,11 +368,8 @@ void LLLineEditor::setText(const LLStringExplicit &new_text) } setCursor(llmin((S32)mText.length(), getCursor())); - // Newly set text goes always in the last line of history. - // Possible empty strings (as with chat line) will be deleted later. - mLineHistory.insert( mLineHistory.end(), new_text ); // Set current history line to end of history. - mCurrentHistoryLine = mLineHistory.size() - 1; + mCurrentHistoryLine = mLineHistory.end() - 1; mPrevText = mText; } @@ -1254,9 +1262,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) case KEY_UP: if( mHaveHistory && ( MASK_CONTROL == mask ) ) { - if( mCurrentHistoryLine > 0 ) + if( mCurrentHistoryLine > mLineHistory.begin() ) { - mText.assign( mLineHistory[ --mCurrentHistoryLine ] ); + mText.assign( *(--mCurrentHistoryLine) ); setCursor(llmin((S32)mText.length(), getCursor())); } else @@ -1271,9 +1279,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) case KEY_DOWN: if( mHaveHistory && ( MASK_CONTROL == mask ) ) { - if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.size() - 1 ) + if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.end() - 1 ) { - mText.assign( mLineHistory[ ++mCurrentHistoryLine ] ); + mText.assign( *(++mCurrentHistoryLine) ); setCursor(llmin((S32)mText.length(), getCursor())); } else @@ -2291,14 +2299,20 @@ BOOL LLLineEditor::hasPreeditString() const void LLLineEditor::resetPreedit() { - if (hasPreeditString()) + if (hasSelection()) { - if (hasSelection()) + if (hasPreeditString()) { llwarns << "Preedit and selection!" << llendl; deselect(); } - + else + { + deleteSelection(); + } + } + if (hasPreeditString()) + { const S32 preedit_pos = mPreeditPositions.front(); mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos); mText.insert(preedit_pos, mPreeditOverwrittenWString); @@ -2500,20 +2514,3 @@ LLWString LLLineEditor::getConvertedText() const } return text; } - -namespace LLInitParam -{ - template<> - bool ParamCompare<LLLinePrevalidateFunc>::equals(const LLLinePrevalidateFunc &a, const LLLinePrevalidateFunc &b) - { - return false; - } - - template<> - bool ParamCompare<boost::function<void (LLLineEditor *)> >::equals( - const boost::function<void (LLLineEditor *)> &a, - const boost::function<void (LLLineEditor *)> &b) - { - return false; - } -} diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 48d68b9935..3d7bbdff89 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -286,8 +286,9 @@ protected: // line history support: BOOL mHaveHistory; // flag for enabled line history - std::vector<std::string> mLineHistory; // line history storage - U32 mCurrentHistoryLine; // currently browsed history line + typedef std::vector<std::string> line_history_t; + line_history_t mLineHistory; // line history storage + line_history_t::iterator mCurrentHistoryLine; // currently browsed history line LLViewBorder* mBorder; const LLFontGL* mGLFont; @@ -390,15 +391,4 @@ private: }; // end class LLLineEditor -namespace LLInitParam -{ - template<> - bool ParamCompare<LLLinePrevalidateFunc>::equals( - const LLLinePrevalidateFunc &a, const LLLinePrevalidateFunc &b); - - template<> - bool ParamCompare<boost::function<void (LLLineEditor *)> >::equals( - const boost::function<void (LLLineEditor *)> &a, const boost::function<void (LLLineEditor *)> &b); -} - #endif // LL_LINEEDITOR_ diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 14bee0465c..cf013efca0 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -279,47 +279,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp) // the current accelerator key and mask to the provided string. void LLMenuItemGL::appendAcceleratorString( std::string& st ) const { - // break early if this is a silly thing to do. - if( KEY_NONE == mAcceleratorKey ) - { - return; - } - - // Append any masks -#ifdef LL_DARWIN - // Standard Mac names for modifier keys in menu equivalents - // We could use the symbol characters, but they only exist in certain fonts. - if( mAcceleratorMask & MASK_CONTROL ) - { - if ( mAcceleratorMask & MASK_MAC_CONTROL ) - { - st.append( "Ctrl-" ); - } - else - { - st.append( "Cmd-" ); // Symbol would be "\xE2\x8C\x98" - } - } - if( mAcceleratorMask & MASK_ALT ) - st.append( "Opt-" ); // Symbol would be "\xE2\x8C\xA5" - if( mAcceleratorMask & MASK_SHIFT ) - st.append( "Shift-" ); // Symbol would be "\xE2\x8C\xA7" -#else - if( mAcceleratorMask & MASK_CONTROL ) - st.append( "Ctrl-" ); - if( mAcceleratorMask & MASK_ALT ) - st.append( "Alt-" ); - if( mAcceleratorMask & MASK_SHIFT ) - st.append( "Shift-" ); -#endif - - std::string keystr = LLKeyboard::stringFromKey( mAcceleratorKey ); - if ((mAcceleratorMask & MASK_NORMALKEYS) && - (keystr[0] == '-' || keystr[0] == '=')) - { - st.append( " " ); - } - st.append( keystr ); + st = LLKeyboard::stringFromAccelerator( mAcceleratorMask, mAcceleratorKey ); LL_DEBUGS("HotKeys") << "appendAcceleratorString: " << st << LL_ENDL; } diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 69ff3dddc3..742427525b 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -810,6 +810,47 @@ LLPanel *LLPanel::childGetVisibleTab(const std::string& id) const return NULL; } +static LLPanel *childGetVisibleTabWithHelp(LLView *parent) +{ + LLView *child; + + // look through immediate children first for an active tab with help + for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) + { + LLTabContainer *tab = dynamic_cast<LLTabContainer *>(child); + if (tab && tab->getVisible()) + { + LLPanel *curTabPanel = tab->getCurrentPanel(); + if (curTabPanel && !curTabPanel->getHelpTopic().empty()) + { + return curTabPanel; + } + } + } + + // then try a bit harder and recurse through all children + for (child = parent->getFirstChild(); child; child = parent->findNextSibling(child)) + { + if (child->getVisible()) + { + LLPanel* tab = ::childGetVisibleTabWithHelp(child); + if (tab) + { + return tab; + } + } + } + + // couldn't find any active tabs with a help topic string + return NULL; +} + +LLPanel *LLPanel::childGetVisibleTabWithHelp() +{ + // find a visible tab with a help topic (to determine help context) + return ::childGetVisibleTabWithHelp(this); +} + void LLPanel::childSetPrevalidate(const std::string& id, BOOL (*func)(const LLWString &) ) { LLLineEditor* child = findChild<LLLineEditor>(id); diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index 0594762333..e8db68ffbb 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -208,6 +208,7 @@ public: // LLTabContainer void childShowTab(const std::string& id, const std::string& tabname, bool visible = true); LLPanel *childGetVisibleTab(const std::string& id) const; + LLPanel *childGetVisibleTabWithHelp(); // LLTextBox/LLTextEditor/LLLineEditor void childSetText(const std::string& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); } diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp index a4e23a605b..ed870d46d5 100644 --- a/indra/llui/llresmgr.cpp +++ b/indra/llui/llresmgr.cpp @@ -279,6 +279,14 @@ std::string LLResMgr::getMonetaryString( S32 input ) const void LLResMgr::getIntegerString( std::string& output, S32 input ) const { + // handle special case of input value being zero + if (input == 0) + { + output = "0"; + return; + } + + // *NOTE: this method does not handle negative input integers correctly S32 fraction = 0; std::string fraction_string; S32 remaining_count = input; diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index 7db34a0608..cb4147709d 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -640,15 +640,3 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data ) { changeLine( mStepSize, TRUE ); } - - -namespace LLInitParam -{ - template<> - bool ParamCompare<boost::function<void (S32, LLScrollbar*)> >::equals( - const boost::function<void (S32, LLScrollbar*)> &a, - const boost::function<void (S32, LLScrollbar*)> &b) - { - return false; - } -} diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index e4c5712fb7..2e95779624 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -167,11 +167,4 @@ private: }; -namespace LLInitParam -{ - template<> - bool ParamCompare<boost::function<void (S32, LLScrollbar*)> >::equals( - const boost::function<void (S32, LLScrollbar*)> &a, const boost::function<void (S32, LLScrollbar*)> &b); -} - #endif // LL_SCROLLBAR_H diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 7b74b1f93b..a6cd6412e5 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1411,6 +1411,7 @@ void LLScrollListCtrl::drawItems() cur_y, mItemListRect.getWidth(), mLineHeight ); + item->setRect(item_rect); //llinfos << item_rect.getWidth() << llendl; @@ -1708,7 +1709,7 @@ BOOL LLScrollListCtrl::handleMouseDown(S32 x, S32 y, MASK mask) } BOOL LLScrollListCtrl::handleMouseUp(S32 x, S32 y, MASK mask) -{ +{ if (hasMouseCapture()) { // release mouse capture immediately so diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h index 0ec7fbcc2c..15b86cc945 100644 --- a/indra/llui/llscrolllistitem.h +++ b/indra/llui/llscrolllistitem.h @@ -97,6 +97,9 @@ public: LLUUID getUUID() const { return mItemValue.asUUID(); } LLSD getValue() const { return mItemValue; } + + void setRect(LLRect rect) { mRectangle = rect; } + LLRect getRect() const { return mRectangle; } void addColumn( const LLScrollListCell::Params& p ); @@ -122,6 +125,7 @@ private: void* mUserdata; LLSD mItemValue; std::vector<LLScrollListCell *> mColumns; + LLRect mRectangle; }; #endif diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp index b87f645f3f..fad2b7bc99 100644 --- a/indra/llui/llsearcheditor.cpp +++ b/indra/llui/llsearcheditor.cpp @@ -37,9 +37,9 @@ #include "llsearcheditor.h" LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p) -: LLUICtrl(p) - , mSearchButton(NULL) - , mClearButton(NULL) +: LLUICtrl(p), + mSearchButton(NULL), + mClearButton(NULL) { S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height; S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index b1067ad6f3..3ca05ff0ff 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -107,9 +107,10 @@ static LLDefaultChildRegistry::Register<LLTabContainer> r2("tab_container"); LLTabContainer::Params::Params() : tab_width("tab_width"), - tab_position("tab_position"), tab_min_width("tab_min_width"), tab_max_width("tab_max_width"), + tab_height("tab_height"), + tab_position("tab_position"), hide_tabs("hide_tabs", false), tab_padding_right("tab_padding_right"), tab_top_image_unselected("tab_top_image_unselected"), @@ -136,6 +137,7 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) mLockedTabCount(0), mMinTabWidth(0), mMaxTabWidth(p.tab_max_width), + mTabHeight(p.tab_height), mPrevArrowBtn(NULL), mNextArrowBtn(NULL), mIsVertical( p.tab_position == LEFT ), @@ -802,7 +804,6 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel) static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); static LLUICachedControl<S32> tabcntr_button_panel_overlap ("UITabCntrButtonPanelOverlap", 0); - static LLUICachedControl<S32> tabcntr_tab_height ("UITabCntrTabHeight", 0); static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); if (child->getParent() == this) { @@ -830,14 +831,14 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel) { if( getTabPosition() == LLTabContainer::TOP ) { - S32 tab_height = mIsVertical ? BTN_HEIGHT : tabcntr_tab_height; + S32 tab_height = mIsVertical ? BTN_HEIGHT : mTabHeight; tab_panel_top = getRect().getHeight() - getTopBorderHeight() - (tab_height - tabcntr_button_panel_overlap); tab_panel_bottom = LLPANEL_BORDER_WIDTH; } else { tab_panel_top = getRect().getHeight() - getTopBorderHeight(); - tab_panel_bottom = (tabcntr_tab_height - tabcntr_button_panel_overlap); // Run to the edge, covering up the border + tab_panel_bottom = (mTabHeight - tabcntr_button_panel_overlap); // Run to the edge, covering up the border } } else @@ -886,13 +887,13 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel) } else if( getTabPosition() == LLTabContainer::TOP ) { - btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, tabcntr_tab_height ); + btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, mTabHeight); tab_img = mImageTopUnselected.get(); tab_selected_img = mImageTopSelected.get(); } else { - btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, tabcntr_tab_height ); + btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, mTabHeight); tab_img = mImageBottomUnselected.get(); tab_selected_img = mImageBottomSelected.get(); } diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 7bbecc1abc..e3af5384b1 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -67,7 +67,9 @@ public: Optional<TabPosition, TabPositions> tab_position; Optional<S32> tab_width, tab_min_width, - tab_max_width; + tab_max_width, + tab_height; + Optional<bool> hide_tabs; Optional<S32> tab_padding_right; @@ -246,6 +248,7 @@ private: S32 mMaxTabWidth; S32 mTotalTabWidth; + S32 mTabHeight; LLFrameTimer mDragAndDropDelayTimer; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 3dacf979c7..3c5213a0b3 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -124,17 +124,6 @@ struct LLTextBase::line_end_compare ////////////////////////////////////////////////////////////////////////// // -// LLTextBase::DocumentPanel -// - - -LLTextBase::DocumentPanel::DocumentPanel(const Params& p) -: LLPanel(p) -{} - - -////////////////////////////////////////////////////////////////////////// -// // LLTextBase // @@ -157,8 +146,7 @@ LLTextBase::Params::Params() bg_readonly_color("bg_readonly_color"), bg_writeable_color("bg_writeable_color"), bg_focus_color("bg_focus_color"), - hide_scrollbar("hide_scrollbar"), - clip_to_rect("clip_to_rect", true), + allow_scroll("allow_scroll", true), track_end("track_end", false), read_only("read_only", false), v_pad("v_pad", 0), @@ -205,35 +193,42 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mSelectionStart( 0 ), mSelectionEnd( 0 ), mIsSelecting( FALSE ), - mClip(p.clip_to_rect), mWordWrap(p.wrap), mUseEllipses( p.use_ellipses ), mParseHTML(p.allow_html), mParseHighlights(p.parse_highlights), - mHideScrollbar(p.hide_scrollbar) -{ - LLScrollContainer::Params scroll_params; - scroll_params.name = "text scroller"; - scroll_params.rect = getLocalRect(); - scroll_params.follows.flags = FOLLOWS_ALL; - scroll_params.is_opaque = false; - scroll_params.mouse_opaque = false; - scroll_params.min_auto_scroll_rate = 200; - scroll_params.max_auto_scroll_rate = 800; - scroll_params.hide_scrollbar = p.hide_scrollbar; - scroll_params.border_visible = p.border_visible; - mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params); - addChild(mScroller); - - LLPanel::Params panel_params; - panel_params.name = "text_contents"; - panel_params.rect = LLRect(0, 500, 500, 0); - panel_params.background_visible = p.bg_visible; - panel_params.background_opaque = true; - panel_params.mouse_opaque = false; - - mDocumentPanel = LLUICtrlFactory::create<DocumentPanel>(panel_params); - mScroller->addChild(mDocumentPanel); + mBGVisible(p.bg_visible), + mScroller(NULL) +{ + if(p.allow_scroll) + { + LLScrollContainer::Params scroll_params; + scroll_params.name = "text scroller"; + scroll_params.rect = getLocalRect(); + scroll_params.follows.flags = FOLLOWS_ALL; + scroll_params.is_opaque = false; + scroll_params.mouse_opaque = false; + scroll_params.min_auto_scroll_rate = 200; + scroll_params.max_auto_scroll_rate = 800; + scroll_params.border_visible = p.border_visible; + mScroller = LLUICtrlFactory::create<LLScrollContainer>(scroll_params); + addChild(mScroller); + } + + LLView::Params view_params; + view_params.name = "text_contents"; + view_params.rect = LLRect(0, 500, 500, 0); + view_params.mouse_opaque = false; + + mDocumentView = LLUICtrlFactory::create<LLView>(view_params); + if (mScroller) + { + mScroller->addChild(mDocumentView); + } + else + { + addChild(mDocumentView); + } createDefaultSegment(); @@ -314,7 +309,7 @@ void LLTextBase::drawSelectionBackground() LLRect selection_rect = mTextRect; // Skip through the lines we aren't drawing. - LLRect content_display_rect = mScroller->getVisibleContentRect(); + LLRect content_display_rect = getVisibleDocumentRect(); // binary search for line that starts before top of visible buffer line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); @@ -418,6 +413,9 @@ void LLTextBase::drawCursor() return; } + if (!mTextRect.contains(cursor_rect)) + return; + // Draw the cursor // (Flash the cursor every half second starting a fixed time after the last keystroke) F32 elapsed = mCursorBlinkTimer.getElapsedTimeF32(); @@ -496,8 +494,7 @@ void LLTextBase::drawText() selection_right = llmax( mSelectionStart, mSelectionEnd ); } - LLRect scrolled_view_rect = mScroller->getVisibleContentRect(); - LLRect content_rect = mScroller->getContentWindowRect(); + LLRect scrolled_view_rect = getVisibleDocumentRect(); std::pair<S32, S32> line_range = getVisibleLines(); S32 first_line = line_range.first; S32 last_line = line_range.second; @@ -540,7 +537,7 @@ void LLTextBase::drawText() LLRect text_rect(line.mRect.mLeft + mTextRect.mLeft - scrolled_view_rect.mLeft, line.mRect.mTop - scrolled_view_rect.mBottom + mTextRect.mBottom, - mDocumentPanel->getRect().getWidth() - scrolled_view_rect.mLeft, + mDocumentView->getRect().getWidth() - scrolled_view_rect.mLeft, line.mRect.mBottom - scrolled_view_rect.mBottom + mTextRect.mBottom); // draw a single line of text @@ -645,6 +642,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s } onValueChange(pos, pos + insert_len); + needsReflow(); return insert_len; } @@ -704,6 +702,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length) createDefaultSegment(); onValueChange(pos, pos); + needsReflow(); return -length; // This will be wrong if someone calls removeStringNoUndo with an excessive length } @@ -719,6 +718,7 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc) getViewModel()->setDisplay(text); onValueChange(pos, pos + 1); + needsReflow(); return 1; } @@ -949,29 +949,31 @@ void LLTextBase::draw() // then update scroll position, as cursor may have moved updateScrollFromCursor(); - LLColor4 bg_color = mReadOnly - ? mReadOnlyBgColor.get() - : hasFocus() - ? mFocusBgColor.get() - : mWriteableBgColor.get(); + if (mBGVisible) + { + // clip background rect against extents, if we support scrolling + LLLocalClipRect clip(getLocalRect(), mScroller != NULL); - mDocumentPanel->setBackgroundColor(bg_color); + LLColor4 bg_color = mReadOnly + ? mReadOnlyBgColor.get() + : hasFocus() + ? mFocusBgColor.get() + : mWriteableBgColor.get(); + gl_rect_2d(mDocumentView->getRect(), bg_color, TRUE); + } + // draw document view LLUICtrl::draw(); + { - LLLocalClipRect clip(mTextRect, mClip); + // only clip if we support scrolling (mScroller != NULL) + LLLocalClipRect clip(mTextRect, mScroller != NULL); drawSelectionBackground(); drawText(); drawCursor(); } } -//virtual -void LLTextBase::clear() -{ - getViewModel()->setDisplay(LLWStringUtil::null); - clearSegments(); -} //virtual void LLTextBase::setColor( const LLColor4& c ) @@ -1000,14 +1002,14 @@ void LLTextBase::updateScrollFromCursor() // Update scroll position even in read-only mode (when there's no cursor displayed) // because startOfDoc()/endOfDoc() modify cursor position. See EXT-736. - if (!mScrollNeeded) + if (!mScrollNeeded || !mScroller) { return; } mScrollNeeded = FALSE; // scroll so that the cursor is at the top of the page - LLRect scroller_doc_window = mScroller->getVisibleContentRect(); + LLRect scroller_doc_window = getVisibleDocumentRect(); LLRect cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos); cursor_rect_doc.translate(scroller_doc_window.mLeft, scroller_doc_window.mBottom); mScroller->scrollToShowRect(cursor_rect_doc, LLRect(0, scroller_doc_window.getHeight() - 5, scroller_doc_window.getWidth(), 5)); @@ -1042,7 +1044,7 @@ void LLTextBase::reflow(S32 start_index) { mReflowNeeded = FALSE; - bool scrolled_to_bottom = mScroller->isAtBottom(); + bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false; LLRect old_cursor_rect = getLocalRectFromDocIndex(mCursorPos); bool follow_selection = mTextRect.overlaps(old_cursor_rect); // cursor is visible @@ -1104,12 +1106,17 @@ void LLTextBase::reflow(S32 start_index) S32 segment_width = segment->getWidth(seg_offset, character_count); remaining_pixels -= segment_width; - S32 text_left = getLeftOffset(text_width - remaining_pixels); seg_offset += character_count; S32 last_segment_char_on_line = segment->getStart() + seg_offset; + S32 text_left = getLeftOffset(text_width - remaining_pixels); + LLRect line_rect(text_left, + cur_top, + text_left + (text_width - remaining_pixels), + cur_top - line_height); + // if we didn't finish the current segment... if (last_segment_char_on_line < segment->getEnd()) { @@ -1127,10 +1134,7 @@ void LLTextBase::reflow(S32 start_index) mLineInfoList.push_back(line_info( line_start_index, last_segment_char_on_line, - LLRect(text_left, - cur_top, - text_left + (text_width - remaining_pixels), - cur_top - line_height), + line_rect, line_count)); line_start_index = segment->getStart() + seg_offset; @@ -1145,15 +1149,12 @@ void LLTextBase::reflow(S32 start_index) mLineInfoList.push_back(line_info( line_start_index, last_segment_char_on_line, - LLRect(text_left, - cur_top, - text_left + (text_width - remaining_pixels), - cur_top - line_height), + line_rect, line_count)); cur_top -= llround((F32)line_height * mLineSpacingMult) + mLineSpacingPixels; break; } - // finished a segment and there are segments remaining on this line + // ...or finished a segment and there are segments remaining on this line else { // subtract pixels used and increment segment @@ -1183,17 +1184,29 @@ void LLTextBase::reflow(S32 start_index) mContentsRect.stretch(1); } - // change mDocumentPanel document size to accomodate reflowed text + // change mDocumentView size to accomodate reflowed text LLRect document_rect; - document_rect.setOriginAndSize(1, 1, - mScroller->getContentWindowRect().getWidth(), - llmax(mScroller->getContentWindowRect().getHeight(), mContentsRect.getHeight())); - mDocumentPanel->setShape(document_rect); + if (mScroller) + { + // document is size of scroller or size of text contents, whichever is larger + document_rect.setOriginAndSize(0, 0, + mScroller->getContentWindowRect().getWidth(), + llmax(mScroller->getContentWindowRect().getHeight(), mContentsRect.getHeight())); + } + else + { + // document size is just extents of reflowed text, reset to origin 0,0 + document_rect.set(0, + getLocalRect().getHeight(), + getLocalRect().getWidth(), + llmin(0, getLocalRect().getHeight() - mContentsRect.getHeight())); + } + mDocumentView->setShape(document_rect); // after making document big enough to hold all the text, move the text to fit in the document if (!mLineInfoList.empty()) { - S32 delta_pos = mDocumentPanel->getRect().getHeight() - mLineInfoList.begin()->mRect.mTop - mVPad; + S32 delta_pos = mDocumentView->getRect().getHeight() - mLineInfoList.begin()->mRect.mTop - mVPad; // move line segments to fit new document rect for (line_list_t::iterator it = mLineInfoList.begin(); it != mLineInfoList.end(); ++it) { @@ -1215,9 +1228,9 @@ void LLTextBase::reflow(S32 start_index) } // apply scroll constraints after reflowing text - if (!hasMouseCapture()) + if (!hasMouseCapture() && mScroller) { - LLRect visible_content_rect = mScroller->getVisibleContentRect(); + LLRect visible_content_rect = getVisibleDocumentRect(); if (scrolled_to_bottom && mTrackEnd) { // keep bottom of text buffer visible @@ -1329,7 +1342,7 @@ S32 LLTextBase::getLineOffsetFromDocIndex( S32 startpos, bool include_wordwrap) S32 LLTextBase::getFirstVisibleLine() const { - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); // binary search for line that starts before top of visible buffer line_list_t::const_iterator iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), visible_region.mTop, compare_bottom()); @@ -1339,7 +1352,7 @@ S32 LLTextBase::getFirstVisibleLine() const std::pair<S32, S32> LLTextBase::getVisibleLines(bool fully_visible) { - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); line_list_t::const_iterator first_iter; line_list_t::const_iterator last_iter; @@ -1370,12 +1383,12 @@ LLTextViewModel* LLTextBase::getViewModel() const void LLTextBase::addDocumentChild(LLView* view) { - mDocumentPanel->addChild(view); + mDocumentView->addChild(view); } void LLTextBase::removeDocumentChild(LLView* view) { - mDocumentPanel->removeChild(view); + mDocumentView->removeChild(view); } @@ -1481,11 +1494,10 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url) void LLTextBase::setText(const LLStringExplicit &utf8str) { // clear out the existing text and segments - clear(); - - truncate(); + getViewModel()->setDisplay(LLWStringUtil::null); - createDefaultSegment(); + clearSegments(); +// createDefaultSegment(); startOfDoc(); deselect(); @@ -1496,10 +1508,9 @@ void LLTextBase::setText(const LLStringExplicit &utf8str) appendText(text, false); - needsReflow(); - //resetDirty(); onValueChange(0, getLength()); + needsReflow(); } //virtual @@ -1767,7 +1778,7 @@ LLWString LLTextBase::getWText() const S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const { // Figure out which line we're nearest to. - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); // binary search for line that starts before local_y line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mTextRect.mBottom + visible_region.mBottom, compare_bottom()); @@ -1838,7 +1849,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const // find line that contains cursor line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); - LLRect scrolled_view_rect = mScroller->getVisibleContentRect(); + LLRect scrolled_view_rect = getVisibleDocumentRect(); local_rect.mLeft = mTextRect.mLeft - scrolled_view_rect.mLeft + line_iter->mRect.mLeft; local_rect.mBottom = mTextRect.mBottom + (line_iter->mRect.mBottom - scrolled_view_rect.mBottom); local_rect.mTop = mTextRect.mBottom + (line_iter->mRect.mTop - scrolled_view_rect.mBottom); @@ -1917,7 +1928,7 @@ void LLTextBase::endOfDoc() void LLTextBase::changePage( S32 delta ) { const S32 PIXEL_OVERLAP_ON_PAGE_CHANGE = 10; - if (delta == 0) return; + if (delta == 0 || !mScroller) return; LLRect cursor_rect = getLocalRectFromDocIndex(mCursorPos); @@ -1970,7 +1981,7 @@ void LLTextBase::changeLine( S32 delta ) new_line = line + 1; } - LLRect visible_region = mScroller->getVisibleContentRect(); + LLRect visible_region = getVisibleDocumentRect(); S32 new_cursor_pos = getDocIndexFromLocalCoord(mDesiredXPixel, mLineInfoList[new_line].mRect.mBottom + mTextRect.mBottom - visible_region.mBottom, TRUE); setCursorPos(new_cursor_pos, true); @@ -2047,7 +2058,7 @@ S32 LLTextBase::getEditableIndex(S32 index, bool increasing_direction) void LLTextBase::updateTextRect() { LLRect old_text_rect = mTextRect; - mTextRect = mScroller->getContentWindowRect(); + mTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect(); //FIXME: replace border with image? if (mBorderVisible) { @@ -2081,6 +2092,22 @@ void LLTextBase::endSelection() } } +// get portion of document that is visible in text editor +LLRect LLTextBase::getVisibleDocumentRect() const +{ + if (mScroller) + { + return mScroller->getVisibleContentRect(); + } + else + { + // entire document rect when not scrolling + LLRect doc_rect = mDocumentView->getLocalRect(); + doc_rect.translate(-mDocumentView->getRect().mLeft, -mDocumentView->getRect().mBottom); + return doc_rect; + } +} + // // LLTextSegment // @@ -2150,6 +2177,7 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec { if ( mStyle->isImage() && (start >= 0) && (end <= mEnd - mStart)) { + LLColor4 color = LLColor4::white % mEditor.getDrawContext().mAlpha; LLUIImagePtr image = mStyle->getImage(); S32 style_image_height = image->getHeight(); S32 style_image_width = image->getWidth(); @@ -2398,7 +2426,7 @@ S32 LLInlineViewSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin void LLInlineViewSegment::updateLayout(const LLTextBase& editor) { LLRect start_rect = editor.getLocalRectFromDocIndex(mStart); - LLRect doc_rect = editor.getDocumentPanel()->getRect(); + LLRect doc_rect = editor.getDocumentView()->getRect(); mView->setOrigin(doc_rect.mLeft + start_rect.mLeft, doc_rect.mBottom + start_rect.mBottom); } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index f20134fd6d..903396c78a 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -80,8 +80,7 @@ public: border_visible, track_end, read_only, - hide_scrollbar, - clip_to_rect, + allow_scroll, wrap, use_ellipses, allow_html, @@ -118,7 +117,6 @@ public: // LLUICtrl interface /*virtual*/ BOOL acceptsTextInput() const { return !mReadOnly; } - /*virtual*/ void clear(); /*virtual*/ void setColor( const LLColor4& c ); /*virtual*/ void setValue(const LLSD& value ); /*virtual*/ LLTextViewModel* getViewModel() const; @@ -149,16 +147,13 @@ public: S32 getLength() const { return getWText().length(); } S32 getLineCount() const { return mLineInfoList.size(); } - class DocumentPanel : public LLPanel - { - public: - DocumentPanel(const Params&); - }; void addDocumentChild(LLView* view); void removeDocumentChild(LLView* view); - const DocumentPanel* getDocumentPanel() const { return mDocumentPanel; } + const LLView* getDocumentView() const { return mDocumentView; } LLRect getTextRect() { return mTextRect; } LLRect getContentsRect(); + LLRect getVisibleDocumentRect() const; + S32 getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round ) const; LLRect getLocalRectFromDocIndex(S32 pos) const; @@ -344,13 +339,12 @@ protected: bool mUseEllipses; bool mTrackEnd; // if true, keeps scroll position at end of document during resize bool mReadOnly; - bool mClip; - bool mHideScrollbar; + bool mBGVisible; // render background? S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes // support widgets LLContextMenu* mPopupMenu; - DocumentPanel* mDocumentPanel; + LLView* mDocumentView; class LLScrollContainer* mScroller; // transient state diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 997c5b8fa8..74ffad0f53 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -990,7 +990,7 @@ void LLTextEditor::removeChar() // Add a single character to the text S32 LLTextEditor::addChar(S32 pos, llwchar wc) { - if ( (wstring_utf8_length( getWText() ) + wchar_utf8_length( wc )) >= mMaxTextByteLength) + if ( (wstring_utf8_length( getWText() ) + wchar_utf8_length( wc )) > mMaxTextByteLength) { make_ui_sound("UISndBadKeystroke"); return 0; @@ -2916,3 +2916,10 @@ void LLTextEditor::onKeyStroke() { mKeystrokeSignal(this); } + +//virtual +void LLTextEditor::clear() +{ + getViewModel()->setDisplay(LLWStringUtil::null); + clearSegments(); +} diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 0e5707a3a6..e232efbfb3 100644 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -116,6 +116,7 @@ public: virtual void setEnabled(BOOL enabled); // uictrl overrides + virtual void clear(); virtual void setFocus( BOOL b ); virtual BOOL isDirty() const; diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index c55273cacf..f30e56b907 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -147,6 +147,7 @@ static LLDefaultChildRegistry::Register<LLToolTip> r("tool_tip"); LLToolTip::Params::Params() : max_width("max_width", 200), padding("padding", 4), + wrap("wrap", true), pos("pos"), message("message"), delay_time("delay_time", LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" )), @@ -181,6 +182,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p) params.bg_visible = false; params.font = p.font; params.use_ellipses = true; + params.wrap = p.wrap; mTextBox = LLUICtrlFactory::create<LLTextBox> (params); addChild(mTextBox); diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index 6715da1611..63e7249a12 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -83,6 +83,7 @@ public: Optional<LLUIImage*> image; Optional<S32> max_width; Optional<S32> padding; + Optional<bool> wrap; Params(); }; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index c89e5944fa..f253857851 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1556,6 +1556,9 @@ void LLUI::initClass(const settings_map_t& settings, // Button initialization callback for toggle buttons LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2)); + // Button initialization callback for toggle buttons on dockale floaters + LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetDockableFloaterToggle", boost::bind(&LLButton::setDockableFloaterToggle, _1, _2)); + // Display the help topic for the current context LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2)); @@ -1915,16 +1918,11 @@ namespace LLInitParam declare("blue", LLColor4::blue); } - template<> - class ParamCompare<const LLFontGL*> + bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) { - public: - static bool equals(const LLFontGL* a, const LLFontGL* b) - { - return !(a->getFontDesc() < b->getFontDesc()) - && !(b->getFontDesc() < a->getFontDesc()); - } - }; + return !(a->getFontDesc() < b->getFontDesc()) + && !(b->getFontDesc() < a->getFontDesc()); + } TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) : super_t(descriptor, _name, value, func, min_count, max_count), diff --git a/indra/llui/llui.h b/indra/llui/llui.h index f071e8dc47..6ab78ab3cd 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -437,6 +437,13 @@ namespace LLInitParam }; template<> + struct ParamCompare<const LLFontGL*, false> + { + static bool equals(const LLFontGL* a, const LLFontGL* b); + }; + + + template<> class TypedParam<LLCoordGL> : public BlockValue<LLCoordGL> { diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 5b72f87a78..0faff5eff6 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -795,16 +795,29 @@ bool LLUICtrl::findHelpTopic(std::string& help_topic_out) LLUICtrl* ctrl = this; // search back through the control's parents for a panel - // with a help_topic string defined + // or tab with a help_topic string defined while (ctrl) { LLPanel *panel = dynamic_cast<LLPanel *>(ctrl); - if (panel && !panel->getHelpTopic().empty()) + + if (panel) { - help_topic_out = panel->getHelpTopic(); - return true; // success + // does the panel have an active tab with a help topic? + LLPanel *tab = panel->childGetVisibleTabWithHelp(); + if (tab) + { + help_topic_out = tab->getHelpTopic(); + return true; // success (tab) + } + + // otherwise, does the panel have a help topic itself? + if (!panel->getHelpTopic().empty()) + { + help_topic_out = panel->getHelpTopic(); + return true; // success (panel) + } } - + ctrl = ctrl->getParentUICtrl(); } @@ -836,24 +849,3 @@ BOOL LLUICtrl::getTentative() const // virtual void LLUICtrl::setColor(const LLColor4& color) { } - - -namespace LLInitParam -{ - template<> - bool ParamCompare<LLUICtrl::commit_callback_t>::equals( - const LLUICtrl::commit_callback_t &a, - const LLUICtrl::commit_callback_t &b) - { - return false; - } - - - template<> - bool ParamCompare<LLUICtrl::enable_callback_t>::equals( - const LLUICtrl::enable_callback_t &a, - const LLUICtrl::enable_callback_t &b) - { - return false; - } -} diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 69207eb8ea..45fe47772b 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -228,7 +228,11 @@ public: // Default to no-op: virtual void onTabInto(); + + // Clear any user-provided input (text in a text editor, checked checkbox, + // selected radio button, etc.). Defaults to no-op. virtual void clear(); + virtual void setColor(const LLColor4& color); BOOL focusNextItem(BOOL text_entry_only); @@ -323,21 +327,4 @@ private: class DefaultTabGroupFirstSorter; }; -namespace LLInitParam -{ - template<> - bool ParamCompare<LLUICtrl::commit_callback_t>::equals( - const LLUICtrl::commit_callback_t &a, - const LLUICtrl::commit_callback_t &b); - - template<> - bool ParamCompare<LLUICtrl::enable_callback_t>::equals( - const LLUICtrl::enable_callback_t &a, - const LLUICtrl::enable_callback_t &b); - - template<> - bool ParamCompare<LLLazyValue<LLColor4> >::equals( - const LLLazyValue<LLColor4> &a, const LLLazyValue<LLColor4> &b); -} - #endif // LL_LLUICTRL_H diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 4ce6677294..209ee76940 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -170,7 +170,7 @@ static LLFastTimer::DeclareTimer FTM_BUILD_FLOATERS("Build Floaters"); //----------------------------------------------------------------------------- // buildFloater() //----------------------------------------------------------------------------- -void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node) +bool LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filename, LLXMLNodePtr output_node) { LLFastTimer timer(FTM_BUILD_FLOATERS); LLXMLNodePtr root; @@ -182,22 +182,24 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen if (!LLUICtrlFactory::getLocalizedXMLNode(filename, root)) { llwarns << "Couldn't parse floater from: " << LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return; + return false; } } else if (!LLUICtrlFactory::getLayeredXMLNode(filename, root)) { llwarns << "Couldn't parse floater from: " << LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + filename << llendl; - return; + return false; } // root must be called floater if( !(root->hasName("floater") || root->hasName("multi_floater")) ) { llwarns << "Root node should be named floater in: " << filename << llendl; - return; + return false; } - + + bool res = true; + lldebugs << "Building floater " << filename << llendl; mFileNames.push_back(gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), filename)); { @@ -210,7 +212,7 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen floaterp->getCommitCallbackRegistrar().pushScope(); floaterp->getEnableCallbackRegistrar().pushScope(); - floaterp->initFloaterXML(root, floaterp->getParent(), output_node); + res = floaterp->initFloaterXML(root, floaterp->getParent(), output_node); floaterp->setXMLFilename(filename); @@ -223,6 +225,8 @@ void LLUICtrlFactory::buildFloater(LLFloater* floaterp, const std::string& filen } } mFileNames.pop_back(); + + return res; } //----------------------------------------------------------------------------- diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 3c77c655b8..5e6dad312c 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -157,7 +157,7 @@ public: return ParamDefaults<typename T::Params, 0>::instance().get(); } - void buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node); + bool buildFloater(LLFloater* floaterp, const std::string &filename, LLXMLNodePtr output_node); BOOL buildPanel(LLPanel* panelp, const std::string &filename, LLXMLNodePtr output_node = NULL); // Does what you want for LLFloaters and LLPanels diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index ab0d65e731..6c1a32722f 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -152,8 +152,7 @@ namespace LLInitParam } - template<> - bool ParamCompare<LLUIImage*>::equals( + bool ParamCompare<LLUIImage*, false>::equals( LLUIImage* const &a, LLUIImage* const &b) { diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index 4ec24e98dc..9d734bcfdf 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -108,8 +108,10 @@ namespace LLInitParam // Need custom comparison function for our test app, which only loads // LLUIImage* as NULL. template<> - bool ParamCompare<LLUIImage*>::equals( - LLUIImage* const &a, LLUIImage* const &b); + struct ParamCompare<LLUIImage*, false> + { + static bool equals(LLUIImage* const &a, LLUIImage* const &b); + }; } typedef LLPointer<LLUIImage> LLUIImagePtr; diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h index aedeca27cb..195f21a6a7 100644 --- a/indra/llui/lluistring.h +++ b/indra/llui/lluistring.h @@ -51,9 +51,9 @@ // llinfos << mMessage.getString() << llendl; // outputs "Welcome Steve to Second Life" // mMessage.setArg("[USERNAME]", "Joe"); // llinfos << mMessage.getString() << llendl; // outputs "Welcome Joe to Second Life" -// mMessage = "Recepcin a la [SECONDLIFE] [USERNAME]" +// mMessage = "Bienvenido a la [SECONDLIFE] [USERNAME]" // mMessage.setArg("[SECONDLIFE]", "Segunda Vida"); -// llinfos << mMessage.getString() << llendl; // outputs "Recepcin a la Segunda Vida Joe" +// llinfos << mMessage.getString() << llendl; // outputs "Bienvenido a la Segunda Vida Joe" // Implementation Notes: // Attempting to have operator[](const std::string& s) return mArgs[s] fails because we have diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 1df8838738..7db6eab9ad 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -57,14 +57,13 @@ #include "lltexteditor.h" #include "lltextbox.h" -BOOL LLView::sDebugRects = FALSE; -BOOL LLView::sDebugKeys = FALSE; S32 LLView::sDepth = 0; -BOOL LLView::sDebugMouseHandling = FALSE; +bool LLView::sDebugRects = false; +bool LLView::sDebugRectsShowNames = true; +bool LLView::sDebugKeys = false; +bool LLView::sDebugMouseHandling = false; std::string LLView::sMouseHandlerMessage; -//BOOL LLView::sEditingUI = FALSE; BOOL LLView::sForceReshape = FALSE; -//LLView* LLView::sEditingUIView = NULL; std::set<LLView*> LLView::sPreviewHighlightedElements; BOOL LLView::sHighlightingDiffs = FALSE; LLView* LLView::sPreviewClickedElement = NULL; @@ -1353,7 +1352,7 @@ void LLView::drawDebugRect() LLRect debug_rect = mUseBoundingRect ? mBoundingRect : mRect; // draw red rectangle for the border - LLColor4 border_color(0.f, 0.f, 0.f, 1.f); + LLColor4 border_color(0.25f, 0.25f, 0.25f, 1.f); if(preview_iter != sPreviewHighlightedElements.end()) { if(LLView::sPreviewClickedElement && this == sPreviewClickedElement) @@ -1388,7 +1387,9 @@ void LLView::drawDebugRect() gGL.end(); // Draw the name if it's not a leaf node or not in editing or preview mode - if (mChildList.size() && preview_iter == sPreviewHighlightedElements.end()) + if (mChildList.size() + && preview_iter == sPreviewHighlightedElements.end() + && sDebugRectsShowNames) { //char temp[256]; S32 x, y; diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 7ddff2bd9e..5e35068733 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -586,14 +586,20 @@ private: default_widget_map_t& getDefaultWidgetMap() const; public: - static BOOL sDebugRects; // Draw debug rects behind everything. - static BOOL sDebugKeys; + // Depth in view hierarchy during rendering static S32 sDepth; - static BOOL sDebugMouseHandling; + + // Draw debug rectangles around widgets to help with alignment and spacing + static bool sDebugRects; + + // Draw widget names and sizes when drawing debug rectangles, turning this + // off is useful to make the rectangles themselves easier to see. + static bool sDebugRectsShowNames; + + static bool sDebugKeys; + static bool sDebugMouseHandling; static std::string sMouseHandlerMessage; static S32 sSelectID; -// static BOOL sEditingUI; -// static LLView* sEditingUIView; static std::set<LLView*> sPreviewHighlightedElements; // DEV-16869 static BOOL sHighlightingDiffs; // DEV-16869 static LLView* sPreviewClickedElement; // DEV-16869 diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index cc0297e3dc..05c7c7860c 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -23,6 +23,7 @@ set(llvfs_HEADER_FILES CMakeLists.txt lldir.h + lldirguard.h lllfsthread.h llpidlock.h llvfile.h @@ -64,3 +65,17 @@ if (DARWIN) find_library(CARBON_LIBRARY Carbon) target_link_libraries(llvfs ${CARBON_LIBRARY}) endif (DARWIN) + + +# Add tests +include(LLAddBuildTest) +# UNIT TESTS +SET(llvfs_TEST_SOURCE_FILES + # none so far + ) +LL_ADD_PROJECT_UNIT_TESTS(llvfs "${llvfs_TEST_SOURCE_FILES}") + +# INTEGRATION TESTS +set(test_libs llmath llcommon llvfs ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) +# TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests. +LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}") diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 745e53c980..781321e5e4 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -404,6 +404,12 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd prefix = getExecutableDir(); break; + case LL_PATH_FONTS: + prefix = getAppRODataDir(); + prefix += mDirDelimiter; + prefix += "fonts"; + break; + default: llassert(0); } @@ -419,6 +425,11 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd filename = subdir1 + mDirDelimiter + filename; } + if (prefix.empty()) + { + llwarns << "prefix is empty, possible bad filename" << llendl; + } + std::string expanded_filename; if (!filename.empty()) { @@ -673,11 +684,6 @@ void LLDir::dumpCurrentDirectories() LL_DEBUGS2("AppInit","Directories") << " CAFile: " << getCAFile() << LL_ENDL; LL_DEBUGS2("AppInit","Directories") << " SkinBaseDir: " << getSkinBaseDir() << LL_ENDL; LL_DEBUGS2("AppInit","Directories") << " SkinDir: " << getSkinDir() << LL_ENDL; - -#if LL_LIBXUL_ENABLED - LL_DEBUGS2("AppInit","Directories") << " HTML Path: " << getExpandedFilename( LL_PATH_HTML, "" ) << llendl; - LL_DEBUGS2("AppInit","Directories") << " Mozilla Profile Path: " << getExpandedFilename( LL_PATH_MOZILLA_PROFILE, "" ) << llendl; -#endif } diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 6c9fea6b6a..07c814769e 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -60,6 +60,7 @@ typedef enum ELLPath // LL_PATH_HTML = 16, LL_PATH_EXECUTABLE = 16, LL_PATH_DEFAULT_SKIN = 17, + LL_PATH_FONTS = 18, LL_PATH_LAST } ELLPath; diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index 346f7dd8ed..7bc6f63e1f 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -68,7 +68,8 @@ static void CFStringRefToLLString(CFStringRef stringRef, std::string &llString, { if (stringRef) { - long bufferSize = CFStringGetLength(stringRef) + 1; + long stringSize = CFStringGetLength(stringRef) + 1; + long bufferSize = CFStringGetMaximumSizeForEncoding(stringSize,kCFStringEncodingUTF8); char* buffer = new char[bufferSize]; memset(buffer, 0, bufferSize); if (CFStringGetCString(stringRef, buffer, bufferSize, kCFStringEncodingUTF8)) diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 3e302764de..4c376f11a5 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -121,17 +121,22 @@ LLDir_Win32::LLDir_Win32() GetCurrentDirectory(MAX_PATH, w_str); mExecutableDir = utf16str_to_utf8str(llutf16string(w_str)); #endif - - // When running in a dev tree, app_settings is under indra/newview/ - // but in production it is under Program Files/SecondLife/ - // Attempt to detect which one we're using. JC - if (mExecutableDir.find("indra") != std::string::npos) - mAppRODataDir = getCurPath(); - else - mAppRODataDir = mExecutableDir; + + mAppRODataDir = "."; mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins"; + if (mExecutableDir.find("indra") == std::string::npos) + { + // Running from installed directory. Make sure current + // directory isn't something crazy (e.g. if invoking from + // command line). + SetCurrentDirectory(utf8str_to_utf16str(mExecutableDir).c_str()); + GetCurrentDirectory(MAX_PATH, w_str); + mWorkingDir = utf16str_to_utf8str(llutf16string(w_str)); + } + llinfos << "mAppRODataDir = " << mAppRODataDir << llendl; + // Build the default cache directory mDefaultCacheDir = buildSLOSCacheDir(); diff --git a/indra/llvfs/lldirguard.h b/indra/llvfs/lldirguard.h new file mode 100644 index 0000000000..85366120d8 --- /dev/null +++ b/indra/llvfs/lldirguard.h @@ -0,0 +1,78 @@ +/** + * @file lldirguard.h + * @brief Protect working directory from being changed in scope. + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_DIRGUARD_H +#define LL_DIRGUARD_H + +#include "linden_common.h" +#include "llerror.h" + +#if LL_WINDOWS +class LLDirectoryGuard +{ +public: + LLDirectoryGuard() + { + mOrigDirLen = GetCurrentDirectory(MAX_PATH, mOrigDir); + } + + ~LLDirectoryGuard() + { + mFinalDirLen = GetCurrentDirectory(MAX_PATH, mFinalDir); + if ((mOrigDirLen!=mFinalDirLen) || + (wcsncmp(mOrigDir,mFinalDir,mOrigDirLen)!=0)) + { + // Dir has changed + std::string mOrigDirUtf8 = utf16str_to_utf8str(llutf16string(mOrigDir)); + std::string mFinalDirUtf8 = utf16str_to_utf8str(llutf16string(mFinalDir)); + llinfos << "Resetting working dir from " << mFinalDirUtf8 << " to " << mOrigDirUtf8 << llendl; + SetCurrentDirectory(mOrigDir); + } + } + +private: + TCHAR mOrigDir[MAX_PATH]; + DWORD mOrigDirLen; + TCHAR mFinalDir[MAX_PATH]; + DWORD mFinalDirLen; +}; +#else // No-op outside Windows. +class LLDirectoryGuard +{ +public: + LLDirectoryGuard() {} + ~LLDirectoryGuard() {} +}; +#endif + + +#endif diff --git a/indra/llvfs/tests/lldir_test.cpp b/indra/llvfs/tests/lldir_test.cpp new file mode 100644 index 0000000000..a275e60882 --- /dev/null +++ b/indra/llvfs/tests/lldir_test.cpp @@ -0,0 +1,266 @@ +/** + * @file lldir_tut.cpp + * @date 2008-05 + * @brief LLDir test cases. + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 2008-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "../lldir.h" + +#include "../test/lltut.h" + + +namespace tut +{ + struct LLDirTest + { + }; + typedef test_group<LLDirTest> LLDirTest_t; + typedef LLDirTest_t::object LLDirTest_object_t; + tut::LLDirTest_t tut_LLDirTest("LLDir"); + + template<> template<> + void LLDirTest_object_t::test<1>() + // getDirDelimiter + { + ensure("getDirDelimiter", !gDirUtilp->getDirDelimiter().empty()); + } + + template<> template<> + void LLDirTest_object_t::test<2>() + // getBaseFileName + { + std::string delim = gDirUtilp->getDirDelimiter(); + std::string rawFile = "foo"; + std::string rawFileExt = "foo.bAr"; + std::string rawFileNullExt = "foo."; + std::string rawExt = ".bAr"; + std::string rawDot = "."; + std::string pathNoExt = "aa" + delim + "bb" + delim + "cc" + delim + "dd" + delim + "ee"; + std::string pathExt = pathNoExt + ".eXt"; + std::string dottedPathNoExt = "aa" + delim + "bb" + delim + "cc.dd" + delim + "ee"; + std::string dottedPathExt = dottedPathNoExt + ".eXt"; + + // foo[.bAr] + + ensure_equals("getBaseFileName/r-no-ext/no-strip-exten", + gDirUtilp->getBaseFileName(rawFile, false), + "foo"); + + ensure_equals("getBaseFileName/r-no-ext/strip-exten", + gDirUtilp->getBaseFileName(rawFile, true), + "foo"); + + ensure_equals("getBaseFileName/r-ext/no-strip-exten", + gDirUtilp->getBaseFileName(rawFileExt, false), + "foo.bAr"); + + ensure_equals("getBaseFileName/r-ext/strip-exten", + gDirUtilp->getBaseFileName(rawFileExt, true), + "foo"); + + // foo. + + ensure_equals("getBaseFileName/rn-no-ext/no-strip-exten", + gDirUtilp->getBaseFileName(rawFileNullExt, false), + "foo."); + + ensure_equals("getBaseFileName/rn-no-ext/strip-exten", + gDirUtilp->getBaseFileName(rawFileNullExt, true), + "foo"); + + // .bAr + // interesting case - with no basename, this IS the basename, not the extension. + + ensure_equals("getBaseFileName/e-ext/no-strip-exten", + gDirUtilp->getBaseFileName(rawExt, false), + ".bAr"); + + ensure_equals("getBaseFileName/e-ext/strip-exten", + gDirUtilp->getBaseFileName(rawExt, true), + ".bAr"); + + // . + + ensure_equals("getBaseFileName/d/no-strip-exten", + gDirUtilp->getBaseFileName(rawDot, false), + "."); + + ensure_equals("getBaseFileName/d/strip-exten", + gDirUtilp->getBaseFileName(rawDot, true), + "."); + + // aa/bb/cc/dd/ee[.eXt] + + ensure_equals("getBaseFileName/no-ext/no-strip-exten", + gDirUtilp->getBaseFileName(pathNoExt, false), + "ee"); + + ensure_equals("getBaseFileName/no-ext/strip-exten", + gDirUtilp->getBaseFileName(pathNoExt, true), + "ee"); + + ensure_equals("getBaseFileName/ext/no-strip-exten", + gDirUtilp->getBaseFileName(pathExt, false), + "ee.eXt"); + + ensure_equals("getBaseFileName/ext/strip-exten", + gDirUtilp->getBaseFileName(pathExt, true), + "ee"); + + // aa/bb/cc.dd/ee[.eXt] + + ensure_equals("getBaseFileName/d-no-ext/no-strip-exten", + gDirUtilp->getBaseFileName(dottedPathNoExt, false), + "ee"); + + ensure_equals("getBaseFileName/d-no-ext/strip-exten", + gDirUtilp->getBaseFileName(dottedPathNoExt, true), + "ee"); + + ensure_equals("getBaseFileName/d-ext/no-strip-exten", + gDirUtilp->getBaseFileName(dottedPathExt, false), + "ee.eXt"); + + ensure_equals("getBaseFileName/d-ext/strip-exten", + gDirUtilp->getBaseFileName(dottedPathExt, true), + "ee"); + } + + template<> template<> + void LLDirTest_object_t::test<3>() + // getDirName + { + std::string delim = gDirUtilp->getDirDelimiter(); + std::string rawFile = "foo"; + std::string rawFileExt = "foo.bAr"; + std::string pathNoExt = "aa" + delim + "bb" + delim + "cc" + delim + "dd" + delim + "ee"; + std::string pathExt = pathNoExt + ".eXt"; + std::string dottedPathNoExt = "aa" + delim + "bb" + delim + "cc.dd" + delim + "ee"; + std::string dottedPathExt = dottedPathNoExt + ".eXt"; + + // foo[.bAr] + + ensure_equals("getDirName/r-no-ext", + gDirUtilp->getDirName(rawFile), + ""); + + ensure_equals("getDirName/r-ext", + gDirUtilp->getDirName(rawFileExt), + ""); + + // aa/bb/cc/dd/ee[.eXt] + + ensure_equals("getDirName/no-ext", + gDirUtilp->getDirName(pathNoExt), + "aa" + delim + "bb" + delim + "cc" + delim + "dd"); + + ensure_equals("getDirName/ext", + gDirUtilp->getDirName(pathExt), + "aa" + delim + "bb" + delim + "cc" + delim + "dd"); + + // aa/bb/cc.dd/ee[.eXt] + + ensure_equals("getDirName/d-no-ext", + gDirUtilp->getDirName(dottedPathNoExt), + "aa" + delim + "bb" + delim + "cc.dd"); + + ensure_equals("getDirName/d-ext", + gDirUtilp->getDirName(dottedPathExt), + "aa" + delim + "bb" + delim + "cc.dd"); + } + + template<> template<> + void LLDirTest_object_t::test<4>() + // getExtension + { + std::string delim = gDirUtilp->getDirDelimiter(); + std::string rawFile = "foo"; + std::string rawFileExt = "foo.bAr"; + std::string rawFileNullExt = "foo."; + std::string rawExt = ".bAr"; + std::string rawDot = "."; + std::string pathNoExt = "aa" + delim + "bb" + delim + "cc" + delim + "dd" + delim + "ee"; + std::string pathExt = pathNoExt + ".eXt"; + std::string dottedPathNoExt = "aa" + delim + "bb" + delim + "cc.dd" + delim + "ee"; + std::string dottedPathExt = dottedPathNoExt + ".eXt"; + + // foo[.bAr] + + ensure_equals("getExtension/r-no-ext", + gDirUtilp->getExtension(rawFile), + ""); + + ensure_equals("getExtension/r-ext", + gDirUtilp->getExtension(rawFileExt), + "bar"); + + // foo. + + ensure_equals("getExtension/rn-no-ext", + gDirUtilp->getExtension(rawFileNullExt), + ""); + + // .bAr + // interesting case - with no basename, this IS the basename, not the extension. + + ensure_equals("getExtension/e-ext", + gDirUtilp->getExtension(rawExt), + ""); + + // . + + ensure_equals("getExtension/d", + gDirUtilp->getExtension(rawDot), + ""); + + // aa/bb/cc/dd/ee[.eXt] + + ensure_equals("getExtension/no-ext", + gDirUtilp->getExtension(pathNoExt), + ""); + + ensure_equals("getExtension/ext", + gDirUtilp->getExtension(pathExt), + "ext"); + + // aa/bb/cc.dd/ee[.eXt] + + ensure_equals("getExtension/d-no-ext", + gDirUtilp->getExtension(dottedPathNoExt), + ""); + + ensure_equals("getExtension/d-ext", + gDirUtilp->getExtension(dottedPathExt), + "ext"); + } +} + diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp index f0f618aef1..16cbf815e0 100644 --- a/indra/llwindow/llkeyboard.cpp +++ b/indra/llwindow/llkeyboard.cpp @@ -36,7 +36,6 @@ #include "llwindowcallbacks.h" - // // Globals // @@ -46,6 +45,8 @@ LLKeyboard *gKeyboard = NULL; //static std::map<KEY,std::string> LLKeyboard::sKeysToNames; std::map<std::string,KEY> LLKeyboard::sNamesToKeys; +LLKeyStringTranslatorFunc* LLKeyboard::mStringTranslator = NULL; // Used for l10n + PC/Mac/Linux accelerator labeling + // // Class Implementation @@ -346,6 +347,65 @@ std::string LLKeyboard::stringFromKey(KEY key) } +//static +std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key ) +{ + std::string res; + + // break early if this is a silly thing to do. + if( KEY_NONE == key ) + { + return res; + } + + LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator; + + if( trans == NULL ) + { + llerrs << "No mKeyStringTranslator" << llendl; + return res; + } + + // Append any masks +#ifdef LL_DARWIN + // Standard Mac names for modifier keys in menu equivalents + // We could use the symbol characters, but they only exist in certain fonts. + if( accel_mask & MASK_CONTROL ) + { + if ( accel_mask & MASK_MAC_CONTROL ) + { + res.append( trans("accel-mac-control") ); + } + else + { + res.append( trans("accel-mac-command") ); // Symbol would be "\xE2\x8C\x98" + } + } + if( accel_mask & MASK_ALT ) + res.append( trans("accel-mac-option") ); // Symbol would be "\xE2\x8C\xA5" + if( accel_mask & MASK_SHIFT ) + res.append( trans("accel-mac-shift") ); // Symbol would be "\xE2\x8C\xA7" +#else + if( accel_mask & MASK_CONTROL ) + res.append( trans("accel-win-control") ); + if( accel_mask & MASK_ALT ) + res.append( trans("accel-win-alt") ); + if( accel_mask & MASK_SHIFT ) + res.append( trans("accel-win-shift") ); +#endif + std::string key_string = LLKeyboard::stringFromKey(key); + if ((accel_mask & MASK_NORMALKEYS) && + (key_string[0] == '-' || key_string[0] == '=' || key_string[0] == '+')) + { + res.append( " " ); + } + + std::string keystr = stringFromKey( key ); + res.append( keystr ); + + return res; +} + //static BOOL LLKeyboard::maskFromString(const std::string& str, MASK *mask) @@ -396,3 +456,10 @@ BOOL LLKeyboard::maskFromString(const std::string& str, MASK *mask) return FALSE; } } + + +//static +void LLKeyboard::setStringTranslatorFunc( LLKeyStringTranslatorFunc *trans_func ) +{ + mStringTranslator = trans_func; +} diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h index 0261bcbeb3..d545034070 100644 --- a/indra/llwindow/llkeyboard.h +++ b/indra/llwindow/llkeyboard.h @@ -47,7 +47,8 @@ enum EKeystate }; typedef void (*LLKeyFunc)(EKeystate keystate); - +typedef std::string (LLKeyStringTranslatorFunc)(const char *label); + enum EKeyboardInsertMode { LL_KIM_INSERT, @@ -111,7 +112,7 @@ public: static BOOL maskFromString(const std::string& str, MASK *mask); // False on failure static BOOL keyFromString(const std::string& str, KEY *key); // False on failure static std::string stringFromKey(KEY key); - + static std::string stringFromAccelerator( MASK accel_mask, KEY key ); e_numpad_distinct getNumpadDistinct() { return mNumpadDistinct; } void setNumpadDistinct(e_numpad_distinct val) { mNumpadDistinct = val; } @@ -119,6 +120,8 @@ public: F32 getKeyElapsedTime( KEY key ); // Returns time in seconds since key was pressed. S32 getKeyElapsedFrameCount( KEY key ); // Returns time in frames since key was pressed. + static void setStringTranslatorFunc( LLKeyStringTranslatorFunc *trans_func ); + protected: void addKeyName(KEY key, const std::string& name); @@ -136,6 +139,8 @@ protected: KEY mCurTranslatedKey; KEY mCurScanKey; // Used during the scanKeyboard() + static LLKeyStringTranslatorFunc* mStringTranslator; // Used for l10n + PC/Mac/Linux accelerator labeling + e_numpad_distinct mNumpadDistinct; EKeyboardInsertMode mInsertMode; diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index ea11e0537e..35a3e7621a 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -65,7 +65,7 @@ LLKeyboardWin32::LLKeyboardWin32() // numpad number keys for (cur_char = 0x60; cur_char <= 0x69; cur_char++) { - mTranslateKeyMap[cur_char] = (KEY)('0' + (0x60 - cur_char)); + mTranslateKeyMap[cur_char] = (KEY)('0' + (cur_char - 0x60)); } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 7137c93476..96e5a1b7ca 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1389,11 +1389,11 @@ void LLWindowMacOSX::setMouseClipping( BOOL b ) if(b) { - // llinfos << "setMouseClipping(TRUE)" << llendl + // llinfos << "setMouseClipping(TRUE)" << llendl; } else { - // llinfos << "setMouseClipping(FALSE)" << llendl + // llinfos << "setMouseClipping(FALSE)" << llendl; } adjustCursorDecouple(); @@ -1411,7 +1411,7 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position) CGPoint newPosition; - // llinfos << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << llendl + // llinfos << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << llendl; newPosition.x = screen_pos.mX; newPosition.y = screen_pos.mY; diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 00a8d429ba..9f03c8f695 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -70,7 +70,7 @@ extern BOOL gDebugWindowProc; const S32 MAX_NUM_RESOLUTIONS = 200; // static variable for ATI mouse cursor crash work-around: -static bool ATIbug = false; +static bool ATIbug = false; // // LLWindowSDL @@ -219,8 +219,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks, #endif // LL_X11 #if LL_GTK - // We MUST be the first to initialize GTK, i.e. we have to beat - // our embedded Mozilla to the punch so that GTK doesn't get badly + // We MUST be the first to initialize GTK so that GTK doesn't get badly // initialized with a non-C locale and cause lots of serious random // weirdness. ll_try_gtk_init(); @@ -674,12 +673,12 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B glGetIntegerv(GL_DEPTH_BITS, &depthBits); glGetIntegerv(GL_STENCIL_BITS, &stencilBits); - llinfos << "GL buffer:" << llendl - llinfos << " Red Bits " << S32(redBits) << llendl - llinfos << " Green Bits " << S32(greenBits) << llendl - llinfos << " Blue Bits " << S32(blueBits) << llendl - llinfos << " Alpha Bits " << S32(alphaBits) << llendl - llinfos << " Depth Bits " << S32(depthBits) << llendl + llinfos << "GL buffer:" << llendl; + llinfos << " Red Bits " << S32(redBits) << llendl; + llinfos << " Green Bits " << S32(greenBits) << llendl; + llinfos << " Blue Bits " << S32(blueBits) << llendl; + llinfos << " Alpha Bits " << S32(alphaBits) << llendl; + llinfos << " Depth Bits " << S32(depthBits) << llendl; llinfos << " Stencil Bits " << S32(stencilBits) << llendl; GLint colorBits = redBits + greenBits + blueBits + alphaBits; @@ -2252,6 +2251,7 @@ BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b) GtkColorSelection *colorsel = GTK_COLOR_SELECTION (GTK_COLOR_SELECTION_DIALOG(win)->colorsel); GdkColor color, orig_color; + orig_color.pixel = 0; orig_color.red = guint16(65535 * *r); orig_color.green= guint16(65535 * *g); orig_color.blue = guint16(65535 * *b); diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index 1b867b79c9..6dd1f93baf 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -127,7 +127,7 @@ namespace LLInitParam bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent) { - if (!deserializeBlock(p, boost::make_iterator_range(name_stack.begin(), name_stack.end()))) + if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()))) { if (!silent) { @@ -304,11 +304,11 @@ namespace LLInitParam bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack) { BlockDescriptor& block_data = getBlockDescriptor(); - bool names_left = !name_stack.empty(); + bool names_left = name_stack.first != name_stack.second; if (names_left) { - const std::string& top_name = name_stack.front().first; + const std::string& top_name = name_stack.first->first; ParamDescriptor::deserialize_func_t deserialize_func = NULL; Param* paramp = NULL; @@ -331,10 +331,11 @@ namespace LLInitParam } } - Parser::name_stack_range_t new_name_stack(++name_stack.begin(), name_stack.end()); + Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second); + ++new_name_stack.first; if (deserialize_func) { - return deserialize_func(*paramp, p, new_name_stack, name_stack.empty() ? -1 : name_stack.front().second); + return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second); } } @@ -346,7 +347,7 @@ namespace LLInitParam Param* paramp = getParamFromHandle((*it)->mParamHandle); ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc; - if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.empty() ? -1 : name_stack.front().second)) + if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second)) { mLastChangedParam = (*it)->mParamHandle; return true; @@ -499,33 +500,7 @@ namespace LLInitParam return param_changed; } - - template<> - bool ParamCompare<boost::function<void (const std::string &,void *)> >::equals( - const boost::function<void (const std::string &,void *)> &a, - const boost::function<void (const std::string &,void *)> &b) - { - return false; - } - - template<> - bool ParamCompare<boost::function<void (const LLSD &,const LLSD &)> >::equals( - const boost::function<void (const LLSD &,const LLSD &)> &a, - const boost::function<void (const LLSD &,const LLSD &)> &b) - { - return false; - } - - template<> - bool ParamCompare<boost::function<void (void)> >::equals( - const boost::function<void (void)> &a, - const boost::function<void (void)> &b) - { - return false; - } - - template<> - bool ParamCompare<LLSD>::equals(const LLSD &a, const LLSD &b) + bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b) { return false; } diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 88bc430504..b280dfdf63 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -39,25 +39,31 @@ #include <stddef.h> #include <boost/function.hpp> #include <boost/bind.hpp> -#include <boost/range/iterator_range.hpp> +#include <boost/type_traits/is_convertible.hpp> #include "llregistry.h" #include "llmemory.h" namespace LLInitParam { - template <typename T> - class ParamCompare { - public: - static bool equals(const T &a, const T &b); + template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value > + struct ParamCompare + { + static bool equals(const T &a, const T &b) + { + return a == b; + } }; - template<class T> - bool ParamCompare<T>::equals(const T &a, const T&b) - { - return a == b; - } - + // boost function types are not comparable + template<typename T> + struct ParamCompare<T, true> + { + static bool equals(const T&a, const T &b) + { + return false; + } + }; // default constructor adaptor for InitParam Values // constructs default instances of the given type, returned by const reference @@ -192,7 +198,7 @@ namespace LLInitParam }; typedef std::vector<std::pair<std::string, S32> > name_stack_t; - typedef boost::iterator_range<name_stack_t::const_iterator> name_stack_range_t; + typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator> name_stack_range_t; typedef std::vector<std::string> possible_values_t; typedef boost::function<bool (void*)> parser_read_func_t; @@ -535,7 +541,7 @@ namespace LLInitParam { self_t& typed_param = static_cast<self_t&>(param); // no further names in stack, attempt to parse value now - if (name_stack.empty()) + if (name_stack.first == name_stack.second) { if (parser.readValue<T>(typed_param.mData.mValue)) { @@ -886,7 +892,7 @@ namespace LLInitParam self_t& typed_param = static_cast<self_t&>(param); value_t value; // no further names in stack, attempt to parse value now - if (name_stack.empty()) + if (name_stack.first == name_stack.second) { // attempt to read value directly if (parser.readValue<value_t>(value)) @@ -1541,7 +1547,7 @@ namespace LLInitParam static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) { - if (name_stack.empty()) + if (name_stack.first == name_stack.second) { //std::string message = llformat("Deprecated value %s ignored", getName().c_str()); //parser.parserWarning(message); @@ -1600,7 +1606,7 @@ namespace LLInitParam { self_t& typed_param = static_cast<self_t&>(param); // type to apply parse direct value T - if (name_stack.empty()) + if (name_stack.first == name_stack.second) { if(parser.readValue<T>(typed_param.mData.mValue)) { @@ -1811,24 +1817,11 @@ namespace LLInitParam } }; - template<> - bool ParamCompare<boost::function<void (const std::string &,void *)> >::equals( - const boost::function<void (const std::string &,void *)> &a, - const boost::function<void (const std::string &,void *)> &b); - - template<> - bool ParamCompare<boost::function<void (const LLSD &,const LLSD &)> >::equals( - const boost::function<void (const LLSD &,const LLSD &)> &a, - const boost::function<void (const LLSD &,const LLSD &)> &b); - - template<> - bool ParamCompare<boost::function<void (void)> >::equals( - const boost::function<void (void)> &a, - const boost::function<void (void)> &b); - - - template<> - bool ParamCompare<LLSD>::equals(const LLSD &a, const LLSD &b); + template<> + struct ParamCompare<LLSD, false> + { + static bool equals(const LLSD &a, const LLSD &b); + }; } #endif // LL_LLPARAM_H diff --git a/indra/llxuixml/lltrans.h b/indra/llxuixml/lltrans.h index 79df5802e5..856b9e04fc 100644 --- a/indra/llxuixml/lltrans.h +++ b/indra/llxuixml/lltrans.h @@ -103,6 +103,11 @@ public: return findString(result, xml_desc, empty); } + static std::string getKeyboardString(const char* keystring) + { + // These map directly - no need to specialize + return getString( ll_safe_string(keystring) ); + } // get the default args static const LLStringUtil::format_map_t& getDefaultArgs() diff --git a/indra/llxuixml/lluicolor.cpp b/indra/llxuixml/lluicolor.cpp index fe02907e14..424d878a6b 100644 --- a/indra/llxuixml/lluicolor.cpp +++ b/indra/llxuixml/lluicolor.cpp @@ -60,14 +60,9 @@ bool LLUIColor::isReference() const namespace LLInitParam { // used to detect equivalence with default values on export - template<> - class ParamCompare<LLUIColor> + bool ParamCompare<LLUIColor, false>::equals(const LLUIColor &a, const LLUIColor &b) { - public: - static bool equals(const LLUIColor &a, const LLUIColor &b) - { - // do not detect value equivalence, treat pointers to colors as distinct from color values - return (a.mColorPtr == NULL && b.mColorPtr == NULL ? a.mColor == b.mColor : a.mColorPtr == b.mColorPtr); - } - }; + // do not detect value equivalence, treat pointers to colors as distinct from color values + return (a.mColorPtr == NULL && b.mColorPtr == NULL ? a.mColor == b.mColor : a.mColorPtr == b.mColorPtr); + } } diff --git a/indra/llxuixml/lluicolor.h b/indra/llxuixml/lluicolor.h index 365f61003b..fb9c6b9161 100644 --- a/indra/llxuixml/lluicolor.h +++ b/indra/llxuixml/lluicolor.h @@ -11,11 +11,12 @@ #define LL_LLUICOLOR_H_ #include "v4color.h" +#include <boost/type_traits/integral_constant.hpp> // for boost::false_type namespace LLInitParam { - template<typename T> - class ParamCompare; + template<typename T, bool> + struct ParamCompare; } class LLUIColor @@ -36,10 +37,19 @@ public: bool isReference() const; private: - friend class LLInitParam::ParamCompare<LLUIColor>; + friend struct LLInitParam::ParamCompare<LLUIColor, false>; const LLColor4* mColorPtr; LLColor4 mColor; }; +namespace LLInitParam +{ + template<> + struct ParamCompare<LLUIColor, false> + { + static bool equals(const class LLUIColor& a, const class LLUIColor& b); + }; +} + #endif diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 0bfb0023c2..24c16d22bf 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -137,7 +137,6 @@ set(viewer_SOURCE_FILES llfeaturemanager.cpp llfilepicker.cpp llfirstuse.cpp - llfirsttimetipmanager.cpp llflexibleobject.cpp llfloaterabout.cpp llfloateractivespeakers.cpp @@ -162,7 +161,6 @@ set(viewer_SOURCE_FILES llfloaterdaycycle.cpp llfloaterdirectory.cpp llfloaterenvsettings.cpp - llfloaterfirsttimetip.cpp llfloaterfriends.cpp llfloaterfonttest.cpp llfloatergesture.cpp @@ -327,7 +325,6 @@ set(viewer_SOURCE_FILES llpanelmedia.cpp llpanelmediahud.cpp llpanelmeprofile.cpp - llpanelmovetip.cpp llpanelmediasettingsgeneral.cpp llpanelmediasettingssecurity.cpp llpanelmediasettingspermissions.cpp @@ -614,7 +611,6 @@ set(viewer_HEADER_FILES llfeaturemanager.h llfilepicker.h llfirstuse.h - llfirsttimetipmanager.h llflexibleobject.h llfloaterabout.h llfloateractivespeakers.h @@ -639,7 +635,6 @@ set(viewer_HEADER_FILES llfloaterdaycycle.h llfloaterdirectory.h llfloaterenvsettings.h - llfloaterfirsttimetip.h llfloaterfonttest.h llfloaterfriends.h llfloatergesture.h @@ -800,7 +795,6 @@ set(viewer_HEADER_FILES llpanelmedia.h llpanelmediahud.h llpanelmeprofile.h - llpanelmovetip.h llpanelmediasettingsgeneral.h llpanelmediasettingssecurity.h llpanelmediasettingspermissions.h @@ -1042,7 +1036,7 @@ endif (DARWIN) if (LINUX) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp) LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp) - LIST(APPEND CMAKE_EXE_LINKER_FLAGS -Wl,--as-needed) + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") set(viewer_LIBRARIES Xinerama @@ -1130,7 +1124,9 @@ if (WINDOWS) SOURCE_GROUP("Resource Files" FILES ${viewer_RESOURCE_FILES}) - list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES}) + if (NOT STANDALONE) + list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES}) + endif (NOT STANDALONE) find_library(DINPUT_LIBRARY dinput8 ${DIRECTX_LIBRARY_DIR}) find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR}) @@ -1248,8 +1244,9 @@ source_group("Character File" FILES ${viewer_CHARACTER_FILES}) set_source_files_properties(${viewer_CHARACTER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) - -list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES}) +if (NOT STANDALONE) + list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES}) +endif (NOT STANDALONE) if (WINDOWS) file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi) diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index 5d52158298..544f1c598e 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -459,6 +459,7 @@ PARCEL_FLAG_ALLOW_LANDMARK Used with llGetParcelFlags to find if a parcel allo PARCEL_FLAG_ALLOW_TERRAFORM Used with llGetParcelFlags to find if a parcel allows anyone to terraform the land PARCEL_FLAG_ALLOW_DAMAGE Used with llGetParcelFlags to find if a parcel allows damage PARCEL_FLAG_ALLOW_CREATE_OBJECTS Used with llGetParcelFlags to find if a parcel allows anyone to create objects +PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS Used with llGetParcelFlags to find if a parcel allows group members or objects to create objects PARCEL_FLAG_USE_ACCESS_GROUP Used with llGetParcelFlags to find if a parcel limits access to a group PARCEL_FLAG_USE_ACCESS_LIST Used with llGetParcelFlags to find if a parcel limits access to a list of residents PARCEL_FLAG_USE_BAN_LIST Used with llGetParcelFlags to find if a parcel uses a ban list diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index f1e5acdd74..f898c2d0c1 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1599,7 +1599,7 @@ <key>Cursor3D</key> <map> <key>Comment</key> - <string>Tread Joystick values as absolute positions (not deltas).</string> + <string>Treat Joystick values as absolute positions (not deltas).</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -3851,6 +3851,17 @@ <key>Value</key> <string /> </map> + <key>JoystickMouselookYaw</key> + <map> + <key>Comment</key> + <string>Pass joystick yaw to scripts in Mouselook.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>JoystickRunThreshold</key> <map> <key>Comment</key> @@ -4158,7 +4169,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>LipSyncOoh</key> <map> @@ -7632,6 +7643,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>ShowSnapshotButton</key> + <map> + <key>Comment</key> + <string>Show/Hide Snapshot button button in the bottom tray</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>ShowMoveButton</key> <map> <key>Comment</key> @@ -9656,17 +9678,6 @@ <key>Value</key> <integer>16</integer> </map> - <key>UITabCntrTabHeight</key> - <map> - <key>Comment</key> - <string>UI Tab Container Tab Height</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>S32</string> - <key>Value</key> - <integer>16</integer> - </map> <key>UITabCntrTabHPad</key> <map> <key>Comment</key> diff --git a/indra/newview/installers/darwin/firstlook-dmg/_DS_Store b/indra/newview/installers/darwin/firstlook-dmg/_DS_Store Binary files differindex 6c5a3f3452..408a4d4992 100644 --- a/indra/newview/installers/darwin/firstlook-dmg/_DS_Store +++ b/indra/newview/installers/darwin/firstlook-dmg/_DS_Store diff --git a/indra/newview/installers/darwin/publicnightly-dmg/_DS_Store b/indra/newview/installers/darwin/publicnightly-dmg/_DS_Store Binary files differindex 6a91b38d6d..b901e46b65 100644 --- a/indra/newview/installers/darwin/publicnightly-dmg/_DS_Store +++ b/indra/newview/installers/darwin/publicnightly-dmg/_DS_Store diff --git a/indra/newview/installers/darwin/releasecandidate-dmg/_DS_Store b/indra/newview/installers/darwin/releasecandidate-dmg/_DS_Store Binary files differindex a8b757372e..309c8adaaa 100644 --- a/indra/newview/installers/darwin/releasecandidate-dmg/_DS_Store +++ b/indra/newview/installers/darwin/releasecandidate-dmg/_DS_Store diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index ab9db303b5..a4b33162d6 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -332,7 +332,7 @@ LLAgent::LLAgent() : mLeftKey(0), mUpKey(0), mYawKey(0.f), - mPitchKey(0), + mPitchKey(0.f), mOrbitLeftKey(0.f), mOrbitRightKey(0.f), @@ -727,15 +727,15 @@ void LLAgent::moveYaw(F32 mag, bool reset_view) //----------------------------------------------------------------------------- // movePitch() //----------------------------------------------------------------------------- -void LLAgent::movePitch(S32 direction) +void LLAgent::movePitch(F32 mag) { - setKey(direction, mPitchKey); + mPitchKey = mag; - if (direction > 0) + if (mag > 0) { - setControlFlags(AGENT_CONTROL_PITCH_POS ); + setControlFlags(AGENT_CONTROL_PITCH_POS); } - else if (direction < 0) + else if (mag < 0) { setControlFlags(AGENT_CONTROL_PITCH_NEG); } @@ -2513,10 +2513,10 @@ void LLAgent::propagate(const F32 dt) // handle rotation based on keyboard levels const F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second - yaw( YAW_RATE * mYawKey * dt ); + yaw(YAW_RATE * mYawKey * dt); const F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second - pitch(PITCH_RATE * (F32) mPitchKey * dt); + pitch(PITCH_RATE * mPitchKey * dt); // handle auto-land behavior if (mAvatarObject.notNull()) @@ -2541,7 +2541,7 @@ void LLAgent::propagate(const F32 dt) mLeftKey = 0; mUpKey = 0; mYawKey = 0.f; - mPitchKey = 0; + mPitchKey = 0.f; } //----------------------------------------------------------------------------- @@ -3172,6 +3172,7 @@ void LLAgent::updateCamera() mFollowCam.copyParams(*current_cam); mFollowCam.setSubjectPositionAndRotation( mAvatarObject->getRenderPosition(), avatarRotationForFollowCam ); mFollowCam.update(); + LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); } else { @@ -4249,7 +4250,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani { if(avatar_animate) { - // Remove any pitch from the avatar + // Remove any pitch from the avatar LLVector3 at = mFrameAgent.getAtAxis(); at.mV[VZ] = 0.f; at.normalize(); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 09400b3a88..99a9bdd8e6 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -475,7 +475,7 @@ private: S32 mLeftKey; S32 mUpKey; F32 mYawKey; - S32 mPitchKey; + F32 mPitchKey; //-------------------------------------------------------------------- // Movement from user input @@ -490,7 +490,7 @@ public: void moveLeftNudge(S32 direction); void moveUp(S32 direction); void moveYaw(F32 mag, bool reset_view = true); - void movePitch(S32 direction); + void movePitch(F32 mag); //-------------------------------------------------------------------- // Orbit diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 50d378335e..2cfa8d2a54 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -563,16 +563,32 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(EWearableType type, return item; } -const LLWearable* LLAgentWearables::getWearableFromWearableItem(const LLUUID& item_id) const +const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const { for (S32 i=0; i < WT_COUNT; i++) { for (U32 j=0; j < getWearableCount((EWearableType)i); j++) { - LLUUID curr_item_id = getWearableItemID((EWearableType)i, j); - if (curr_item_id == item_id) + const LLWearable * curr_wearable = getWearable((EWearableType)i, j); + if (curr_wearable && (curr_wearable->getItemID() == item_id)) { - return getWearable((EWearableType)i, j); + return curr_wearable; + } + } + } + return NULL; +} + +const LLWearable* LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) const +{ + for (S32 i=0; i < WT_COUNT; i++) + { + for (U32 j=0; j < getWearableCount((EWearableType)i); j++) + { + const LLWearable * curr_wearable = getWearable((EWearableType)i, j); + if (curr_wearable && (curr_wearable->getAssetID() == asset_id)) + { + return curr_wearable; } } } @@ -683,10 +699,19 @@ const LLUUID LLAgentWearables::getWearableItemID(EWearableType type, U32 index) return LLUUID(); } +const LLUUID LLAgentWearables::getWearableAssetID(EWearableType type, U32 index) const +{ + const LLWearable *wearable = getWearable(type,index); + if (wearable) + return wearable->getAssetID(); + else + return LLUUID(); +} + // Warning: include_linked_items = TRUE makes this operation expensive. BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_items) const { - if (getWearableFromWearableItem(item_id) != NULL) return TRUE; + if (getWearableFromItemID(item_id) != NULL) return TRUE; if (include_linked_items) { LLInventoryModel::item_array_t item_array; @@ -696,8 +721,8 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_ iter++) { LLViewerInventoryItem *linked_item = (*iter); - const LLUUID &item_id = linked_item->getUUID(); - if (getWearableFromWearableItem(item_id) != NULL) return TRUE; + const LLUUID &linked_item_id = linked_item->getUUID(); + if (getWearableFromItemID(linked_item_id) != NULL) return TRUE; } } return FALSE; @@ -1152,26 +1177,6 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name) return LLUUID::null; } - LLDynamicArray<S32> wearables_to_include; - getAllWearablesArray(wearables_to_include); - - LLDynamicArray<S32> attachments_to_include; - mAvatarObject->getAllAttachmentsArray(attachments_to_include); - - return makeNewOutfitLinks(new_folder_name, wearables_to_include, attachments_to_include); -} - -// Note: wearables_to_include should be a list of EWearableType types -// attachments_to_include should be a list of attachment points -LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name, - const LLDynamicArray<S32>& wearables_to_include, - const LLDynamicArray<S32>& attachments_to_include) -{ - if (mAvatarObject.isNull()) - { - return LLUUID::null; - } - // First, make a folder in the My Outfits directory. LLUUID parent_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_MY_OUTFITS); LLUUID folder_id = gInventory.createNewCategory( @@ -1180,8 +1185,8 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name, new_folder_name); LLAppearanceManager::shallowCopyCategory(LLAppearanceManager::getCOF(),folder_id, NULL); - -#if 0 + +#if 0 // BAP - fix to go into rename state automatically after outfit is created. LLViewerInventoryCategory *parent_category = gInventory.getCategory(parent_id); if (parent_category) { @@ -1839,7 +1844,7 @@ void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_arra msg->nextBlockFast(_PREHASH_HeaderData); msg->addUUIDFast(_PREHASH_CompoundMsgID, compound_msg_id ); msg->addU8Fast(_PREHASH_TotalObjects, obj_count ); - msg->addBOOLFast(_PREHASH_FirstDetachAll, true ); // BAP changing this doesn't seem to matter? + msg->addBOOLFast(_PREHASH_FirstDetachAll, false ); } const LLInventoryItem* item = obj_item_array.get(i).get(); @@ -1882,6 +1887,16 @@ void LLAgentWearables::updateWearablesLoaded() mWearablesLoaded = (itemUpdatePendingCount()==0); } +bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const +{ + if (!wearable) return false; + + EWearableType type = wearable->getType(); + // Make sure the user always has at least one shape, skin, eyes, and hair type currently worn. + return !(((type == WT_SHAPE) || (type == WT_SKIN) || (type == WT_HAIR) || (type == WT_EYES)) + && (getWearableCount(type) <= 1) ); +} + void LLAgentWearables::updateServer() { sendAgentWearablesUpdate(); diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 701ce7f05a..8b9d29342a 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -75,20 +75,25 @@ public: BOOL areWearablesLoaded() const; void updateWearablesLoaded(); void checkWearablesLoaded() const; + + // Note: False for shape, skin, eyes, and hair, unless you have MORE than 1. + bool canWearableBeRemoved(const LLWearable* wearable) const; //-------------------------------------------------------------------- // Accessors //-------------------------------------------------------------------- public: - const LLUUID getWearableItemID(EWearableType type, U32 index /*= 0*/) const; - const LLWearable* getWearableFromWearableItem(const LLUUID& item_id) const; - LLInventoryItem* getWearableInventoryItem(EWearableType type, U32 index /*= 0*/); + const LLUUID getWearableItemID(EWearableType type, U32 index /*= 0*/) const; + const LLUUID getWearableAssetID(EWearableType type, U32 index /*= 0*/) const; + const LLWearable* getWearableFromItemID(const LLUUID& item_id) const; + const LLWearable* getWearableFromAssetID(const LLUUID& asset_id) const; + LLInventoryItem* getWearableInventoryItem(EWearableType type, U32 index /*= 0*/); // MULTI-WEARABLE: assuming one per type. - static BOOL selfHasWearable(EWearableType type); - LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/); + static BOOL selfHasWearable(EWearableType type); + LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/); const LLWearable* getWearable(const EWearableType type, U32 index /*= 0*/) const; - U32 getWearableCount(const EWearableType type) const; + U32 getWearableCount(const EWearableType type) const; //-------------------------------------------------------------------- @@ -159,9 +164,7 @@ public: // Note: wearables_to_include should be a list of EWearableType types // attachments_to_include should be a list of attachment points LLUUID makeNewOutfitLinks(const std::string& new_folder_name); - LLUUID makeNewOutfitLinks(const std::string& new_folder_name, - const LLDynamicArray<S32>& wearables_to_include, - const LLDynamicArray<S32>& attachments_to_include); + private: void makeNewOutfitDone(S32 type, U32 index); diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 3831846e2e..cf8d852dfe 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -165,6 +165,8 @@ void LLOutfitObserver::done() cb); } } + // BAP fixes a lag in display of created dir. + gInventory.notifyObservers(); } else { @@ -495,11 +497,16 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory } else if (item->getActualType() == LLAssetType::AT_LINK_FOLDER) { - link_inventory_item(gAgent.getID(), - item->getLinkedUUID(), - dst_id, - item->getName(), - LLAssetType::AT_LINK_FOLDER, cb); + LLViewerInventoryCategory *catp = item->getLinkedCategory(); + // Skip copying outfit links. + if (catp && catp->getPreferredType() != LLAssetType::AT_OUTFIT) + { + link_inventory_item(gAgent.getID(), + item->getLinkedUUID(), + dst_id, + item->getName(), + LLAssetType::AT_LINK_FOLDER, cb); + } } else { @@ -519,6 +526,9 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory { lldebugs << "rebuildCOFFromOutfit()" << llendl; + dumpCat(category,"start, source outfit"); + dumpCat(getCOF(),"start, COF"); + // Find all the wearables that are in the category's subtree. LLInventoryModel::item_array_t items; getCOFValidDescendents(category, items); @@ -538,6 +548,8 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory gInventory.collectDescendents(current_outfit_id, cof_cats, cof_items, LLInventoryModel::EXCLUDE_TRASH); + //dumpCat(current_outfit_id,"COF before remove:"); + if (items.count() > 0) { for (S32 i = 0; i < cof_items.count(); ++i) @@ -547,15 +559,19 @@ void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventory gInventory.notifyObservers(); } + //dumpCat(current_outfit_id,"COF after remove:"); + LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy; LLAppearanceManager::shallowCopyCategory(category, current_outfit_id, link_waiter); + //dumpCat(current_outfit_id,"COF after shallow copy:"); + // Create a link to the outfit that we wore. LLViewerInventoryCategory* catp = gInventory.getCategory(category); if (catp && catp->getPreferredType() == LLAssetType::AT_OUTFIT) { link_inventory_item(gAgent.getID(), category, current_outfit_id, catp->getName(), - LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL)); + LLAssetType::AT_LINK_FOLDER, link_waiter); } } @@ -628,6 +644,8 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder, /* static */ void LLAppearanceManager::updateAppearanceFromCOF() { + dumpCat(getCOF(),"COF, start"); + bool follow_folder_links = true; LLUUID current_outfit_id = getCOF(); @@ -921,3 +939,26 @@ void LLAppearanceManager::removeItemLinks(LLUUID& item_id, bool do_update) LLAppearanceManager::updateAppearanceFromCOF(); } } + +/* static */ +void LLAppearanceManager::dumpCat(const LLUUID& cat_id, std::string str) +{ + LLInventoryModel::cat_array_t cats; + LLInventoryModel::item_array_t items; + gInventory.collectDescendents(cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH); + +#if 0 + llinfos << llendl; + llinfos << str << llendl; + S32 hitcount = 0; + for(S32 i=0; i<items.count(); i++) + { + LLViewerInventoryItem *item = items.get(i); + if (item) + hitcount++; + llinfos << i <<" "<< item->getName() <<llendl; + } +#endif + llinfos << str << " count " << items.count() << llendl; +} + diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 2aa10e0bea..fe24696182 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -64,6 +64,9 @@ public: // Remove COF entries static void removeItemLinks(LLUUID& item_id, bool do_update = true); + // For debugging - could be moved elsewhere. + static void dumpCat(const LLUUID& cat_id, std::string str); + private: static void getCOFValidDescendents(const LLUUID& category, LLInventoryModel::item_array_t& items); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a631314d5b..b4b30d0cde 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -180,6 +180,7 @@ #include "llimview.h" #include "llviewerthrottle.h" #include "llparcel.h" +#include "llavatariconctrl.h" // *FIX: These extern globals should be cleaned up. // The globals either represent state/config/resource-storage of either @@ -604,7 +605,8 @@ bool LLAppViewer::init() // into the log files during normal startup until AFTER // we run the "program crashed last time" error handler below. // - + LLFastTimer::reset(); + // Need to do this initialization before we do anything else, since anything // that touches files should really go through the lldir API gDirUtilp->initAppDirs("SecondLife"); @@ -695,8 +697,12 @@ bool LLAppViewer::init() LLUI::setupPaths(); LLTransUtil::parseStrings("strings.xml", default_trans_args); LLTransUtil::parseLanguageStrings("language_settings.xml"); - LLWeb::initClass(); // do this after LLUI + + // LLKeyboard relies on LLUI to know what some accelerator keys are called. + LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString ); + LLWeb::initClass(); // do this after LLUI + // Provide the text fields with callbacks for opening Urls LLUrlAction::setOpenURLCallback(&LLWeb::loadURL); LLUrlAction::setOpenURLInternalCallback(&LLWeb::loadURLInternal); @@ -1491,6 +1497,9 @@ bool LLAppViewer::cleanup() sImageDecodeThread = NULL; LLLocationHistory::getInstance()->save(); + + LLAvatarIconIDCache::getInstance()->save(); + delete mFastTimerLogThread; mFastTimerLogThread = NULL; @@ -1830,8 +1839,18 @@ bool LLAppViewer::initConfiguration() gSavedSettings.setString("VersionChannelName", LL_CHANNEL); #ifndef LL_RELEASE_FOR_DOWNLOAD - gSavedSettings.setBOOL("ShowConsoleWindow", TRUE); - gSavedSettings.setBOOL("AllowMultipleViewers", TRUE); + // provide developer build only overrides for these control variables that are not + // persisted to settings.xml + LLControlVariable* c = gSavedSettings.getControl("ShowConsoleWindow"); + if (c) + { + c->setValue(true, false); + } + c = gSavedSettings.getControl("AllowMultipleViewers"); + if (c) + { + c->setValue(true, false); + } #endif //*FIX:Mani - Set default to disabling watchdog mainloop diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index ed291c16a8..d34bcb4a68 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -188,7 +188,7 @@ static inline BOOL do_basic_glibc_backtrace() for (i = 0; i < size; i++) { // the format of the StraceFile is very specific, to allow (kludgy) machine-parsing - fprintf(StraceFile, "%-3d ", i); + fprintf(StraceFile, "%-3lu ", (unsigned long)i); fprintf(StraceFile, "%-32s\t", "unknown"); fprintf(StraceFile, "%p ", stackarray[i]); fprintf(StraceFile, "%s\n", strings[i]); @@ -263,7 +263,7 @@ static inline BOOL do_elfio_glibc_backtrace() for (btpos = 0; btpos < btsize; ++btpos) { // the format of the StraceFile is very specific, to allow (kludgy) machine-parsing - fprintf(StraceFile, "%-3d ", btpos); + fprintf(StraceFile, "%-3ld ", (long)btpos); int symidx; for (symidx = 0; symidx < nSymNo; ++symidx) { @@ -354,7 +354,7 @@ bool LLAppViewerLinux::init() bool LLAppViewerLinux::restoreErrorTrap() { - // *NOTE:Mani there is a case for implementing this or the mac. + // *NOTE:Mani there is a case for implementing this on the mac. // Linux doesn't need it to my knowledge. return true; } @@ -727,8 +727,26 @@ std::string LLAppViewerLinux::generateSerialNumber() { char serial_md5[MD5HEX_STR_SIZE]; serial_md5[0] = 0; + std::string best; + std::string uuiddir("/dev/disk/by-uuid/"); - // TODO + // trawl /dev/disk/by-uuid looking for a good-looking UUID to grab + std::string this_name; + BOOL wrap = FALSE; + while (gDirUtilp->getNextFileInDir(uuiddir, "*", this_name, wrap)) + { + if (this_name.length() > best.length() || + (this_name.length() == best.length() && + this_name > best)) + { + // longest (and secondarily alphabetically last) so far + best = this_name; + } + } + + // we don't return the actual serial number, just a hash of it. + LLMD5 md5( reinterpret_cast<const unsigned char*>(best.c_str()) ); + md5.hex_digest(serial_md5); return serial_md5; } diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index 365fcfeb6b..230c0dc24b 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -33,9 +33,12 @@ #ifndef LL_LLAPPVIEWERLINUX_H #define LL_LLAPPVIEWERLINUX_H -#if LL_DBUS_ENABLED extern "C" { # include <glib.h> +} + +#if LL_DBUS_ENABLED +extern "C" { # include <glib-object.h> # include <dbus/dbus-glib.h> } diff --git a/indra/newview/llappviewerlinux_api_dbus.cpp b/indra/newview/llappviewerlinux_api_dbus.cpp index ee160d0151..da67493e67 100644 --- a/indra/newview/llappviewerlinux_api_dbus.cpp +++ b/indra/newview/llappviewerlinux_api_dbus.cpp @@ -41,9 +41,9 @@ extern "C" { #include "apr_dso.h" } -#define DEBUGMSG(...) lldebugs << llformat(__VA_ARGS__) << llendl -#define INFOMSG(...) llinfos << llformat(__VA_ARGS__) << llendl -#define WARNMSG(...) llwarns << llformat(__VA_ARGS__) << llendl +#define DEBUGMSG(...) do { lldebugs << llformat(__VA_ARGS__) << llendl; } while(0) +#define INFOMSG(...) do { llinfos << llformat(__VA_ARGS__) << llendl; } while(0) +#define WARNMSG(...) do { llwarns << llformat(__VA_ARGS__) << llendl; } while(0) #define LL_DBUS_SYM(REQUIRED, DBUSSYM, RTN, ...) RTN (*ll##DBUSSYM)(__VA_ARGS__) = NULL #include "llappviewerlinux_api_dbus_syms_raw.inc" diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 2b3939d92f..1282e437f2 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -159,15 +159,7 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp) clp.addOptionDesc("psn", NULL, 1, "MacOSX process serial number"); clp.setCustomParser(parse_psn); - // First parse the command line, not often used on the mac. - if(clp.parseCommandLine(gArgC, gArgV) == false) - { - return false; - } - - // Now read in the args from arguments txt. - // Succesive calls to clp.parse... will NOT override earlier - // options. + // First read in the args from arguments txt. const char* filename = "arguments.txt"; llifstream ifs(filename, llifstream::binary); if (!ifs.is_open()) @@ -180,7 +172,14 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp) { return false; } - + + // Then parse the user's command line, so that any --url arg can appear last + // Succesive calls to clp.parse... will NOT override earlier options. + if(clp.parseCommandLine(gArgC, gArgV) == false) + { + return false; + } + // Get the user's preferred language string based on the Mac OS localization mechanism. // To add a new localization: // go to the "Resources" section of the project diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 827ae5855b..cd3963050f 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -539,7 +539,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) gVFS->removeFile(content["new_asset"].asUUID(), LLAssetType::AT_NOTECARD); } - + nc->setAssetId(content["new_asset"].asUUID()); nc->refreshFromInventory(); } break; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 2b5e2369bb..2f67401301 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -255,6 +255,7 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id) LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(id)); if (widget) { + widget->removeNoneOption(); widget->center(); widget->setPowersMask(GP_MEMBER_INVITE); widget->setSelectGroupCallback(boost::bind(callback_invite_to_group, _1, id)); diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp index 1d5fa9ffa7..3e411583ac 100644 --- a/indra/newview/llavatariconctrl.cpp +++ b/indra/newview/llavatariconctrl.cpp @@ -50,7 +50,94 @@ static LLDefaultChildRegistry::Register<LLAvatarIconCtrl> r("avatar_icon"); -LLAvatarIconCtrl::avatar_image_map_t LLAvatarIconCtrl::sImagesCache; +bool LLAvatarIconIDCache::LLAvatarIconIDCacheItem::expired() +{ + const F64 SEC_PER_DAY_PLUS_HOUR = (24.0 + 1.0) * 60.0 * 60.0; + F64 delta = LLDate::now().secondsSinceEpoch() - cached_time.secondsSinceEpoch(); + if (delta > SEC_PER_DAY_PLUS_HOUR) + return true; + return false; +} + +void LLAvatarIconIDCache::load () +{ + llinfos << "Loading avatar icon id cache." << llendl; + + // build filename for each user + std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, mFilename); + llifstream file(resolved_filename); + + if (!file.is_open()) + return; + + // add each line in the file to the list + int uuid_len = UUID_STR_LENGTH-1; + std::string line; + while (std::getline(file, line)) + { + LLUUID avatar_id; + LLUUID icon_id; + LLDate date; + + std::string avatar_id_str = line.substr(0,uuid_len); + std::string icon_id_str = line.substr(uuid_len,uuid_len); + + std::string date_str = line.substr(uuid_len*2, line.length()-uuid_len*2); + + if(!avatar_id.set(avatar_id_str) || !icon_id.set(icon_id_str) || !date.fromString(date_str)) + continue; + + LLAvatarIconIDCacheItem item = {icon_id,date}; + mCache[avatar_id] = item; + } + + file.close(); + +} + +void LLAvatarIconIDCache::save () +{ + std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, mFilename); + + // open a file for writing + llofstream file (resolved_filename); + if (!file.is_open()) + { + llwarns << "can't open avatar icons cache file\"" << mFilename << "\" for writing" << llendl; + return; + } + + for(std::map<LLUUID,LLAvatarIconIDCacheItem>::iterator it = mCache.begin();it!=mCache.end();++it) + { + if(!it->second.expired()) + { + file << it->first << it->second.icon_id << it->second.cached_time << std::endl; + } + } + + file.close(); +} + +LLUUID* LLAvatarIconIDCache::get (const LLUUID& avatar_id) +{ + std::map<LLUUID,LLAvatarIconIDCacheItem>::iterator it = mCache.find(avatar_id); + if(it==mCache.end()) + return 0; + if(it->second.expired()) + return 0; + return &it->second.icon_id; +} + +void LLAvatarIconIDCache::add (const LLUUID& avatar_id,const LLUUID& icon_id) +{ + LLAvatarIconIDCacheItem item = {icon_id,LLDate::now()}; + mCache[avatar_id] = item; +} + +void LLAvatarIconIDCache::remove (const LLUUID& avatar_id) +{ + mCache.erase(avatar_id); +} LLAvatarIconCtrl::Params::Params() @@ -161,18 +248,13 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) // an avatar. // Check if cache already contains image_id for that avatar - avatar_image_map_t::iterator it = sImagesCache.find(mAvatarId); - if (it != sImagesCache.end()) - { - updateFromCache(it->second); - } - else + + if (!updateFromCache()) { - app->addObserver(value.asUUID(), this); - app->sendAvatarPropertiesRequest(value.asUUID()); + app->addObserver(mAvatarId, this); + app->sendAvatarPropertiesRequest(mAvatarId); } } - } else { @@ -182,12 +264,18 @@ void LLAvatarIconCtrl::setValue(const LLSD& value) gCacheName->get(mAvatarId, FALSE, boost::bind(&LLAvatarIconCtrl::nameUpdatedCallback, this, _1, _2, _3, _4)); } -void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data) +bool LLAvatarIconCtrl::updateFromCache() { + LLUUID* icon_id_ptr = LLAvatarIconIDCache::getInstance()->get(mAvatarId); + if(!icon_id_ptr) + return false; + + const LLUUID& icon_id = *icon_id_ptr; + // Update the avatar - if (data.image_id.notNull()) + if (icon_id.notNull()) { - LLIconCtrl::setValue(data.image_id); + LLIconCtrl::setValue(icon_id); } else { @@ -224,6 +312,7 @@ void LLAvatarIconCtrl::updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data) setToolTip((LLStringExplicit)""); } } + return true; } //virtual @@ -239,10 +328,8 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type) return; } - LLAvatarIconCtrl::LLImagesCacheItem data(avatar_data->image_id, avatar_data->flags); - - updateFromCache(data); - sImagesCache.insert(std::pair<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem>(mAvatarId, data)); + LLAvatarIconIDCache::getInstance()->add(mAvatarId,avatar_data->image_id); + updateFromCache(); } } } diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h index 49e304a521..77390eb233 100644 --- a/indra/newview/llavatariconctrl.h +++ b/indra/newview/llavatariconctrl.h @@ -37,6 +37,35 @@ #include "llavatarpropertiesprocessor.h" #include "llviewermenu.h" +class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache> +{ +public: + struct LLAvatarIconIDCacheItem + { + LLUUID icon_id; + LLDate cached_time; + + bool expired(); + }; + + LLAvatarIconIDCache():mFilename("avatar_icons_cache.txt") + { + } + + void load (); + void save (); + + LLUUID* get (const LLUUID& id); + void add (const LLUUID& avatar_id,const LLUUID& icon_id); + + void remove (const LLUUID& id); +protected: + + + std::string mFilename; + std::map<LLUUID,LLAvatarIconIDCacheItem> mCache;//we cache only LLUID and time +}; + class LLAvatarIconCtrl : public LLIconCtrl, public LLAvatarPropertiesObserver { @@ -82,19 +111,8 @@ protected: LLHandle<LLView> mPopupMenuHandle; bool mDrawTooltip; - struct LLImagesCacheItem - { - LLUUID image_id; - U32 flags; - - LLImagesCacheItem(LLUUID image_id_, U32 flags_) : image_id(image_id_), flags(flags_) {} - }; - - typedef std::map<LLUUID, LLAvatarIconCtrl::LLImagesCacheItem> avatar_image_map_t; - - static avatar_image_map_t sImagesCache; - void updateFromCache(LLAvatarIconCtrl::LLImagesCacheItem data); + bool updateFromCache(); }; #endif // LL_LLAVATARICONCTRL_H diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 51545bcc07..4179d7a58d 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -33,6 +33,7 @@ #include "llviewerprecompiledheaders.h" +#include "llavataractions.h" #include "llavatarlistitem.h" #include "llfloaterreg.h" @@ -49,6 +50,7 @@ LLAvatarListItem::LLAvatarListItem() mStatus(NULL), mSpeakingIndicator(NULL), mInfoBtn(NULL), + mProfileBtn(NULL), mContextMenu(NULL), mAvatarId(LLUUID::null) { @@ -63,10 +65,14 @@ BOOL LLAvatarListItem::postBuild() mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator"); mInfoBtn = getChild<LLButton>("info_btn"); + mProfileBtn = getChild<LLButton>("profile_btn"); mInfoBtn->setVisible(false); mInfoBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onInfoBtnClick, this)); + mProfileBtn->setVisible(false); + mProfileBtn->setClickedCallback(boost::bind(&LLAvatarListItem::onProfileBtnClick, this)); + /* if(!p.buttons.profile) { @@ -104,6 +110,7 @@ void LLAvatarListItem::onMouseEnter(S32 x, S32 y, MASK mask) { childSetVisible("hovered_icon", true); mInfoBtn->setVisible(true); + mProfileBtn->setVisible(true); LLPanel::onMouseEnter(x, y, mask); } @@ -112,6 +119,7 @@ void LLAvatarListItem::onMouseLeave(S32 x, S32 y, MASK mask) { childSetVisible("hovered_icon", false); mInfoBtn->setVisible(false); + mProfileBtn->setVisible(false); LLPanel::onMouseLeave(x, y, mask); } @@ -171,6 +179,11 @@ void LLAvatarListItem::onInfoBtnClick() */ } +void LLAvatarListItem::onProfileBtnClick() +{ + LLAvatarActions::showProfile(mAvatarId); +} + void LLAvatarListItem::showStatus(bool show_status) { // *HACK: dirty hack until we can determine correct avatar status (EXT-1076). diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h index bde9250e4a..871441b2d3 100644 --- a/indra/newview/llavatarlistitem.h +++ b/indra/newview/llavatarlistitem.h @@ -66,6 +66,7 @@ public: const std::string getAvatarName() const; void onInfoBtnClick(); + void onProfileBtnClick(); void showSpeakingIndicator(bool show) { mSpeakingIndicator->setVisible(show); } void showInfoBtn(bool show_info_btn) {mInfoBtn->setVisible(show_info_btn); } @@ -82,6 +83,7 @@ private: LLOutputMonitorCtrl* mSpeakingIndicator; LLButton* mInfoBtn; + LLButton* mProfileBtn; ContextMenu* mContextMenu; LLUUID mAvatarId; diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp index 8771611b1c..0ff8ca7d26 100644 --- a/indra/newview/llbottomtray.cpp +++ b/indra/newview/llbottomtray.cpp @@ -87,6 +87,7 @@ BOOL LLBottomTray::postBuild() mMovementPanel = getChild<LLPanel>("movement_panel"); mGestureCombo = getChild<LLComboBox>("Gesture"); mCamPanel = getChild<LLPanel>("cam_panel"); + mSnapshotPanel = getChild<LLPanel>("snapshot_panel"); setRightMouseDownCallback(boost::bind(&LLBottomTray::showBottomTrayContextMenu,this, _2, _3,_4)); return TRUE; @@ -212,7 +213,7 @@ void LLBottomTray::setVisible(BOOL visible) LLView* viewp = *child_it; std::string name = viewp->getName(); - if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name) + if ("chat_bar" == name || "movement_panel" == name || "cam_panel" == name || "snapshot_panel" == name) continue; else { @@ -266,3 +267,8 @@ void LLBottomTray::showCameraButton(BOOL visible) { mCamPanel->setVisible(visible); } + +void LLBottomTray::showSnapshotButton(BOOL visible) +{ + mSnapshotPanel->setVisible(visible); +} diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h index b25dec7b92..4724c5ecef 100644 --- a/indra/newview/llbottomtray.h +++ b/indra/newview/llbottomtray.h @@ -76,6 +76,7 @@ public: void showGestureButton(BOOL visible); void showMoveButton(BOOL visible); void showCameraButton(BOOL visible); + void showSnapshotButton(BOOL visible); private: @@ -100,6 +101,7 @@ protected: LLMenuGL* mBottomTrayContextMenu; LLPanel* mMovementPanel; LLPanel* mCamPanel; + LLPanel* mSnapshotPanel; LLComboBox* mGestureCombo; }; diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index e3440ee779..2b7bd83ca3 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -682,7 +682,11 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) { std::string notifyMsg = notification->getMessage(); if (!notifyMsg.empty()) + { floater->addHistoryLine(notifyMsg,LLUIColorTable::instance().getColor("SystemChatColor")); + + LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, notifyMsg); + } } } diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index 25620c2aed..63b9fd8e66 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -59,6 +59,7 @@ static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f; static const S32 msg_left_offset = 30; static const S32 msg_right_offset = 10; +static const S32 msg_height_pad = 2; //static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl> t2("chat_items_container"); @@ -178,14 +179,14 @@ void LLNearbyChatToastPanel::setMessage (const LLChat& chat_msg) void LLNearbyChatToastPanel::snapToMessageHeight () { LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false); - S32 new_height = text_box->getTextPixelHeight(); + S32 new_height = text_box->getTextPixelHeight() + msg_height_pad; LLRect panel_rect = getRect(); S32 caption_height = 0; LLPanel* caption = getChild<LLPanel>("msg_caption", false); caption_height = caption->getRect().getHeight(); - panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth() , caption_height + new_height); + panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), caption_height + new_height); reshape( getRect().getWidth(), caption_height + new_height, 1); diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp index 6eaafc9059..12626e3b43 100644 --- a/indra/newview/llchatmsgbox.cpp +++ b/indra/newview/llchatmsgbox.cpp @@ -59,7 +59,7 @@ public: /*virtual*/ S32 getWidth(S32 first_char, S32 num_chars) const { - return mEditor->getDocumentPanel()->getRect().getWidth(); + return mEditor->getDocumentView()->getRect().getWidth(); } /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 23664fa6d6..340b0fa22c 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -763,15 +763,14 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index) if(mScrollArea->addChild(chiclet)) { S32 offset = 0; - // Do not scroll chiclets if chiclets are scrolled right and new - // chiclet is added to the beginning of the list - if(canScrollLeft()) + + // if index == 0 and chickelt list isn't empty insert chiclet before first in the list + // without scrolling, so other visible chicklets aren't change screen position + if (0 == index && !mChicletList.empty()) { - offset = - (chiclet->getRequiredRect().getWidth() + getChicletPadding()); - if(0 == index) - { - offset += getChiclet(0)->getRect().mLeft; - } + offset = getChiclet(0)->getRect().mLeft + - (chiclet->getRequiredRect().getWidth() + + getChicletPadding()); } mChicletList.insert(mChicletList.begin() + index, chiclet); @@ -1128,6 +1127,25 @@ BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks) return TRUE; } +bool LLChicletPanel::isAnyIMFloaterDoked() +{ + bool res = false; + for (chiclet_list_t::iterator it = mChicletList.begin(); it + != mChicletList.end(); it++) + { + LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>( + "impanel", (*it)->getSessionId()); + if (im_floater != NULL && im_floater->getVisible() + && !im_floater->isMinimized() && im_floater->isDocked()) + { + res = true; + break; + } + } + + return res; +} + ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index ef47b54333..458bc73bc4 100644 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -752,6 +752,8 @@ protected: S32 getScrollingOffset() { return mScrollingOffset; } + bool isAnyIMFloaterDoked(); + protected: chiclet_list_t mChicletList; @@ -818,7 +820,10 @@ T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S3 return NULL; } - scrollToChiclet(chiclet); + if (!isAnyIMFloaterDoked()) + { + scrollToChiclet(chiclet); + } chiclet->setSessionId(session_id); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index f56359afc3..21e17cc207 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -369,7 +369,7 @@ void LLDrawPoolWater::shade() LLVector3 light_dir; LLColor3 light_color; - if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) { light_dir = gSky.getSunDirection(); light_dir.normVec(); diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 2467356018..e2d6bcee8f 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -57,7 +57,20 @@ public: { return start_offset; } - /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const { return getEnd() - getStart(); } + /*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const + { + // require full line to ourselves + if (line_offset == 0) + { + // print all our text + return getEnd() - getStart(); + } + else + { + // wait for next line + return 0; + } + } /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { F32 right_x; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index b0ae13348b..4246cbc27f 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -280,6 +280,11 @@ void LLFace::setTexture(LLViewerTexture* tex) mTexture = tex ; } +void LLFace::dirtyTexture() +{ + gPipeline.markTextured(getDrawable()); +} + void LLFace::switchTexture(LLViewerTexture* new_texture) { if(mTexture == new_texture) @@ -295,7 +300,7 @@ void LLFace::switchTexture(LLViewerTexture* new_texture) getViewerObject()->changeTEImage(mTEOffset, new_texture) ; setTexture(new_texture) ; - gPipeline.markTextured(getDrawable()); + dirtyTexture(); } void LLFace::setTEOffset(const S32 te_offset) diff --git a/indra/newview/llface.h b/indra/newview/llface.h index f6ffefcb7c..d734b327d9 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -90,6 +90,7 @@ public: U16 getGeomStart() const { return mGeomIndex; } // index into draw pool void setTexture(LLViewerTexture* tex) ; void switchTexture(LLViewerTexture* new_texture); + void dirtyTexture(); LLXformMatrix* getXform() const { return mXform; } BOOL hasGeometry() const { return mGeomCount > 0; } LLVector3 getPositionAgent() const; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 2be8ac4a0e..2ab17d6220 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -496,7 +496,7 @@ void LLFastTimerView::draw() // Draw the history bars if (LLFastTimer::getLastFrameIndex() >= 0) { - LLLocalClipRect clip(LLRect(xleft, ytop - margin, getRect().getWidth() - margin, margin)); + LLLocalClipRect clip(LLRect(xleft, ytop, getRect().getWidth() - margin, margin)); U64 totalticks; if (!LLFastTimer::sPauseHistory) diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp index 48fcb6b6de..007c6b2c4c 100644 --- a/indra/newview/llfavoritesbar.cpp +++ b/indra/newview/llfavoritesbar.cpp @@ -164,33 +164,6 @@ private: LLSLURLGetter mUrlGetter; }; -class LLFavoritesToggleableMenu : public LLToggleableMenu -{ -public: - virtual BOOL handleHover(S32 x, S32 y, MASK mask) - { - if (fb) - { - fb->handleHover(x, y, mask); - } - - return LLToggleableMenu::handleHover(x, y, mask); - } - - void initFavoritesBarPointer(LLFavoritesBarCtrl* fb) { this->fb = fb; } - -protected: - LLFavoritesToggleableMenu(const LLToggleableMenu::Params& p): - LLToggleableMenu(p) - { - } - - friend class LLUICtrlFactory; - -private: - LLFavoritesBarCtrl* fb; -}; - /** * This class is needed to override LLMenuItemCallGL default handleToolTip function and * show SLURL as button tooltip. @@ -221,6 +194,18 @@ public: return LLMenuItemCallGL::handleMouseUp(x, y, mask); } + virtual BOOL handleHover(S32 x, S32 y, MASK mask) + { + if (fb) + { + fb->handleHover(x, y, mask); + } + + return TRUE; + } + + void initFavoritesBarPointer(LLFavoritesBarCtrl* fb) { this->fb = fb; } + protected: LLFavoriteLandmarkMenuItem(const LLMenuItemCallGL::Params& p) : LLMenuItemCallGL(p) {} @@ -228,6 +213,36 @@ protected: private: LLSLURLGetter mUrlGetter; + LLFavoritesBarCtrl* fb; +}; + +/** + * This class was introduced just for fixing the following issue: + * EXT-836 Nav bar: Favorites overflow menu passes left-mouse click through. + * We must explicitly handle drag and drop event by returning TRUE + * because otherwise LLToolDragAndDrop will initiate drag and drop operation + * with the world. + */ +class LLFavoriteLandmarkToggleableMenu : public LLToggleableMenu +{ +public: + virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) + { + *accept = ACCEPT_NO; + return TRUE; + } + +protected: + LLFavoriteLandmarkToggleableMenu(const LLToggleableMenu::Params& p): + LLToggleableMenu(p) + { + } + + friend class LLUICtrlFactory; }; /** @@ -312,8 +327,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p) boost::bind(&LLFavoritesBarCtrl::doToSelected, this, _2)); // Add this if we need to selectively enable items - //LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Favorites.EnableSelected", - // boost::bind(&LLFavoritesBarCtrl::enableSelected, this, _2)); + LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Favorites.EnableSelected", + boost::bind(&LLFavoritesBarCtrl::enableSelected, this, _2)); gInventory.addObserver(this); } @@ -433,7 +448,7 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y) saveItemsOrder(mItems); - LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*) mPopupMenuHandle.get(); + LLToggleableMenu* menu = (LLToggleableMenu*) mPopupMenuHandle.get(); if (menu && menu->getVisible()) { @@ -794,7 +809,7 @@ void LLFavoritesBarCtrl::showDropDownMenu() { if (mPopupMenuHandle.isDead()) { - LLFavoritesToggleableMenu::Params menu_p; + LLToggleableMenu::Params menu_p; menu_p.name("favorites menu"); menu_p.can_tear_off(false); menu_p.visible(false); @@ -802,12 +817,11 @@ void LLFavoritesBarCtrl::showDropDownMenu() menu_p.max_scrollable_items = 10; menu_p.preferred_width = DROP_DOWN_MENU_WIDTH; - LLFavoritesToggleableMenu* menu = LLUICtrlFactory::create<LLFavoritesToggleableMenu>(menu_p); - menu->initFavoritesBarPointer(this); + LLToggleableMenu* menu = LLUICtrlFactory::create<LLFavoriteLandmarkToggleableMenu>(menu_p); mPopupMenuHandle = menu->getHandle(); } - LLFavoritesToggleableMenu* menu = (LLFavoritesToggleableMenu*)mPopupMenuHandle.get(); + LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get(); if(menu) { @@ -873,6 +887,7 @@ void LLFavoritesBarCtrl::showDropDownMenu() item_params.on_click.function(boost::bind(&LLFavoritesBarCtrl::onButtonClick, this, item->getUUID())); LLFavoriteLandmarkMenuItem *menu_item = LLUICtrlFactory::create<LLFavoriteLandmarkMenuItem>(item_params); + menu_item->initFavoritesBarPointer(this); menu_item->setRightMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonRightClick, this,item->getUUID(),_1,_2,_3,_4)); menu_item->LLUICtrl::setMouseDownCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseDown, this, item->getUUID(), _1, _2, _3, _4)); menu_item->LLUICtrl::setMouseUpCallback(boost::bind(&LLFavoritesBarCtrl::onButtonMouseUp, this, item->getUUID(), _1, _2, _3, _4)); @@ -951,6 +966,18 @@ void copy_slurl_to_clipboard_cb(std::string& slurl) } +bool LLFavoritesBarCtrl::enableSelected(const LLSD& userdata) +{ + std::string param = userdata.asString(); + + if (param == std::string("can_paste")) + { + return isClipboardPasteable(); + } + + return false; +} + void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata) { std::string action = userdata.asString(); @@ -1072,6 +1099,7 @@ void LLFavoritesBarCtrl::pastFromClipboard() const void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask) { mDragItemId = id; + mStartDrag = TRUE; S32 screenX, screenY; localPointToScreen(x, y, &screenX, &screenY); @@ -1081,6 +1109,7 @@ void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 void LLFavoritesBarCtrl::onButtonMouseUp(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask) { + mStartDrag = FALSE; mDragItemId = LLUUID::null; } @@ -1095,7 +1124,7 @@ void LLFavoritesBarCtrl::onEndDrag() BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask) { - if (mDragItemId != LLUUID::null) + if (mDragItemId != LLUUID::null && mStartDrag) { S32 screenX, screenY; localPointToScreen(x, y, &screenX, &screenY); @@ -1106,6 +1135,8 @@ BOOL LLFavoritesBarCtrl::handleHover(S32 x, S32 y, MASK mask) DAD_LANDMARK, mDragItemId, LLToolDragAndDrop::SOURCE_LIBRARY); + mStartDrag = FALSE; + return LLToolDragAndDrop::getInstance()->handleHover(x, y, mask); } } diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h index 97117c3b4a..ea2a3d08e2 100644 --- a/indra/newview/llfavoritesbar.h +++ b/indra/newview/llfavoritesbar.h @@ -81,10 +81,12 @@ protected: void onButtonRightClick(LLUUID id,LLView* button,S32 x,S32 y,MASK mask); void onButtonMouseDown(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask); + void onOverflowMenuItemMouseDown(LLUUID id, LLUICtrl* item, S32 x, S32 y, MASK mask); void onButtonMouseUp(LLUUID id, LLUICtrl* button, S32 x, S32 y, MASK mask); void onEndDrag(); + bool enableSelected(const LLSD& userdata); void doToSelected(const LLSD& userdata); BOOL isClipboardPasteable() const; void pastFromClipboard() const; @@ -149,6 +151,7 @@ private: LLUICtrl* mLastTab; LLUUID mDragItemId; + BOOL mStartDrag; LLInventoryModel::item_array_t mItems; BOOL mTabsHighlightEnabled; diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index c062e6ccf2..55b7ed0c99 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -426,8 +426,8 @@ void LLFloaterAnimPreview::resetMotion() LLUUID base_id = mIDList[childGetValue("preview_base_anim").asString()]; avatarp->deactivateAllMotions(); - avatarp->startMotion(base_id, BASE_ANIM_TIME_OFFSET); avatarp->startMotion(mMotionID, 0.0f); + avatarp->startMotion(base_id, BASE_ANIM_TIME_OFFSET); childSetValue("playback_slider", 0.0f); // Set pose @@ -638,10 +638,10 @@ void LLFloaterAnimPreview::onCommitBaseAnim(LLUICtrl* ctrl, void* data) BOOL paused = avatarp->areAnimationsPaused(); // stop all other possible base motions - avatarp->stopMotion(ANIM_AGENT_STAND, TRUE); - avatarp->stopMotion(ANIM_AGENT_WALK, TRUE); - avatarp->stopMotion(ANIM_AGENT_SIT, TRUE); - avatarp->stopMotion(ANIM_AGENT_HOVER, TRUE); + avatarp->stopMotion(previewp->mIDList["Standing"], TRUE); + avatarp->stopMotion(previewp->mIDList["Walking"], TRUE); + avatarp->stopMotion(previewp->mIDList["Sitting"], TRUE); + avatarp->stopMotion(previewp->mIDList["Flying"], TRUE); previewp->resetMotion(); diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index da2a4d9d93..262dc1804d 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -33,6 +33,7 @@ #include "llviewerprecompiledheaders.h" #include "llfloaterauction.h" +#include "llfloaterregioninfo.h" #include "lldir.h" #include "llgl.h" @@ -56,6 +57,8 @@ #include "llviewercontrol.h" #include "llui.h" #include "llrender.h" +#include "llsdutil.h" +#include "llsdutil_math.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs @@ -77,7 +80,9 @@ LLFloaterAuction::LLFloaterAuction(const LLSD& key) { // LLUICtrlFactory::getInstance()->buildFloater(this, "floater_auction.xml"); mCommitCallbackRegistrar.add("ClickSnapshot", boost::bind(&LLFloaterAuction::onClickSnapshot, this)); - mCommitCallbackRegistrar.add("ClickOK", boost::bind(&LLFloaterAuction::onClickOK, this)); + mCommitCallbackRegistrar.add("ClickSellToAnyone", boost::bind(&LLFloaterAuction::onClickSellToAnyone, this)); + mCommitCallbackRegistrar.add("ClickStartAuction", boost::bind(&LLFloaterAuction::onClickStartAuction, this)); + mCommitCallbackRegistrar.add("ClickResetParcel", boost::bind(&LLFloaterAuction::onClickResetParcel, this)); } // Destroys the object @@ -97,6 +102,8 @@ void LLFloaterAuction::onOpen(const LLSD& key) void LLFloaterAuction::initialize() { + mParcelUpdateCapUrl.clear(); + mParcelp = LLViewerParcelMgr::getInstance()->getParcelSelection(); LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); LLParcel* parcelp = mParcelp->getParcel(); @@ -104,10 +111,23 @@ void LLFloaterAuction::initialize() { mParcelHost = region->getHost(); mParcelID = parcelp->getLocalID(); + mParcelUpdateCapUrl = region->getCapability("ParcelPropertiesUpdate"); childSetText("parcel_text", parcelp->getName()); childEnable("snapshot_btn"); - childEnable("ok_btn"); + childEnable("reset_parcel_btn"); + childEnable("start_auction_btn"); + + LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate(); + if (panel) + { // Only enable "Sell to Anyone" on Teen grid or if we don't know the ID yet + U32 estate_id = panel->getEstateID(); + childSetEnabled("sell_to_anyone_btn", (estate_id == ESTATE_TEEN || estate_id == 0)); + } + else + { // Don't have the panel up, so don't know if we're on the teen grid or not. Default to enabling it + childEnable("sell_to_anyone_btn"); + } } else { @@ -122,8 +142,11 @@ void LLFloaterAuction::initialize() } mParcelID = -1; childSetEnabled("snapshot_btn", false); - childSetEnabled("ok_btn", false); + childSetEnabled("reset_parcel_btn", false); + childSetEnabled("sell_to_anyone_btn", false); + childSetEnabled("start_auction_btn", false); } + mImageID.setNull(); mImage = NULL; } @@ -205,7 +228,7 @@ void LLFloaterAuction::onClickSnapshot(void* data) } // static -void LLFloaterAuction::onClickOK(void* data) +void LLFloaterAuction::onClickStartAuction(void* data) { LLFloaterAuction* self = (LLFloaterAuction*)(data); @@ -244,11 +267,264 @@ void LLFloaterAuction::onClickOK(void* data) msg->sendReliable(self->mParcelHost); // clean up floater, and get out - self->mImageID.setNull(); - self->mImage = NULL; - self->mParcelID = -1; - self->mParcelHost.invalidate(); - self->closeFloater(); + self->cleanupAndClose(); +} + + +void LLFloaterAuction::cleanupAndClose() +{ + mImageID.setNull(); + mImage = NULL; + mParcelID = -1; + mParcelHost.invalidate(); + closeFloater(); +} + + + +// static glue +void LLFloaterAuction::onClickResetParcel(void* data) +{ + LLFloaterAuction* self = (LLFloaterAuction*)(data); + if (self) + { + self->doResetParcel(); + } +} + + +// Reset all the values for the parcel in preparation for a sale +void LLFloaterAuction::doResetParcel() +{ + LLParcel* parcelp = mParcelp->getParcel(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + + if (parcelp + && region + && !mParcelUpdateCapUrl.empty()) + { + LLSD body; + std::string empty; + + // request new properties update from simulator + U32 message_flags = 0x01; + body["flags"] = ll_sd_from_U32(message_flags); + + // Set all the default parcel properties for auction + body["local_id"] = parcelp->getLocalID(); + + U32 parcel_flags = PF_ALLOW_LANDMARK | + PF_ALLOW_FLY | + PF_CREATE_GROUP_OBJECTS | + PF_ALLOW_ALL_OBJECT_ENTRY | + PF_ALLOW_GROUP_OBJECT_ENTRY | + PF_ALLOW_GROUP_SCRIPTS | + PF_RESTRICT_PUSHOBJECT | + PF_SOUND_LOCAL | + PF_ALLOW_VOICE_CHAT | + PF_USE_ESTATE_VOICE_CHAN; + + body["parcel_flags"] = ll_sd_from_U32(parcel_flags); + + // Build a parcel name like "Ahern (128,128) PG 4032m" + std::ostringstream parcel_name; + LLVector3 center_point( parcelp->getCenterpoint() ); + center_point.snap(0); // Get rid of fractions + parcel_name << region->getName() + << " (" + << (S32) center_point.mV[VX] + << "," + << (S32) center_point.mV[VY] + << ") " + << region->getSimAccessString() + << " " + << parcelp->getArea() + << "m"; + + std::string new_name(parcel_name.str().c_str()); + body["name"] = new_name; + childSetText("parcel_text", new_name); // Set name in dialog as well, since it won't get updated otherwise + + body["sale_price"] = (S32) 0; + body["description"] = empty; + body["music_url"] = empty; + body["media_url"] = empty; + body["media_desc"] = empty; + body["media_type"] = std::string("none/none"); + body["media_width"] = (S32) 0; + body["media_height"] = (S32) 0; + body["auto_scale"] = (S32) 0; + body["media_loop"] = (S32) 0; + body["obscure_media"] = (S32) 0; + body["obscure_music"] = (S32) 0; + body["media_id"] = LLUUID::null; + body["group_id"] = MAINTENANCE_GROUP_ID; // Use maintenance group + body["pass_price"] = (S32) 10; // Defaults to $10 + body["pass_hours"] = 0.0f; + body["category"] = (U8) LLParcel::C_NONE; + body["auth_buyer_id"] = LLUUID::null; + body["snapshot_id"] = LLUUID::null; + body["user_location"] = ll_sd_from_vector3( LLVector3::zero ); + body["user_look_at"] = ll_sd_from_vector3( LLVector3::zero ); + body["landing_type"] = (U8) LLParcel::L_DIRECT; + + llinfos << "Sending parcel update to reset for auction via capability to: " + << mParcelUpdateCapUrl << llendl; + LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder()); + + // Send a message to clear the object return time + LLMessageSystem *msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ParcelSetOtherCleanTime); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_LocalID, parcelp->getLocalID()); + msg->addS32Fast(_PREHASH_OtherCleanTime, 5); // 5 minute object auto-return + + msg->sendReliable(region->getHost()); + + // Clear the access lists + clearParcelAccessLists(parcelp, region); + } +} + + + +void LLFloaterAuction::clearParcelAccessLists(LLParcel* parcel, LLViewerRegion* region) +{ + if (!region || !parcel) return; + + LLUUID transactionUUID; + transactionUUID.generate(); + + LLMessageSystem* msg = gMessageSystem; + + // Clear access list + // parcel->mAccessList.clear(); + + msg->newMessageFast(_PREHASH_ParcelAccessListUpdate); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + msg->nextBlockFast(_PREHASH_Data); + msg->addU32Fast(_PREHASH_Flags, AL_ACCESS); + msg->addS32(_PREHASH_LocalID, parcel->getLocalID() ); + msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID); + msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id + msg->addS32Fast(_PREHASH_Sections, 0); // num_sections + + // pack an empty block since there will be no data + msg->nextBlockFast(_PREHASH_List); + msg->addUUIDFast(_PREHASH_ID, LLUUID::null ); + msg->addS32Fast(_PREHASH_Time, 0 ); + msg->addU32Fast(_PREHASH_Flags, 0 ); + + msg->sendReliable( region->getHost() ); + + // Send message for empty ban list + //parcel->mBanList.clear(); + msg->newMessageFast(_PREHASH_ParcelAccessListUpdate); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); + msg->nextBlockFast(_PREHASH_Data); + msg->addU32Fast(_PREHASH_Flags, AL_BAN); + msg->addS32(_PREHASH_LocalID, parcel->getLocalID() ); + msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID); + msg->addS32Fast(_PREHASH_SequenceID, 1); // sequence_id + msg->addS32Fast(_PREHASH_Sections, 0); // num_sections + + // pack an empty block since there will be no data + msg->nextBlockFast(_PREHASH_List); + msg->addUUIDFast(_PREHASH_ID, LLUUID::null ); + msg->addS32Fast(_PREHASH_Time, 0 ); + msg->addU32Fast(_PREHASH_Flags, 0 ); + + msg->sendReliable( region->getHost() ); +} + + + +// static - 'Sell to Anyone' clicked, throw up a confirmation dialog +void LLFloaterAuction::onClickSellToAnyone(void* data) +{ + LLFloaterAuction* self = (LLFloaterAuction*)(data); + if (self) + { + LLParcel* parcelp = self->mParcelp->getParcel(); + + // Do a confirmation + S32 sale_price = parcelp->getArea(); // Selling for L$1 per meter + S32 area = parcelp->getArea(); + + LLSD args; + args["LAND_SIZE"] = llformat("%d", area); + args["SALE_PRICE"] = llformat("%d", sale_price); + args["NAME"] = "Anyone"; + + LLNotification::Params params("ConfirmLandSaleChange"); // Re-use existing dialog + params.substitutions(args) + .functor.function(boost::bind(&LLFloaterAuction::onSellToAnyoneConfirmed, self, _1, _2)); + + params.name("ConfirmLandSaleToAnyoneChange"); + + // ask away + LLNotifications::instance().add(params); + } +} + + +// Sell confirmation clicked +bool LLFloaterAuction::onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotification::getSelectedOption(notification, response); + if (option == 0) + { + doSellToAnyone(); + } + + return false; +} + + + +// Reset all the values for the parcel in preparation for a sale +void LLFloaterAuction::doSellToAnyone() +{ + LLParcel* parcelp = mParcelp->getParcel(); + LLViewerRegion* region = LLViewerParcelMgr::getInstance()->getSelectionRegion(); + + if (parcelp + && region + && !mParcelUpdateCapUrl.empty()) + { + LLSD body; + std::string empty; + + // request new properties update from simulator + U32 message_flags = 0x01; + body["flags"] = ll_sd_from_U32(message_flags); + + // Set all the default parcel properties for auction + body["local_id"] = parcelp->getLocalID(); + + // Set 'for sale' flag + U32 parcel_flags = parcelp->getParcelFlags() | PF_FOR_SALE; + // Ensure objects not included + parcel_flags &= ~PF_FOR_SALE_OBJECTS; + body["parcel_flags"] = ll_sd_from_U32(parcel_flags); + + body["sale_price"] = parcelp->getArea(); // Sell for L$1 per square meter + body["auth_buyer_id"] = LLUUID::null; // To anyone + + llinfos << "Sending parcel update to sell to anyone for L$1 via capability to: " + << mParcelUpdateCapUrl << llendl; + LLHTTPClient::post(mParcelUpdateCapUrl, body, new LLHTTPClient::Responder()); + + // clean up floater, and get out + cleanupAndClose(); + } } diff --git a/indra/newview/llfloaterauction.h b/indra/newview/llfloaterauction.h index 1acc08057c..c599af782d 100644 --- a/indra/newview/llfloaterauction.h +++ b/indra/newview/llfloaterauction.h @@ -45,6 +45,8 @@ // Class which holds the functionality to start auctions. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LLParcelSelection; +class LLParcel; +class LLViewerRegion; class LLFloaterAuction : public LLFloater { @@ -62,16 +64,28 @@ private: void initialize(); static void onClickSnapshot(void* data); - static void onClickOK(void* data); + static void onClickResetParcel(void* data); + static void onClickSellToAnyone(void* data); // Sell to anyone clicked + bool onSellToAnyoneConfirmed(const LLSD& notification, const LLSD& response); // Sell confirmation clicked + static void onClickStartAuction(void* data); /*virtual*/ BOOL postBuild(); + + void doResetParcel(); + void doSellToAnyone(); + void clearParcelAccessLists( LLParcel* parcel, LLViewerRegion* region ); + void cleanupAndClose(); + private: + LLTransactionID mTransactionID; LLAssetID mImageID; LLPointer<LLViewerTexture> mImage; LLSafeHandle<LLParcelSelection> mParcelp; S32 mParcelID; LLHost mParcelHost; + + std::string mParcelUpdateCapUrl; // "ParcelPropertiesUpdate" capability }; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 890d863db7..ccfe7d4b64 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -69,7 +69,7 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(callback_t callback, // Default constructor LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key) : LLFloater(key), - mResultsReturned(FALSE), + mNumResultsReturned(0), mCallback(NULL), mCallbackUserdata(NULL), mNearMeListComplete(FALSE), @@ -314,7 +314,7 @@ void LLFloaterAvatarPicker::find() getChild<LLScrollListCtrl>("SearchResults")->setCommentText(getString("searching")); childSetEnabled("Select", FALSE); - mResultsReturned = FALSE; + mNumResultsReturned = 0; } void LLFloaterAvatarPicker::setAllowMultiple(BOOL allow_multiple) @@ -349,9 +349,10 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* LLScrollListCtrl* search_results = floater->getChild<LLScrollListCtrl>("SearchResults"); // clear "Searching" label on first results - search_results->deleteAllItems(); - - floater->mResultsReturned = TRUE; + if (floater->mNumResultsReturned++ == 0) + { + search_results->deleteAllItems(); + } BOOL found_one = FALSE; S32 num_new_rows = msg->getNumberOfBlocks("Data"); diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index f3b9aefb9c..85aacb68a5 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -76,7 +76,7 @@ private: virtual BOOL handleKeyHere(KEY key, MASK mask); LLUUID mQueryID; - BOOL mResultsReturned; + int mNumResultsReturned; BOOL mNearMeListComplete; BOOL mCloseOnSelect; diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index 5c4b8552a6..e160cd01be 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -175,48 +175,54 @@ void LLFloaterBuyCurrencyUI::updateUI() bool hasError = mManager.hasError(); mManager.updateUI(!hasError && !mManager.buying()); - // section zero: title area - { - childSetVisible("info_buying", false); - childSetVisible("info_cannot_buy", false); - childSetVisible("info_need_more", false); - if (hasError) - { - childSetVisible("info_cannot_buy", true); - } - else if (mHasTarget) - { - childSetVisible("info_need_more", true); - } - else - { - childSetVisible("info_buying", true); - } - } - - // error section + // hide most widgets - we'll turn them on as needed next + childHide("info_buying"); + childHide("info_cannot_buy"); + childHide("info_need_more"); + childHide("purchase_warning_repurchase"); + childHide("purchase_warning_notenough"); + childHide("contacting"); + childHide("buy_action"); + if (hasError) { + // display an error from the server childHide("normal_background"); childShow("error_background"); + childShow("info_cannot_buy"); childShow("cannot_buy_message"); - childShow("error_web"); + childHide("balance_label"); + childHide("balance_amount"); + childHide("buying_label"); + childHide("buying_amount"); + childHide("total_label"); + childHide("total_amount"); + + LLTextBox* message = getChild<LLTextBox>("cannot_buy_message"); + if (message) + { + message->setText(mManager.errorMessage()); + } + + childSetVisible("error_web", !mManager.errorURI().empty()); } else { + // display the main Buy L$ interface childShow("normal_background"); childHide("error_background"); childHide("cannot_buy_message"); childHide("error_web"); - } - // currency - childSetVisible("contacting", false); - childSetVisible("buy_action", false); - childSetVisible("buy_action_unknown", false); - - if (!hasError) - { + if (mHasTarget) + { + childShow("info_need_more"); + } + else + { + childShow("info_buying"); + } + if (mManager.buying()) { childSetVisible("contacting", true); @@ -229,10 +235,6 @@ void LLFloaterBuyCurrencyUI::updateUI() childSetTextArg("buy_action", "[NAME]", mTargetName); childSetTextArg("buy_action", "[PRICE]", llformat("%d",mTargetPrice)); } - else - { - childSetVisible("buy_action_unknown", true); - } } S32 balance = gStatusBar->getBalance(); @@ -250,8 +252,6 @@ void LLFloaterBuyCurrencyUI::updateUI() childShow("total_amount"); childSetTextArg("total_amount", "[AMT]", llformat("%d", total)); - childSetVisible("purchase_warning_repurchase", false); - childSetVisible("purchase_warning_notenough", false); if (mHasTarget) { if (total >= mTargetPrice) @@ -264,24 +264,8 @@ void LLFloaterBuyCurrencyUI::updateUI() } } } - else - { - childHide("step_1"); - childHide("balance_label"); - childHide("balance_amount"); - childHide("buying_label"); - childHide("buying_amount"); - childHide("total_label"); - childHide("total_amount"); - childHide("purchase_warning_repurchase"); - childHide("purchase_warning_notenough"); - } - - childHide("getting_data"); - if (!mManager.canBuy() && !hasError) - { - childShow("getting_data"); - } + + childSetVisible("getting_data", !mManager.canBuy() && !hasError); } void LLFloaterBuyCurrencyUI::onClickBuy() @@ -297,7 +281,7 @@ void LLFloaterBuyCurrencyUI::onClickCancel() void LLFloaterBuyCurrencyUI::onClickErrorWeb() { - LLWeb::loadURLExternal(getString("account_website")); + LLWeb::loadURLExternal(mManager.errorURI()); closeFloater(); } diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 0511ec1063..db20b11efd 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -39,7 +39,6 @@ // Viewer includes #include "lljoystickbutton.h" -#include "llfirsttimetipmanager.h" #include "llviewercontrol.h" #include "llbottomtray.h" #include "llagent.h" @@ -54,10 +53,6 @@ const F32 CAMERA_BUTTON_DELAY = 0.0f; #define CONTROLS "controls" -void show_tip(LLFirstTimeTipsManager::EFirstTimeTipType tipType, LLView* anchorView) -{ - LLFirstTimeTipsManager::showTipsFor(tipType, anchorView, LLFirstTimeTipsManager::TPA_POS_RIGHT_ALIGN_TOP); -} // // Member functions // @@ -88,7 +83,6 @@ void LLFloaterCamera::update() { ECameraControlMode mode = determineMode(); if (mode != mCurrMode) setMode(mode); - show_tip(mMode2TipType[mode], this); } @@ -129,12 +123,11 @@ void LLFloaterCamera::onOpen(const LLSD& key) anchor_panel, this, getDockTongue(), LLDockControl::TOP)); - show_tip(mMode2TipType[mCurrMode], this); } LLFloaterCamera::LLFloaterCamera(const LLSD& val) -: LLDockableFloater(NULL, false, val), +: LLDockableFloater(NULL, val), mCurrMode(CAMERA_CTRL_MODE_ORBIT), mPrevMode(CAMERA_CTRL_MODE_ORBIT) { @@ -149,8 +142,6 @@ BOOL LLFloaterCamera::postBuild() mZoom = getChild<LLJoystickCameraZoom>("zoom"); mTrack = getChild<LLJoystickCameraTrack>(PAN); - initMode2TipTypeMap(); - assignButton2Mode(CAMERA_CTRL_MODE_ORBIT, "orbit_btn"); assignButton2Mode(CAMERA_CTRL_MODE_PAN, "pan_btn"); assignButton2Mode(CAMERA_CTRL_MODE_FREE_CAMERA, "freecamera_btn"); @@ -236,7 +227,6 @@ void LLFloaterCamera::onClickBtn(ECameraControlMode mode) switchMode(mode); - show_tip(mMode2TipType[mode], this); } void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::string& button_name) @@ -247,15 +237,6 @@ void LLFloaterCamera::assignButton2Mode(ECameraControlMode mode, const std::stri mMode2Button[mode] = button; } -void LLFloaterCamera::initMode2TipTypeMap() -{ - mMode2TipType[CAMERA_CTRL_MODE_ORBIT] = LLFirstTimeTipsManager::FTT_CAMERA_ORBIT_MODE; - mMode2TipType[CAMERA_CTRL_MODE_PAN] = LLFirstTimeTipsManager::FTT_CAMERA_PAN_MODE; - mMode2TipType[CAMERA_CTRL_MODE_FREE_CAMERA] = LLFirstTimeTipsManager::FTT_CAMERA_FREE_MODE; - mMode2TipType[CAMERA_CTRL_MODE_AVATAR_VIEW] = LLFirstTimeTipsManager::FTT_AVATAR_FREE_MODE; -} - - void LLFloaterCamera::updateState() { //updating buttons @@ -305,7 +286,7 @@ void LLFloaterCamera::updateState() //-------------LLFloaterCameraPresets------------------------ LLFloaterCameraPresets::LLFloaterCameraPresets(const LLSD& key): -LLDockableFloater(NULL, false, key) +LLDockableFloater(NULL, key) {} BOOL LLFloaterCameraPresets::postBuild() @@ -330,17 +311,14 @@ void LLFloaterCameraPresets::onClickCameraPresets(LLUICtrl* ctrl, const LLSD& pa if ("rear_view" == name) { - LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_REAR, ctrl); gAgent.switchCameraPreset(CAMERA_PRESET_REAR_VIEW); } else if ("group_view" == name) { - LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_GROUP); gAgent.switchCameraPreset(CAMERA_PRESET_GROUP_VIEW); } else if ("front_view" == name) { - LLFirstTimeTipsManager::showTipsFor(LLFirstTimeTipsManager::FTT_CAMERA_PRESET_FRONT); gAgent.switchCameraPreset(CAMERA_PRESET_FRONT_VIEW); } diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 020cae7e82..69df861a20 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -35,8 +35,6 @@ #include "lldockablefloater.h" -#include "llfirsttimetipmanager.h" - class LLJoystickCameraRotate; class LLJoystickCameraZoom; class LLJoystickCameraTrack; @@ -105,13 +103,11 @@ private: void onClickBtn(ECameraControlMode mode); void assignButton2Mode(ECameraControlMode mode, const std::string& button_name); - void initMode2TipTypeMap(); - + ECameraControlMode mPrevMode; ECameraControlMode mCurrMode; std::map<ECameraControlMode, LLButton*> mMode2Button; - std::map<ECameraControlMode, LLFirstTimeTipsManager::EFirstTimeTipType> mMode2TipType; }; diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp index e0fe87f9ae..1300103423 100644 --- a/indra/newview/llfloatergesture.cpp +++ b/indra/newview/llfloatergesture.cpp @@ -211,25 +211,16 @@ void LLFloaterGesture::buildGestureList() std::string key_string = LLKeyboard::stringFromKey(gesture->mKey); std::string buffer; + if (gesture->mKey == KEY_NONE) { - if (gesture->mKey == KEY_NONE) - { - buffer = "---"; - key_string = "~~~"; // alphabetize to end - } - else - { - if (gesture->mMask & MASK_CONTROL) buffer.append("Ctrl-"); - if (gesture->mMask & MASK_ALT) buffer.append("Alt-"); - if (gesture->mMask & MASK_SHIFT) buffer.append("Shift-"); - if ((gesture->mMask & (MASK_CONTROL|MASK_ALT|MASK_SHIFT)) && - (key_string[0] == '-' || key_string[0] == '=')) - { - buffer.append(" "); - } - buffer.append(key_string); - } + buffer = "---"; + key_string = "~~~"; // alphabetize to end } + else + { + buffer = LLKeyboard::stringFromAccelerator( gesture->mMask, gesture->mKey ); + } + element["columns"][1]["column"] = "shortcut"; element["columns"][1]["value"] = buffer; element["columns"][1]["font"]["name"] = "SANSSERIF"; diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp index 3648898f28..45af515a86 100644 --- a/indra/newview/llfloatergroups.cpp +++ b/indra/newview/llfloatergroups.cpp @@ -89,15 +89,6 @@ BOOL LLFloaterGroupPicker::postBuild() list_ctrl->setContextMenu(LLScrollListCtrl::MENU_GROUP); } - // Remove group "none" from list. Group "none" is added in init_group_list(). - // Some UI elements use group "none", we need to manually delete it here. - // Group "none" ID is LLUUID:null. - LLCtrlListInterface* group_list = list_ctrl->getListInterface(); - if(group_list) - { - group_list->selectByValue(LLUUID::null); - group_list->operateOnSelection(LLCtrlListInterface::OP_DELETE); - } childSetAction("OK", onBtnOK, this); @@ -110,6 +101,20 @@ BOOL LLFloaterGroupPicker::postBuild() return TRUE; } +void LLFloaterGroupPicker::removeNoneOption() +{ + // Remove group "none" from list. Group "none" is added in init_group_list(). + // Some UI elements use group "none", we need to manually delete it here. + // Group "none" ID is LLUUID:null. + LLCtrlListInterface* group_list = getChild<LLScrollListCtrl>("group list")->getListInterface(); + if(group_list) + { + group_list->selectByValue(LLUUID::null); + group_list->operateOnSelection(LLCtrlListInterface::OP_DELETE); + } +} + + void LLFloaterGroupPicker::onBtnOK(void* userdata) { LLFloaterGroupPicker* self = (LLFloaterGroupPicker*)userdata; diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h index 489238356d..ce3a470a23 100644 --- a/indra/newview/llfloatergroups.h +++ b/indra/newview/llfloatergroups.h @@ -72,6 +72,9 @@ public: static LLFloaterGroupPicker* findInstance(const LLSD& seed); static LLFloaterGroupPicker* createInstance(const LLSD& seed); + // for cases like inviting avatar to group we don't want the none option + void removeNoneOption(); + protected: void ok(); static void onBtnOK(void* userdata); diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp index 3c3508b65c..9947cdc217 100644 --- a/indra/newview/llfloaterhardwaresettings.cpp +++ b/indra/newview/llfloaterhardwaresettings.cpp @@ -47,7 +47,7 @@ #include "llradiogroup.h" #include "lluictrlfactory.h" #include "llwindow.h" -#include "llslider.h" +#include "llsliderctrl.h" LLFloaterHardwareSettings::LLFloaterHardwareSettings(const LLSD& key) : LLFloater(key) @@ -91,8 +91,8 @@ void LLFloaterHardwareSettings::refreshEnabledState() { S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting(); S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(); - getChild<LLSlider>("GrapicsCardTextureMemory")->setMinValue(min_tex_mem); - getChild<LLSlider>("GrapicsCardTextureMemory")->setMinValue(max_tex_mem); + getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem); + getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem); if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || !gGLManager.mHasVertexBufferObject) diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp index 116286329c..d9cd929606 100644 --- a/indra/newview/llfloaterinventory.cpp +++ b/indra/newview/llfloaterinventory.cpp @@ -1491,7 +1491,8 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id) { LLFolderViewFolder::Params p; p.name = new_listener->getDisplayName(); - p.icon = new_listener->getIcon(); + p.icon = LLUI::getUIImage("Inv_FolderClosed"); + p.icon_open = LLUI::getUIImage("Inv_FolderOpen"); p.root = mFolders; p.listener = new_listener; LLFolderViewFolder* folderp = LLUICtrlFactory::create<LLFolderViewFolder>(p); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index a378a511b5..c1031ee437 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -105,7 +105,7 @@ public: // LLFloaterLand //--------------------------------------------------------------------------- -void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, +void send_parcel_select_objects(S32 parcel_local_id, U32 return_type, uuid_list_t* return_ids = NULL) { LLMessageSystem *msg = gMessageSystem; @@ -123,7 +123,7 @@ void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_ParcelData); msg->addS32Fast(_PREHASH_LocalID, parcel_local_id); - msg->addS32Fast(_PREHASH_ReturnType, return_type); + msg->addU32Fast(_PREHASH_ReturnType, return_type); // Throw all return ids into the packet. // TODO: Check for too many ids. diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index eac1b65f7d..0c9a759f32 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -30,7 +30,6 @@ * $/LicenseInfo$ */ -#include <string> #include "llviewerprecompiledheaders.h" // self include @@ -52,13 +51,6 @@ #include "llviewermenu.h" // -// Constants -// -const F32 MAP_SCALE_MIN = 64; -const F32 MAP_SCALE_MID = 172; -const F32 MAP_SCALE_MAX = 512; - -// // Member functions // diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 0330a8c692..e15fdd3e35 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1522,6 +1522,7 @@ bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& re LLFloaterGroupPicker* widget = LLFloaterReg::showTypedInstance<LLFloaterGroupPicker>("group_picker", LLSD(gAgent.getID())); if (widget) { + widget->removeNoneOption(); widget->setSelectGroupCallback(boost::bind(&LLPanelEstateInfo::addAllowedGroup2, this, _1)); if (parent_floater) { diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 1ec869da73..70a3ad5252 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -143,6 +143,7 @@ BOOL LLFloaterReporter::postBuild() LLViewerRegion *regionp = gAgent.getRegion(); if (regionp) { + childSetText("sim_field", regionp->getName()); pos -= regionp->getOriginGlobal(); } setPosBox(pos); diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp index 43d31aa30a..2d8ccd1aef 100644 --- a/indra/newview/llfloatersellland.cpp +++ b/indra/newview/llfloatersellland.cpp @@ -47,7 +47,7 @@ #include "llviewerwindow.h" // defined in llfloaterland.cpp -void send_parcel_select_objects(S32 parcel_local_id, S32 return_type, +void send_parcel_select_objects(S32 parcel_local_id, U32 return_type, uuid_list_t* return_ids = NULL); enum Badge { BADGE_OK, BADGE_NOTE, BADGE_WARN, BADGE_ERROR }; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 320647ff1a..e00b352c9b 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -417,6 +417,11 @@ void LLFloaterTools::refresh() LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount()); childSetTextArg("prim_count", "[COUNT]", prim_count_string); + // disable the object and prim counts if nothing selected + bool have_selection = ! LLSelectMgr::getInstance()->getSelection()->isEmpty(); + childSetEnabled("obj_count", have_selection); + childSetEnabled("prim_count", have_selection); + // Refresh child tabs mPanelPermissions->refresh(); mPanelObject->refresh(); @@ -1060,7 +1065,7 @@ void LLFloaterTools::getMediaState() return; } - bool editable = (first_object->permModify());// && selectedMediaEditable()); + bool editable = (first_object->permModify() || selectedMediaEditable()); // Media settings U8 has_media = (U8)0; @@ -1114,7 +1119,7 @@ void LLFloaterTools::getMediaState() // Media data is valid if(media_data_get!=default_media_data) { - //TODO: get Meida title + //TODO: get media title //media_title = media_data_get->getTile(); //LLFloaterMediaSettings::getInstance()->mIdenticalValidMedia = true; media_title = media_data_get.getHomeURL(); @@ -1149,7 +1154,7 @@ void LLFloaterTools::getMediaState() // Media data is valid if(media_data_get!=default_media_data) { - //TODO: get Meida title + //TODO: get media title //media_title = media_data_get->getTile(); media_title = media_data_get.getHomeURL(); } diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index ffccf93943..59acef6071 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -114,7 +114,6 @@ private: void refreshMedia(); void getMediaState(); void updateMediaSettings(); - void getMeidaState(); static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response); static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response); static void setObjectType( LLPCode pcode ); diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 98ca33c9cc..de0b995f8f 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -56,8 +56,13 @@ #include "llfilepicker.h" #include "lldraghandle.h" #include "lllayoutstack.h" +#include "lltooltip.h" #include "llviewermenu.h" #include "llrngwriter.h" +#include "llfloater.h" // superclass +#include "llfloaterreg.h" +#include "llscrollcontainer.h" // scroll container for overlapping elements +#include "lllivefile.h" // live file poll/stat/reload // Boost (for linux/unix command-line execv) #include <boost/tokenizer.hpp> @@ -65,6 +70,8 @@ // External utility #include <string> +#include <list> +#include <map> #if LL_DARWIN #include <CoreFoundation/CFURL.h> @@ -74,6 +81,7 @@ static const S32 PRIMARY_FLOATER = 1; static const S32 SECONDARY_FLOATER = 2; +class LLOverlapPanel; static LLDefaultChildRegistry::Register<LLOverlapPanel> register_overlap_panel("overlap_panel"); static std::string get_xui_dir() @@ -82,6 +90,134 @@ static std::string get_xui_dir() return gDirUtilp->getSkinBaseDir() + delim + "default" + delim + "xui" + delim; } +// Forward declarations to avoid header dependencies +class LLEventTimer; +class LLColor; +class LLScrollListCtrl; +class LLComboBox; +class LLButton; +class LLLineEditor; +class LLXmlTreeNode; +class LLFloaterUIPreview; +class LLFadeEventTimer; + +class LLLocalizationResetForcer; +class LLGUIPreviewLiveFile; +class LLFadeEventTimer; +class LLPreviewedFloater; + +// Implementation of custom overlapping element display panel +class LLOverlapPanel : public LLPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLPanel::Params> + { + Params() {} + }; + LLOverlapPanel(Params p = Params()) : LLPanel(p), + mSpacing(10), + // mClickedElement(NULL), + mLastClickedElement(NULL) + { + mOriginalWidth = getRect().getWidth(); + mOriginalHeight = getRect().getHeight(); + } + virtual void draw(); + + typedef std::map<LLView*, std::list<LLView*> > OverlapMap; + OverlapMap mOverlapMap; // map, of XUI element to a list of XUI elements it overlaps + + // LLView *mClickedElement; + LLView *mLastClickedElement; + int mOriginalWidth, mOriginalHeight, mSpacing; +}; + + +class LLFloaterUIPreview : public LLFloater +{ +public: + // Setup + LLFloaterUIPreview(const LLSD& key); + virtual ~LLFloaterUIPreview(); + + std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu + void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void onClose(bool app_quitting); + + void refreshList(); // refresh list (empty it out and fill it up from scratch) + void addFloaterEntry(const std::string& path); // add a single file's entry to the list of floaters + + static BOOL containerType(LLView* viewp); // check if the element is a container type and tree traverses need to look at its children + +public: + LLPreviewedFloater* mDisplayedFloater; // the floater which is currently being displayed + LLPreviewedFloater* mDisplayedFloater_2; // the floater which is currently being displayed + LLGUIPreviewLiveFile* mLiveFile; // live file for checking for updates to the currently-displayed XML file + LLOverlapPanel* mOverlapPanel; // custom overlapping elements panel + // BOOL mHighlightingDiffs; // bool for whether localization diffs are being highlighted or not + BOOL mHighlightingOverlaps; // bool for whether overlapping elements are being highlighted + + // typedef std::map<std::string,std::pair<std::list<std::string>,std::list<std::string> > > DiffMap; // this version copies the lists etc., and thus is bad memory-wise + typedef std::list<std::string> StringList; + typedef boost::shared_ptr<StringList> StringListPtr; + typedef std::map<std::string, std::pair<StringListPtr,StringListPtr> > DiffMap; + DiffMap mDiffsMap; // map, of filename to pair of list of changed element paths and list of errors + +private: + // XUI elements for this floater + LLScrollListCtrl* mFileList; // scroll list control for file list + LLLineEditor* mEditorPathTextBox; // text field for path to editor executable + LLLineEditor* mEditorArgsTextBox; // text field for arguments to editor executable + LLLineEditor* mDiffPathTextBox; // text field for path to diff file + LLButton* mDisplayFloaterBtn; // button to display primary floater + LLButton* mDisplayFloaterBtn_2; // button to display secondary floater + LLButton* mEditFloaterBtn; // button to edit floater + LLButton* mExecutableBrowseButton; // button to browse for executable + LLButton* mCloseOtherButton; // button to close primary displayed floater + LLButton* mCloseOtherButton_2; // button to close secondary displayed floater + LLButton* mDiffBrowseButton; // button to browse for diff file + LLButton* mToggleHighlightButton; // button to toggle highlight of files/elements with diffs + LLButton* mToggleOverlapButton; // button to togle overlap panel/highlighting + LLComboBox* mLanguageSelection; // combo box for primary language selection + LLComboBox* mLanguageSelection_2; // combo box for secondary language selection + LLScrollContainer* mOverlapScrollView; // overlapping elements scroll container + S32 mLastDisplayedX, mLastDisplayedY; // stored position of last floater so the new one opens up in the same place + std::string mDelim; // the OS-specific delimiter character (/ or \) (*TODO: this shouldn't be needed, right?) + + std::string mSavedEditorPath; // stored editor path so closing this floater doesn't reset it + std::string mSavedEditorArgs; // stored editor args so closing this floater doesn't reset it + std::string mSavedDiffPath; // stored diff file path so closing this floater doesn't reset it + + // Internal functionality + static void popupAndPrintWarning(std::string& warning); // pop up a warning + std::string getLocalizedDirectory(); // build and return the path to the XUI directory for the currently-selected localization + void scanDiffFile(LLXmlTreeNode* file_node); // scan a given XML node for diff entries and highlight them in its associated file + void highlightChangedElements(); // look up the list of elements to highlight and highlight them in the current floater + void highlightChangedFiles(); // look up the list of changed files to highlight and highlight them in the scroll list + void findOverlapsInChildren(LLView* parent); // fill the map below with element overlap information + static BOOL overlapIgnorable(LLView* viewp); // check it the element can be ignored for overlap/localization purposes + + // check if two elements overlap using their rectangles + // used instead of llrect functions because by adding a few pixels of leeway I can cut down drastically on the number of overlaps + BOOL elementOverlap(LLView* view1, LLView* view2); + + // Button/drop-down action listeners (self explanatory) + void onClickDisplayFloater(S32 id); + void onClickSaveFloater(S32 id); + void onClickSaveAll(S32 id); + void onClickEditFloater(); + void onClickBrowseForEditor(); + void onClickBrowseForDiffs(); + void onClickToggleDiffHighlighting(); + void onClickToggleOverlapping(); + void onClickCloseDisplayedFloater(S32 id); + void onLanguageComboSelect(LLUICtrl* ctrl); + void onClickExportSchema(); + void onClickShowRectangles(const LLSD& data); +}; + //---------------------------------------------------------------------------- // Local class declarations // Reset object to ensure that when we change the current language setting for preview purposes, @@ -137,11 +273,17 @@ public: } virtual void draw(); BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); + BOOL handleToolTip(S32 x, S32 y, MASK mask); BOOL selectElement(LLView* parent, int x, int y, int depth); // select element to display its overlappers LLFloaterUIPreview* mFloaterUIPreview; + + // draw widget outlines + static bool sShowRectangles; }; +bool LLPreviewedFloater::sShowRectangles = false; + //---------------------------------------------------------------------------- // Localization reset forcer -- ensures that when localization is temporarily changed for previewed floater, it is reset @@ -257,7 +399,6 @@ LLFloaterUIPreview::LLFloaterUIPreview(const LLSD& key) mHighlightingOverlaps(FALSE), mLastDisplayedX(0), mLastDisplayedY(0) - { // called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_ui_preview.xml"); } @@ -317,6 +458,8 @@ BOOL LLFloaterUIPreview::postBuild() main_panel_tmp->getChild<LLButton>("save_all_floaters")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickSaveAll, this, PRIMARY_FLOATER)); getChild<LLButton>("export_schema")->setClickedCallback(boost::bind(&LLFloaterUIPreview::onClickExportSchema, this)); + getChild<LLUICtrl>("show_rectangles")->setCommitCallback( + boost::bind(&LLFloaterUIPreview::onClickShowRectangles, this, _2)); // get pointers to text fields mEditorPathTextBox = editor_panel_tmp->getChild<LLLineEditor>("executable_path_field"); @@ -438,6 +581,10 @@ void LLFloaterUIPreview::onClickExportSchema() gViewerWindow->setCursor(UI_CURSOR_ARROW); } +void LLFloaterUIPreview::onClickShowRectangles(const LLSD& data) +{ + LLPreviewedFloater::sShowRectangles = data.asBoolean(); +} // Close click handler -- delete my displayed floater if it exists void LLFloaterUIPreview::onClose(bool app_quitting) @@ -1357,6 +1504,73 @@ void LLFloaterUIPreview::onClickCloseDisplayedFloater(S32 caller_id) } +void append_view_tooltip(LLView* tooltip_view, std::string *tooltip_msg) +{ + LLRect rect = tooltip_view->getRect(); + LLRect parent_rect = tooltip_view->getParent()->getRect(); + S32 left = rect.mLeft; + // invert coordinate system for XUI top-left layout + S32 top = parent_rect.getHeight() - rect.mTop; + if (!tooltip_msg->empty()) + { + tooltip_msg->append("\n"); + } + std::string msg = llformat("%s %d, %d (%d x %d)", + tooltip_view->getName().c_str(), + left, + top, + rect.getWidth(), + rect.getHeight() ); + tooltip_msg->append( msg ); +} + +BOOL LLPreviewedFloater::handleToolTip(S32 x, S32 y, MASK mask) +{ + if (!sShowRectangles) + { + return LLFloater::handleToolTip(x, y, mask); + } + + S32 screen_x, screen_y; + localPointToScreen(x, y, &screen_x, &screen_y); + std::string tooltip_msg; + LLView* tooltip_view = this; + LLView::tree_iterator_t end_it = endTreeDFS(); + for (LLView::tree_iterator_t it = beginTreeDFS(); it != end_it; ++it) + { + LLView* viewp = *it; + LLRect screen_rect; + viewp->localRectToScreen(viewp->getLocalRect(), &screen_rect); + if (!(viewp->getVisible() + && screen_rect.pointInRect(screen_x, screen_y))) + { + it.skipDescendants(); + } + // only report xui names for LLUICtrls, not the various container LLViews + + else if (dynamic_cast<LLUICtrl*>(viewp)) + { + // if we are in a new part of the tree (not a descendent of current tooltip_view) + // then push the results for tooltip_view and start with a new potential view + // NOTE: this emulates visiting only the leaf nodes that meet our criteria + + if (tooltip_view != this + && !viewp->hasAncestor(tooltip_view)) + { + append_view_tooltip(tooltip_view, &tooltip_msg); + } + tooltip_view = viewp; + } + } + + append_view_tooltip(tooltip_view, &tooltip_msg); + + LLToolTipMgr::instance().show(LLToolTip::Params() + .message(tooltip_msg) + .max_width(400)); + return TRUE; +} + BOOL LLPreviewedFloater::handleRightMouseDown(S32 x, S32 y, MASK mask) { selectElement(this,x,y,0); @@ -1415,7 +1629,22 @@ void LLPreviewedFloater::draw() { LLView::sDrawPreviewHighlights = TRUE; } + + // If we're looking for truncations, draw debug rects for the displayed + // floater only. + bool old_debug_rects = LLView::sDebugRects; + bool old_show_names = LLView::sDebugRectsShowNames; + if (sShowRectangles) + { + LLView::sDebugRects = true; + LLView::sDebugRectsShowNames = false; + } + LLFloater::draw(); + + LLView::sDebugRects = old_debug_rects; + LLView::sDebugRectsShowNames = old_show_names; + if(mFloaterUIPreview->mHighlightingOverlaps) { LLView::sDrawPreviewHighlights = FALSE; @@ -1635,3 +1864,9 @@ void LLOverlapPanel::draw() mLastClickedElement = LLView::sPreviewClickedElement; } } + +void LLFloaterUIPreviewUtil::registerFloater() +{ + LLFloaterReg::add("ui_preview", "floater_ui_preview.xml", + &LLFloaterReg::build<LLFloaterUIPreview>); +} diff --git a/indra/newview/llfloateruipreview.h b/indra/newview/llfloateruipreview.h index 2a98c90727..2a31b2df59 100644 --- a/indra/newview/llfloateruipreview.h +++ b/indra/newview/llfloateruipreview.h @@ -37,137 +37,10 @@ #ifndef LL_LLUIPREVIEW_H #define LL_LLUIPREVIEW_H -#include "llfloater.h" // superclass -#include "llscrollcontainer.h" // scroll container for overlapping elements -#include "lllivefile.h" // live file poll/stat/reload -#include <list> -#include <map> - -// Forward declarations to avoid header dependencies -class LLEventTimer; -class LLColor; -class LLScrollListCtrl; -class LLComboBox; -class LLButton; -class LLLineEditor; -class LLXmlTreeNode; -class LLFloaterUIPreview; -class LLFadeEventTimer; - -class LLLocalizationResetForcer; -class LLGUIPreviewLiveFile; -class LLFadeEventTimer; -class LLPreviewedFloater; - -// Implementation of custom overlapping element display panel -class LLOverlapPanel : public LLPanel +namespace LLFloaterUIPreviewUtil { -public: - struct Params : public LLInitParam::Block<Params, LLPanel::Params> - { - Params() {} - }; - LLOverlapPanel(Params p = Params()) : LLPanel(p), - mSpacing(10), - // mClickedElement(NULL), - mLastClickedElement(NULL) - { - mOriginalWidth = getRect().getWidth(); - mOriginalHeight = getRect().getHeight(); - } - virtual void draw(); - - typedef std::map<LLView*, std::list<LLView*> > OverlapMap; - OverlapMap mOverlapMap; // map, of XUI element to a list of XUI elements it overlaps - - // LLView *mClickedElement; - LLView *mLastClickedElement; - int mOriginalWidth, mOriginalHeight, mSpacing; -}; - - -class LLFloaterUIPreview : public LLFloater -{ -public: - // Setup - LLFloaterUIPreview(const LLSD& key); - virtual ~LLFloaterUIPreview(); - - std::string getLocStr(S32 ID); // fetches the localization string based on what is selected in the drop-down menu - void displayFloater(BOOL click, S32 ID, bool save = false); // needs to be public so live file can call it when it finds an update - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onClose(bool app_quitting); - - void refreshList(); // refresh list (empty it out and fill it up from scratch) - void addFloaterEntry(const std::string& path); // add a single file's entry to the list of floaters - - static BOOL containerType(LLView* viewp); // check if the element is a container type and tree traverses need to look at its children - -public: - LLPreviewedFloater* mDisplayedFloater; // the floater which is currently being displayed - LLPreviewedFloater* mDisplayedFloater_2; // the floater which is currently being displayed - LLGUIPreviewLiveFile* mLiveFile; // live file for checking for updates to the currently-displayed XML file - LLOverlapPanel* mOverlapPanel; // custom overlapping elements panel - // BOOL mHighlightingDiffs; // bool for whether localization diffs are being highlighted or not - BOOL mHighlightingOverlaps; // bool for whether overlapping elements are being highlighted - - // typedef std::map<std::string,std::pair<std::list<std::string>,std::list<std::string> > > DiffMap; // this version copies the lists etc., and thus is bad memory-wise - typedef std::list<std::string> StringList; - typedef boost::shared_ptr<StringList> StringListPtr; - typedef std::map<std::string, std::pair<StringListPtr,StringListPtr> > DiffMap; - DiffMap mDiffsMap; // map, of filename to pair of list of changed element paths and list of errors - -private: - // XUI elements for this floater - LLScrollListCtrl* mFileList; // scroll list control for file list - LLLineEditor* mEditorPathTextBox; // text field for path to editor executable - LLLineEditor* mEditorArgsTextBox; // text field for arguments to editor executable - LLLineEditor* mDiffPathTextBox; // text field for path to diff file - LLButton* mDisplayFloaterBtn; // button to display primary floater - LLButton* mDisplayFloaterBtn_2; // button to display secondary floater - LLButton* mEditFloaterBtn; // button to edit floater - LLButton* mExecutableBrowseButton; // button to browse for executable - LLButton* mCloseOtherButton; // button to close primary displayed floater - LLButton* mCloseOtherButton_2; // button to close secondary displayed floater - LLButton* mDiffBrowseButton; // button to browse for diff file - LLButton* mToggleHighlightButton; // button to toggle highlight of files/elements with diffs - LLButton* mToggleOverlapButton; // button to togle overlap panel/highlighting - LLComboBox* mLanguageSelection; // combo box for primary language selection - LLComboBox* mLanguageSelection_2; // combo box for secondary language selection - LLScrollContainer* mOverlapScrollView; // overlapping elements scroll container - S32 mLastDisplayedX, mLastDisplayedY; // stored position of last floater so the new one opens up in the same place - std::string mDelim; // the OS-specific delimiter character (/ or \) (*TODO: this shouldn't be needed, right?) - - std::string mSavedEditorPath; // stored editor path so closing this floater doesn't reset it - std::string mSavedEditorArgs; // stored editor args so closing this floater doesn't reset it - std::string mSavedDiffPath; // stored diff file path so closing this floater doesn't reset it - - // Internal functionality - static void popupAndPrintWarning(std::string& warning); // pop up a warning - std::string getLocalizedDirectory(); // build and return the path to the XUI directory for the currently-selected localization - void scanDiffFile(LLXmlTreeNode* file_node); // scan a given XML node for diff entries and highlight them in its associated file - void highlightChangedElements(); // look up the list of elements to highlight and highlight them in the current floater - void highlightChangedFiles(); // look up the list of changed files to highlight and highlight them in the scroll list - void findOverlapsInChildren(LLView* parent); // fill the map below with element overlap information - static BOOL overlapIgnorable(LLView* viewp); // check it the element can be ignored for overlap/localization purposes - - // check if two elements overlap using their rectangles - // used instead of llrect functions because by adding a few pixels of leeway I can cut down drastically on the number of overlaps - BOOL elementOverlap(LLView* view1, LLView* view2); + void registerFloater(); +} - // Button/drop-down action listeners (self explanatory) - void onClickDisplayFloater(S32 id); - void onClickSaveFloater(S32 id); - void onClickSaveAll(S32 id); - void onClickEditFloater(); - void onClickBrowseForEditor(); - void onClickBrowseForDiffs(); - void onClickToggleDiffHighlighting(); - void onClickToggleOverlapping(); - void onClickCloseDisplayedFloater(S32 id); - void onLanguageComboSelect(LLUICtrl* ctrl); - void onClickExportSchema(); -}; #endif // LL_LLUIPREVIEW_H diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index d653d44f8c..b7e8835fb8 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -49,6 +49,7 @@ #include "llfirstuse.h" #include "llfloaterreg.h" // getTypedInstance() #include "llfocusmgr.h" +#include "llinventorymodel.h" #include "lllandmarklist.h" #include "lllineeditor.h" #include "llregionhandle.h" @@ -57,7 +58,7 @@ #include "lltabcontainer.h" #include "lltextbox.h" #include "lltracker.h" -#include "llinventorymodel.h" +#include "lltrans.h" #include "llviewerinventory.h" // LLViewerInventoryItem #include "llviewermenu.h" #include "llviewerregion.h" @@ -151,7 +152,6 @@ LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key) mFriendObserver(NULL), mCompletingRegionName(""), mWaitingForTracker(FALSE), - mExactMatch(FALSE), mIsClosing(FALSE), mSetToUserPosition(TRUE), mTrackedLocation(0,0,0), @@ -903,7 +903,6 @@ void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui) } LLWorldMap::getInstance()->mIsTrackingCommit = FALSE; mCompletingRegionName = ""; - mExactMatch = FALSE; } @@ -1163,7 +1162,6 @@ void LLFloaterWorldMap::onLocationCommit() LLStringUtil::toLower(str); mCompletingRegionName = str; LLWorldMap::getInstance()->mIsTrackingCommit = TRUE; - mExactMatch = FALSE; if (str.length() >= 3) { LLWorldMap::getInstance()->sendNamedRegionRequest(str); @@ -1418,11 +1416,10 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) LLScrollListCtrl *list = getChild<LLScrollListCtrl>("search_results"); list->operateOnAll(LLCtrlListInterface::OP_DELETE); - LLSD selected_value = list->getSelectedValue(); - S32 name_length = mCompletingRegionName.length(); - BOOL match_found = FALSE; + LLSD match; + S32 num_results = 0; std::map<U64, LLSimInfo*>::const_iterator it; for (it = LLWorldMap::getInstance()->mSimInfoMap.begin(); it != LLWorldMap::getInstance()->mSimInfoMap.end(); ++it) @@ -1434,15 +1431,11 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) if (sim_name_lower.substr(0, name_length) == mCompletingRegionName) { - if (LLWorldMap::getInstance()->mIsTrackingCommit) + if (sim_name_lower == mCompletingRegionName) { - if (sim_name_lower == mCompletingRegionName) - { - selected_value = sim_name; - match_found = TRUE; - } + match = sim_name; } - + LLSD value; value["id"] = sim_name; value["columns"][0]["column"] = "sim_name"; @@ -1451,29 +1444,24 @@ void LLFloaterWorldMap::updateSims(bool found_null_sim) num_results++; } } - - list->selectByValue(selected_value); if (found_null_sim) { mCompletingRegionName = ""; } - if (match_found) - { - mExactMatch = TRUE; - childSetFocus("search_results"); - onCommitSearchResult(); - } - else if (!mExactMatch && num_results > 0) + // if match found, highlight it and go + if (!match.isUndefined()) { - list->selectFirstItem(); // select first item by default + list->selectByValue(match); childSetFocus("search_results"); onCommitSearchResult(); } - else if (num_results == 0) + + // if we found nothing, say "none" + if (num_results == 0) { - list->setCommentText(std::string("None found.")); + list->setCommentText(LLTrans::getString("worldmap_results_none_found")); list->operateOnAll(LLCtrlListInterface::OP_DESELECT); } } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 6d5b7543d4..20a8e6d321 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -174,7 +174,6 @@ protected: std::string mCompletingRegionName; std::string mLastRegionName; BOOL mWaitingForTracker; - BOOL mExactMatch; BOOL mIsClosing; BOOL mSetToUserPosition; diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index ee5fba5ace..2b1dd83d72 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -125,6 +125,8 @@ LLFolderViewItem::LLFolderViewItem(LLFolderViewItem::Params p) mLabel(p.name), mRoot(p.root), mCreationDate(p.creation_date), + mIcon(p.icon), + mIconOpen(p.icon_open), mListener(p.listener), mArrowImage(p.folder_arrow_image), mBoxImage(p.selection_image) @@ -598,6 +600,11 @@ BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask ) BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) { + if (LLView::childrenHandleMouseDown(x, y, mask)) + { + return TRUE; + } + // No handler needed for focus lost since this class has no // state that depends on it. gFocusMgr.setMouseCapture( this ); @@ -717,6 +724,11 @@ BOOL LLFolderViewItem::handleScrollWheel(S32 x, S32 y, S32 clicks) BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask ) { + if (LLView::childrenHandleMouseUp(x, y, mask)) + { + return TRUE; + } + // if mouse hasn't moved since mouse down... if ( pointInView(x, y) && mSelectPending ) { @@ -893,11 +905,15 @@ void LLFolderViewItem::draw() mDragAndDropTarget = FALSE; } - - if(mIcon) - { - mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight()); + // First case is used for open folders + if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) + { + mIconOpen->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight()); } + else if(mIcon) + { + mIcon->draw(mIndentation + ARROW_SIZE + TEXT_PAD, getRect().getHeight() - mIcon->getHeight()); + } if (!mLabel.empty()) { diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index e9aab560c8..09c97662d9 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -96,6 +96,7 @@ public: struct Params : public LLInitParam::Block<Params, LLView::Params> { Optional<LLUIImage*> icon; + Optional<LLUIImage*> icon_open; // used for folders Optional<LLFolderView*> root; Optional<LLFolderViewEventListener*> listener; @@ -143,6 +144,7 @@ protected: std::string mLabelSuffix; LLUIImagePtr mIcon; std::string mStatusText; + LLUIImagePtr mIconOpen; BOOL mHasVisibleChildren; S32 mIndentation; S32 mNumDescendantsSelected; diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp index 4caef8e000..ae869d9ac4 100644 --- a/indra/newview/llgrouplist.cpp +++ b/indra/newview/llgrouplist.cpp @@ -315,7 +315,7 @@ void LLGroupListItem::setActive(bool active) // rebuild the text. This will cause problems if the text contains // hyperlinks, as their styles will be wrong. std::string text = mGroupNameBox->getText(); - mGroupNameBox->clear(); + mGroupNameBox->setText(LLStringUtil::null);// *HACK: replace with clear() when it's fixed. mGroupNameBox->appendText(text, false, style_params); } diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp index 3e449e2c82..680106c7bb 100644 --- a/indra/newview/llimfloater.cpp +++ b/indra/newview/llimfloater.cpp @@ -40,9 +40,11 @@ #include "llbottomtray.h" #include "llchannelmanager.h" #include "llchiclet.h" +#include "llfloaterchat.h" #include "llfloaterreg.h" #include "llimview.h" #include "lllineeditor.h" +#include "lllogchat.h" #include "llpanelimcontrolpanel.h" #include "llscreenchannel.h" #include "lltrans.h" @@ -90,16 +92,6 @@ void LLIMFloater::onClose(bool app_quitting) gIMMgr->removeSession(mSessionID); } -void LLIMFloater::setMinimized(BOOL minimize) -{ - if(!isDocked()) - { - setVisible(!minimize); - } - - LLFloater::setMinimized(minimize); -} - /* static */ void LLIMFloater::newIMCallback(const LLSD& data){ @@ -203,6 +195,12 @@ BOOL LLIMFloater::postBuild() setTitle(LLIMModel::instance().getName(mSessionID)); setDocked(true); + if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) + { + LLLogChat::loadHistory(getTitle(), &chatFromLogFile, (void *)this); + } + + return LLDockableFloater::postBuild(); } @@ -316,13 +314,19 @@ void LLIMFloater::setVisible(BOOL visible) bool LLIMFloater::toggle(const LLUUID& session_id) { LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id); - if (floater && floater->getVisible()) + if (floater && floater->getVisible() && floater->isDocked()) { // clicking on chiclet to close floater just hides it to maintain existing // scroll/text entry state floater->setVisible(false); return false; } + else if(floater && !floater->isDocked()) + { + floater->setVisible(TRUE); + floater->setFocus(TRUE); + return true; + } else { // ensure the list of messages is updated when floater is made visible @@ -419,3 +423,37 @@ void LLIMFloater::setTyping(BOOL typing) { } +void LLIMFloater::chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata) +{ + if (!userdata) return; + + LLIMFloater* self = (LLIMFloater*) userdata; + std::string message = line; + S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions"); + switch (type) + { + case LLLogChat::LOG_EMPTY: + // add warning log enabled message + if (im_log_option!=LOG_CHAT) + { + message = LLTrans::getString("IM_logging_string"); + } + break; + case LLLogChat::LOG_END: + // add log end message + if (im_log_option!=LOG_CHAT) + { + message = LLTrans::getString("IM_logging_string"); + } + break; + case LLLogChat::LOG_LINE: + // just add normal lines from file + break; + default: + // nothing + break; + } + + self->mHistoryEditor->appendText(message, true, LLStyle::Params().color(LLUIColorTable::instance().getColor("ChatHistoryTextColor"))); + self->mHistoryEditor->blockUndo(); +} diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h index f85a941be3..5276013568 100644 --- a/indra/newview/llimfloater.h +++ b/indra/newview/llimfloater.h @@ -34,6 +34,7 @@ #define LL_IMFLOATER_H #include "lldockablefloater.h" +#include "lllogchat.h" class LLLineEditor; class LLPanelChatControlPanel; @@ -59,7 +60,6 @@ public: /*virtual*/ void onClose(bool app_quitting); /*virtual*/ void setDocked(bool docked, bool pop_on_undock = true); // override LLFloater's minimization according to EXT-1216 - /*virtual*/ void setMinimized(BOOL minimize); // Make IM conversion visible and update the message history static LLIMFloater* show(const LLUUID& session_id); @@ -91,7 +91,10 @@ private: static void* createPanelGroupControl(void* userdata); // gets a rect that bounds possible positions for the LLIMFloater on a screen (EXT-1111) void getAllowedRect(LLRect& rect); - + + static void chatFromLogFile(LLLogChat::ELogLineType type, std::string line, void* userdata); + + LLPanelChatControlPanel* mControlPanel; LLUUID mSessionID; S32 mLastMessageIndex; diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index 4435bba0ed..0ff3bd24e9 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1013,33 +1013,28 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label, (void *)this); } - if ( !mSessionInitialized ) + //*TODO we probably need the same "awaiting message" thing in LLIMFloater + LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionUUID); + if (!im_session) { - if ( !LLIMModel::instance().sendStartSession( - mSessionUUID, - mOtherParticipantUUID, - mSessionInitialTargetIDs, - mDialog) ) - { - //we don't need to need to wait for any responses - //so we're already initialized - mSessionInitialized = TRUE; - mSessionStartMsgPos = 0; - } - else - { - //locally echo a little "starting session" message - LLUIString session_start = sSessionStartString; + llerror("im session with id " + mSessionUUID.asString() + " does not exist!", 0); + return; + } - session_start.setArg("[NAME]", getTitle()); - mSessionStartMsgPos = - mHistoryEditor->getWText().length(); + mSessionInitialized = im_session->mSessionInitialized; + if (!mSessionInitialized) + { + //locally echo a little "starting session" message + LLUIString session_start = sSessionStartString; - addHistoryLine( - session_start, - LLUIColorTable::instance().getColor("SystemChatColor"), - false); - } + session_start.setArg("[NAME]", getTitle()); + mSessionStartMsgPos = + mHistoryEditor->getWText().length(); + + addHistoryLine( + session_start, + LLUIColorTable::instance().getColor("SystemChatColor"), + false); } } @@ -1162,8 +1157,12 @@ void LLFloaterIMPanel::draw() childSetEnabled("start_call_btn", enable_connect); childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty()); + LLPointer<LLSpeaker> self_speaker; LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID); - LLPointer<LLSpeaker> self_speaker = speaker_mgr->findSpeaker(gAgent.getID()); + if (speaker_mgr) + { + self_speaker = speaker_mgr->findSpeaker(gAgent.getID()); + } if(!mTextIMPossible) { mInputEditor->setEnabled(FALSE); @@ -1342,25 +1341,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 mHistoryEditor->appendText(utf8msg, prepend_newline, LLStyle::Params().color(color)); mHistoryEditor->blockUndo(); - S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions"); - if (log_to_file && (im_log_option!=LOG_CHAT)) - { - std::string histstr; - if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) - histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + name + separator_string + utf8msg; - else - histstr = name + separator_string + utf8msg; - - if(im_log_option==LOG_BOTH_TOGETHER) - { - LLLogChat::saveHistory(std::string("chat"),histstr); - } - else - { - LLLogChat::saveHistory(getTitle(),histstr); - } - } - if (!isInVisibleChain()) { mNumUnreadMessages++; @@ -1650,6 +1630,8 @@ void LLFloaterIMPanel::sendMsg() LLWString text = mInputEditor->getConvertedText(); if(!text.empty()) { + // store sent line in history, duplicates will get filtered + if (mInputEditor) mInputEditor->updateHistory(); // Truncate and convert to UTF8 for transport std::string utf8_text = wstring_to_utf8str(text); utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1); @@ -1751,8 +1733,9 @@ void LLFloaterIMPanel::setTyping(BOOL typing) // Will send typing state after a short delay. mSentTypingState = FALSE; } - - speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE); + + if (speaker_mgr) + speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE); } else { @@ -1762,7 +1745,8 @@ void LLFloaterIMPanel::setTyping(BOOL typing) sendTypingState(FALSE); mSentTypingState = TRUE; } - speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); + if (speaker_mgr) + speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE); } mTyping = typing; @@ -1822,7 +1806,11 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info) mHistoryEditor->removeTextFromEnd(chars_to_remove); if (im_info) { - LLIMModel::getInstance()->getSpeakerManager(mSessionUUID)->setSpeakerTyping(im_info->mFromID, FALSE); + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID); + if (speaker_mgr) + { + speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE); + } } } } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index b5ac3526d2..4478a62ea3 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -86,6 +86,7 @@ LLIMMgr* gIMMgr = NULL; // // *FIXME: make these all either UIStrings or Strings +const static std::string IM_SEPARATOR(": "); std::map<LLUUID, LLIMModel::LLIMSession*> LLIMModel::sSessionsMap; @@ -119,14 +120,16 @@ LLIMModel::LLIMModel() } -LLIMModel::LLIMSession::LLIMSession( const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id ) +LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids) : mSessionID(session_id), mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id), + mInitialTargetIDs(ids), mVoiceChannel(NULL), - mSpeakers(NULL) + mSpeakers(NULL), + mSessionInitialized(false) { if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type) { @@ -140,6 +143,14 @@ LLIMModel::LLIMSession::LLIMSession( const LLUUID& session_id, const std::string // All participants will be added to the list of people we've recently interacted with. mSpeakers->addListener(&LLRecentPeople::instance(), "add"); + + if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, + mInitialTargetIDs, mType)) + { + //we don't need to wait for any responses + //so we're already initialized + mSessionInitialized = true; + } } LLIMModel::LLIMSession::~LLIMSession() @@ -186,11 +197,18 @@ void LLIMModel::updateSessionID(const LLUUID& old_session_id, const LLUUID& new_ session->mSessionID = new_session_id; session->mVoiceChannel->updateSessionID(new_session_id); - //*TODO set session initialized flag here? (IB) + session->mSessionInitialized = true; sSessionsMap.erase(old_session_id); sSessionsMap[new_session_id] = session; } + + //*TODO remove this "floater" stuff when Communicate Floater is gone + LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(old_session_id); + if (floater) + { + floater->sessionInitReplyReceived(new_session_id); + } } void LLIMModel::testMessages() @@ -219,7 +237,7 @@ void LLIMModel::testMessages() } -bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id) +bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id, const std::vector<LLUUID>& ids) { if (is_in_map(sSessionsMap, session_id)) { @@ -227,7 +245,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage return false; } - LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id); + LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids); sSessionsMap[session_id] = session; LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id); @@ -303,9 +321,34 @@ bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string ut } - -bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) { +//*TODO rewrite chat history persistence using LLSD serialization (IB) +bool LLIMModel::logToFile(const LLUUID& session_id, const std::string& from, const std::string& utf8_text) +{ + S32 im_log_option = gSavedPerAccountSettings.getS32("IMLogOptions"); + if (im_log_option != LOG_CHAT) + { + std::string histstr; + if (gSavedPerAccountSettings.getBOOL("LogTimestamp")) + histstr = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate")) + from + IM_SEPARATOR + utf8_text; + else + histstr = from + IM_SEPARATOR + utf8_text; + + if(im_log_option == LOG_BOTH_TOGETHER) + { + LLLogChat::saveHistory(std::string("chat"), histstr); + return true; + } + else + { + LLLogChat::saveHistory(LLIMModel::getInstance()->getName(session_id), histstr); + return true; + } + } + return false; +} +//*TODO add const qualifier and pass by references (IB) +bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text, bool log2file /* = true */) { LLIMSession* session = findIMSession(session_id); if (!session) @@ -315,10 +358,8 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, } addToHistory(session_id, from, utf8_text); + if (log2file) logToFile(session_id, from, utf8_text); - std::string agent_name; - LLAgentUI::buildFullname(agent_name); - session->mNumUnread++; // notify listeners @@ -527,7 +568,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text, // Do we have to replace the /me's here? std::string from; LLAgentUI::buildFullname(from); - LLIMModel::instance().addToHistory(im_session_id, from, utf8_text); + LLIMModel::getInstance()->addMessage(im_session_id, from, gAgentID, utf8_text); //local echo for the legacy communicate panel std::string history_echo; @@ -1194,7 +1235,7 @@ LLIMMgr::LLIMMgr() : static bool registered_dialog = false; if (!registered_dialog) { - LLFloaterReg::add("incoming_call", "floater_incoming_call.xml.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>); + LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>); registered_dialog = true; } @@ -1432,12 +1473,15 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name, { LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id); - LLVoiceChannelP2P* voice_channel = (LLVoiceChannelP2P*) LLIMModel::getInstance()->getSpeakerManager(session_id); - if (voice_channel) + LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id); + if (speaker_mgr) { - voice_channel->setSessionHandle(voice_session_handle, caller_uri); + LLVoiceChannelP2P* voice_channel = dynamic_cast<LLVoiceChannelP2P*>(speaker_mgr->getVoiceChannel()); + if (voice_channel) + { + voice_channel->setSessionHandle(voice_session_handle, caller_uri); + } } - return session_id; } @@ -1472,9 +1516,12 @@ LLUUID LLIMMgr::addSession( if (!LLIMModel::getInstance()->findIMSession(session_id)) { - LLIMModel::instance().newSession(session_id, name, dialog, other_participant_id); + LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids); } + LLIMFloater::show(session_id); + + //*TODO remove this "floater" thing when Communicate Floater's gone LLFloaterIMPanel* floater = findFloaterBySession(session_id); if(!floater) { @@ -1487,19 +1534,17 @@ LLUUID LLIMMgr::addSession( dialog, TRUE, ids); + } - if ( !floater ) return LLUUID::null; - - noteOfflineUsers(floater, ids); + noteOfflineUsers(session_id, floater, ids); - // Only warn for regular IMs - not group IMs - if( dialog == IM_NOTHING_SPECIAL ) - { - noteMutedUsers(floater, ids); - } + // Only warn for regular IMs - not group IMs + if( dialog == IM_NOTHING_SPECIAL ) + { + noteMutedUsers(session_id, floater, ids); } - floater->setInputFocus(TRUE); - LLIMFloater::show(session_id); + + return session_id; } @@ -1865,18 +1910,25 @@ LLFloaterIMPanel* LLIMMgr::createFloater( } void LLIMMgr::noteOfflineUsers( + const LLUUID& session_id, LLFloaterIMPanel* floater, const LLDynamicArray<LLUUID>& ids) { S32 count = ids.count(); if(count == 0) { - floater->addHistoryLine(LLTrans::getString("only_user_message"), LLUIColorTable::instance().getColor("SystemChatColor")); + const std::string& only_user = LLTrans::getString("only_user_message"); + if (floater) + { + floater->addHistoryLine(only_user, LLUIColorTable::instance().getColor("SystemChatColor")); + } + LLIMModel::getInstance()->addMessage(session_id, SYSTEM_FROM, LLUUID::null, only_user); } else { const LLRelationship* info = NULL; LLAvatarTracker& at = LLAvatarTracker::instance(); + LLIMModel* im_model = LLIMModel::getInstance(); for(S32 i = 0; i < count; ++i) { info = at.getBuddyInfo(ids.get(i)); @@ -1887,13 +1939,19 @@ void LLIMMgr::noteOfflineUsers( LLUIString offline = LLTrans::getString("offline_message"); offline.setArg("[FIRST]", first); offline.setArg("[LAST]", last); - floater->addHistoryLine(offline, LLUIColorTable::instance().getColor("SystemChatColor")); + + if (floater) + { + floater->addHistoryLine(offline, LLUIColorTable::instance().getColor("SystemChatColor")); + } + + im_model->addMessage(session_id, SYSTEM_FROM, LLUUID::null, offline); } } } } -void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater, +void LLIMMgr::noteMutedUsers(const LLUUID& session_id, LLFloaterIMPanel* floater, const LLDynamicArray<LLUUID>& ids) { // Don't do this if we don't have a mute list. @@ -1906,12 +1964,18 @@ void LLIMMgr::noteMutedUsers(LLFloaterIMPanel* floater, S32 count = ids.count(); if(count > 0) { + LLIMModel* im_model = LLIMModel::getInstance(); + for(S32 i = 0; i < count; ++i) { if( ml->isMuted(ids.get(i)) ) { LLUIString muted = LLTrans::getString("muted_message"); + + //*TODO remove this "floater" thing when Communicate Floater's gone floater->addHistoryLine(muted); + + im_model->addMessage(session_id, SYSTEM_FROM, LLUUID::null, muted); break; } } @@ -1938,17 +2002,6 @@ void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing) } } -void LLIMMgr::updateFloaterSessionID( - const LLUUID& old_session_id, - const LLUUID& new_session_id) -{ - LLFloaterIMPanel* floater = findFloaterBySession(old_session_id); - if (floater) - { - floater->sessionInitReplyReceived(new_session_id); - } -} - class LLViewerChatterBoxSessionStartReply : public LLHTTPNode { public: @@ -1977,9 +2030,6 @@ public: if ( success ) { session_id = body["session_id"].asUUID(); - gIMMgr->updateFloaterSessionID( - temp_session_id, - session_id); LLIMModel::getInstance()->updateSessionID(temp_session_id, session_id); diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index 9a94d01bb2..df28c16bb1 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -53,18 +53,21 @@ public: struct LLIMSession { LLIMSession(const LLUUID& session_id, const std::string& name, - const EInstantMessage& type, const LLUUID& other_participant_id); + const EInstantMessage& type, const LLUUID& other_participant_id, const std::vector<LLUUID>& ids); virtual ~LLIMSession(); LLUUID mSessionID; std::string mName; EInstantMessage mType; LLUUID mOtherParticipantID; + std::vector<LLUUID> mInitialTargetIDs; S32 mNumUnread; std::list<LLSD> mMsgs; LLVoiceChannel* mVoiceChannel; LLIMSpeakerMgr* mSpeakers; + + bool mSessionInitialized; }; @@ -88,11 +91,16 @@ public: boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb ); - bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id); + bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id, + const std::vector<LLUUID>& ids = std::vector<LLUUID>()); bool clearSession(LLUUID session_id); std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0); - bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text); + + bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text, bool log2file = true); bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); + + bool logToFile(const LLUUID& session_id, const std::string& from, const std::string& utf8_text); + //used to get the name of the session, for use as the title //currently just the other avatar name const std::string& getName(const LLUUID& session_id) const; @@ -223,12 +231,6 @@ public: const std::string& session_handle = LLStringUtil::null, const std::string& session_uri = LLStringUtil::null); - //Updates a given session's session IDs. Does not open, - //create or do anything new. If the old session doesn't - //exist, then nothing happens. - void updateFloaterSessionID(const LLUUID& old_session_id, - const LLUUID& new_session_id); - void processIMTypingStart(const LLIMInfo* im_info); void processIMTypingStop(const LLIMInfo* im_info); @@ -293,8 +295,8 @@ private: // prints a simple message if they are not online. Used to help // reduce 'hello' messages to the linden employees unlucky enough // to have their calling card in the default inventory. - void noteOfflineUsers(LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids); - void noteMutedUsers(LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids); + void noteOfflineUsers(const LLUUID& session_id, LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids); + void noteMutedUsers(const LLUUID& session_id, LLFloaterIMPanel* panel, const LLDynamicArray<LLUUID>& ids); void processIMTypingCore(const LLIMInfo* im_info, BOOL typing); diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp index 4046c893c1..44dd11dd86 100644 --- a/indra/newview/llinspectavatar.cpp +++ b/indra/newview/llinspectavatar.cpp @@ -39,7 +39,6 @@ #include "llavataractions.h" #include "llavatarpropertiesprocessor.h" #include "llcallingcard.h" -#include "lldateutil.h" // ageFromDate() #include "llfloaterreporter.h" #include "llfloaterworldmap.h" #include "llmutelist.h" @@ -109,10 +108,11 @@ private: void onClickPay(); void onClickBlock(); void onClickReport(); + void onClickZoomIn(); + void onClickFindOnMap(); bool onVisibleFindOnMap(); bool onVisibleGodMode(); void onClickMuteVolume(); - void onFindOnMap(); void onVolumeChange(const LLSD& data); // Callback for gCacheName to look up avatar name @@ -196,7 +196,8 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd) mCommitCallbackRegistrar.add("InspectAvatar.Pay", boost::bind(&LLInspectAvatar::onClickPay, this)); mCommitCallbackRegistrar.add("InspectAvatar.Block", boost::bind(&LLInspectAvatar::onClickBlock, this)); mCommitCallbackRegistrar.add("InspectAvatar.Report", boost::bind(&LLInspectAvatar::onClickReport, this)); - mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap", boost::bind(&LLInspectAvatar::onFindOnMap, this)); + mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap", boost::bind(&LLInspectAvatar::onClickFindOnMap, this)); + mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this)); mVisibleCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap", boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this)); mVisibleCallbackRegistrar.add("InspectAvatar.VisibleGodMode", boost::bind(&LLInspectAvatar::onVisibleGodMode, this)); @@ -274,6 +275,11 @@ void LLInspectAvatar::onOpen(const LLSD& data) mAvatarID = data["avatar_id"]; mPartnerID = LLUUID::null; + BOOL self = mAvatarID == gAgent.getID(); + + getChild<LLUICtrl>("gear_self_btn")->setVisible(self); + getChild<LLUICtrl>("gear_btn")->setVisible(!self); + // Position the inspector relative to the mouse cursor // Similar to how tooltips are positioned // See LLToolTipMgr::createToolTip @@ -352,7 +358,7 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data) { LLStringUtil::format_map_t args; args["[BORN_ON]"] = data->born_on; - args["[AGE]"] = LLDateUtil::ageFromDate(data->born_on); + args["[AGE]"] = data->born_on; args["[SL_PROFILE]"] = data->about_text; args["[RW_PROFILE"] = data->fl_about_text; args["[ACCTTYPE]"] = LLAvatarPropertiesProcessor::accountType(data); @@ -476,7 +482,6 @@ void LLInspectAvatar::onClickViewProfile() // hide inspector when showing profile setFocus(FALSE); LLAvatarActions::showProfile(mAvatarID); - } bool LLInspectAvatar::onVisibleFindOnMap() @@ -521,8 +526,13 @@ void LLInspectAvatar::onClickReport() LLFloaterReporter::showFromObject(mAvatarID); } +void LLInspectAvatar::onClickZoomIn() +{ + handle_zoom_to_object(mAvatarID); + closeFloater(); +} -void LLInspectAvatar::onFindOnMap() +void LLInspectAvatar::onClickFindOnMap() { gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName); LLFloaterReg::showInstance("world_map"); diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp index 8c38e785e9..cdb3a10dfc 100644 --- a/indra/newview/llinspectobject.cpp +++ b/indra/newview/llinspectobject.cpp @@ -109,6 +109,7 @@ private: void onClickSit(); void onClickOpen(); void onClickMoreInfo(); + void onClickZoomIn(); private: LLUUID mObjectID; @@ -132,6 +133,7 @@ LLInspectObject::LLInspectObject(const LLSD& sd) mCommitCallbackRegistrar.add("InspectObject.Sit", boost::bind(&LLInspectObject::onClickSit, this)); mCommitCallbackRegistrar.add("InspectObject.Open", boost::bind(&LLInspectObject::onClickOpen, this)); mCommitCallbackRegistrar.add("InspectObject.MoreInfo", boost::bind(&LLInspectObject::onClickMoreInfo, this)); + mCommitCallbackRegistrar.add("InspectObject.ZoomIn", boost::bind(&LLInspectObject::onClickZoomIn, this)); } @@ -554,6 +556,12 @@ void LLInspectObject::onClickMoreInfo() closeFloater(); } +void LLInspectObject::onClickZoomIn() +{ + handle_look_at_selection("zoom"); + closeFloater(); +} + ////////////////////////////////////////////////////////////////////////////// // LLInspectObjectUtil ////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index e5cf8ccf66..1880a574a7 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -120,38 +120,38 @@ bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& respon std::string ICON_NAME[ICON_NAME_COUNT] = { - "inv_item_texture.tga", - "inv_item_sound.tga", - "inv_item_callingcard_online.tga", - "inv_item_callingcard_offline.tga", - "inv_item_landmark.tga", - "inv_item_landmark_visited.tga", - "inv_item_script.tga", - "inv_item_clothing.tga", - "inv_item_object.tga", - "inv_item_object_multi.tga", - "inv_item_notecard.tga", - "inv_item_skin.tga", - "inv_item_snapshot.tga", - - "inv_item_shape.tga", - "inv_item_skin.tga", - "inv_item_hair.tga", - "inv_item_eyes.tga", - "inv_item_shirt.tga", - "inv_item_pants.tga", - "inv_item_shoes.tga", - "inv_item_socks.tga", - "inv_item_jacket.tga", - "inv_item_gloves.tga", - "inv_item_undershirt.tga", - "inv_item_underpants.tga", - "inv_item_skirt.tga", + "Inv_Texture", + "Inv_Sound", + "Inv_CallingCard", + "Inv_CallingCard", + "Inv_Landmark", + "Inv_Landmark", + "Inv_Script", + "Inv_Clothing", + "Inv_Object", + "Inv_Object", + "Inv_Notecard", + "Inv_Skin", + "Inv_Snapshot", + + "Inv_BodyShape", + "Inv_Skin", + "Inv_Hair", + "Inv_Eye", + "Inv_Shirt", + "Inv_Pants", + "Inv_Shoe", + "Inv_Socks", + "Inv_Jacket", + "Inv_Gloves", + "Inv_Undershirt", + "Inv_Underpants", + "Inv_Skirt", "inv_item_alpha.tga", "inv_item_tattoo.tga", - "inv_item_animation.tga", - "inv_item_gesture.tga", + "Inv_Animation", + "Inv_Gesture", "inv_item_linkitem.tga", "inv_item_linkfolder.tga" @@ -2099,81 +2099,8 @@ LLUIImagePtr LLFolderBridge::getIcon() const LLUIImagePtr LLFolderBridge::getIcon(LLAssetType::EType preferred_type) { - if (preferred_type >= LLAssetType::AT_FOLDER_ENSEMBLE_START && - preferred_type <= LLAssetType::AT_FOLDER_ENSEMBLE_END) - { - LLUIImage* icon = LLUI::getUIImage(LLFolderType::lookupIconName(preferred_type)); - if (icon) - return icon; - } - - const char* control = NULL; - switch(preferred_type) - { - case LLAssetType::AT_TEXTURE: - control = "inv_folder_texture.tga"; - break; - case LLAssetType::AT_SOUND: - control = "inv_folder_sound.tga"; - break; - case LLAssetType::AT_CALLINGCARD: - control = "inv_folder_callingcard.tga"; - break; - case LLAssetType::AT_LANDMARK: - control = "inv_folder_landmark.tga"; - break; - case LLAssetType::AT_SCRIPT: - case LLAssetType::AT_LSL_TEXT: - control = "inv_folder_script.tga"; - break; - case LLAssetType::AT_OBJECT: - control = "inv_folder_object.tga"; - break; - case LLAssetType::AT_NOTECARD: - control = "inv_folder_notecard.tga"; - break; - case LLAssetType::AT_CATEGORY: - control = "inv_folder_plain_closed.tga"; - break; - case LLAssetType::AT_CLOTHING: - control = "inv_folder_clothing.tga"; - break; - case LLAssetType::AT_BODYPART: - control = "inv_folder_bodypart.tga"; - break; - case LLAssetType::AT_TRASH: - control = "inv_folder_trash.tga"; - break; - case LLAssetType::AT_SNAPSHOT_CATEGORY: - control = "inv_folder_snapshot.tga"; - break; - case LLAssetType::AT_LOST_AND_FOUND: - control = "inv_folder_lostandfound.tga"; - break; - case LLAssetType::AT_ANIMATION: - control = "inv_folder_animation.tga"; - break; - case LLAssetType::AT_GESTURE: - control = "inv_folder_gesture.tga"; - break; - case LLAssetType::AT_FAVORITE: - //TODO - need icon - control = "inv_folder_plain_closed.tga"; - break; - case LLAssetType::AT_OUTFIT: - control = "inv_folder_outfit.tga"; - break; - case LLAssetType::AT_CURRENT_OUTFIT: - control = "inv_folder_current_outfit.tga"; - break; - case LLAssetType::AT_MY_OUTFITS: - control = "inv_folder_my_outfits.tga"; - break; - default: - control = "inv_folder_plain_closed.tga"; - break; - } - return LLUI::getUIImage(control); + // we only have one folder image now + return LLUI::getUIImage("Inv_FolderClosed"); } BOOL LLFolderBridge::renameItem(const std::string& new_name) @@ -2389,6 +2316,8 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) LLUUID trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH); LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND); + mItems.clear(); //adding code to clear out member Items (which means Items should not have other data here at this point) + mDisabledItems.clear(); //adding code to clear out disabled members from previous if (lost_and_found_id == mUUID) { // This is the lost+found folder. @@ -4494,7 +4423,7 @@ void LLWearableBridge::onEditOnAvatar(void* user_data) void LLWearableBridge::editOnAvatar() { - const LLWearable* wearable = gAgentWearables.getWearableFromWearableItem(mUUID); + const LLWearable* wearable = gAgentWearables.getWearableFromItemID(mUUID); if( wearable ) { // Set the tab to the right wearable. diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index b4d3f4575b..7ec8d3d003 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -131,6 +131,13 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item) && (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) && ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) && (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate); + + BOOL is_folder = (dynamic_cast<LLFolderViewFolder*>(item) != NULL); + if (is_folder && mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS) + { + passed = TRUE; + } + return passed; } diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp index 0542199fc1..7c759e22a8 100644 --- a/indra/newview/lllandmarkactions.cpp +++ b/indra/newview/lllandmarkactions.cpp @@ -131,16 +131,36 @@ public: } }; +static void fetch_landmarks(LLInventoryModel::cat_array_t& cats, + LLInventoryModel::item_array_t& items, + LLInventoryCollectFunctor& add) +{ + // Look in "My Favorites" + LLUUID favorites_folder_id = + gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); + gInventory.collectDescendentsIf(favorites_folder_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + add); + + // Look in "Landmarks" + LLUUID landmarks_folder_id = + gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + gInventory.collectDescendentsIf(landmarks_folder_id, + cats, + items, + LLInventoryModel::EXCLUDE_TRASH, + add); +} + LLInventoryModel::item_array_t LLLandmarkActions::fetchLandmarksByName(std::string& name, BOOL use_substring) { LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; - LLFetchLandmarksByName fetchLandmarks(name, use_substring); - gInventory.collectDescendentsIf(gInventory.getRootFolderID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - fetchLandmarks); + LLFetchLandmarksByName by_name(name, use_substring); + fetch_landmarks(cats, items, by_name); + return items; } @@ -151,17 +171,15 @@ bool LLLandmarkActions::landmarkAlreadyExists() } +// *TODO: This could be made more efficient by only fetching the FIRST +// landmark that meets the criteria LLViewerInventoryItem* LLLandmarkActions::findLandmarkForGlobalPos(const LLVector3d &pos) { // Determine whether there are landmarks pointing to the current parcel. LLInventoryModel::cat_array_t cats; LLInventoryModel::item_array_t items; LLFetchlLandmarkByPos is_current_pos_landmark(pos); - gInventory.collectDescendentsIf(gInventory.getRootFolderID(), - cats, - items, - LLInventoryModel::EXCLUDE_TRASH, - is_current_pos_landmark); + fetch_landmarks(cats, items, is_current_pos_landmark); if(items.empty()) { diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp index 16a10dc502..a3296dbffc 100644 --- a/indra/newview/lllocationinputctrl.cpp +++ b/indra/newview/lllocationinputctrl.cpp @@ -159,7 +159,9 @@ LLLocationInputCtrl::Params::Params() add_landmark_image_selected("add_landmark_image_selected"), add_landmark_button("add_landmark_button"), add_landmark_hpad("add_landmark_hpad", 0), - info_button("info_button") + info_button("info_button"), + add_landmark_tool_tip("add_landmark_tool_tip"), + edit_landmark_tool_tip("edit_landmark_tool_tip") { } @@ -170,7 +172,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mLocationContextMenu(NULL), mAddLandmarkBtn(NULL), mLandmarkImageOn(NULL), - mLandmarkImageOff(NULL) + mLandmarkImageOff(NULL), + mAddLandmarkTooltip(p.add_landmark_tool_tip), + mEditLandmarkTooltip(p.edit_landmark_tool_tip) { // Lets replace default LLLineEditor with LLLocationLineEditor // to make needed escaping while copying and cutting url @@ -261,9 +265,6 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p) mAddLandmarkObserver = new LLAddLandmarkObserver(this); gInventory.addObserver(mRemoveLandmarkObserver); gInventory.addObserver(mAddLandmarkObserver); - - mAddLandmarkTooltip = LLTrans::getString("location_ctrl_add_landmark"); - mEditLandmarkTooltip = LLTrans::getString("location_ctrl_edit_landmark"); } LLLocationInputCtrl::~LLLocationInputCtrl() diff --git a/indra/newview/lllocationinputctrl.h b/indra/newview/lllocationinputctrl.h index c74a294ca3..cd5c482005 100644 --- a/indra/newview/lllocationinputctrl.h +++ b/indra/newview/lllocationinputctrl.h @@ -66,6 +66,8 @@ public: Optional<S32> add_landmark_hpad; Optional<LLButton::Params> add_landmark_button, info_button; + Optional<std::string> add_landmark_tool_tip; + Optional<std::string> edit_landmark_tool_tip; Params(); }; diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 14a8b7cb59..c99e67be3f 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1234,9 +1234,9 @@ LLVector3 LLManipRotate::getConstraintAxis() else { #ifndef LL_RELEASE_FOR_DOWNLOAD - llerrs << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl + llerrs << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl; #else - llwarns << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl + llwarns << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl; #endif axis.mV[0] = 1.f; } diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index d8f00ec370..1bbcc3f98e 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -44,9 +44,7 @@ #include "llvoavatarself.h" // to check gAgent.getAvatarObject()->isSitting() #include "llbottomtray.h" #include "llbutton.h" -#include "llfirsttimetipmanager.h" #include "llfloaterreg.h" -#include "llfloaterfirsttimetip.h" #include "lljoystickbutton.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" @@ -54,6 +52,7 @@ #include "llselectmgr.h" #include "llviewerparcelmgr.h" #include "llviewerregion.h" +#include "lltooltip.h" // // Constants @@ -71,7 +70,7 @@ const std::string BOTTOM_TRAY_BUTTON_NAME = "movement_btn"; // protected LLFloaterMove::LLFloaterMove(const LLSD& key) -: LLDockableFloater(NULL, false, key), +: LLDockableFloater(NULL, key), mForwardButton(NULL), mBackwardButton(NULL), mTurnLeftButton(NULL), @@ -305,7 +304,6 @@ void LLFloaterMove::setMovementMode(const EMovementMode mode) showModeButtons(!bHideModeButtons); - showQuickTips(mode); } void LLFloaterMove::updateButtonsWithMovementMode(const EMovementMode newMode) @@ -464,6 +462,11 @@ void LLFloaterMove::enableInstance(BOOL bEnable) if (instance) { instance->setEnabled(bEnable); + + if (gAgent.getFlying()) + { + instance->showModeButtons(FALSE); + } } } @@ -487,8 +490,6 @@ void LLFloaterMove::onOpen(const LLSD& key) anchor_panel, this, getDockTongue(), LLDockControl::TOP)); - showQuickTips(mCurrentMode); - sUpdateFlyingStatus(); } @@ -500,20 +501,6 @@ void LLFloaterMove::setDocked(bool docked, bool pop_on_undock/* = true*/) updateHeight(show_mode_buttons); } -void LLFloaterMove::showQuickTips(const EMovementMode mode) -{ - LLFirstTimeTipsManager::EFirstTimeTipType tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK; - switch (mode) - { - case MM_FLY: tipType = LLFirstTimeTipsManager::FTT_MOVE_FLY; break; - case MM_RUN: tipType = LLFirstTimeTipsManager::FTT_MOVE_RUN; break; - case MM_WALK: tipType = LLFirstTimeTipsManager::FTT_MOVE_WALK; break; - default: llwarns << "Quick Tip type was not detected, FTT_MOVE_WALK will be used" << llendl; - } - - LLFirstTimeTipsManager::showTipsFor(tipType, this, LLFirstTimeTipsManager::TPA_POS_LEFT_ALIGN_TOP); -} - void LLFloaterMove::setModeButtonToggleState(const EMovementMode mode) { llassert_always(mModeControlButtonMap.end() != mModeControlButtonMap.find(mode)); @@ -610,6 +597,22 @@ void LLPanelStandStopFlying::setVisible(BOOL visible) LLPanel::setVisible(visible); } +BOOL LLPanelStandStopFlying::handleToolTip(S32 x, S32 y, MASK mask) +{ + LLToolTipMgr::instance().unblockToolTips(); + + if (mStandButton->getVisible()) + { + LLToolTipMgr::instance().show(mStandButton->getToolTip()); + } + else if (mStopFlyingButton->getVisible()) + { + LLToolTipMgr::instance().show(mStopFlyingButton->getToolTip()); + } + + return TRUE; +} + ////////////////////////////////////////////////////////////////////////// // Private Section ////////////////////////////////////////////////////////////////////////// @@ -635,7 +638,10 @@ void LLPanelStandStopFlying::onStandButtonClick() gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); setFocus(FALSE); // EXT-482 - setVisible(FALSE); + + BOOL fly = gAgent.getFlying(); + mStopFlyingButton->setVisible(fly); + setVisible(fly); } void LLPanelStandStopFlying::onStopFlyingButtonClick() diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index 584c7c494c..cbed36f10d 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -142,6 +142,7 @@ public: // *HACK: due to hard enough to have this control aligned with "Move" button while resizing // let update its position in each frame /*virtual*/ void draw(){updatePosition(); LLPanel::draw();} + /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); protected: diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index b47d6f4214..ff7f08bf97 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -530,6 +530,8 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n { timp->addHistoryLine(message); } + + LLIMModel::getInstance()->addMessage(agent_id, SYSTEM_FROM, LLUUID::null, message); } LLChat auto_chat(message); diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index cc5f37b903..91862112a0 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -430,7 +430,7 @@ void LLNearbyChat::pinn_panel() mEChatTearofState = CHAT_PINNED; LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn",false); - tearoff_btn->setValue("inv_item_landmark_visited.tga"); + tearoff_btn->setValue("Inv_Landmark"); const LLRect& parent_rect = gViewerWindow->getRootView()->getRect(); @@ -451,7 +451,7 @@ void LLNearbyChat::float_panel() mEChatTearofState = CHAT_UNPINNED; LLIconCtrl* tearoff_btn = mChatCaptionPanel->getChild<LLIconCtrl>("tearoff_btn", false); - tearoff_btn->setValue("inv_item_landmark.tga"); + tearoff_btn->setValue("Inv_Landmark"); mResizeBar[LLResizeBar::BOTTOM]->setVisible(true); mResizeBar[LLResizeBar::LEFT]->setVisible(true); mResizeBar[LLResizeBar::RIGHT]->setVisible(true); diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index 1d8789fde0..4f3bca50ff 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -192,7 +192,7 @@ BOOL LLNearbyChatBar::postBuild() mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this); mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this)); - mChatBox->setIgnoreArrowKeys(TRUE); + mChatBox->setIgnoreArrowKeys( FALSE ); mChatBox->setCommitOnFocusLost( FALSE ); mChatBox->setRevertOnEsc( FALSE ); mChatBox->setIgnoreTab(TRUE); @@ -201,35 +201,8 @@ BOOL LLNearbyChatBar::postBuild() mChatBox->setMaxTextLength(1023); mChatBox->setEnableLineHistory(TRUE); - // TODO: Initialization of the output monitor's params should be done via xml - const S32 MONITOR_RIGHT_PAD = 2; - - LLRect monitor_rect = LLRect(0, 18, 18, 0); - LLRect chatbox_rect = mChatBox->getRect(); - - S32 monitor_height = monitor_rect.getHeight(); - monitor_rect.mLeft = chatbox_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD; - monitor_rect.mRight = chatbox_rect.getWidth() - MONITOR_RIGHT_PAD; - monitor_rect.mBottom = (chatbox_rect.getHeight() / 2) - (monitor_height / 2); - monitor_rect.mTop = monitor_rect.mBottom + monitor_height; - - LLOutputMonitorCtrl::Params monitor_params = LLOutputMonitorCtrl::Params(); - monitor_params.name = "output_monitor"; - monitor_params.draw_border(false); - monitor_params.rect(monitor_rect); - monitor_params.auto_update(true); - monitor_params.speaker_id(gAgentID); - - LLView::Follows follows = LLView::Follows(); - follows.flags = FOLLOWS_RIGHT; - monitor_params.follows = follows; - mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params); - mChatBox->addChild(mOutputMonitor); - - // never show "muted" because you can't mute yourself - mOutputMonitor->setIsMuted(false); + mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator"); mOutputMonitor->setVisible(FALSE); - mTalkBtn = getChild<LLTalkButton>("talk"); // Speak button should be initially disabled because @@ -254,6 +227,12 @@ bool LLNearbyChatBar::instanceExists() return LLBottomTray::instanceExists() && LLBottomTray::getInstance()->getNearbyChatBar() != NULL; } +void LLNearbyChatBar::draw() +{ + displaySpeakingIndicator(); + LLPanel::draw(); +} + std::string LLNearbyChatBar::getCurrentChat() { return mChatBox ? mChatBox->getText() : LLStringUtil::null; @@ -470,6 +449,36 @@ void LLNearbyChatBar::onChatBoxCommit() gAgent.stopTyping(); } +void LLNearbyChatBar::displaySpeakingIndicator() +{ + LLSpeakerMgr::speaker_list_t speaker_list; + LLUUID id; + + id.setNull(); + mSpeakerMgr.update(TRUE); + mSpeakerMgr.getSpeakerList(&speaker_list, FALSE); + + for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) + { + LLPointer<LLSpeaker> s = *i; + if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) + { + id = s->mID; + break; + } + } + + if (!id.isNull()) + { + mOutputMonitor->setVisible(TRUE); + mOutputMonitor->setSpeakerId(id); + } + else + { + mOutputMonitor->setVisible(FALSE); + } +} + void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate) { sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate); @@ -622,7 +631,6 @@ LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channe void LLNearbyChatBar::setPTTState(bool state) { mTalkBtn->setSpeakBtnToggleState(state); - mOutputMonitor->setVisible(state); } void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel) diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 1b71ad69f2..d6827315f2 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -40,6 +40,7 @@ #include "llchiclet.h" #include "llvoiceclient.h" #include "lloutputmonitorctrl.h" +#include "llfloateractivespeakers.h" class LLGestureComboBox : public LLComboBox @@ -84,6 +85,8 @@ public: LLLineEditor* getChatBox() { return mChatBox; } + virtual void draw(); + std::string getCurrentChat(); virtual BOOL handleKeyHere( KEY key, MASK mask ); @@ -110,12 +113,15 @@ protected: static LLWString stripChannelNumber(const LLWString &mesg, S32* channel); EChatType processChatTypeTriggers(EChatType type, std::string &str); + void displaySpeakingIndicator(); + // Which non-zero channel did we last chat on? static S32 sLastSpecialChatChannel; LLLineEditor* mChatBox; LLTalkButton* mTalkBtn; LLOutputMonitorCtrl* mOutputMonitor; + LLActiveSpeakerMgr mSpeakerMgr; }; #endif diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index eb42e83994..59b19b6dcb 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -61,7 +61,7 @@ LLToastPanelBase* createToastPanel() class LLNearbyChatScreenChannel: public LLScreenChannelBase { public: - LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mActiveMessages = 0;}; + LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mStopProcessing = false;}; void init (S32 channel_left, S32 channel_right); @@ -75,6 +75,13 @@ public: void onToastDestroyed (LLToast* toast); void onToastFade (LLToast* toast); + void reshape (S32 width, S32 height, BOOL called_from_parent); + + void redrawToasts() + { + arrangeToasts(); + } + // hide all toasts from screen, but not remove them from a channel virtual void hideToastsFromScreen() { @@ -93,6 +100,13 @@ public: m_active_toasts.clear(); }; + virtual void deleteAllChildren() + { + m_toast_pool.clear(); + m_active_toasts.clear(); + LLScreenChannelBase::deleteAllChildren(); + } + protected: void createOverflowToast(S32 bottom, F32 timer); @@ -103,7 +117,7 @@ protected: std::vector<LLToast*> m_active_toasts; std::list<LLToast*> m_toast_pool; - S32 mActiveMessages; + bool mStopProcessing; }; void LLNearbyChatScreenChannel::init(S32 channel_left, S32 channel_right) @@ -122,6 +136,7 @@ void LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer) void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast) { + mStopProcessing = true; } void LLNearbyChatScreenChannel::onToastFade(LLToast* toast) @@ -161,7 +176,8 @@ bool LLNearbyChatScreenChannel::createPoolToast() void LLNearbyChatScreenChannel::addNotification(LLSD& notification) { //look in pool. if there is any message - + if(mStopProcessing) + return; if(m_toast_pool.empty()) { @@ -204,35 +220,48 @@ void LLNearbyChatScreenChannel::arrangeToasts() void LLNearbyChatScreenChannel::showToastsBottom() { - LLRect rect = getRect(); + if(mStopProcessing) + return; LLRect toast_rect; S32 bottom = getRect().mBottom; + S32 margin = gSavedSettings.getS32("ToastMargin"); for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it) { LLToast* toast = (*it); - toast_rect = toast->getRect(); - toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight()); - - toast->setRect(toast_rect); + S32 toast_top = bottom + toast->getRect().getHeight() + margin; - if(toast->getRect().mTop > getRect().getHeight()) + if(toast_top > gFloaterView->getRect().getHeight()) { while(it!=m_active_toasts.end()) { - (*it)->setVisible(FALSE); - (*it)->stopTimer(); - m_toast_pool.push_back(*it); + toast->setVisible(FALSE); + toast->stopTimer(); + m_toast_pool.push_back(toast); it=m_active_toasts.erase(it); } break; } - toast->setVisible(TRUE); - bottom = toast->getRect().mTop; + else + { + toast_rect = toast->getRect(); + toast_rect.setLeftTopAndSize(getRect().mLeft , toast_top, toast_rect.getWidth() ,toast_rect.getHeight()); + + toast->setRect(toast_rect); + + toast->setVisible(TRUE); + bottom = toast->getRect().mTop; + } } } +void LLNearbyChatScreenChannel::reshape (S32 width, S32 height, BOOL called_from_parent) +{ + LLScreenChannelBase::reshape(width, height, called_from_parent); + arrangeToasts(); +} + //----------------------------------------------------------------------------------------------- //LLNearbyChatHandler diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index bd6e6cd0cb..b6b433c28f 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -65,21 +65,30 @@ static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map"); -const F32 MAP_SCALE_MIN = 64; -const F32 MAP_SCALE_MID = 172; -const F32 MAP_SCALE_MAX = 512; const F32 MAP_SCALE_INCREMENT = 16; const F32 MAP_MIN_PICK_DIST = 4; const F32 MAX_PRIM_RADIUS = 256.0f; // Don't try to draw giant mega-prims on the mini map -LLNetMap::LLNetMap (const Params & p) : - LLUICtrl (p), - mScale(128.0f), +LLNetMap::LLNetMap (const Params & p) +: LLUICtrl (p), mBackgroundColor (p.bg_color()), - mRotateMap(FALSE) + mScale( MAP_SCALE_MID ), + mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ), + mObjectMapTPM(0.f), + mObjectMapPixels(0.f), + mTargetPanX(0.f), + mTargetPanY(0.f), + mCurPanX(0.f), + mCurPanY(0.f), + mUpdateNow(FALSE), + mObjectImageCenterGlobal( gAgent.getCameraPositionGlobal() ), + mObjectRawImagep(), + mObjectImagep(), + mClosestAgentToCursor(), + mClosestAgentAtLastRightClick(), + mRotateMap(FALSE), + mToolTipMsg() { - mObjectImageCenterGlobal = gAgent.getCameraPositionGlobal(); - mPixelsPerMeter = mScale / REGION_WIDTH_METERS; } LLNetMap::~LLNetMap() diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 821c348835..5ebdd13384 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -38,12 +38,17 @@ #include "v3math.h" #include "v3dmath.h" #include "v4color.h" -#include "llimage.h" +#include "llpointer.h" class LLColor4U; class LLCoordGL; +class LLImageRaw; class LLTextBox; -class LLViewerTexture ; +class LLViewerTexture; + +const F32 MAP_SCALE_MIN = 64.f; +const F32 MAP_SCALE_MID = 172.f; +const F32 MAP_SCALE_MAX = 512.f; class LLNetMap : public LLUICtrl { diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index d9cdf2e04f..8bac9937f0 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -222,7 +222,7 @@ void LLOutputMonitorCtrl::draw() void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id) { - if (speaker_id.isNull()) return; + if (speaker_id.isNull() || speaker_id == mSpeakerId) return; mSpeakerId = speaker_id; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index c543f85f22..3a3ea1fc3c 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -38,7 +38,6 @@ #include "llavatarconstants.h" // AVATAR_ONLINE #include "llcallingcard.h" #include "llcombobox.h" -#include "lldateutil.h" #include "llimview.h" #include "lltexteditor.h" #include "lltexturectrl.h" @@ -448,7 +447,7 @@ void LLPanelAvatarProfile::processGroupProperties(const LLAvatarGroups* avatar_g void LLPanelAvatarProfile::fillCommonData(const LLAvatarData* avatar_data) { - childSetValue("register_date", LLDateUtil::ageFromDate(avatar_data->born_on)); + childSetValue("register_date", avatar_data->born_on ); childSetValue("sl_description_edit", avatar_data->about_text); childSetValue("fl_description_edit",avatar_data->fl_about_text); childSetValue("2nd_life_pic", avatar_data->image_id); diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 2b584910a3..206d8428be 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -54,6 +54,7 @@ #include "llsidetray.h" #include "llaccordionctrltab.h" +#include "llaccordionctrl.h" static LLRegisterPanelClassWrapper<LLPanelGroup> t_panel_group("panel_group_info_sidetray"); @@ -100,14 +101,13 @@ void LLPanelGroupTab::handleClickHelp() } LLPanelGroup::LLPanelGroup() -: LLPanel() - ,LLGroupMgrObserver( LLUUID() ) - ,mAllowEdit(TRUE) +: LLPanel(), + LLGroupMgrObserver( LLUUID() ), + mAllowEdit( TRUE ) { // Set up the factory callbacks. // Roles sub tabs LLGroupMgr::getInstance()->addObserver(this); - } @@ -210,9 +210,19 @@ void LLPanelGroup::reposButton(const std::string& name) button->setRect(btn_rect); } -void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent ) +void LLPanelGroup::reposButtons() { - LLPanel::reshape(width, height, called_from_parent ); + LLButton* button_refresh = findChild<LLButton>("btn_refresh"); + LLButton* button_cancel = findChild<LLButton>("btn_cancel"); + + if(button_refresh && button_cancel && button_refresh->getVisible() && button_cancel->getVisible()) + { + LLRect btn_refresh_rect = button_refresh->getRect(); + LLRect btn_cancel_rect = button_cancel->getRect(); + btn_refresh_rect.setLeftTopAndSize( btn_cancel_rect.mLeft + btn_cancel_rect.getWidth() + 2, + btn_refresh_rect.getHeight() + 2, btn_refresh_rect.getWidth(), btn_refresh_rect.getHeight()); + button_refresh->setRect(btn_refresh_rect); + } reposButton("btn_apply"); reposButton("btn_create"); @@ -220,6 +230,13 @@ void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent ) reposButton("btn_cancel"); } +void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent ) +{ + LLPanel::reshape(width, height, called_from_parent ); + + reposButtons(); +} + void LLPanelGroup::onBackBtnClick() { LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent()); @@ -229,6 +246,7 @@ void LLPanelGroup::onBackBtnClick() } } + void LLPanelGroup::onBtnCreate() { LLPanelGroupGeneral* panel_general = findChild<LLPanelGroupGeneral>("group_general_tab_panel"); @@ -375,17 +393,23 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) getChild<LLUICtrl>("prepend_founded_by")->setVisible(!is_null_group_id); + LLAccordionCtrl* tab_ctrl = findChild<LLAccordionCtrl>("group_accordion"); + if(tab_ctrl) + tab_ctrl->reset(); + LLAccordionCtrlTab* tab_general = findChild<LLAccordionCtrlTab>("group_general_tab"); LLAccordionCtrlTab* tab_roles = findChild<LLAccordionCtrlTab>("group_roles_tab"); LLAccordionCtrlTab* tab_notices = findChild<LLAccordionCtrlTab>("group_notices_tab"); LLAccordionCtrlTab* tab_land = findChild<LLAccordionCtrlTab>("group_land_tab"); + if(!tab_general || !tab_roles || !tab_notices || !tab_land) return; if(button_join) button_join->setVisible(false); + if(is_null_group_id)//creating new group { if(!tab_general->getDisplayChildren()) @@ -404,7 +428,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) getChild<LLUICtrl>("group_name")->setVisible(false); getChild<LLUICtrl>("group_name_editor")->setVisible(true); - } else { @@ -424,6 +447,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id) getChild<LLUICtrl>("group_name")->setVisible(true); getChild<LLUICtrl>("group_name_editor")->setVisible(false); } + + reposButtons(); } bool LLPanelGroup::apply(LLPanelGroupTab* tab) diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h index f2118a7244..628e2389b6 100644 --- a/indra/newview/llpanelgroup.h +++ b/indra/newview/llpanelgroup.h @@ -104,6 +104,7 @@ protected: static bool joinDlgCB(const LLSD& notification, const LLSD& response); void reposButton(const std::string& name); + void reposButtons(); protected: diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 0331fad60c..1c2875bf46 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -186,7 +186,7 @@ BOOL LLPanelGroupGeneral::postBuild() } mIncompleteMemberDataStr = getString("incomplete_member_data_str"); - + // If the group_id is null, then we are creating a new group if (mGroupID.isNull()) { @@ -476,8 +476,15 @@ bool LLPanelGroupGeneral::confirmMatureApply(const LLSD& notification, const LLS // If we got here it means they set a valid value std::string mesg = ""; - apply(mesg); - return false; + bool ret = apply(mesg); + if ( !mesg.empty() ) + { + LLSD args; + args["MESSAGE"] = mesg; + LLNotifications::instance().add("GenericAlert", args); + } + + return ret; } // static diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 1521c1113a..71486c908c 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -517,6 +517,8 @@ void LLPanelGroupSubTab::setGroupID(const LLUUID& id) void LLPanelGroupSubTab::setSearchFilter(const std::string& filter) { + if(mSearchFilter == filter) + return; lldebugs << "LLPanelGroupSubTab::setSearchFilter() ==> '" << filter << "'" << llendl; mSearchFilter = filter; LLStringUtil::toLower(mSearchFilter); @@ -1515,9 +1517,6 @@ void LLPanelGroupMembersSubTab::update(LLGroupChange gc) return; } - // Rebuild the members list. - mMembersList->deleteAllItems(); - // Wait for both all data to be retrieved before displaying anything. if ( gdatap->isMemberDataComplete() && gdatap->isRoleDataComplete() @@ -1557,6 +1556,9 @@ void LLPanelGroupMembersSubTab::updateMembers() { mPendingMemberUpdate = FALSE; + // Rebuild the members list. + mMembersList->deleteAllItems(); + lldebugs << "LLPanelGroupMembersSubTab::updateMembers()" << llendl; LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index e8a16859c7..76dcd89028 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -39,6 +39,7 @@ #include "llspinctrl.h" #include "lluictrlfactory.h" #include "llviewerwindow.h" +#include "llviewermedia.h" #include "llsdutil.h" #include "llselectmgr.h" #include "llbutton.h" @@ -68,11 +69,12 @@ LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() : mHomeURL( NULL ), mCurrentURL( NULL ), mAltImageEnable( NULL ), - mParent( NULL ) + mParent( NULL ), + mMediaEditable(false) { // build dialog from XML LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_general.xml"); - mCommitCallbackRegistrar.add("Media.ResetCurrentUrl", boost::bind(&LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl, this)); +// mCommitCallbackRegistrar.add("Media.ResetCurrentUrl", boost::bind(&LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl, this)); // mCommitCallbackRegistrar.add("Media.CommitHomeURL", boost::bind(&LLPanelMediaSettingsGeneral::onCommitHomeURL, this)); } @@ -97,7 +99,7 @@ BOOL LLPanelMediaSettingsGeneral::postBuild() // watch commit action for HOME URL childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this); - + childSetCommitCallback( "current_url_reset_btn",onBtnResetCurrentUrl, this); // interrogates controls and updates widgets as required updateMediaPreview(); updateCurrentURL(); @@ -162,7 +164,7 @@ void LLPanelMediaSettingsGeneral::draw() // updateCurrentURL(); LLPermissions perm; - bool user_can_press_reset = gFloaterTools->selectedMediaEditable(); + bool user_can_press_reset = mMediaEditable; // several places modify this widget so we must collect states in one place if ( reset_button_is_active ) @@ -220,6 +222,7 @@ void LLPanelMediaSettingsGeneral::clearValues( void* userdata, bool editable) void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings ,bool editable) { LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata; + self->mMediaEditable = editable; //llinfos << "---------------" << llendl; //llinfos << ll_pretty_print_sd(media_settings) << llendl; @@ -230,7 +233,7 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_ { if(LLFloaterMediaSettings::getInstance()->mMultipleMedia) { - self->clearValues(self, editable); + self->clearValues(self, self->mMediaEditable); // only show multiple self->mHomeURL ->setText(LLTrans::getString("Multiple Media")); return; @@ -241,7 +244,7 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_ { if(LLFloaterMediaSettings::getInstance()->mMultipleValidMedia) { - self->clearValues(self, editable); + self->clearValues(self, self->mMediaEditable); // only show multiple self->mHomeURL ->setText(LLTrans::getString("Multiple Media")); return; @@ -298,7 +301,7 @@ void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_ static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )-> setValue( media_settings[ base_key ].asInteger() ); - data_set[ i ].ctrl_ptr->setEnabled(editable); + data_set[ i ].ctrl_ptr->setEnabled(self->mMediaEditable); data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() ); }; }; @@ -354,12 +357,12 @@ void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdat self->updateMediaPreview(); } - //////////////////////////////////////////////////////////////////////////////// -void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl() +// static +void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl(LLUICtrl* ctrl, void *userdata) { - // TODO: reset home URL but need to consider permissions too - //LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata; + LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata; + self->navigateHomeSelectedFace(); } //////////////////////////////////////////////////////////////////////////////// @@ -399,3 +402,39 @@ void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent ) { mParent = parent; }; + +bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace() +{ + // HACK: This is directly referencing an impl name. BAD! + // This can be removed when we have a truly generic media browser that only + // builds an impl based on the type of url it is passed. + struct functor_navigate_media : public LLSelectedTEGetFunctor< bool> + { + bool get( LLViewerObject* object, S32 face ) + { + if ( object ) + if ( object->getTE(face) ) + if ( object->getTE(face)->getMediaData() ) + { + if(object->permModify()) + { + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); + if(media_impl) + { + media_impl->navigateHome(); + return true; + } + } + } + return false; + }; + + } functor_navigate_media; + + bool all_face_media_navigated = false; + LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection(); + selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated ); + + return all_face_media_navigated; +} + diff --git a/indra/newview/llpanelmediasettingsgeneral.h b/indra/newview/llpanelmediasettingsgeneral.h index 5acfa39181..1b60909786 100644 --- a/indra/newview/llpanelmediasettingsgeneral.h +++ b/indra/newview/llpanelmediasettingsgeneral.h @@ -61,14 +61,16 @@ public: static void initValues( void* userdata, const LLSD& media_settings ,bool editable); static void clearValues( void* userdata, bool editable); + bool navigateHomeSelectedFace(); void updateMediaPreview(); void updateCurrentURL(); protected: LLFloaterMediaSettings* mParent; + bool mMediaEditable; private: - void onBtnResetCurrentUrl(); + static void onBtnResetCurrentUrl(LLUICtrl* ctrl, void *userdata); static void onCommitHomeURL(LLUICtrl* ctrl, void *userdata ); LLComboBox* mControls; diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp index eb432335a1..8ed22ebbde 100644 --- a/indra/newview/llpanelplaceinfo.cpp +++ b/indra/newview/llpanelplaceinfo.cpp @@ -568,7 +568,8 @@ void LLPanelPlaceInfo::displayParcelInfo(const LLUUID& region_id, void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel, LLViewerRegion* region, - const LLVector3d& pos_global) + const LLVector3d& pos_global, + bool is_current_parcel) { if (!region || !parcel) return; @@ -799,6 +800,9 @@ void LLPanelPlaceInfo::displaySelectedParcelInfo(LLParcel* parcel, processParcelInfo(parcel_data); + // TODO: If agent is in currently within the selected parcel + // show the "You Are Here" banner. + getChild<LLAccordionCtrlTab>("sales_tab")->setVisible(for_sale); } @@ -846,14 +850,17 @@ void LLPanelPlaceInfo::toggleLandmarkEditMode(BOOL enabled) mTitle->setText(mCurrentTitle); } - mTitleEditor->setEnabled(enabled); - mNotesEditor->setReadOnly(!enabled); - mFolderCombo->setVisible(enabled); - getChild<LLTextBox>("folder_lable")->setVisible(enabled); - - // HACK: To change the text color in a text editor - // when it was enabled/disabled we set the text once again. - mNotesEditor->setText(mNotesEditor->getText()); + if (mNotesEditor->getReadOnly() == (enabled == TRUE)) + { + mTitleEditor->setEnabled(enabled); + mNotesEditor->setReadOnly(!enabled); + mFolderCombo->setVisible(enabled); + getChild<LLTextBox>("folder_lable")->setVisible(enabled); + + // HACK: To change the text color in a text editor + // when it was enabled/disabled we set the text once again. + mNotesEditor->setText(mNotesEditor->getText()); + } } const std::string& LLPanelPlaceInfo::getLandmarkTitle() const @@ -871,6 +878,11 @@ const LLUUID LLPanelPlaceInfo::getLandmarkFolder() const return mFolderCombo->getValue().asUUID(); } +BOOL LLPanelPlaceInfo::setLandmarkFolder(const LLUUID& id) +{ + return mFolderCombo->setCurrentByID(id); +} + void LLPanelPlaceInfo::createLandmark(const LLUUID& folder_id) { std::string name = mTitleEditor->getText(); @@ -913,17 +925,6 @@ void LLPanelPlaceInfo::createPick(const LLVector3d& pos_global, LLPanelPick* pic } // virtual -void LLPanelPlaceInfo::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - if (mMinHeight > 0 && mScrollingPanel != NULL) - { - mScrollingPanel->reshape(mScrollingPanel->getRect().getWidth(), mMinHeight); - } - - LLView::reshape(width, height, called_from_parent); -} - -// virtual void LLPanelPlaceInfo::handleVisibilityChange (BOOL new_visibility) { LLPanel::handleVisibilityChange(new_visibility); diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h index 49aa195490..3e8344ff12 100644 --- a/indra/newview/llpanelplaceinfo.h +++ b/indra/newview/llpanelplaceinfo.h @@ -105,9 +105,11 @@ public: // Displays information about the currently selected parcel // without sending a request to the server. + // If is_current_parcel true shows "You Are Here" banner. void displaySelectedParcelInfo(LLParcel* parcel, LLViewerRegion* region, - const LLVector3d& pos_global); + const LLVector3d& pos_global, + bool is_current_parcel); void updateEstateName(const std::string& name); void updateEstateOwnerName(const std::string& name); @@ -124,8 +126,10 @@ public: const std::string getLandmarkNotes() const; const LLUUID getLandmarkFolder() const; + // Select current landmark folder in combobox. + BOOL setLandmarkFolder(const LLUUID& id); + /*virtual*/ void processParcelInfo(const LLParcelData& parcel_data); - /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); /*virtual*/ void handleVisibilityChange (BOOL new_visibility); private: diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 35206f54c7..d415b17538 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -200,7 +200,7 @@ BOOL LLPanelPlaces::postBuild() mFilterEditor = getChild<LLFilterEditor>("Filter"); if (mFilterEditor) { - mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2)); + mFilterEditor->setCommitCallback(boost::bind(&LLPanelPlaces::onFilterEdit, this, _2, false)); } mPlaceInfo = getChild<LLPanelPlaceInfo>("panel_place_info"); @@ -225,11 +225,12 @@ void LLPanelPlaces::onOpen(const LLSD& key) return; mFilterEditor->clear(); - onFilterEdit(""); + onFilterEdit("", false); mPlaceInfoType = key["type"].asString(); mPosGlobal.setZero(); mItem = NULL; + isLandmarkEditModeOn = false; togglePlaceInfoPanel(TRUE); updateVerbs(); @@ -317,21 +318,38 @@ void LLPanelPlaces::onOpen(const LLSD& key) void LLPanelPlaces::setItem(LLInventoryItem* item) { - if (!item) + if (!mPlaceInfo || !item) return; mItem = item; - - // If the item is a link get a linked item - if (mItem->getType() == LLAssetType::AT_LINK) + + LLAssetType::EType item_type = mItem->getActualType(); + if (item_type == LLAssetType::AT_LANDMARK || item_type == LLAssetType::AT_LINK) { - mItem = gInventory.getItem(mItem->getAssetUUID()); - if (mItem.isNull()) - return; + // If the item is a link get a linked item + if (item_type == LLAssetType::AT_LINK) + { + mItem = gInventory.getItem(mItem->getLinkedUUID()); + if (mItem.isNull()) + return; + } } - - if (!mPlaceInfo) + else + { return; + } + + // Check if item is in agent's inventory and he has the permission to modify it. + BOOL is_landmark_editable = gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) && + mItem->getPermissions().allowModifyBy(gAgent.getID()); + + mEditBtn->setEnabled(is_landmark_editable); + mSaveBtn->setEnabled(is_landmark_editable); + + if (is_landmark_editable) + { + mPlaceInfo->setLandmarkFolder(mItem->getParentUUID()); + } mPlaceInfo->displayItemInfo(mItem); @@ -352,17 +370,11 @@ void LLPanelPlaces::onLandmarkLoaded(LLLandmark* landmark) landmark->getRegionID(region_id); landmark->getGlobalPos(mPosGlobal); mPlaceInfo->displayParcelInfo(region_id, mPosGlobal); - - // Check if item is in agent's inventory and he has the permission to modify it. - BOOL is_landmark_editable = mItem.notNull() && - gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.getRootFolderID()) && - mItem->getPermissions().allowModifyBy(gAgent.getID()); - mEditBtn->setEnabled(is_landmark_editable); } -void LLPanelPlaces::onFilterEdit(const std::string& search_string) +void LLPanelPlaces::onFilterEdit(const std::string& search_string, bool force_filter) { - if (mFilterSubString != search_string) + if (force_filter || mFilterSubString != search_string) { mFilterSubString = search_string; @@ -381,7 +393,7 @@ void LLPanelPlaces::onTabSelected() if (!mActivePanel) return; - onFilterEdit(mFilterSubString); + onFilterEdit(mFilterSubString, true); mActivePanel->updateVerbs(); } @@ -487,22 +499,6 @@ void LLPanelPlaces::onSaveButtonClicked() if (!mPlaceInfo || mItem.isNull()) return; - LLAssetType::EType item_type = mItem->getType(); - if (item_type == LLAssetType::AT_LANDMARK || item_type != LLAssetType::AT_LINK) - { - // If the item is a link get a linked item - if (item_type == LLAssetType::AT_LINK) - { - mItem = gInventory.getItem(mItem->getAssetUUID()); - if (mItem.isNull()) - return; - } - } - else - { - return; - } - std::string current_title_value = mPlaceInfo->getLandmarkTitle(); std::string item_title_value = mItem->getName(); std::string current_notes_value = mPlaceInfo->getLandmarkNotes(); @@ -511,73 +507,35 @@ void LLPanelPlaces::onSaveButtonClicked() LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_notes_value); - bool is_item_update_needed = false; + LLUUID item_id = mItem->getUUID(); + LLUUID folder_id = mPlaceInfo->getLandmarkFolder(); + + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem); if (!current_title_value.empty() && (item_title_value != current_title_value || item_notes_value != current_notes_value)) { - is_item_update_needed = true; + new_item->rename(current_title_value); + new_item->setDescription(current_notes_value); + new_item->updateServer(FALSE); } - LLUUID item_id = mItem->getUUID(); - LLUUID folder_id = mPlaceInfo->getLandmarkFolder(); - - // Check if item is in agent's inventory and he has the permission to modify it. - if (!gInventory.isObjectDescendentOf(item_id, gInventory.getRootFolderID()) || - !mItem->getPermissions().allowModifyBy(gAgent.getID())) - return; - - if(folder_id != mItem->getParentUUID() || is_item_update_needed) + if(folder_id != mItem->getParentUUID()) { - LLViewerInventoryItem* item = (LLViewerInventoryItem*)mItem.get(); - LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); - - LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_FAVORITE); - - // If target is the favorites folder we create link to it. - if (favorites_id == folder_id) - { - if (is_item_update_needed) - { - new_item->rename(current_title_value); - new_item->setDescription(current_notes_value); - new_item->updateServer(FALSE); - - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } - - link_inventory_item(gAgent.getID(), - item->getUUID(), - folder_id, - item->getName(), - LLAssetType::AT_LINK, - LLPointer<LLInventoryCallback>(NULL)); - } - else - { - if (is_item_update_needed) - { - new_item->rename(current_title_value); - new_item->setDescription(current_notes_value); - new_item->updateServer(FALSE); - } + LLInventoryModel::update_list_t update; + LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1); + update.push_back(old_folder); + LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1); + update.push_back(new_folder); + gInventory.accountForUpdate(update); - LLInventoryModel::update_list_t update; - LLInventoryModel::LLCategoryUpdate old_folder(item->getParentUUID(),-1); - update.push_back(old_folder); - LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1); - update.push_back(new_folder); - gInventory.accountForUpdate(update); - - new_item->setParent(folder_id); - new_item->updateParentOnServer(FALSE); - - gInventory.updateItem(new_item); - gInventory.notifyObservers(); - } + new_item->setParent(folder_id); + new_item->updateParentOnServer(FALSE); } + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + onCancelButtonClicked(); } @@ -593,6 +551,8 @@ void LLPanelPlaces::onCancelButtonClicked() else { mPlaceInfo->toggleLandmarkEditMode(FALSE); + isLandmarkEditModeOn = false; + updateVerbs(); // Reload the landmark properties. @@ -707,6 +667,8 @@ void LLPanelPlaces::onBackButtonClicked() // Resetting mPlaceInfoType when Place Info panel is closed. mPlaceInfoType = LLStringUtil::null; + + isLandmarkEditModeOn = false; } updateVerbs(); @@ -766,7 +728,8 @@ void LLPanelPlaces::changedParcelSelection() // If agent is inside the selected parcel show agent's region<X, Y, Z>, // otherwise show region<X, Y, Z> of agent's selection point. - if (is_agent_in_selected_parcel(parcel)) + bool is_current_parcel = is_agent_in_selected_parcel(parcel); + if (is_current_parcel) { mPosGlobal = gAgent.getPositionGlobal(); } @@ -780,7 +743,7 @@ void LLPanelPlaces::changedParcelSelection() } mPlaceInfo->resetLocation(); - mPlaceInfo->displaySelectedParcelInfo(parcel, region, mPosGlobal); + mPlaceInfo->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel); updateVerbs(); } @@ -885,8 +848,6 @@ void LLPanelPlaces::updateVerbs() if (mActivePanel) mActivePanel->updateVerbs(); } - - isLandmarkEditModeOn = false; } static bool is_agent_in_selected_parcel(LLParcel* parcel) diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h index 0b3b3b5fc3..ce20ffdc91 100644 --- a/indra/newview/llpanelplaces.h +++ b/indra/newview/llpanelplaces.h @@ -66,7 +66,7 @@ public: private: void onLandmarkLoaded(LLLandmark* landmark); - void onFilterEdit(const std::string& search_string); + void onFilterEdit(const std::string& search_string, bool force_filter); void onTabSelected(); //void onShareButtonClicked(); diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index bc0dec1fdb..e1e3fe4677 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -163,11 +163,6 @@ void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, mIndex = index; mMenu = createMenu(); - LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos( - LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos); - - mMenu->setItemEnabled("Make Landmark", !landmark || landmark->getUUID().isNull()); - mMenu->show(x, y); LLMenuGL::showPopup(spawning_view, mMenu, x, y); } @@ -181,7 +176,6 @@ LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu() registrar.add("TeleportHistory.Teleport", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this)); registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this)); registrar.add("TeleportHistory.Copy", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopy, this)); - registrar.add("TeleportHistory.MakeLandmark", boost::bind(&LLTeleportHistoryPanel::ContextMenu::onMakeLandmark, this)); // create the context menu from the XUI return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( @@ -211,12 +205,6 @@ void LLTeleportHistoryPanel::ContextMenu::onCopy() boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1), false); } -void LLTeleportHistoryPanel::ContextMenu::onMakeLandmark() -{ - //FIXME: it creates landmark for current agent positon, not for the global position of item of teleport history - LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); -} - // Not yet implemented; need to remove buildPanel() from constructor when we switch //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history"); @@ -225,6 +213,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() mFilterSubString(LLStringUtil::null), mTeleportHistory(NULL), mHistoryAccordion(NULL), + mStarButton(NULL), mAccordionTabMenu(NULL), mLastSelectedScrollList(NULL) { @@ -233,6 +222,7 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel() LLTeleportHistoryPanel::~LLTeleportHistoryPanel() { + LLView::deleteViewByHandle(mGearMenuHandle); } BOOL LLTeleportHistoryPanel::postBuild() @@ -247,13 +237,13 @@ BOOL LLTeleportHistoryPanel::postBuild() if (mHistoryAccordion) { - for (child_list_const_iter_t iter = mHistoryAccordion->beginChild(); iter != mHistoryAccordion->endChild(); iter++) { if (dynamic_cast<LLAccordionCtrlTab*>(*iter)) { LLAccordionCtrlTab* tab = (LLAccordionCtrlTab*)*iter; tab->setRightMouseDownCallback(boost::bind(&LLTeleportHistoryPanel::onAccordionTabRightClick, this, _1, _2, _3, _4)); + tab->setDisplayChildren(false); mItemContainers.put(tab); @@ -266,8 +256,30 @@ BOOL LLTeleportHistoryPanel::postBuild() } } } + + // Open first 2 accordion tabs + if (mItemContainers.size() > 1) + mItemContainers.get(mItemContainers.size() - 1)->setDisplayChildren(true); + + if (mItemContainers.size() > 2) + mItemContainers.get(mItemContainers.size() - 2)->setDisplayChildren(true); } + getChild<LLPanel>("bottom_panel")->childSetAction("gear_btn",boost::bind(&LLTeleportHistoryPanel::onGearButtonClicked, this)); + + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; + + registrar.add("TeleportHistory.ExpandAllFolders", boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders, this)); + registrar.add("TeleportHistory.CollapseAllFolders", boost::bind(&LLTeleportHistoryPanel::onCollapseAllFolders, this)); + registrar.add("TeleportHistory.ClearTeleportHistory", boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory, this)); + + LLMenuGL* gear_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); + if(gear_menu) + mGearMenuHandle = gear_menu->getHandle(); + + mStarButton = getChild<LLButton>("star_btn"); + mStarButton->setCommitCallback(boost::bind(&LLTeleportHistoryPanel::onStarButtonCommit, this)); + return TRUE; } @@ -293,7 +305,7 @@ void LLTeleportHistoryPanel::onShowOnMap() return; LLVector3d global_pos = mTeleportHistory->getItems()[itemp->getIndex()].mGlobalPos; - + if (!global_pos.isExactlyZero()) { LLFloaterWorldMap::getInstance()->trackLocation(global_pos); @@ -342,20 +354,47 @@ void LLTeleportHistoryPanel::onCopySLURL() // virtual void LLTeleportHistoryPanel::updateVerbs() { - if (!isTabVisible()) + if (!isTabVisible()) return; if (!mLastSelectedScrollList) { mTeleportBtn->setEnabled(false); mShowOnMapBtn->setEnabled(false); + mStarButton->setEnabled(false); + mStarButton->setToolTip(LLStringExplicit("")); return; } LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem()); - mTeleportBtn->setEnabled(NULL != itemp && 0 < itemp->getIndex()); + mTeleportBtn->setEnabled(NULL != itemp && itemp->getIndex() < (S32)mTeleportHistory->getItems().size() - 1); mShowOnMapBtn->setEnabled(NULL != itemp); + + if (NULL != itemp) + { + LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos( + mTeleportHistory->getItems()[itemp->getIndex()].mGlobalPos); + + mStarButton->setEnabled(true); + if (!landmark || landmark->getUUID().isNull()) + { + mStarButton->setToggleState(true); + // Landmark can be created only for current agent positon, which is most recent (last) item in teleport history. + // mTeleportBtn is disabled only for that item. + mStarButton->setToolTip(mTeleportBtn->getEnabled() ? getString("cant_create_lm_here") : getString("create_landmark")); + } + else + { + mStarButton->setToggleState(false); + mStarButton->setToolTip(getString("open_landmark")); + } + } + else + { + mStarButton->setEnabled(false); + mStarButton->setToolTip(LLStringExplicit("")); + } } void LLTeleportHistoryPanel::showTeleportHistory() @@ -375,23 +414,23 @@ void LLTeleportHistoryPanel::showTeleportHistory() curr_date.split(&curr_year, &curr_month, &curr_day); curr_date.fromYMDHMS(curr_year, curr_month, curr_day); // Set hour, min, and sec to 0 curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() + seconds_in_day); - + LLFlatListView* curr_flat_view = NULL; S32 index = hist_items.size() - 1; for (LLTeleportHistoryStorage::slurl_list_t::const_reverse_iterator iter = hist_items.rbegin(); - iter != hist_items.rend(); ++iter) + iter != hist_items.rend(); ++iter, --index) { std::string landmark_title = (*iter).mTitle; LLStringUtil::toUpper(landmark_title); std::string::size_type match_offset = mFilterSubString.size() ? landmark_title.find(mFilterSubString) : std::string::npos; bool passed = mFilterSubString.size() == 0 || match_offset != std::string::npos; - + if (!passed) continue; - + if (curr_tab < tabs_cnt - 1) { const LLDate &date = (*iter).mDate; @@ -405,7 +444,7 @@ void LLTeleportHistoryPanel::showTeleportHistory() tab = mItemContainers.get(mItemContainers.size() - 1 - curr_tab); tab->setVisible(false); - + if (curr_tab <= tabs_cnt - 4) { curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day); @@ -436,7 +475,6 @@ void LLTeleportHistoryPanel::showTeleportHistory() curr_year--; } curr_date.fromYMDHMS(curr_year, curr_month, curr_day); - } else // 6 months and older { @@ -455,11 +493,9 @@ void LLTeleportHistoryPanel::showTeleportHistory() } if (curr_flat_view) - { + { curr_flat_view->addItem(new LLTeleportHistoryFlatItem(index, &mContextMenu, (*iter).mTitle)); } - - index--; } // Hide empty tabs from current to bottom @@ -553,6 +589,50 @@ void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab) mHistoryAccordion->arrange(); } +void LLTeleportHistoryPanel::onExpandAllFolders() +{ + S32 tabs_cnt = mItemContainers.size(); + + for (S32 n = 0; n < tabs_cnt; n++) + { + mItemContainers.get(n)->setDisplayChildren(true); + } + mHistoryAccordion->arrange(); +} + +void LLTeleportHistoryPanel::onCollapseAllFolders() +{ + S32 tabs_cnt = mItemContainers.size(); + + for (S32 n = 0; n < tabs_cnt; n++) + { + mItemContainers.get(n)->setDisplayChildren(false); + } + mHistoryAccordion->arrange(); +} + +void LLTeleportHistoryPanel::onClearTeleportHistory() +{ + LLNotifications::instance().add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2)); +} + +bool LLTeleportHistoryPanel::onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response) +{ + + S32 option = LLNotification::getSelectedOption(notification, response); + + if (0 == option) + { + LLTeleportHistoryStorage *th = LLTeleportHistoryStorage::getInstance(); + th->purgeItems(); + th->save(); + + showTeleportHistory(); + } + + return false; +} + LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTab *tab) { for (child_list_const_iter_t iter = tab->beginChild(); iter != tab->endChild(); iter++) @@ -566,3 +646,49 @@ LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTa return NULL; } +void LLTeleportHistoryPanel::onGearButtonClicked() +{ + LLMenuGL* menu = (LLMenuGL*)mGearMenuHandle.get(); + if (!menu) + return; + + // Shows the menu at the top of the button bar. + + // Calculate its coordinates. + LLPanel* bottom_panel = getChild<LLPanel>("bottom_panel"); + menu->arrangeAndClear(); + S32 menu_height = menu->getRect().getHeight(); + S32 menu_x = -2; // *HACK: compensates HPAD in showPopup() + S32 menu_y = bottom_panel->getRect().mTop + menu_height; + + // Actually show the menu. + menu->buildDrawLabels(); + menu->updateParent(LLMenuGL::sMenuContainer); + LLMenuGL::showPopup(this, menu, menu_x, menu_y); +} + +void LLTeleportHistoryPanel::onStarButtonCommit() +{ + if (!mLastSelectedScrollList) + return; + + LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedScrollList->getSelectedItem()); + if(!itemp) + return; + + if (itemp->getIndex() < (S32)mTeleportHistory->getItems().size() - 1) + { + LLTeleportHistoryFlatItem::showPlaceInfoPanel(itemp->getIndex()); + } + else + { + LLViewerInventoryItem *landmark = LLLandmarkActions::findLandmarkForGlobalPos( + mTeleportHistory->getItems()[itemp->getIndex()].mGlobalPos); + + if (!landmark || landmark->getUUID().isNull()) + LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "create_landmark")); + else + LLTeleportHistoryFlatItem::showPlaceInfoPanel(itemp->getIndex()); + } +} + diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h index c4b7f995e0..f487c92836 100644 --- a/indra/newview/llpanelteleporthistory.h +++ b/indra/newview/llpanelteleporthistory.h @@ -52,16 +52,15 @@ public: public: ContextMenu(); void show(LLView* spawning_view, S32 index, S32 x, S32 y); - + private: LLContextMenu* createMenu(); void onTeleport(); void onInfo(); void onCopy(); - void onMakeLandmark(); static void gotSLURLCallback(const std::string& slurl); - + LLContextMenu* mMenu; S32 mIndex; }; @@ -82,12 +81,21 @@ private: void onAccordionTabRightClick(LLView *view, S32 x, S32 y, MASK mask); void onAccordionTabOpen(LLAccordionCtrlTab *tab); void onAccordionTabClose(LLAccordionCtrlTab *tab); + void onExpandAllFolders(); + void onCollapseAllFolders(); + void onClearTeleportHistory(); + bool onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response); + void showTeleportHistory(); void handleItemSelect(LLFlatListView* ); LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *); + void onGearButtonClicked(); + void onStarButtonCommit(); LLTeleportHistoryStorage* mTeleportHistory; LLAccordionCtrl* mHistoryAccordion; + LLButton * mStarButton; + LLFlatListView* mLastSelectedScrollList; std::string mFilterSubString; @@ -96,6 +104,7 @@ private: ContextMenu mContextMenu; LLContextMenu* mAccordionTabMenu; + LLHandle<LLView> mGearMenuHandle; }; #endif //LL_LLPANELTELEPORTHISTORY_H diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp index ab253e012d..b06e70c00a 100644 --- a/indra/newview/llpreview.cpp +++ b/indra/newview/llpreview.cpp @@ -492,3 +492,31 @@ void LLMultiPreview::tabOpen(LLFloater* opened_floater, bool from_click) } } + +void LLPreview::setAssetId(const LLUUID& asset_id) +{ + const LLViewerInventoryItem* item = dynamic_cast<const LLViewerInventoryItem*>(getItem()); + if(NULL == item) + { + return; + } + + if(mObjectUUID.isNull()) + { + // Update avatar inventory asset_id. + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item); + new_item->setAssetUUID(asset_id); + gInventory.updateItem(new_item); + gInventory.notifyObservers(); + } + else + { + // Update object inventory asset_id. + LLViewerObject* object = gObjectList.findObject(mObjectUUID); + if(NULL == object) + { + return; + } + object->updateViewerInventoryAsset(item, asset_id); + } +} diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h index c5f2bfcf47..506c135ca6 100644 --- a/indra/newview/llpreview.h +++ b/indra/newview/llpreview.h @@ -77,6 +77,7 @@ public: void setObjectID(const LLUUID& object_id); void setItem( LLInventoryItem* item ); + void setAssetId(const LLUUID& asset_id); const LLInventoryItem* getItem() const; // searches if not constructed with it static void hide(const LLUUID& item_uuid, BOOL no_saving = FALSE ); diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 32ed20bd56..ab2afb8056 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -1178,7 +1178,7 @@ void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data, else { llwarns << "Inventory item for gesture " << info->mItemUUID - << " is no longer in agent inventory." << llendl + << " is no longer in agent inventory." << llendl; } } else diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 19bb60b237..ac7abf1448 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -1260,7 +1260,7 @@ void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 else { llwarns << "Inventory item for script " << info->mItemUUID - << " is no longer in agent inventory." << llendl + << " is no longer in agent inventory." << llendl; } // Find our window and close it if requested. @@ -1383,6 +1383,7 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset delete item_uuid; } + /// --------------------------------------------------------------------------- /// LLLiveLSLEditor /// --------------------------------------------------------------------------- @@ -2145,6 +2146,7 @@ void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) } } + void LLLiveLSLEditor::onMonoCheckboxClicked(LLUICtrl*, void* userdata) { LLLiveLSLEditor* self = static_cast<LLLiveLSLEditor*>(userdata); diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 9d7338c111..9c21faa3be 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -38,6 +38,7 @@ #include "llagent.h" #include "llbutton.h" +#include "llcombobox.h" #include "llfilepicker.h" #include "llfloaterreg.h" #include "llimagetga.h" @@ -57,6 +58,10 @@ const S32 CLIENT_RECT_VPAD = 4; const F32 SECONDS_TO_SHOW_FILE_SAVED_MSG = 8.f; +const F32 PREVIEW_TEXTURE_MAX_ASPECT = 200.f; +const F32 PREVIEW_TEXTURE_MIN_ASPECT = 0.005f; + + LLPreviewTexture::LLPreviewTexture(const LLSD& key) : LLPreview( key ), mLoadingFullImage( FALSE ), @@ -65,7 +70,8 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key) mIsCopyable(FALSE), mUpdateDimensions(TRUE), mLastHeight(0), - mLastWidth(0) + mLastWidth(0), + mAspectRatio(0.f) { const LLInventoryItem *item = getItem(); if(item) @@ -144,6 +150,10 @@ BOOL LLPreviewTexture::postBuild() } } + childSetCommitCallback("combo_aspect_ratio", onAspectRatioCommit, this); + LLComboBox* combo = getChild<LLComboBox>("combo_aspect_ratio"); + combo->setCurrentByIndex(0); + return LLPreview::postBuild(); } @@ -369,8 +379,13 @@ void LLPreviewTexture::updateDimensions() S32 max_client_width = gViewerWindow->getWindowWidth() - horiz_pad; S32 max_client_height = gViewerWindow->getWindowHeight() - vert_pad; + if (mAspectRatio > 0.f) + { + client_height = llceil((F32)client_width / mAspectRatio); + } + while ((client_width > max_client_width) || - (client_height > max_client_height ) ) + (client_height > max_client_height )) { client_width /= 2; client_height /= 2; @@ -383,12 +398,12 @@ void LLPreviewTexture::updateDimensions() childSetTextArg("dimensions", "[WIDTH]", llformat("%d", mImage->getFullWidth())); childSetTextArg("dimensions", "[HEIGHT]", llformat("%d", mImage->getFullHeight())); - // add space for dimensions + // add space for dimensions and aspect ratio S32 info_height = 0; - LLRect dim_rect; - childGetRect("dimensions", dim_rect); - S32 dim_height = dim_rect.getHeight(); - info_height += dim_height + CLIENT_RECT_VPAD; + LLRect aspect_rect; + childGetRect("combo_aspect_ratio", aspect_rect); + S32 aspect_height = aspect_rect.getHeight(); + info_height += aspect_height + CLIENT_RECT_VPAD; view_height += info_height; S32 button_height = 0; @@ -445,24 +460,96 @@ void LLPreviewTexture::updateDimensions() else { client_width = getRect().getWidth() - horiz_pad; - client_height = getRect().getHeight() - vert_pad; + if (mAspectRatio > 0) + { + client_height = llround(client_width / mAspectRatio); + } + else + { + client_height = getRect().getHeight() - vert_pad; + } } - S32 max_height = getRect().getHeight() - PREVIEW_BORDER - button_height + S32 max_height = getRect().getHeight() - PREVIEW_BORDER - button_height - CLIENT_RECT_VPAD - info_height - CLIENT_RECT_VPAD - PREVIEW_HEADER_SIZE; - S32 max_width = getRect().getWidth() - horiz_pad; - client_height = llclamp(client_height, 1, max_height); - client_width = llclamp(client_width, 1, max_width); + if (mAspectRatio > 0.f) + { + max_height = llmax(max_height, 1); + + if (client_height > max_height) + { + client_height = max_height; + client_width = llround(client_height * mAspectRatio); + } + } + else + { + S32 max_width = getRect().getWidth() - horiz_pad; + + client_height = llclamp(client_height, 1, max_height); + client_width = llclamp(client_width, 1, max_width); + } LLRect window_rect(0, getRect().getHeight(), getRect().getWidth(), 0); window_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD); window_rect.mBottom += PREVIEW_BORDER + button_height + CLIENT_RECT_VPAD + info_height + CLIENT_RECT_VPAD; - mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height); + mClientRect.setLeftTopAndSize(window_rect.getCenterX() - (client_width / 2), window_rect.mTop, client_width, client_height); + + // Hide the aspect ratio label if the window is too narrow + // Assumes the label should be to the right of the dimensions + LLRect dim_rect, aspect_label_rect; + childGetRect("aspect_ratio", aspect_label_rect); + childGetRect("dimensions", dim_rect); + childSetVisible("aspect_ratio", dim_rect.mRight < aspect_label_rect.mLeft); +} + + +// Return true if everything went fine, false if we somewhat modified the ratio as we bumped on border values +bool LLPreviewTexture::setAspectRatio(const F32 width, const F32 height) +{ + mUpdateDimensions = TRUE; + + // We don't allow negative width or height. Also, if height is positive but too small, we reset to default + // A default 0.f value for mAspectRatio means "unconstrained" in the rest of the code + if ((width <= 0.f) || (height <= F_APPROXIMATELY_ZERO)) + { + mAspectRatio = 0.f; + return false; + } + + // Compute and store the ratio + F32 ratio = width / height; + mAspectRatio = llclamp(ratio, PREVIEW_TEXTURE_MIN_ASPECT, PREVIEW_TEXTURE_MAX_ASPECT); + + // Return false if we clamped the value, true otherwise + return (ratio == mAspectRatio); } +void LLPreviewTexture::onAspectRatioCommit(LLUICtrl* ctrl, void* userdata) +{ + LLPreviewTexture* self = (LLPreviewTexture*) userdata; + + std::string ratio(ctrl->getValue().asString()); + std::string::size_type separator(ratio.find_first_of(":/\\")); + + if (std::string::npos == separator) { + // If there's no separator assume we want an unconstrained ratio + self->setAspectRatio( 0.f, 0.f ); + return; + } + + F32 width, height; + std::istringstream numerator(ratio.substr(0, separator)); + std::istringstream denominator(ratio.substr(separator + 1)); + numerator >> width; + denominator >> height; + + self->setAspectRatio( width, height ); +} + void LLPreviewTexture::loadAsset() { mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, FALSE, LLViewerTexture::LOD_TEXTURE); diff --git a/indra/newview/llpreviewtexture.h b/indra/newview/llpreviewtexture.h index 9ace304fa6..520626b49f 100644 --- a/indra/newview/llpreviewtexture.h +++ b/indra/newview/llpreviewtexture.h @@ -38,6 +38,7 @@ #include "llframetimer.h" #include "llviewertexture.h" +class LLComboBox; class LLImageRaw; class LLPreviewTexture : public LLPreview @@ -71,7 +72,9 @@ public: protected: void init(); /* virtual */ BOOL postBuild(); - + bool setAspectRatio(const F32 width, const F32 height); + static void onAspectRatioCommit(LLUICtrl*,void* userdata); + private: void updateDimensions(); LLUUID mImageID; @@ -88,6 +91,7 @@ private: S32 mLastHeight; S32 mLastWidth; + F32 mAspectRatio; BOOL mUpdateDimensions; }; diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index d163ceb30e..288cf728b9 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -545,7 +545,7 @@ BOOL LLSelectMgr::removeObjectFromSelections(const LLUUID &id) object_found = TRUE; break; // must break here, may have removed multiple objects from list } - else if (object->isAvatar()) + else if (object->isAvatar() && object->getParent() && ((LLViewerObject*)object->getParent())->mID == id) { // It's possible the item being removed has an avatar sitting on it // So remove the avatar that is sitting on the object. diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index a49b07c5d9..de99cb86fa 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -66,6 +66,9 @@ F32 elevation_from_vector(const LLVector3 &v); LLSky gSky; // ---------------- LLSky ---------------- +const F32 LLSky::NIGHTTIME_ELEVATION = -8.0f; // degrees +const F32 LLSky::NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index abd4205e6c..d7796dea83 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -42,9 +42,6 @@ #include "llvosky.h" #include "llvoground.h" -const F32 NIGHTTIME_ELEVATION = -8.0f; // degrees -const F32 NIGHTTIME_ELEVATION_COS = (F32)sin(NIGHTTIME_ELEVATION*DEG_TO_RAD); - class LLViewerCamera; class LLVOWLSky; @@ -111,6 +108,9 @@ public: // Legacy stuff LLVector3 mSunDefaultPosition; + static const F32 NIGHTTIME_ELEVATION; // degrees + static const F32 NIGHTTIME_ELEVATION_COS; + protected: BOOL mOverrideSimSunPosition; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index fed6836588..26c8030dd1 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -187,6 +187,7 @@ #include "llwearable.h" #include "llinventorybridge.h" #include "llappearancemgr.h" +#include "llavatariconctrl.h" #include "lllogin.h" #include "llevents.h" @@ -963,6 +964,13 @@ bool idle_startup() LLFile::mkdir(gDirUtilp->getChatLogsDir()); LLFile::mkdir(gDirUtilp->getPerAccountChatLogsDir()); + // chat history must be loaded AFTER chat directories are defined. + if (!gNoRender && gSavedPerAccountSettings.getBOOL("LogShowHistory")) + { + LLFloaterChat::loadHistory(); + } + + //good as place as any to create user windlight directories std::string user_windlight_path_name(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight", "")); LLFile::mkdir(user_windlight_path_name.c_str()); @@ -993,6 +1001,9 @@ bool idle_startup() // Load location history LLLocationHistory::getInstance()->load(); + // Load Avatars icons cache + LLAvatarIconIDCache::getInstance()->load(); + //------------------------------------------------- // Handle startup progress screen //------------------------------------------------- diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp index c5a92f52d0..67a0528a06 100644 --- a/indra/newview/llsyswellwindow.cpp +++ b/indra/newview/llsyswellwindow.cpp @@ -112,9 +112,12 @@ BOOL LLSysWellWindow::postBuild() void LLSysWellWindow::setMinimized(BOOL minimize) { // we don't show empty Message Well window - setVisible(!minimize && !isWindowEmpty()); + if (!minimize) + { + setVisible(!isWindowEmpty()); + } - LLFloater::setMinimized(minimize); + LLDockableFloater::setMinimized(minimize); } //--------------------------------------------------------------------------------- @@ -264,7 +267,7 @@ void LLSysWellWindow::toggleWindow() getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1))); } - if(!getVisible()) + if(!getVisible() || isMinimized()) { if(isWindowEmpty()) { @@ -273,7 +276,7 @@ void LLSysWellWindow::toggleWindow() setVisible(TRUE); } - else + else if (isDocked()) { setVisible(FALSE); } diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp index 0bb5a727e0..a588153ca2 100644 --- a/indra/newview/llteleporthistorystorage.cpp +++ b/indra/newview/llteleporthistorystorage.cpp @@ -100,6 +100,7 @@ void LLTeleportHistoryStorage::onTeleportHistoryChange() void LLTeleportHistoryStorage::purgeItems() { mItems.clear(); + mHistoryChangedSignal(); } void LLTeleportHistoryStorage::addItem(const std::string title, const LLVector3d& global_pos) diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 43f82e592b..b5aec1b80b 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -1066,15 +1066,17 @@ BOOL LLTextureCtrl::handleHover(S32 x, S32 y, MASK mask) BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = LLUICtrl::handleMouseDown( x, y , mask ); - if( handled ) + + if( !handled ) { showPicker(FALSE); - //grab textures first... gInventory.startBackgroundFetch(gInventory.findCategoryUUIDForType(LLAssetType::AT_TEXTURE)); //...then start full inventory fetch. gInventory.startBackgroundFetch(); + handled = TRUE; } + return handled; } diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 63af170fa9..88fc7f98c0 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1371,7 +1371,7 @@ bool LLTextureFetch::createRequest(const std::string& filename, const LLUUID& id } else if (w*h*c > 0) { - // If the requester knows the dimentions of the image, + // If the requester knows the dimensions of the image, // this will calculate how much data we need without having to parse the header desired_size = LLImageJ2C::calcDataSizeJ2C(w, h, c, desired_discard); diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index 6f373a74bd..e26a0776ff 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -128,7 +128,18 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification pAttachLink->setVisible(hasInventory); pAttachIcon->setVisible(hasInventory); if (hasInventory) { - pAttachLink->setValue(payload["inventory_name"]); + std::string dis_name; + std::string inv_name = payload["inventory_name"]; + + if (LLViewerInventoryItem::extractSortFieldAndDisplayName(inv_name, NULL, &dis_name)) + { + pAttachLink->setValue(dis_name); + } + else + { + pAttachLink->setValue(inv_name); + } + mInventoryOffer = new LLOfferInfo(payload["inventory_offer"]); childSetActionTextbox("attachment", boost::bind( &LLToastGroupNotifyPanel::onClickAttachment, this)); diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp index fe1492d937..c2cd63900b 100644 --- a/indra/newview/lltoastimpanel.cpp +++ b/indra/newview/lltoastimpanel.cpp @@ -66,6 +66,7 @@ LLToastIMPanel::LLToastIMPanel(LLToastIMPanel::Params &p) : LLToastPanel(p.notif mReplyBtn->setVisible(FALSE); S32 btn_height = mReplyBtn->getRect().getHeight(); LLRect msg_rect = mMessage->getRect(); + mMessage->reshape(msg_rect.getWidth(), msg_rect.getHeight() + btn_height); msg_rect.setLeftTopAndSize(msg_rect.mLeft, msg_rect.mTop, msg_rect.getWidth(), msg_rect.getHeight() + btn_height); mMessage->setRect(msg_rect); } diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index 68ad043129..7b477470aa 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -65,7 +65,6 @@ void LLToastPanel::snapToMessageHeight(LLTextBox* message, S32 maxLineCount) //This needed to calculate lines count according to specified text heightDelta = maxTextHeight - oldTextHeight; reshape( getRect().getWidth(), getRect().getHeight() + heightDelta); - message->setValue(message->getText()); //Knowing the height is set to max allowed, getTextPixelHeight returns needed text height //Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape. @@ -77,7 +76,6 @@ void LLToastPanel::snapToMessageHeight(LLTextBox* message, S32 maxLineCount) //reshape the panel with new height reshape( getRect().getWidth(), getRect().getHeight() + heightDelta); - message->setValue(message->getText()); } } diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index beb16c267e..b015f668e4 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -703,7 +703,8 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask) .image(LLUI::getUIImage("Info")) .click_callback(boost::bind(showAvatarInspector, hover_object->getID())) .visible_time_near(6.f) - .visible_time_far(3.f)); + .visible_time_far(3.f) + .wrap(false)); } } else @@ -746,7 +747,8 @@ BOOL LLToolPie::handleToolTip(S32 local_x, S32 local_y, MASK mask) .image(LLUI::getUIImage("Info")) .click_callback(boost::bind(showObjectInspector, hover_object->getID())) .visible_time_near(6.f) - .visible_time_far(3.f)); + .visible_time_far(3.f) + .wrap(false)); } } } diff --git a/indra/newview/llurllineeditorctrl.cpp b/indra/newview/llurllineeditorctrl.cpp index 046b3e619b..258c3ddd75 100644 --- a/indra/newview/llurllineeditorctrl.cpp +++ b/indra/newview/llurllineeditorctrl.cpp @@ -38,6 +38,7 @@ #include "llurllineeditorctrl.h" #include "llweb.h" +#include "llslurl.h" //Constructor LLURLLineEditor::LLURLLineEditor(const LLLineEditor::Params& p) @@ -87,8 +88,13 @@ void LLURLLineEditor::copyEscapedURLToClipboard() S32 length = llabs( mSelectionStart - mSelectionEnd ); const std::string unescaped_text = wstring_to_utf8str(mText.getWString().substr(left_pos, length)); - LLWString selected_escaped_text = utf8str_to_wstring(LLWeb::escapeURL(unescaped_text)); - gClipboard.copyFromString( selected_escaped_text ); + LLWString text_to_copy; + if (LLSLURL::isSLURL(unescaped_text)) + text_to_copy = utf8str_to_wstring(LLWeb::escapeURL(unescaped_text)); + else + text_to_copy = utf8str_to_wstring(unescaped_text); + + gClipboard.copyFromString( text_to_copy ); } // Makes UISndBadKeystroke sound void LLURLLineEditor::reportBadKeystroke() diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp index ee6ef6ffee..f65baea6ca 100644 --- a/indra/newview/llviewercamera.cpp +++ b/indra/newview/llviewercamera.cpp @@ -120,9 +120,8 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 ¢er, const LLVector3 &up_direction, const LLVector3 &point_of_interest) { - // do not update if we are in build mode AND avatar didn't move - if (LLToolMgr::getInstance()->inBuildMode() - && !LLViewerJoystick::getInstance()->getCameraNeedsUpdate()) + // do not update if avatar didn't move + if (!LLViewerJoystick::getInstance()->getCameraNeedsUpdate()) { return; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 24f4745c18..b71291f834 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -503,6 +503,12 @@ bool toggle_show_camera_button(const LLSD& newvalue) return true; } +bool toggle_show_snapshot_button(const LLSD& newvalue) +{ + LLBottomTray::getInstance()->showSnapshotButton(newvalue.asBoolean()); + return true; +} + bool toggle_show_navigation_panel(const LLSD& newvalue) { LLNavigationBar::getInstance()->showNavigationPanel(newvalue.asBoolean()); @@ -654,6 +660,7 @@ void settings_setup_listeners() gSavedSettings.getControl("ShowGestureButton")->getSignal()->connect(boost::bind(&toggle_show_gesture_button, _2)); gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&toggle_show_move_button, _2)); gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&toggle_show_camera_button, _2)); + gSavedSettings.getControl("ShowSnapshotButton")->getSignal()->connect(boost::bind(&toggle_show_snapshot_button, _2)); gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2)); gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2)); } @@ -681,7 +688,7 @@ static LLCachedControl<std::string> test_BrowserHomePage("BrowserHomePage", "hah void test_cached_control() { -#define TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl +#define do { TEST_LLCC(T, V) if((T)mySetting_##T != V) llerrs << "Fail "#T << llendl; } while(0) TEST_LLCC(U32, 666); TEST_LLCC(S32, (S32)-666); TEST_LLCC(F32, (F32)-666.666); diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 8c46949d70..22081f9efa 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -58,7 +58,6 @@ #include "llfloaterchatterbox.h" #include "llfloaterdaycycle.h" #include "llfloaterdirectory.h" -#include "llfloaterfirsttimetip.h" #include "llfloaterenvsettings.h" #include "llfloaterfonttest.h" #include "llfloatergesture.h" @@ -154,7 +153,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>); LLFloaterReg::add("contacts", "floater_my_friends.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMyFriends>); - LLFloaterReg::add("first_time_tip", "floater_first_time_tip.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterFirstTimeTip>); LLFloaterReg::add("env_day_cycle", "floater_day_cycle_options.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDayCycle>); LLFloaterReg::add("env_post_process", "floater_post_process.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostProcess>); LLFloaterReg::add("env_settings", "floater_env_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterEnvSettings>); @@ -234,7 +232,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); LLFloaterReg::add("search", "floater_directory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDirectory>); - LLFloaterReg::add("ui_preview", "floater_ui_preview.xml", &LLFloaterReg::build<LLFloaterUIPreview>); + LLFloaterUIPreviewUtil::registerFloater(); LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAnimPreview>, "upload"); LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterImagePreview>, "upload"); LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload"); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 176e1b5499..dc53358311 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -121,41 +121,6 @@ LLViewerInventoryItem::~LLViewerInventoryItem() { } -BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const -{ - using std::string; - using std::stringstream; - - const char separator = getSeparator(); - const string::size_type separatorPos = mName.find(separator, 0); - - BOOL result = FALSE; - - if (separatorPos < string::npos) - { - if (sortField) - { - /* - * The conversion from string to S32 is made this way instead of old plain - * atoi() to ensure portability. If on some other platform S32 will not be - * defined to be signed int, this conversion will still work because of - * operators overloading, but atoi() may fail. - */ - stringstream ss(mName.substr(0, separatorPos)); - ss >> *sortField; - } - - if (displayName) - { - *displayName = mName.substr(separatorPos + 1, string::npos); - } - - result = TRUE; - } - - return result; -} - void LLViewerInventoryItem::copyViewerItem(const LLViewerInventoryItem* other) { LLInventoryItem::copyItem(other); @@ -1314,6 +1279,41 @@ U32 LLViewerInventoryItem::getCRC32() const return LLInventoryItem::getCRC32(); } +BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName) +{ + using std::string; + using std::stringstream; + + const char separator = getSeparator(); + const string::size_type separatorPos = name.find(separator, 0); + + BOOL result = FALSE; + + if (separatorPos < string::npos) + { + if (sortField) + { + /* + * The conversion from string to S32 is made this way instead of old plain + * atoi() to ensure portability. If on some other platform S32 will not be + * defined to be signed int, this conversion will still work because of + * operators overloading, but atoi() may fail. + */ + stringstream ss(name.substr(0, separatorPos)); + ss >> *sortField; + } + + if (displayName) + { + *displayName = name.substr(separatorPos + 1, string::npos); + } + + result = TRUE; + } + + return result; +} + // This returns true if the item that this item points to // doesn't exist in memory (i.e. LLInventoryModel). The baseitem // might still be in the database but just not loaded yet. diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h index d5b99ac160..5692875ec6 100644 --- a/indra/newview/llviewerinventory.h +++ b/indra/newview/llviewerinventory.h @@ -57,7 +57,7 @@ public: protected: ~LLViewerInventoryItem( void ); // ref counted - BOOL extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const; + BOOL extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const { return extractSortFieldAndDisplayName(mName, sortField, displayName); } static char getSeparator() { return '@'; } mutable std::string mDisplayName; @@ -78,6 +78,8 @@ public: virtual time_t getCreationDate() const; virtual U32 getCRC32() const; // really more of a checksum. + static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName); + // construct a complete viewer inventory item LLViewerInventoryItem(const LLUUID& uuid, const LLUUID& parent_uuid, const LLPermissions& permissions, diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index b919e3d1c1..b593fbfb00 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -414,14 +414,41 @@ void LLViewerJoystick::agentFly(F32 inc) } // ----------------------------------------------------------------------------- -void LLViewerJoystick::agentRotate(F32 pitch_inc, F32 yaw_inc) +void LLViewerJoystick::agentPitch(F32 pitch_inc) { - LLQuaternion new_rot; - pitch_inc = gAgent.clampPitchToLimits(-pitch_inc); - const LLQuaternion qx(pitch_inc, gAgent.getLeftAxis()); - const LLQuaternion qy(-yaw_inc, gAgent.getReferenceUpVector()); - new_rot.setQuat(qx * qy); - gAgent.rotate(new_rot); + if (pitch_inc < 0) + { + gAgent.setControlFlags(AGENT_CONTROL_PITCH_POS); + } + else if (pitch_inc > 0) + { + gAgent.setControlFlags(AGENT_CONTROL_PITCH_NEG); + } + + gAgent.pitch(-pitch_inc); +} + +// ----------------------------------------------------------------------------- +void LLViewerJoystick::agentYaw(F32 yaw_inc) +{ + // Cannot steer some vehicles in mouselook if the script grabs the controls + if (gAgent.cameraMouselook() && !gSavedSettings.getBOOL("JoystickMouselookYaw")) + { + gAgent.rotate(-yaw_inc, gAgent.getReferenceUpVector()); + } + else + { + if (yaw_inc < 0) + { + gAgent.setControlFlags(AGENT_CONTROL_YAW_POS); + } + else if (yaw_inc > 0) + { + gAgent.setControlFlags(AGENT_CONTROL_YAW_NEG); + } + + gAgent.yaw(-yaw_inc); + } } // ----------------------------------------------------------------------------- @@ -595,12 +622,38 @@ void LLViewerJoystick::moveAvatar(bool reset) } bool is_zero = true; + static bool button_held = false; if (mBtn[1] == 1) { - agentJump(); + // If AutomaticFly is enabled, then button1 merely causes a + // jump (as the up/down axis already controls flying) if on the + // ground, or cease flight if already flying. + // If AutomaticFly is disabled, then button1 toggles flying. + if (gSavedSettings.getBOOL("AutomaticFly")) + { + if (!gAgent.getFlying()) + { + gAgent.moveUp(1); + } + else if (!button_held) + { + button_held = true; + gAgent.setFlying(FALSE); + } + } + else if (!button_held) + { + button_held = true; + gAgent.setFlying(!gAgent.getFlying()); + } + is_zero = false; } + else + { + button_held = false; + } F32 axis_scale[] = { @@ -758,11 +811,13 @@ void LLViewerJoystick::moveAvatar(bool reset) { if (gAgent.getFlying()) { - agentRotate(eff_rx, eff_ry); + agentPitch(eff_rx); + agentYaw(eff_ry); } else { - agentRotate(eff_rx, 2.f * eff_ry); + agentPitch(eff_rx); + agentYaw(2.f * eff_ry); } } } @@ -771,7 +826,8 @@ void LLViewerJoystick::moveAvatar(bool reset) agentSlide(sDelta[X_I]); // move sideways agentFly(sDelta[Y_I]); // up/down & crouch agentPush(sDelta[Z_I]); // forward/back - agentRotate(sDelta[RX_I], sDelta[RY_I]); // pitch & turn + agentPitch(sDelta[RX_I]); // pitch + agentYaw(sDelta[RY_I]); // turn } } @@ -963,15 +1019,10 @@ bool LLViewerJoystick::toggleFlycam() moveFlycam(true); } - else if (!LLToolMgr::getInstance()->inBuildMode()) - { - moveAvatar(true); - } else { - // we are in build mode, exiting from the flycam mode: since we are - // going to keep the flycam POV for the main camera until the avatar - // moves, we need to track this situation. + // Exiting from the flycam mode: since we are going to keep the flycam POV for + // the main camera until the avatar moves, we need to track this situation. setCameraNeedsUpdate(false); setNeedsReset(true); } diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index b565ed5696..a3904bd2c3 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -82,8 +82,9 @@ protected: void agentSlide(F32 inc); void agentPush(F32 inc); void agentFly(F32 inc); - void agentRotate(F32 pitch_inc, F32 turn_inc); - void agentJump(); + void agentPitch(F32 pitch_inc); + void agentYaw(F32 yaw_inc); + void agentJump(); void resetDeltas(S32 axis[]); #if LIB_NDOF static NDOF_HotPlugResult HotPlugAddCallback(NDOF_Device *dev); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 6a40c76757..bac1f170b0 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1008,6 +1008,7 @@ BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } + ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::navigateHome() { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 1310fc7d53..bee34dde8f 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -82,7 +82,6 @@ #include "llface.h" #include "llfilepicker.h" #include "llfirstuse.h" -#include "llfirsttimetipmanager.h" #include "llfloater.h" #include "llfloaterabout.h" #include "llfloaterbuycurrency.h" @@ -278,7 +277,6 @@ void handle_compress_image(void*); // Edit menu void handle_dump_group_info(void *); void handle_dump_capabilities_info(void *); -void handle_dump_focus(void*); // Advanced->Consoles menu void handle_region_dump_settings(void*); @@ -325,7 +323,6 @@ BOOL check_show_xui_names(void *); // Debug UI -void handle_web_browser_test(void*); void handle_buy_currency_test(void*); void handle_save_to_xml(void*); void handle_load_from_xml(void*); @@ -1237,15 +1234,6 @@ class LLAdvancedDumpRegionObjectCache : public view_listener_t } }; -class LLAdvancedWebBrowserTest : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - handle_web_browser_test(NULL); - return true; - } -}; - class LLAdvancedBuyCurrencyTest : public view_listener_t { bool handleEvent(const LLSD& userdata) @@ -1288,22 +1276,6 @@ class LLAdvancedDumpInventory : public view_listener_t -/////////////////////// -// DUMP FOCUS HOLDER // -/////////////////////// - - -class LLAdvancedDumpFocusHolder : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - handle_dump_focus(NULL); - return true; - } -}; - - - //////////////////////////////// // PRINT SELECTED OBJECT INFO // //////////////////////////////// @@ -3467,7 +3439,7 @@ void handle_dump_region_object_cache(void*) } } -void handle_dump_focus(void *) +void handle_dump_focus() { LLUICtrl *ctrl = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus()); @@ -3483,14 +3455,11 @@ class LLSelfStandUp : public view_listener_t } }; -class LLSelfEnableStandUp : public view_listener_t +bool enable_standup_self() { - bool handleEvent(const LLSD& userdata) - { - bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting(); - return new_value; - } -}; + bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->isSitting(); + return new_value; +} class LLSelfFriends : public view_listener_t { @@ -4767,6 +4736,96 @@ class LLToolsSnapObjectXY : public view_listener_t } }; +// Determine if the option to cycle between linked prims is shown +class LLToolsEnableSelectNextPart : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + bool new_value = (gSavedSettings.getBOOL("EditLinkedParts") && + !LLSelectMgr::getInstance()->getSelection()->isEmpty()); + return new_value; + } +}; + +// Cycle selection through linked children in selected object. +// FIXME: Order of children list is not always the same as sim's idea of link order. This may confuse +// resis. Need link position added to sim messages to address this. +class LLToolsSelectNextPart : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (gSavedSettings.getBOOL("EditLinkedParts") && object_count) + { + LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + if (selected && selected->getRootEdit()) + { + bool fwd = (userdata.asString() == "next"); + bool prev = (userdata.asString() == "previous"); + bool ifwd = (userdata.asString() == "includenext"); + bool iprev = (userdata.asString() == "includeprevious"); + LLViewerObject* to_select = NULL; + LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren(); + children.push_front(selected->getRootEdit()); // need root in the list too + + for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter) + { + if ((*iter)->isSelected()) + { + if (object_count > 1 && (fwd || prev)) // multiple selection, find first or last selected if not include + { + to_select = *iter; + if (fwd) + { + // stop searching if going forward; repeat to get last hit if backward + break; + } + } + else if ((object_count == 1) || (ifwd || iprev)) // single selection or include + { + if (fwd || ifwd) + { + ++iter; + while (iter != children.end() && ((*iter)->isAvatar() || (ifwd && (*iter)->isSelected()))) + { + ++iter; // skip sitting avatars and selected if include + } + } + else // backward + { + iter = (iter == children.begin() ? children.end() : iter); + --iter; + while (iter != children.begin() && ((*iter)->isAvatar() || (iprev && (*iter)->isSelected()))) + { + --iter; // skip sitting avatars and selected if include + } + } + iter = (iter == children.end() ? children.begin() : iter); + to_select = *iter; + break; + } + } + } + + if (to_select) + { + if (gFocusMgr.childHasKeyboardFocus(gFloaterTools)) + { + gFocusMgr.setKeyboardFocus(NULL); // force edit toolbox to commit any changes + } + if (fwd || prev) + { + LLSelectMgr::getInstance()->deselectAll(); + } + LLSelectMgr::getInstance()->selectObjectOnly(to_select); + return true; + } + } + } + return true; + } +}; + // in order to link, all objects must have the same owner, and the // agent must have the ability to modify all of the objects. However, // we're not answering that question with this method. The question @@ -5341,42 +5400,64 @@ class LLWorldCreateLandmark : public view_listener_t } }; -class LLToolsLookAtSelection : public view_listener_t +void handle_look_at_selection(const LLSD& param) { - bool handleEvent(const LLSD& userdata) + const F32 PADDING_FACTOR = 2.f; + BOOL zoom = (param.asString() == "zoom"); + if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) { - const F32 PADDING_FACTOR = 2.f; - BOOL zoom = (userdata.asString() == "zoom"); - if (!LLSelectMgr::getInstance()->getSelection()->isEmpty()) - { - gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusOnAvatar(FALSE, ANIMATE); - LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); - F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); - F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); + LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection(); + F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); + F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); - LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - selection_bbox.getCenterAgent(); - obj_to_cam.normVec(); + LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - selection_bbox.getCenterAgent(); + obj_to_cam.normVec(); - LLUUID object_id; - if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) - { - object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID; - } - if (zoom) - { - gAgent.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), - LLSelectMgr::getInstance()->getSelectionCenterGlobal(), - object_id ); - } - else - { - gAgent.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id ); - } + LLUUID object_id; + if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()) + { + object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID; + } + if (zoom) + { + gAgent.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), + LLSelectMgr::getInstance()->getSelectionCenterGlobal(), + object_id ); + } + else + { + gAgent.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id ); } - return true; } -}; +} + +void handle_zoom_to_object(LLUUID object_id) +{ + const F32 PADDING_FACTOR = 2.f; + + LLViewerObject* object = gObjectList.findObject(object_id); + + if (object) + { + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + + LLBBox bbox = object->getBoundingBoxAgent() ; + F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView()); + F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); + + LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent(); + obj_to_cam.normVec(); + + + LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent()); + + gAgent.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance), + object_center_global, + object_id ); + } +} class LLAvatarInviteToGroup : public view_listener_t { @@ -6816,6 +6897,11 @@ void handle_dump_avatar_local_textures(void*) gAgent.getAvatarObject()->dumpLocalTextures(); } +void handle_dump_timers() +{ + LLFastTimer::dumpCurTimes(); +} + void handle_debug_avatar_textures(void*) { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); @@ -7081,9 +7167,14 @@ void handle_load_from_xml(void*) } } -void handle_web_browser_test(void*) +void handle_web_browser_test(const LLSD& param) { - LLWeb::loadURL("http://secondlife.com/app/search/slurls.html"); + std::string url = param.asString(); + if (url.empty()) + { + url = "about:blank"; + } + LLWeb::loadURL(url); } void handle_buy_currency_test(void*) @@ -7604,24 +7695,6 @@ class LLWorldDayCycle : public view_listener_t } }; -/// Show First Time Tips calbacks -class LLHelpCheckShowFirstTimeTip : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - return LLFirstTimeTipsManager::tipsEnabled(); - } -}; - -class LLHelpShowFirstTimeTip : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - LLFirstTimeTipsManager::enabledTip(!userdata.asBoolean()); - return true; - } -}; - void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y) { static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", @@ -7739,9 +7812,6 @@ void initialize_menus() view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess"); view_listener_t::addMenu(new LLWorldDayCycle(), "World.DayCycle"); - view_listener_t::addMenu(new LLHelpCheckShowFirstTimeTip(), "Help.CheckShowFirstTimeTip"); - view_listener_t::addMenu(new LLHelpShowFirstTimeTip(), "Help.ShowQuickTips"); - // Tools menu view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects"); @@ -7752,12 +7822,13 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts"); view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY"); view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid"); + view_listener_t::addMenu(new LLToolsSelectNextPart(), "Tools.SelectNextPart"); view_listener_t::addMenu(new LLToolsLink(), "Tools.Link"); view_listener_t::addMenu(new LLToolsUnlink(), "Tools.Unlink"); view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations"); view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys"); - view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys"); - view_listener_t::addMenu(new LLToolsLookAtSelection(), "Tools.LookAtSelection"); + view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys"); + commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2)); commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take)); commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy)); view_listener_t::addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory"); @@ -7765,6 +7836,7 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie"); + view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart"); view_listener_t::addMenu(new LLToolsEnableLink(), "Tools.EnableLink"); view_listener_t::addMenu(new LLToolsEnableUnlink(), "Tools.EnableUnlink"); view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake"); @@ -7832,11 +7904,12 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache"); // Advanced > UI - view_listener_t::addMenu(new LLAdvancedWebBrowserTest(), "Advanced.WebBrowserTest"); + commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest"); view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr"); view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory"); - view_listener_t::addMenu(new LLAdvancedDumpFocusHolder(), "Advanced.DumpFocusHolder"); + commit.add("Advanced.DumpTimers", boost::bind(&handle_dump_timers) ); + commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) ); view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo"); view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo"); view_listener_t::addMenu(new LLAdvancedPrintTextureMemoryStats(), "Advanced.PrintTextureMemoryStats"); @@ -7949,7 +8022,8 @@ void initialize_menus() view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp"); view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments"); - view_listener_t::addMenu(new LLSelfEnableStandUp(), "Self.EnableStandUp"); + visible.add("Self.VisibleStandUp", boost::bind(&enable_standup_self)); + enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self)); view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments"); // we don't use boost::bind directly to delay side tray construction diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h index 75f4f08bde..d28d54c933 100644 --- a/indra/newview/llviewermenu.h +++ b/indra/newview/llviewermenu.h @@ -98,8 +98,9 @@ bool enable_object_open(); // Buy either contents or object itself void handle_buy(); - void handle_take_copy(); +void handle_look_at_selection(const LLSD& param); +void handle_zoom_to_object(LLUUID object_id); // Can anyone take a free copy of the object? // *TODO: Move to separate file diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 1cfeec5627..d3a9e1cef8 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -219,7 +219,7 @@ const std::string upload_pick(void* data) args["EXTENSION"] = ext; args["VALIDS"] = valid_extensions; LLNotifications::instance().add("InvalidFileExtension", args); - return NULL; + return std::string(); } }//end else (non-null extension) diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index acdc2c2513..1d982265ca 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -174,11 +174,28 @@ BOOL LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject &object) U32 port = region_host.getPort(); U64 ipport = (((U64)ip) << 32) | (U64)port; U32 index = sIPAndPortToIndex[ipport]; - + + // llinfos << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << llendl; + U64 indexid = (((U64)index) << 32) | (U64)local_id; - return sIndexAndLocalIDToUUID.erase(indexid) > 0 ? TRUE : FALSE; + + std::map<U64, LLUUID>::iterator iter = sIndexAndLocalIDToUUID.find(indexid); + if (iter == sIndexAndLocalIDToUUID.end()) + { + return FALSE; + } + + // Found existing entry + if (iter->second == object.getID()) + { // Full UUIDs match, so remove the entry + sIndexAndLocalIDToUUID.erase(iter); + return TRUE; + } + // UUIDs did not match - this would zap a valid entry, so don't erase it + //llinfos << "Tried to erase entry where id in table (" + // << iter->second << ") did not match object " << object.getID() << llendl; } - + return FALSE ; } @@ -200,6 +217,9 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id, U64 indexid = (((U64)index) << 32) | (U64)local_id; sIndexAndLocalIDToUUID[indexid] = id; + + //llinfos << "Adding object to table, full ID " << id + // << ", local ID " << local_id << ", ip " << ip << ":" << port << llendl; } S32 gFullObjectUpdates = 0; @@ -246,8 +266,8 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, { if ( LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() ) { - //llinfos << "DEBUG selecting " << objectp->mID << " " - // << objectp->mLocalID << llendl; + // llinfos << "DEBUG selecting " << objectp->mID << " " + // << objectp->mLocalID << llendl; LLSelectMgr::getInstance()->selectObjectAndFamily(objectp); dialog_refresh_all(); } @@ -294,7 +314,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { size = mesgsys->getReceiveSize(); } -// llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; + // llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; } else { @@ -308,7 +328,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, size = mesgsys->getReceiveSize(); } -// llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; + // llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl; gFullObjectUpdates += num_objects; } @@ -318,7 +338,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (!regionp) { - llwarns << "Object update from unknown region!" << llendl; + llwarns << "Object update from unknown region! " << region_handle << llendl; return; } @@ -357,7 +377,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U8 compbuffer[2048]; S32 uncompressed_length = 2048; S32 compressed_length; - compressed_dp.reset(); U32 flags = 0; @@ -398,7 +417,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, gMessageSystem->getSenderPort()); if (fullid.isNull()) { - //llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl; + // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << ":" << gMessageSystem->getSenderPort() << llendl; mNumUnknownUpdates++; } } @@ -412,7 +431,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, gMessageSystem->getSenderPort()); if (fullid.isNull()) { - //llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl; + // llwarns << "update for unknown localid " << local_id << " host " << gMessageSystem->getSender() << llendl; mNumUnknownUpdates++; } } @@ -420,19 +439,43 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i); mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); - // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl; + // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl; } objectp = findObject(fullid); // This looks like it will break if the local_id of the object doesn't change // upon boundary crossing, but we check for region id matching later... - if (objectp && (objectp->mLocalID != local_id)) + // Reset object local id and region pointer if things have changed + if (objectp && + ((objectp->mLocalID != local_id) || + (objectp->getRegion() != regionp))) { + //if (objectp->getRegion()) + //{ + // llinfos << "Local ID change: Removing object from table, local ID " << objectp->mLocalID + // << ", id from message " << local_id << ", from " + // << LLHost(objectp->getRegion()->getHost().getAddress(), objectp->getRegion()->getHost().getPort()) + // << ", full id " << fullid + // << ", objects id " << objectp->getID() + // << ", regionp " << (U32) regionp << ", object region " << (U32) objectp->getRegion() + // << llendl; + //} removeFromLocalIDTable(*objectp); setUUIDAndLocal(fullid, local_id, gMessageSystem->getSenderIP(), gMessageSystem->getSenderPort()); + + if (objectp->mLocalID != local_id) + { // Update local ID in object with the one sent from the region + objectp->mLocalID = local_id; + } + + if (objectp->getRegion() != regionp) + { // Object changed region, so update it + objectp->setRegion(regionp); + objectp->updateRegion(regionp); // for LLVOAvatar + } } if (!objectp) @@ -441,7 +484,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { if (update_type == OUT_TERSE_IMPROVED) { - // llinfos << "terse update for an unknown object:" << fullid << llendl; + // llinfos << "terse update for an unknown object:" << fullid << llendl; continue; } } @@ -452,7 +495,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { if (update_type != OUT_FULL) { -// llinfos << "terse update for an unknown object:" << fullid << llendl; + // llinfos << "terse update for an unknown object:" << fullid << llendl; continue; } @@ -462,7 +505,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (mDeadObjects.find(fullid) != mDeadObjects.end()) { mNumDeadObjectUpdates++; - //llinfos << "update for a dead object:" << fullid << llendl; + // llinfos << "update for a dead object:" << fullid << llendl; continue; } #endif @@ -475,20 +518,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, justCreated = TRUE; mNumNewObjects++; } - else - { - if (objectp->getRegion() != regionp) - { - // Object has changed region! Update lookup tables, set region pointer. - removeFromLocalIDTable(*objectp); - setUUIDAndLocal(fullid, - local_id, - gMessageSystem->getSenderIP(), - gMessageSystem->getSenderPort()); - objectp->setRegion(regionp); - } - objectp->updateRegion(regionp); // for LLVOAvatar - } if (objectp->isDead()) @@ -623,7 +652,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) mCurLazyUpdateIndex = 0; } - mCurBin = (++mCurBin) % NUM_BINS; + mCurBin = (mCurBin + 1) % NUM_BINS; LLVOAvatar::cullAvatarsByPixelArea(); } @@ -808,6 +837,14 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) // Remove from object map so noone can look it up. mUUIDObjectMap.erase(objectp->mID); + + //if (objectp->getRegion()) + //{ + // llinfos << "cleanupReferences removing object from table, local ID " << objectp->mLocalID << ", ip " + // << objectp->getRegion()->getHost().getAddress() << ":" + // << objectp->getRegion()->getHost().getPort() << llendl; + //} + removeFromLocalIDTable(*objectp); if (objectp->onActiveList()) diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index b853bcb46e..0ce1ecc6ee 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -459,57 +459,26 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const case LLAssetType::AT_TEXTURE: if(item->getInventoryType() == LLInventoryType::IT_SNAPSHOT) { - img_name = "inv_item_snapshot.tga"; + img_name = "Inv_Snapshot"; } else { - img_name = "inv_item_texture.tga"; + img_name = "Inv_Texture"; } break; - case LLAssetType::AT_SOUND: img_name = "inv_item_sound.tga"; break; - case LLAssetType::AT_LANDMARK: - if (item->getFlags() & LLInventoryItem::II_FLAGS_LANDMARK_VISITED) - { - img_name = "inv_item_landmark_visited.tga"; - } - else - { - img_name = "inv_item_landmark.tga"; - } - break; - case LLAssetType::AT_CALLINGCARD: - { - BOOL online; - online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID()); - if (online) - { - img_name = "inv_item_callingcard_online.tga"; break; - } - else - { - img_name = "inv_item_callingcard_offline.tga"; break; - } - break; - } - case LLAssetType::AT_CLOTHING: img_name = "inv_item_clothing.tga"; break; - case LLAssetType::AT_OBJECT: - if (item->getFlags() & LLInventoryItem::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS) - { - img_name = "inv_item_object_multi.tga"; - } - else - { - img_name = "inv_item_object.tga"; - } - break; - case LLAssetType::AT_NOTECARD: img_name = "inv_item_notecard.tga"; break; - case LLAssetType::AT_LSL_TEXT: img_name = "inv_item_script.tga"; break; - case LLAssetType::AT_BODYPART: img_name = "inv_item_skin.tga"; break; - case LLAssetType::AT_ANIMATION: img_name = "inv_item_animation.tga";break; - case LLAssetType::AT_GESTURE: img_name = "inv_item_gesture.tga"; break; + case LLAssetType::AT_SOUND: img_name = "Inv_Sound"; break; + case LLAssetType::AT_CLOTHING: img_name = "Inv_Clothing"; break; + case LLAssetType::AT_OBJECT: img_name = "Inv_Object"; break; + case LLAssetType::AT_CALLINGCARD: img_name = "Inv_CallingCard"; break; + case LLAssetType::AT_LANDMARK: img_name = "Inv_Landmark"; break; + case LLAssetType::AT_NOTECARD: img_name = "Inv_Notecard"; break; + case LLAssetType::AT_LSL_TEXT: img_name = "Inv_Script"; break; + case LLAssetType::AT_BODYPART: img_name = "Inv_Skin"; break; + case LLAssetType::AT_ANIMATION: img_name = "Inv_Animation";break; + case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break; //TODO need img_name - case LLAssetType::AT_FAVORITE: img_name = "inv_item_landmark.tga"; break; + case LLAssetType::AT_FAVORITE: img_name = "Inv_Landmark"; break; default: llassert(0); } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 9f096209dd..a0ab4cb1e6 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1315,7 +1315,10 @@ bool LLViewerFetchedTexture::updateFetch() mComponents = mRawImage->getComponents(); mGLTexturep->setComponents(mComponents) ; - gTextureList.dirtyImage(this); + for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) + { + (*iter)->dirtyTexture() ; + } } mIsRawImageValid = TRUE; gTextureList.mCreateTextureList.insert(this); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d73029df1e..d81c8eec70 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1471,7 +1471,9 @@ void LLViewerWindow::initBase() LLToolTipView::Params hvp; hvp.name("tooltip view"); hvp.rect(full_window); + hvp.follows.flags(FOLLOWS_ALL); gToolTipView = LLUICtrlFactory::create<LLToolTipView>(hvp); + gToolTipView->setFollowsAll(); getRootView()->addChild(gToolTipView); // Add the progress bar view (startup view), which overrides everything @@ -1506,11 +1508,6 @@ void LLViewerWindow::initWorldUI() // currently needs to happen before initializing chat or IM LLFloaterReg::getInstance("communicate"); - if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") ) - { - LLFloaterChat::loadHistory(); - } - LLRect morph_view_rect = full_window; morph_view_rect.stretch( -STATUS_BAR_HEIGHT ); morph_view_rect.mTop = full_window.mTop - 32; @@ -1574,6 +1571,11 @@ void LLViewerWindow::initWorldUI() LLBottomTray::getInstance()->showCameraButton(FALSE); } + if (!gSavedSettings.getBOOL("ShowSnapshotButton")) + { + LLBottomTray::getInstance()->showSnapshotButton(FALSE); + } + if (!gSavedSettings.getBOOL("ShowMoveButton")) { LLBottomTray::getInstance()->showMoveButton(FALSE); @@ -2608,8 +2610,24 @@ void LLViewerWindow::updateUI() { it.skipDescendants(); } - else if (viewp->getMouseOpaque()) + // only report xui names for LLUICtrls, + // and blacklist the various containers we don't care about + else if (dynamic_cast<LLUICtrl*>(viewp) + && viewp != gMenuHolder + && viewp != gFloaterView + && viewp != gNotifyBoxView + && viewp != gConsole) { + if (dynamic_cast<LLFloater*>(viewp)) + { + // constrain search to descendants of this (frontmost) floater + // by resetting iterator + it = viewp->beginTreeDFS(); + } + + // if we are in a new part of the tree (not a descendent of current tooltip_view) + // then push the results for tooltip_view and start with a new potential view + // NOTE: this emulates visiting only the leaf nodes that meet our criteria if (!viewp->hasAncestor(tooltip_view)) { append_xui_tooltip(tooltip_view, tool_tip_msg); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index a9e9169891..7c12186bc7 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5512,7 +5512,9 @@ BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) } else { + LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:"); LLAppearanceManager::removeItemLinks(item_id, false); + } // BAP - needs to change for label to track link. diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 300eabf35c..999a39efd1 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -998,7 +998,9 @@ LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_obj LLViewerInventoryItem *item = gInventory.getItem(attachment->getItemID()); if (item) { + LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:"); LLAppearanceManager::wearItem(item,false); // Add COF link for item. + } gInventory.addChangedMask(LLInventoryObserver::LABEL, attachment->getItemID()); gInventory.notifyObservers(); diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 3c1ac3d571..02f63a848b 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1664,7 +1664,6 @@ void LLVoiceClient::stateMachine() // SLIM SDK: these arguments are no longer necessary. // std::string args = " -p tcp -h -c"; std::string args; - std::string cmd; std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); if(loglevel.empty()) @@ -1679,17 +1678,18 @@ void LLVoiceClient::stateMachine() #if LL_WINDOWS PROCESS_INFORMATION pinfo; - STARTUPINFOA sinfo; + STARTUPINFOW sinfo; memset(&sinfo, 0, sizeof(sinfo)); - std::string exe_dir = gDirUtilp->getAppRODataDir(); - cmd = "SLVoice.exe"; - cmd += args; - - // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string... - char *args2 = new char[args.size() + 1]; - strcpy(args2, args.c_str()); - if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, exe_dir.c_str(), &sinfo, &pinfo)) + std::string exe_dir = gDirUtilp->getExecutableDir(); + + llutf16string exe_path16 = utf8str_to_utf16str(exe_path); + llutf16string exe_dir16 = utf8str_to_utf16str(exe_dir); + llutf16string args16 = utf8str_to_utf16str(args); + // Create a writeable copy to keep Windows happy. + U16 *argscpy_16 = new U16[args16.size() + 1]; + wcscpy_s(argscpy_16,args16.size()+1,args16.c_str()); + if(!CreateProcessW(exe_path16.c_str(), argscpy_16, NULL, NULL, FALSE, 0, NULL, exe_dir16.c_str(), &sinfo, &pinfo)) { // DWORD dwErr = GetLastError(); } @@ -1701,7 +1701,7 @@ void LLVoiceClient::stateMachine() CloseHandle(pinfo.hThread); // stops leaks - nothing else } - delete[] args2; + delete[] argscpy_16; #else // LL_WINDOWS // This should be the same for mac and linux { @@ -4972,7 +4972,7 @@ void LLVoiceClient::sessionState::removeAllParticipants() if(!mParticipantsByUUID.empty()) { - LL_ERRS("Voice") << "Internal error: empty URI map, non-empty UUID map" << LL_ENDL + LL_ERRS("Voice") << "Internal error: empty URI map, non-empty UUID map" << LL_ENDL; } } @@ -6488,7 +6488,7 @@ void LLVoiceClient::deleteSession(sessionState *session) { if(iter->second != session) { - LL_ERRS("Voice") << "Internal error: session mismatch" << LL_ENDL + LL_ERRS("Voice") << "Internal error: session mismatch" << LL_ENDL; } mSessionsByHandle.erase(iter); } @@ -6528,7 +6528,7 @@ void LLVoiceClient::deleteAllSessions() if(!mSessionsByHandle.empty()) { - LL_ERRS("Voice") << "Internal error: empty session map, non-empty handle map" << LL_ENDL + LL_ERRS("Voice") << "Internal error: empty session map, non-empty handle map" << LL_ENDL; } } diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 33b86660fa..d44c543266 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -965,7 +965,7 @@ void LLVOSky::calcAtmospherics(void) // and vary_sunlight will work properly with moon light F32 lighty = unclamped_lightnorm[1]; - if(lighty < NIGHTTIME_ELEVATION_COS) + if(lighty < LLSky::NIGHTTIME_ELEVATION_COS) { lighty = -lighty; } diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 466cdfdcd0..62c934fb41 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -147,7 +147,7 @@ protected: static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } - static S32 stepCurrent() { return (sCurrent = ++sCurrent % 2); } + static S32 stepCurrent() { return (sCurrent = (sCurrent + 1) % 2); } static S32 getNext() { return ((sCurrent+1) % 2); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 136ffe607d..c8cc6a3d8e 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -304,7 +304,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam) mWaterPlane = LLVector4(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm)); LLVector3 sunMoonDir; - if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] > LLSky::NIGHTTIME_ELEVATION_COS) { sunMoonDir = gSky.getSunDirection(); } diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h index 5f0b235c7f..d7b4d3f91e 100644 --- a/indra/newview/llwearable.h +++ b/indra/newview/llwearable.h @@ -62,6 +62,7 @@ public: // Accessors //-------------------------------------------------------------------- public: + const LLUUID& getItemID() const; const LLAssetID& getAssetID() const { return mAssetID; } const LLTransactionID& getTransactionID() const { return mTransactionID; } EWearableType getType() const { return mType; } @@ -77,6 +78,7 @@ public: const std::string& getTypeLabel() const; const std::string& getTypeName() const; LLAssetType::EType getAssetType() const; + LLLocalTextureObject* getLocalTextureObject(S32 index) const; public: BOOL isDirty() const; @@ -102,8 +104,6 @@ public: friend std::ostream& operator<<(std::ostream &s, const LLWearable &w); void setItemID(const LLUUID& item_id); - const LLUUID& getItemID() const; - LLLocalTextureObject* getLocalTextureObject(S32 index) const; void setLocalTextureObject(S32 index, LLLocalTextureObject *lto); private: diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index 4bf64816c7..1581153c19 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -317,7 +317,7 @@ void LLWLParamManager::propagateParameters(void) { mLightDir = sunDir; } - else if(sunDir.mV[1] < 0 && sunDir.mV[1] > NIGHTTIME_ELEVATION_COS) + else if(sunDir.mV[1] < 0 && sunDir.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS) { // clamp v1 to 0 so sun never points up and causes weirdness on some machines LLVector3 vec(sunDir.mV[0], sunDir.mV[1], sunDir.mV[2]); diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp index 71e2427c99..af8cb6b9fb 100644 --- a/indra/newview/llxmlrpclistener.cpp +++ b/indra/newview/llxmlrpclistener.cpp @@ -57,10 +57,10 @@ protected: MapType mMap; }; -class StatusMapper: public StatusMapperBase<LLXMLRPCTransaction::Status> +class StatusMapper: public StatusMapperBase<LLXMLRPCTransaction::EStatus> { public: - StatusMapper(): StatusMapperBase<LLXMLRPCTransaction::Status>("Status") + StatusMapper(): StatusMapperBase<LLXMLRPCTransaction::EStatus>("Status") { mMap[LLXMLRPCTransaction::StatusNotStarted] = "NotStarted"; mMap[LLXMLRPCTransaction::StatusStarted] = "Started"; @@ -314,7 +314,7 @@ public: bool done = mTransaction->process(); CURLcode curlcode; - LLXMLRPCTransaction::Status status; + LLXMLRPCTransaction::EStatus status; { // LLXMLRPCTransaction::status() is defined to accept int* rather // than CURLcode*. I don't feel the urge to fix the signature, but @@ -483,7 +483,7 @@ private: const std::string mReplyPump; LLTempBoundListener mBoundListener; boost::scoped_ptr<LLXMLRPCTransaction> mTransaction; - LLXMLRPCTransaction::Status mPreviousStatus; // To detect state changes. + LLXMLRPCTransaction::EStatus mPreviousStatus; // To detect state changes. }; bool LLXMLRPCListener::process(const LLSD& command) diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 0e1beb377f..70859e8ea5 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -158,11 +158,11 @@ XMLRPC_VALUE LLXMLRPCValue::getValue() const class LLXMLRPCTransaction::Impl { public: - typedef LLXMLRPCTransaction::Status Status; + typedef LLXMLRPCTransaction::EStatus EStatus; LLCurlEasyRequest* mCurlRequest; - Status mStatus; + EStatus mStatus; CURLcode mCurlCode; std::string mStatusMessage; std::string mStatusURI; @@ -184,7 +184,7 @@ public: bool process(); - void setStatus(Status code, + void setStatus(EStatus code, const std::string& message = "", const std::string& uri = ""); void setCurlStatus(CURLcode); @@ -398,7 +398,7 @@ bool LLXMLRPCTransaction::Impl::process() return false; } -void LLXMLRPCTransaction::Impl::setStatus(Status status, +void LLXMLRPCTransaction::Impl::setStatus(EStatus status, const std::string& message, const std::string& uri) { mStatus = status; @@ -522,7 +522,7 @@ bool LLXMLRPCTransaction::process() return impl.process(); } -LLXMLRPCTransaction::Status LLXMLRPCTransaction::status(int* curlCode) +LLXMLRPCTransaction::EStatus LLXMLRPCTransaction::status(int* curlCode) { if (curlCode) { diff --git a/indra/newview/llxmlrpctransaction.h b/indra/newview/llxmlrpctransaction.h index 528451fcb2..c835423d67 100644 --- a/indra/newview/llxmlrpctransaction.h +++ b/indra/newview/llxmlrpctransaction.h @@ -100,7 +100,7 @@ public: ~LLXMLRPCTransaction(); - typedef enum { + typedef enum e_status { StatusNotStarted, StatusStarted, StatusDownloading, @@ -108,12 +108,12 @@ public: StatusCURLError, StatusXMLRPCError, StatusOtherError - } Status; + } EStatus; bool process(); // run the request a little, returns true when done - Status status(int* curlCode); + EStatus status(int* curlCode); // return status, and extended CURL code, if code isn't null std::string statusMessage(); // return a message string, suitable for showing the user diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 38052abfa3..3800b9223d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -35,7 +35,7 @@ #include "pipeline.h" // library includes -#include "llaudioengine.h" // For MAX_BUFFERS for debugging. +#include "llaudioengine.h" // For debugging. #include "imageids.h" #include "llerror.h" #include "llviewercontrol.h" @@ -414,6 +414,9 @@ void LLPipeline::cleanup() { assertInitialized(); + mGroupQ1.clear() ; + mGroupQ2.clear() ; + for(pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ) { @@ -4286,7 +4289,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) } } F32 backlight_mag; - if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) { backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; } @@ -4472,7 +4475,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) // Light 0 = Sun or Moon (All objects) { - if (gSky.getSunDirection().mV[2] >= NIGHTTIME_ELEVATION_COS) + if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) { mSunDir.setVec(gSky.getSunDirection()); mSunDiffuse.setVec(gSky.getSunDiffuseColor()); diff --git a/indra/newview/res-sdl/arrow.BMP b/indra/newview/res-sdl/arrow.BMP Binary files differnew file mode 100644 index 0000000000..a8f6da64b5 --- /dev/null +++ b/indra/newview/res-sdl/arrow.BMP diff --git a/indra/newview/res-sdl/arrowcop.BMP b/indra/newview/res-sdl/arrowcop.BMP Binary files differnew file mode 100644 index 0000000000..1a26a0df34 --- /dev/null +++ b/indra/newview/res-sdl/arrowcop.BMP diff --git a/indra/newview/res-sdl/arrowcopmulti.BMP b/indra/newview/res-sdl/arrowcopmulti.BMP Binary files differnew file mode 100644 index 0000000000..48f153cef6 --- /dev/null +++ b/indra/newview/res-sdl/arrowcopmulti.BMP diff --git a/indra/newview/res-sdl/arrowdrag.BMP b/indra/newview/res-sdl/arrowdrag.BMP Binary files differnew file mode 100644 index 0000000000..cd868eec20 --- /dev/null +++ b/indra/newview/res-sdl/arrowdrag.BMP diff --git a/indra/newview/res-sdl/circleandline.BMP b/indra/newview/res-sdl/circleandline.BMP Binary files differnew file mode 100644 index 0000000000..284ae8b7d5 --- /dev/null +++ b/indra/newview/res-sdl/circleandline.BMP diff --git a/indra/newview/res-sdl/cross.BMP b/indra/newview/res-sdl/cross.BMP Binary files differnew file mode 100644 index 0000000000..0b4672d4d6 --- /dev/null +++ b/indra/newview/res-sdl/cross.BMP diff --git a/indra/newview/res-sdl/hand.BMP b/indra/newview/res-sdl/hand.BMP Binary files differnew file mode 100644 index 0000000000..2a092fbb7f --- /dev/null +++ b/indra/newview/res-sdl/hand.BMP diff --git a/indra/newview/res-sdl/ibeam.BMP b/indra/newview/res-sdl/ibeam.BMP Binary files differnew file mode 100644 index 0000000000..820904a228 --- /dev/null +++ b/indra/newview/res-sdl/ibeam.BMP diff --git a/indra/newview/res-sdl/ll_icon.BMP b/indra/newview/res-sdl/ll_icon.BMP Binary files differnew file mode 100644 index 0000000000..4a44aafbfa --- /dev/null +++ b/indra/newview/res-sdl/ll_icon.BMP diff --git a/indra/newview/res-sdl/llarrow.BMP b/indra/newview/res-sdl/llarrow.BMP Binary files differnew file mode 100644 index 0000000000..a8f6da64b5 --- /dev/null +++ b/indra/newview/res-sdl/llarrow.BMP diff --git a/indra/newview/res-sdl/llarrowdrag.BMP b/indra/newview/res-sdl/llarrowdrag.BMP Binary files differnew file mode 100644 index 0000000000..cd868eec20 --- /dev/null +++ b/indra/newview/res-sdl/llarrowdrag.BMP diff --git a/indra/newview/res-sdl/llarrowdragmulti.BMP b/indra/newview/res-sdl/llarrowdragmulti.BMP Binary files differnew file mode 100644 index 0000000000..fb528bc92d --- /dev/null +++ b/indra/newview/res-sdl/llarrowdragmulti.BMP diff --git a/indra/newview/res-sdl/llarrowlocked.BMP b/indra/newview/res-sdl/llarrowlocked.BMP Binary files differnew file mode 100644 index 0000000000..0aaa441ab1 --- /dev/null +++ b/indra/newview/res-sdl/llarrowlocked.BMP diff --git a/indra/newview/res-sdl/llgrablocked.BMP b/indra/newview/res-sdl/llgrablocked.BMP Binary files differnew file mode 100644 index 0000000000..847439670f --- /dev/null +++ b/indra/newview/res-sdl/llgrablocked.BMP diff --git a/indra/newview/res-sdl/llno.BMP b/indra/newview/res-sdl/llno.BMP Binary files differnew file mode 100644 index 0000000000..284ae8b7d5 --- /dev/null +++ b/indra/newview/res-sdl/llno.BMP diff --git a/indra/newview/res-sdl/llnolocked.BMP b/indra/newview/res-sdl/llnolocked.BMP Binary files differnew file mode 100644 index 0000000000..61f0170cb3 --- /dev/null +++ b/indra/newview/res-sdl/llnolocked.BMP diff --git a/indra/newview/res-sdl/lltoolcamera.BMP b/indra/newview/res-sdl/lltoolcamera.BMP Binary files differnew file mode 100644 index 0000000000..c961d7a49c --- /dev/null +++ b/indra/newview/res-sdl/lltoolcamera.BMP diff --git a/indra/newview/res-sdl/lltoolcreate.BMP b/indra/newview/res-sdl/lltoolcreate.BMP Binary files differnew file mode 100644 index 0000000000..08a4a9322d --- /dev/null +++ b/indra/newview/res-sdl/lltoolcreate.BMP diff --git a/indra/newview/res-sdl/lltoolfocus.BMP b/indra/newview/res-sdl/lltoolfocus.BMP Binary files differnew file mode 100644 index 0000000000..afb90a95e3 --- /dev/null +++ b/indra/newview/res-sdl/lltoolfocus.BMP diff --git a/indra/newview/res-sdl/lltoolgrab.BMP b/indra/newview/res-sdl/lltoolgrab.BMP Binary files differnew file mode 100644 index 0000000000..f2ac68bf3c --- /dev/null +++ b/indra/newview/res-sdl/lltoolgrab.BMP diff --git a/indra/newview/res-sdl/lltoolland.BMP b/indra/newview/res-sdl/lltoolland.BMP Binary files differnew file mode 100644 index 0000000000..64e6365625 --- /dev/null +++ b/indra/newview/res-sdl/lltoolland.BMP diff --git a/indra/newview/res-sdl/lltoolpan.BMP b/indra/newview/res-sdl/lltoolpan.BMP Binary files differnew file mode 100644 index 0000000000..ffbef21ec7 --- /dev/null +++ b/indra/newview/res-sdl/lltoolpan.BMP diff --git a/indra/newview/res-sdl/lltoolpipette.BMP b/indra/newview/res-sdl/lltoolpipette.BMP Binary files differnew file mode 100644 index 0000000000..2d27118289 --- /dev/null +++ b/indra/newview/res-sdl/lltoolpipette.BMP diff --git a/indra/newview/res-sdl/lltoolrotate.BMP b/indra/newview/res-sdl/lltoolrotate.BMP Binary files differnew file mode 100644 index 0000000000..dd84673018 --- /dev/null +++ b/indra/newview/res-sdl/lltoolrotate.BMP diff --git a/indra/newview/res-sdl/lltoolscale.BMP b/indra/newview/res-sdl/lltoolscale.BMP Binary files differnew file mode 100644 index 0000000000..882515e5e3 --- /dev/null +++ b/indra/newview/res-sdl/lltoolscale.BMP diff --git a/indra/newview/res-sdl/lltooltranslate.BMP b/indra/newview/res-sdl/lltooltranslate.BMP Binary files differnew file mode 100644 index 0000000000..d084f6a026 --- /dev/null +++ b/indra/newview/res-sdl/lltooltranslate.BMP diff --git a/indra/newview/res-sdl/lltoolzoomin.BMP b/indra/newview/res-sdl/lltoolzoomin.BMP Binary files differnew file mode 100644 index 0000000000..e4e46cc702 --- /dev/null +++ b/indra/newview/res-sdl/lltoolzoomin.BMP diff --git a/indra/newview/res-sdl/lltoolzoomout.BMP b/indra/newview/res-sdl/lltoolzoomout.BMP Binary files differnew file mode 100644 index 0000000000..7f958383ab --- /dev/null +++ b/indra/newview/res-sdl/lltoolzoomout.BMP diff --git a/indra/newview/res-sdl/sizenesw.BMP b/indra/newview/res-sdl/sizenesw.BMP Binary files differnew file mode 100644 index 0000000000..559579f40e --- /dev/null +++ b/indra/newview/res-sdl/sizenesw.BMP diff --git a/indra/newview/res-sdl/sizens.BMP b/indra/newview/res-sdl/sizens.BMP Binary files differnew file mode 100644 index 0000000000..8373077dff --- /dev/null +++ b/indra/newview/res-sdl/sizens.BMP diff --git a/indra/newview/res-sdl/sizenwse.BMP b/indra/newview/res-sdl/sizenwse.BMP Binary files differnew file mode 100644 index 0000000000..6d069fa765 --- /dev/null +++ b/indra/newview/res-sdl/sizenwse.BMP diff --git a/indra/newview/res-sdl/sizewe.BMP b/indra/newview/res-sdl/sizewe.BMP Binary files differnew file mode 100644 index 0000000000..878df453a4 --- /dev/null +++ b/indra/newview/res-sdl/sizewe.BMP diff --git a/indra/newview/res-sdl/toolmediaopen.BMP b/indra/newview/res-sdl/toolmediaopen.BMP Binary files differnew file mode 100644 index 0000000000..ac4b231994 --- /dev/null +++ b/indra/newview/res-sdl/toolmediaopen.BMP diff --git a/indra/newview/res-sdl/toolpause.BMP b/indra/newview/res-sdl/toolpause.BMP Binary files differnew file mode 100644 index 0000000000..dd2c6857d2 --- /dev/null +++ b/indra/newview/res-sdl/toolpause.BMP diff --git a/indra/newview/res-sdl/toolpickobject.BMP b/indra/newview/res-sdl/toolpickobject.BMP Binary files differnew file mode 100644 index 0000000000..25469fc3a8 --- /dev/null +++ b/indra/newview/res-sdl/toolpickobject.BMP diff --git a/indra/newview/res-sdl/toolpickobject2.BMP b/indra/newview/res-sdl/toolpickobject2.BMP Binary files differnew file mode 100644 index 0000000000..09df69e675 --- /dev/null +++ b/indra/newview/res-sdl/toolpickobject2.BMP diff --git a/indra/newview/res-sdl/toolpickobject3.BMP b/indra/newview/res-sdl/toolpickobject3.BMP Binary files differnew file mode 100644 index 0000000000..fc28698050 --- /dev/null +++ b/indra/newview/res-sdl/toolpickobject3.BMP diff --git a/indra/newview/res-sdl/toolplay.BMP b/indra/newview/res-sdl/toolplay.BMP Binary files differnew file mode 100644 index 0000000000..9c40d7dbec --- /dev/null +++ b/indra/newview/res-sdl/toolplay.BMP diff --git a/indra/newview/res-sdl/wait.BMP b/indra/newview/res-sdl/wait.BMP Binary files differnew file mode 100644 index 0000000000..26dec59afe --- /dev/null +++ b/indra/newview/res-sdl/wait.BMP diff --git a/indra/newview/res-sdl/working.BMP b/indra/newview/res-sdl/working.BMP Binary files differnew file mode 100644 index 0000000000..26dec59afe --- /dev/null +++ b/indra/newview/res-sdl/working.BMP diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index eb62c442db..4d8f88c80b 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -651,13 +651,13 @@ reference="White_10" /> <color name="ToolTipBgColor" - value="DkGray" /> + value="0.937 0.89 0.655 1" /> <color name="ToolTipBorderColor" - value="White_50" /> + value="0.812 0.753 0.451 1" /> <color name="ToolTipTextColor" - reference="LtGray" /> + value="0.749 0.749 0.749 1" /> <color name="UserChatColor" reference="LtGray" /> diff --git a/indra/newview/skins/default/textures/alpha_gradient.tga b/indra/newview/skins/default/textures/alpha_gradient.tga Binary files differdeleted file mode 100644 index 6fdba25d4e..0000000000 --- a/indra/newview/skins/default/textures/alpha_gradient.tga +++ /dev/null diff --git a/indra/newview/skins/default/textures/alpha_gradient_2d.j2c b/indra/newview/skins/default/textures/alpha_gradient_2d.j2c Binary files differdeleted file mode 100644 index 5de5a80a65..0000000000 --- a/indra/newview/skins/default/textures/alpha_gradient_2d.j2c +++ /dev/null diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 2c09689ec6..546a06b93f 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -444,8 +444,6 @@ <texture name="cam_zoom_plus_in.tga" preload="false" /> <texture name="cam_zoom_minus_in.tga" preload="false" /> - <texture name="icn_clear_lineeditor.tga" /> - <texture name="icn_chatbar.tga" /> <texture name="icn_media-pause.tga" /> <texture name="icn_media-play.tga" /> @@ -528,7 +526,6 @@ <texture name="startup_logo.j2c" preload="true" /> <texture name="color_swatch_alpha.tga" preload="true" /> - <texture name="active_voice_tab.tga" /> <texture name="button_anim_pause.tga" /> <texture name="button_anim_pause_selected.tga" /> <texture name="button_anim_play.tga" /> diff --git a/indra/newview/skins/default/xui/da/floater_sell_land.xml b/indra/newview/skins/default/xui/da/floater_sell_land.xml index fc88b3d49a..87023b4f64 100644 --- a/indra/newview/skins/default/xui/da/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/da/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="sell land" title="Sælg land"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Parcel: </text> @@ -55,4 +57,6 @@ </text> <button label="Sæt land til salg" name="sell_btn" /> <button label="Annullér" name="cancel_btn" /> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/da/floater_tools.xml b/indra/newview/skins/default/xui/da/floater_tools.xml index a509d5f046..e50494ff9e 100644 --- a/indra/newview/skins/default/xui/da/floater_tools.xml +++ b/indra/newview/skins/default/xui/da/floater_tools.xml @@ -153,7 +153,7 @@ </combo_box> <panel name="perms_build"> <text name="perm_modify"> - Du kan redigére dette objekt. + Du kan redigére dette objekt </text> <text name="B:"> B: @@ -187,22 +187,22 @@ Du kan redigere disse objekter </string> <string name="text modify info 3"> - Du kan ikke redigere dette objekt. + Du kan ikke redigere dette objekt </string> <string name="text modify info 4"> - Du kan ikke redigere disse objekter. + Du kan ikke redigere disse objekter </string> <string name="text modify warning"> - Du skal vælge hele objektet for at sætte rettigheder. + Du skal vælge hele objektet for at sætte rettigheder </string> <string name="Cost Default"> - Pris: L$ + Pris: L$ </string> <string name="Cost Total"> - Total pris: L$ + Total pris: L$ </string> <string name="Cost Per Unit"> - Pris Pr: L$ + Pris Pr: L$ </string> <string name="Cost Mixed"> Blandet pris @@ -449,8 +449,8 @@ <button label="Ret ind" label_selected="Ret ind" name="button align" left="160"/> </panel> <panel label="Indhold" name="Contents"> - <button label="Nyt script" label_selected="Nyt script..." name="button new script"/> - <button label="Rettigheder..." name="button permissions"/> + <button label="Nyt script" label_selected="Nyt script" name="button new script"/> + <button label="Rettigheder" name="button permissions"/> </panel> </tab_container> <panel name="land info panel"> @@ -464,18 +464,18 @@ Område: [AREA] m². </text> <button label="Om land..." label_selected="Om land..." name="button about land"/> - <check_box label="Vis ejere" name="checkbox show owners" tool_tip="Farver grunde afhængigt af ejerskab"/> + <check_box label="Vis ejere" name="checkbox show owners" tool_tip="Farver grunde afhængigt af ejerskab: Grøn = Dit land Turkis = Din gruppes land Rød = Ejet af andre Gul = Til salg Lilla = På auktion Grå = Offentligt ejet"/> <button label="?" label_selected="?" name="button show owners help"/> <text name="label_parcel_modify"> Redigere grund </text> - <button label="Opdel..." label_selected="Opdel..." name="button subdivide land"/> - <button label="Saml..." label_selected="Saml..." name="button join land"/> + <button label="Opdel" label_selected="Opdel" name="button subdivide land"/> + <button label="Saml" label_selected="Saml" name="button join land"/> <text name="label_parcel_trans"> Transaktioner for land </text> - <button label="Køb land..." label_selected="Køb land..." name="button buy land"/> - <button label="Flyt fra land..." label_selected="Flyt fra land..." name="button abandon land"/> + <button label="Køb land" label_selected="Køb land" name="button buy land"/> + <button label="Flyt fra land" label_selected="Flyt fra land" name="button abandon land"/> </panel> <floater.string name="status_rotate"> Træk i de farvede bånd for at rotere objekt diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 5ab8e4eb30..42f55d4678 100644 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1079,7 +1079,7 @@ Fleksible genstande er ikke fysiske og man kan gå igennem dem, indtil fleksibel <notification name="FirstDebugMenus"> Du har sat avanceret menu til. Denne menu indeholder funktioner brugbare for udviklere, der udbedrer fejl i [SECOND_LIFE]. -For at vise denne menu, skal man i Windows trykke Ctrl-Alt-D. På Mac tryk ⌘-Opt-Shift-D. +For at vise denne menu, skal man i Windows trykke Ctrl+Alt+D. På Mac tryk ⌥⌘D. </notification> <notification name="FirstSculptedPrim"> Du retter en sculpted prim. diff --git a/indra/newview/skins/default/xui/da/panel_edit_profile.xml b/indra/newview/skins/default/xui/da/panel_edit_profile.xml new file mode 100644 index 0000000000..74b7c7dd72 --- /dev/null +++ b/indra/newview/skins/default/xui/da/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Beboer" />
+ <string name="AcctTypeTrial"
+ value="På prøve" />
+ <string name="AcctTypeCharterMember"
+ value="æresmedlem" />
+ <string name="AcctTypeEmployee"
+ value="Linden Lab medarbejder" />
+ <string name="PaymentInfoUsed"
+ value="Betalende medlem" />
+ <string name="PaymentInfoOnFile"
+ value="Registreret betalende" />
+ <string name="NoPaymentInfoOnFile"
+ value="Ingen betalingsinfo" />
+ <string name="AgeVerified"
+ value="Alders-checket" />
+ <string name="NotAgeVerified"
+ value="Ikke alders-checket" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=da
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Optaget autosvar:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_group_general.xml b/indra/newview/skins/default/xui/da/panel_group_general.xml index edce758e7c..4e98ca2bc2 100644 --- a/indra/newview/skins/default/xui/da/panel_group_general.xml +++ b/indra/newview/skins/default/xui/da/panel_group_general.xml @@ -1,9 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="Generelt" name="general_tab"> <string name="help_text"> - Generel-fanen indeholder generel information om -denne gruppe, en liste med ejere og synlige medlemmer, -generel-gruppeindstillinger og medlemsmuligheder. + Generel-fanen indeholder generel information om denne gruppe, en liste med ejere og synlige medlemmer, generel-gruppeindstillinger og medlemsmuligheder. Bevæg din mus over mulighederne for mere hjælp. </string> @@ -47,7 +45,7 @@ Bevæg din mus over mulighederne for mere hjælp. <panel name="preferences_container"> <check_box label="Vis i søgning" name="show_in_group_list" tool_tip="Lad folk se denne gruppe i søgeresultater."/> <check_box label="Åben tilmelding" name="open_enrollement" tool_tip="Angiver om denne gruppe tillader nye medlemmer at tilmelde sig, uden de er inviteret."/> - <check_box label="Tilmeldingsgebyr: L$" name="check_enrollment_fee" tool_tip="Angiver om der kræves et gebyr, for at tilmelde sig gruppen."/> + <check_box label="Tilmeldingsgebyr:" name="check_enrollment_fee" tool_tip="Angiver om der kræves et gebyr, for at tilmelde sig gruppen."/> <spinner name="spin_enrollment_fee" tool_tip="Nye medlemmer skal betale dette gebyr for at tilmelde sig gruppen, når Tilmeldingsgebyr er valgt." width="60" left_delta="130"/> <combo_box name="group_mature_check" tool_tip="Angiver om din gruppes information anses som 'mature'." width="150"> <combo_box.item name="select_mature" label="- Vælg indholdsrating -"/> diff --git a/indra/newview/skins/default/xui/da/panel_group_land_money.xml b/indra/newview/skins/default/xui/da/panel_group_land_money.xml index 029922c413..636a16f97b 100644 --- a/indra/newview/skins/default/xui/da/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/da/panel_group_land_money.xml @@ -48,8 +48,11 @@ <string name="land_contrib_error"> Ikke muligt at lave dit bidrag til landet. </string> + <text name="your_contribution_units"> + ( m² ) + </text> <text name="your_contribution_max_value"> - m² ([AMOUNT] maks.) + ([AMOUNT] maks.) </text> <text name="group_over_limit_text"> Gruppemedlemmer må bidrag med mere, for at understøtte diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml index 9490f94a42..ed23a9a706 100644 --- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml @@ -33,10 +33,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="PG, Mature og Adult"/> <combo_box.item name="Desired_Mature" label="PG and Mature"/> - <combo_box.item name="Desired_PG" label="PG only"/> + <combo_box.item name="Desired_PG" label="PG"/> </combo_box> <text name="maturity_desired_textbox"> - PG only + PG </text> <text name="start_location_textbox"> Start lokation: diff --git a/indra/newview/skins/default/xui/da/panel_region_estate.xml b/indra/newview/skins/default/xui/da/panel_region_estate.xml index 7039f8fd6c..5d0799cab9 100644 --- a/indra/newview/skins/default/xui/da/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/da/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Estate" name="Estate"> +<panel label="Estate" name="Estate"> <text name="estate_help_text"> Ændringer i dette afsnit vil påvirke alle regioner i dette estate. @@ -70,6 +68,4 @@ regioner i dette estate. <button label="?" name="ban_resident_help" /> <button label="Fjern..." name="remove_banned_avatar_btn" /> <button label="Tilføj..." name="add_banned_avatar_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/da/panel_region_texture.xml b/indra/newview/skins/default/xui/da/panel_region_texture.xml index a7477d3a65..65c4743da0 100644 --- a/indra/newview/skins/default/xui/da/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/da/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Terræn textures" name="Textures"> +<panel label="Terræn textures" name="Textures"> <text name="region_text_lbl"> Region: </text> @@ -56,6 +54,4 @@ og HØJ værdien er MIMIMUM højde for texture nummer 4. </text> <button label="Gem" name="apply_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml index 9849f2f56d..945833d57a 100644 --- a/indra/newview/skins/default/xui/da/strings.xml +++ b/indra/newview/skins/default/xui/da/strings.xml @@ -484,16 +484,16 @@ Vælg bibliotek </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Shift- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -603,6 +603,9 @@ <string name="no_ability_error"> Du har ikke den mulighed. </string> + <string name="no_ability"> + Du har ikke den mulighed. + </string> <string name="not_a_mod_error"> Du er ikke moderator for denne samtale. </string> @@ -621,4 +624,31 @@ <string name="close_on_no_ability"> Du har ikke længere mulighed for at deltage i samtalen </string> + <string name="AcctTypeResident"> + Beboer + </string> + <string name="AcctTypeTrial"> + På prøve + </string> + <string name="AcctTypeCharterMember"> + æresmedlem + </string> + <string name="AcctTypeEmployee"> + Linden Lab medarbejder + </string> + <string name="PaymentInfoUsed"> + Betalende medlem + </string> + <string name="PaymentInfoOnFile"> + Registreret betalende + </string> + <string name="NoPaymentInfoOnFile"> + Ingen betalingsinfo + </string> + <string name="AgeVerified"> + Alders-checket + </string> + <string name="NotAgeVerified"> + Ikke alders-checket + </string> </strings> diff --git a/indra/newview/skins/default/xui/de/floater_sell_land.xml b/indra/newview/skins/default/xui/de/floater_sell_land.xml index c34252d8a7..1499bb0152 100644 --- a/indra/newview/skins/default/xui/de/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/de/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="sell land" title="Land verkaufen"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Parzelle: </text> @@ -60,4 +62,6 @@ wechseln den Eigentümer. </text> <button label="Land zum Verkauf freigeben" width="180" name="sell_btn" /> <button label="Abbrechen" name="cancel_btn" /> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index 2875f5d04c..2815fd34a2 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -159,7 +159,7 @@ </combo_box> <panel name="perms_build"> <text name="perm_modify"> - Sie können dieses Objekt ändern. + Sie können dieses Objekt ändern </text> <text name="B:"> B: @@ -187,28 +187,28 @@ <check_box name="checkbox next owner can transfer"/> </panel> <string name="text modify info 1"> - Sie können dieses Objekt ändern. + Sie können dieses Objekt ändern </string> <string name="text modify info 2"> - Sie können diese Objekte ändern. + Sie können diese Objekte ändern </string> <string name="text modify info 3"> - Sie können dieses Objekt nicht ändern. + Sie können dieses Objekt nicht ändern </string> <string name="text modify info 4"> - Sie können diese Objekte nicht ändern. + Sie können diese Objekte nicht ändern </string> <string name="text modify warning"> - Gesamtes Objekt muss gewählt werden, um Berechtigungen festzulegen. + Gesamtes Objekt muss gewählt werden, um Berechtigungen festzulegen </string> <string name="Cost Default"> - Preis:L$ + Preis: L$ </string> <string name="Cost Total"> - Summe:L$ + Summe: L$ </string> <string name="Cost Per Unit"> - Stückpreis:L$ + Stückpreis: L$ </string> <string name="Cost Mixed"> Mischpreis @@ -503,8 +503,8 @@ Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild <button label="Ausrichten" label_selected="Ausrichten" name="button align"/> </panel> <panel label="Inhalt" name="Contents"> - <button label="Neues Skript" label_selected="Neues Skript..." name="button new script"/> - <button label="Berechtigungen..." name="button permissions"/> + <button label="Neues Skript" label_selected="Neues Skript" name="button new script"/> + <button label="Berechtigungen" name="button permissions"/> </panel> </tab_container> <panel name="land info panel"> @@ -512,24 +512,24 @@ Primitiv" name="sculpt texture control" tool_tip="Klicken Sie hier, um ein Bild Parzelleninformation </text> <text name="label_area_price"> - Preis: L$ [PRICE] für [AREA] m2. + Preis: L$ [PRICE] für [AREA] m² </text> <text name="label_area"> - Fläche: [AREA] m2 + Fläche: [AREA] m² </text> <button label="Info zu Land..." label_selected="Info zu Land..." name="button about land"/> - <check_box label="Eigentümer anzeigen" name="checkbox show owners" tool_tip="Parzellen nach Eigentümer farbig kennzeichnen"/> + <check_box label="Eigentümer anzeigen" name="checkbox show owners" tool_tip="Parzellen nach Eigentümer farbig kennzeichnen: Grün = Ihr Land Blau = Das Land Ihrer Gruppe Rot = Im Eigentum anderer Geld = Zum Verkauf Lila = Zur Auktion Grau = Öffentlich"/> <button label="?" label_selected="?" name="button show owners help"/> <text name="label_parcel_modify"> Parzelle ändern </text> - <button label="Unterteilen..." label_selected="Unterteilen..." name="button subdivide land"/> + <button label="Unterteilen" label_selected="Unterteilen" name="button subdivide land"/> <button label="Zusammenlegen" label_selected="Zusammenlegen" name="button join land"/> <text name="label_parcel_trans"> Land-Transaktionen </text> - <button label="Land kaufen..." label_selected="Land kaufen..." name="button buy land"/> - <button label="Land aufgeben..." label_selected="Land aufgeben..." name="button abandon land"/> + <button label="Land kaufen" label_selected="Land kaufen" name="button buy land"/> + <button label="Land aufgeben" label_selected="Land aufgeben" name="button abandon land"/> </panel> <floater.string name="status_rotate"> An den farbigen Bändern ziehen, um das Objekt zu drehen diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index b738b2d864..ebe2d9b260 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -1696,7 +1696,7 @@ Ist die Option aktiviert, können Käufer ihr Land in dieser Region weiterverkau Standard: deaktiviert </notification> <notification label="Skripts deaktivieren" name="HelpRegionDisableScripts"> - Schlechte Sim-Performance ist oftmals auf ein Skript zurückzuführen. Öffnen Sie die Statistikleiste (Strg-Umschalt-1). Sehen Sie sich den Wert für „Simulator Physics FPS“ (Simulator Physik-FPS) an. + Schlechte Sim-Performance ist oftmals auf ein Skript zurückzuführen. Öffnen Sie die Statistikleiste (Strg+Umschalt+1). Sehen Sie sich den Wert für „Simulator Physics FPS“ (Simulator Physik-FPS) an. Wenn der Wert unter 45 liegt, öffnen Sie den Bereich „Time“ (Zeit) ganz unten in der Statistikleiste. Wenn der Wert für „Script Time“ (Skriptzeit) 25 ms oder höher ist, klicken Sie auf „Top-Skripts“. Der Name und die Position der Skripts, die für die schlechte Performance verantwortlich sind, werden angezeigt. Wenn Sie das Kontrollkästchen „Skripts deaktivieren“ aktivieren und auf „Übernehmen“ klicken, werden alle Skripts in der Region zeitweilig deaktiviert. Dieser Schritt ist eventuell notwendig, damit Sie an die Position des gemeldeten „Top-Skripts“ reisen können. Sobald Sie dort angekommen sind, sollten Sie das Skript auf die Ursache des Problems hin untersuchen. Möglicherweise müssen Sie sich an den Skript-Eigentümer wenden oder das Objekt löschen bzw. zurückgeben. Um die Skripte in der Region wieder zu aktivieren, deaktivieren Sie „Skript deaktivieren“ und klicken Sie auf „Übernehmen“. @@ -1704,7 +1704,7 @@ Standard: deaktiviert </notification> <notification label="Kollisionen deaktivieren" name="HelpRegionDisableCollisions"> Schlechte Sim-Performance ist oftmals auf physische Objekte zurückzuführen. -Öffnen Sie die Statistikleiste (Strg-Umschalt-1). Sehen Sie sich den Wert „Simulator Physics FPS“ an. Liegt dieser unter 45, öffnen Sie unten in der Statistikleiste den „Time“-Bereich. Liegt die „Sim Time (Physics)“ bei 20 ms oder darüber, klicken Sie auf „Top-Kollisionsobjekte“. +Öffnen Sie die Statistikleiste (Strg+Umschalt+1). Sehen Sie sich den Wert „Simulator Physics FPS“ an. Liegt dieser unter 45, öffnen Sie unten in der Statistikleiste den „Time“-Bereich. Liegt die „Sim Time (Physics)“ bei 20 ms oder darüber, klicken Sie auf „Top-Kollisionsobjekte“. Der Name und der Standort der physischen Objekte, die das Problem verursachen, werden angezeigt. Wenn Sie das Kontrollkästchen „Kollisionen deaktivieren“ aktivieren und auf „Übernehmen“ klicken, werden alle Objekt-Objekt-Kollisionen in der Region zeitweilig deaktiviert. Dieser Schritt ist eventuell notwendig, damit Sie an die Position des gemeldeten „Top-Kollisionsobjekts“ reisen können. Überprüfen Sie das Objekt an der angegebenen Position. @@ -2849,7 +2849,7 @@ Ein flexibles Objekt ist ein Phantom und nicht physisch, bis die Option „Flexi <notification name="FirstDebugMenus"> Sie haben das Advanced-Menü aktiviert. Dieses Menü enthält nützliche Funktionen zum Debuggen von [SECOND_LIFE]. -Drücken Sie in Windows Strg-Alt-D (Mac: Befehl-Opt-Umschalt-D) zum Ein- und Ausschalten dieses Menüs. +Drücken Sie in Windows Strg+Alt+D (Mac: ⌥⌘D) zum Ein- und Ausschalten dieses Menüs. </notification> <notification name="FirstSculptedPrim"> Sie bearbeiten ein geformtes Primitiv. diff --git a/indra/newview/skins/default/xui/de/panel_edit_profile.xml b/indra/newview/skins/default/xui/de/panel_edit_profile.xml new file mode 100644 index 0000000000..1f67e0231d --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Einwohner" />
+ <string name="AcctTypeTrial"
+ value="Test" />
+ <string name="AcctTypeCharterMember"
+ value="Charta-Mitglied" />
+ <string name="AcctTypeEmployee"
+ value="Linden Lab-Mitarbeiter" />
+ <string name="PaymentInfoUsed"
+ value="Zahlungsinfo verwendet" />
+ <string name="PaymentInfoOnFile"
+ value="Zahlungsinfo archiviert" />
+ <string name="NoPaymentInfoOnFile"
+ value="Keine Zahlungsinfo archiviert" />
+ <string name="AgeVerified"
+ value="Altersgeprüft" />
+ <string name="NotAgeVerified"
+ value="Nicht altersgeprüft" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=de
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Antwort für Beschäftigt-Modus:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_group_general.xml b/indra/newview/skins/default/xui/de/panel_group_general.xml index e214b19ffd..2acc9e0649 100644 --- a/indra/newview/skins/default/xui/de/panel_group_general.xml +++ b/indra/newview/skins/default/xui/de/panel_group_general.xml @@ -1,9 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="Allgemein" name="general_tab"> <string name="help_text"> - Die Registerkarte „Allgemein“ enthält Informationen über -diese Gruppe, eine Liste der Eigentümer und sichtbaren Mitglieder, -allgemeine Gruppeneinstellungen und Mitgliederoptionen. + Die Registerkarte „Allgemein“ enthält Informationen über diese Gruppe, eine Liste der Eigentümer und sichtbaren Mitglieder, allgemeine Gruppeneinstellungen und Mitgliederoptionen. Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen. </string> @@ -47,7 +45,7 @@ Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen. <panel name="preferences_container"> <check_box label="In Suche anzeigen" name="show_in_group_list" tool_tip="Diese Gruppe in Suchergebnissen anzeigen."/> <check_box label="Registrierung offen" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/> - <check_box label="Beitrittsgebühr: L$" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen."/> + <check_box label="Beitrittsgebühr:" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen."/> <spinner name="spin_enrollment_fee" tool_tip="Wenn „Beitrittsgebühr“ aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/> <combo_box name="group_mature_check" tool_tip="Festlegen, ob die Informationen Ihrer Gruppe „Mature“ sind."> <combo_box.item name="select_mature" label="- Mature wählen -"/> @@ -72,88 +70,3 @@ Sind Sie wirklich, WIRKLICH sicher, dass Sie 100 L$ für die Gründung dieser Gr Falls in den nächsten 48 Stunden niemand sonst dieser Gruppe beitritt, wird sie aufgelöst und der Name der Gruppe wird nicht mehr verfügbar sein. </string> </panel> - -<!-- original file - -<?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel label="Allgemein" name="general_tab"> - <string name="help_text"> - Die Registerkarte „Allgemein“ enthält Informationen über -diese Gruppe, eine Liste der Eigentümer und sichtbaren Mitglieder, -allgemeine Gruppeneinstellungen und Mitgliederoptionen. - -Bewegen Sie die Maus über die Optionen, um weitere Informationen anzuzeigen. - </string> - <string name="group_info_unchanged"> - Die allgemeine Gruppeninfo wurde geändert. - </string> - <button label="?" label_selected="?" name="help_button"/> - <line_editor label="Neuen Gruppennamen hier eingeben" name="group_name_editor"/> - <text name="group_name"> - Neuen Gruppennamen hier eingeben - </text> - <text name="prepend_founded_by"> - Gegründet von - </text> - <text left_delta="79" name="founder_name"> - (wartet) - </text> - <text name="group_charter_label"> - Gruppencharta - </text> - <texture_picker label="Gruppeninsignien" name="insignia" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/> - <text_editor name="charter"> - Gruppencharta - </text_editor> - <button label="Beitreten (0 L$)" label_selected="Beitreten (0 L$)" name="join_button"/> - <button label="Detailansicht" label_selected="Detailansicht" name="info_button"/> - <text name="text_owners_and_visible_members"> - Eigentümer und sichtbare Mitglieder - </text> - <text name="text_owners_are_shown_in_bold"> - (Eigentümer werden fettgedruckt angezeigt) - </text> - <name_list name="visible_members"> - <name_list.columns label="Mitgliedsname" name="name" relwidth="0.40"/> - <name_list.columns label="Titel" name="title" relwidth="0.25"/> - <name_list.columns label="Letzte Anmeldung" name="online" relwidth="0.35"/> - </name_list> - <text name="text_group_preferences"> - Gruppeneinstellungen - </text> - <panel name="preferences_container"> - <check_box label="In Suche anzeigen" name="show_in_group_list" tool_tip="Diese Gruppe in Suchergebnissen anzeigen."/> - <check_box label="Registrierung offen" name="open_enrollement" tool_tip="Festlegen, ob der Gruppenbeitritt ohne Einladung zulässig ist."/> - <check_box label="Beitrittsgebühr: L$" name="check_enrollment_fee" tool_tip="Festlegen, ob Neumitglieder eine Beitrittsgebühr zahlen müssen." width="125"/> - <spinner name="spin_enrollment_fee" tool_tip="Wenn „Beitrittsgebühr“ aktiviert ist, müssen neue Mitglieder diesen Betrag zahlen."/> - <combo_box name="group_mature_check" tool_tip="Festlegen, ob die Informationen Ihrer Gruppe „Mature“ sind."> - <combo_box.item name="select_mature"> - - Mature wählen - - </combo_item> - <combo_box.item name="mature"> - Mature-Inhalt - </combo_item> - <combo_box.item name="pg"> - PG-Inhalt - </combo_item> - </combo_box> - <panel name="title_container"> - <text name="active_title_label"> - Mein aktiver Titel - </text> - <combo_box name="active_title" tool_tip="Legt fest, was im Namensschild Ihres Avatars angezeigt wird, wenn diese Gruppe aktiviert ist."/> - </panel> - <check_box label="Gruppenmitteilungen erhalten" name="receive_notices" tool_tip="Festlegen, ob Sie von dieser Gruppe Mitteilungen erhalten können. Deaktivieren Sie diese Option, wenn Sie von der Gruppe Spam erhalten." width="173"/> - <check_box label="Gruppe im Profil anzeigen" name="list_groups_in_profile" tool_tip="Steuert, ob diese Gruppe in Ihrem Profil angezeigt wird"/> - </panel> - <string name="incomplete_member_data_str"> - Mitgliedsdaten werden abgerufen - </string> - <string name="confirm_group_create_str"> - Die Gründung dieser Gruppe kostet 100 L$. -Sind Sie wirklich, WIRKLICH sicher, dass Sie 100 L$ für die Gründung dieser Gruppe ausgeben möchten? -Falls in den nächsten 48 Stunden niemand sonst dieser Gruppe beitritt, wird sie aufgelöst und der Name der Gruppe wird nicht mehr verfügbar sein. - </string> -</panel> - ---> diff --git a/indra/newview/skins/default/xui/de/panel_group_land_money.xml b/indra/newview/skins/default/xui/de/panel_group_land_money.xml index e2e30b7479..bc39a3a1bb 100644 --- a/indra/newview/skins/default/xui/de/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/de/panel_group_land_money.xml @@ -48,8 +48,11 @@ <string name="land_contrib_error"> Ihr Landbeitrag kann nicht festgelegt werden. </string> + <text name="your_contribution_units"> + ( qm ) + </text> <text name="your_contribution_max_value"> - qm (max. [AMOUNT]) + (max. [AMOUNT]) </text> <text name="group_over_limit_text"> Die Gruppenmitglieder müssen mehr Landnutzungsrechte spenden, damit das verwendete Land gehalten werden kann. diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml index bfd4148895..8d9ebe423b 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml @@ -33,10 +33,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="PG, Mature und Adult"/> <combo_box.item name="Desired_Mature" label="PG und Mature"/> - <combo_box.item name="Desired_PG" label="Nur PG"/> + <combo_box.item name="Desired_PG" label="PG"/> </combo_box> <text name="maturity_desired_textbox"> - Nur PG + PG </text> <text name="start_location_textbox"> Startposition: diff --git a/indra/newview/skins/default/xui/de/panel_region_estate.xml b/indra/newview/skins/default/xui/de/panel_region_estate.xml index 790555296d..ddc5941da6 100644 --- a/indra/newview/skins/default/xui/de/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/de/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Grundstück" name="Estate"> +<panel label="Grundstück" name="Estate"> <text name="estate_help_text"> Änderungen auf dieser Registerkarte wirken sich auf alle Regionen auf dem Grundstück aus. @@ -76,6 +74,4 @@ auf alle Regionen auf dem Grundstück aus. <button label="Entfernen..." name="remove_banned_avatar_btn" /> <button label="Nachricht an Grundstück senden..." name="message_estate_btn" /> <button label="Benutzer von Grundstück werfen..." name="kick_user_from_estate_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_region_texture.xml b/indra/newview/skins/default/xui/de/panel_region_texture.xml index 456feb0371..df936ff643 100644 --- a/indra/newview/skins/default/xui/de/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/de/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Bodentexturen" name="Textures"> +<panel label="Bodentexturen" name="Textures"> <text name="region_text_lbl"> Region: </text> @@ -56,6 +54,4 @@ und der OBERE WERT die MINIMALE Höhe von Textur 4. </text> <button label="Übernehmen" name="apply_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml index 5df1570bfd..af9185e0b7 100644 --- a/indra/newview/skins/default/xui/de/strings.xml +++ b/indra/newview/skins/default/xui/de/strings.xml @@ -488,16 +488,16 @@ Verzeichnis auswählen </string> <string name="accel-mac-control"> - Strg- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Umschalt- + ⇧ </string> <string name="accel-win-control"> Strg+ @@ -603,6 +603,9 @@ <string name="no_ability_error"> Sie besitzen diese Fähigkeit nicht. </string> + <string name="no_ability"> + Sie besitzen diese Fähigkeit nicht. + </string> <string name="not_a_mod_error"> Sie sind kein Sitzungsmoderator. </string> @@ -621,4 +624,31 @@ <string name="close_on_no_ability"> Sie haben nicht mehr die Berechtigung an der Chat-Sitzung teilzunehmen. </string> + <string name="AcctTypeResident"> + Einwohner + </string> + <string name="AcctTypeTrial"> + Test + </string> + <string name="AcctTypeCharterMember"> + Charta-Mitglied + </string> + <string name="AcctTypeEmployee"> + Linden Lab-Mitarbeiter + </string> + <string name="PaymentInfoUsed"> + Zahlungsinfo verwendet + </string> + <string name="PaymentInfoOnFile"> + Zahlungsinfo archiviert + </string> + <string name="NoPaymentInfoOnFile"> + Keine Zahlungsinfo archiviert + </string> + <string name="AgeVerified"> + Altersgeprüft + </string> + <string name="NotAgeVerified"> + Nicht altersgeprüft + </string> </strings> diff --git a/indra/newview/skins/default/xui/en/favorites_bar_button.xml b/indra/newview/skins/default/xui/en/favorites_bar_button.xml index dcd85e1f58..a8d3f440c3 100644 --- a/indra/newview/skins/default/xui/en/favorites_bar_button.xml +++ b/indra/newview/skins/default/xui/en/favorites_bar_button.xml @@ -9,15 +9,15 @@ image_disabled_selected="transparent.j2c" image_selected="transparent.j2c" image_unselected="transparent.j2c" - image_hover_selected="PushButton_Selected" - image_hover_unselected="PushButton_Off" - image_pressed="PushButton_Press" - image_pressed_selected="PushButton_Selected_Press" + image_hover_selected="FileMenu_BarSelect" + image_hover_unselected="FileMenu_BarSelect" + image_pressed="FileMenu_BarSelect" + image_pressed_selected="FileMenu_BarSelect" hover_glow_amount="0.15" layout="topleft" - left="2" + left="0" name="favorites_bar_btn" tab_stop="false" - top="2" + top="10" use_ellipses="true" width="120" /> diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 0733280c39..b194b533af 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -78,6 +78,7 @@ <panel border="true" label="Support" + help_topic="about_support_tab" name="support_panel"> <text_editor allow_html="true" @@ -103,6 +104,7 @@ <panel border="true" label="Credits" + help_topic="about_credits_tab" name="credits_panel"> <text_editor enabled="false" @@ -134,6 +136,7 @@ It is a rare mind indeed that can render the hitherto non-existent blindingly ob <panel border="true" label="Licenses" + help_topic="about_licenses_tab" name="licenses_panel"> <text_editor enabled="false" 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 524495d83d..1f366f6c52 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -40,6 +40,7 @@ label="General" layout="topleft" left="1" + help_topic="land_general_tab" name="land_general_panel" top="-31" width="458"> @@ -535,6 +536,7 @@ Go to World menu > About Land or select another parcel to show its details. label="Covenant" layout="topleft" left_delta="-1" + help_topic="land_covenant_tab" name="land_covenant_panel" top_delta="-47" width="458"> @@ -801,6 +803,7 @@ Go to World menu > About Land or select another parcel to show its details. label="Objects" layout="topleft" left_delta="0" + help_topic="land_objects_tab" name="land_objects_panel" top_delta="-47" width="458"> @@ -1166,6 +1169,7 @@ Go to World menu > About Land or select another parcel to show its details. label="Options" layout="topleft" left_delta="0" + help_topic="land_options_tab" name="land_options_panel" top_delta="31" width="458"> @@ -1603,6 +1607,7 @@ Only large parcels can be listed in search. label="Media" layout="topleft" left_delta="0" + help_topic="land_media_tab" name="land_media_panel" top_delta="1" width="458"> @@ -1865,6 +1870,7 @@ Texture: label="Audio" layout="topleft" left_delta="0" + help_topic="land_audio_tab" name="land_audio_panel" top_delta="1" width="458"> @@ -1968,6 +1974,7 @@ Texture: label="Access" layout="topleft" left_delta="0" + help_topic="land_access_tab" name="land_access_panel" top_delta="31" width="458"> diff --git a/indra/newview/skins/default/xui/en/floater_auction.xml b/indra/newview/skins/default/xui/en/floater_auction.xml index 29f8b49794..fb0994b4cd 100644 --- a/indra/newview/skins/default/xui/en/floater_auction.xml +++ b/indra/newview/skins/default/xui/en/floater_auction.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater can_resize="true" - height="368" + height="412" layout="topleft" - min_height="368" + min_height="412" min_width="420" name="floater_auction" help_topic="floater_auction" @@ -49,21 +49,47 @@ left_delta="0" name="snapshot_btn" top_pad="4" - width="96"> + width="150"> <button.commit_callback function="ClickSnapshot" /> </button> <button follows="left|bottom" height="20" - label="OK" - label_selected="OK" + label="Sell to Anyone" + label_selected="Sell to Anyone" + layout="topleft" + left_delta="0" + name="sell_to_anyone_btn" + top_pad="4" + width="150"> + <button.commit_callback + function="ClickSellToAnyone" /> + </button> + <button + follows="left|bottom" + height="20" + label="Clear Settings" + label_selected="Clear Settings" + layout="topleft" + left_delta="0" + name="reset_parcel_btn" + top_pad="4" + width="150"> + <button.commit_callback + function="ClickResetParcel" /> + </button> + <button + follows="left|bottom" + height="20" + label="Start Auction" + label_selected="Start Auction" layout="topleft" left_pad="4" - name="ok_btn" + name="start_auction_btn" top_delta="0" - width="48"> + width="150"> <button.commit_callback - function="ClickOK" /> + function="ClickStartAuction" /> </button> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml index e1f8011cbe..0542d4509e 100644 --- a/indra/newview/skins/default/xui/en/floater_avatar_picker.xml +++ b/indra/newview/skins/default/xui/en/floater_avatar_picker.xml @@ -40,6 +40,7 @@ label="Search" layout="topleft" left="6" + help_topic="avatarpicker_search_tab" name="SearchPanel" top="150" width="132"> @@ -91,6 +92,7 @@ label="Near Me" layout="topleft" left="6" + help_topic="avatarpicker_near_me_tab" name="NearMePanel" top="150" width="132"> diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index 991c9a84a3..041cd2a118 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -12,10 +12,6 @@ name="buy_currency"> Buy L$ [LINDENS] for approx. [LOCALAMOUNT] </floater.string> - <floater.string - name="account_website"> - http://secondlife.com/account/billing.php - </floater.string> <icon height="215" image_name="Linden_Dollar_Background" @@ -35,7 +31,7 @@ top="30" width="300" name="info_need_more"> - You need more L$: + You need more L$ </text> <text type="string" @@ -43,7 +39,8 @@ follows="top|left" height="16" layout="topleft" - left="20" + top="246" + left="15" width="300" name="contacting"> Contacting LindeX... @@ -70,7 +67,7 @@ layout="topleft" left="20" name="balance_label" - top_pad="10" + top="70" width="210"> I have </text> @@ -85,7 +82,7 @@ left="200" name="balance_amount" top_delta="0" - width="100"> + width="120"> L$ [AMT] </text> <text @@ -94,7 +91,7 @@ follows="top|left" font="SansSerifMedium" height="16" - top_pad="15" + top="100" layout="topleft" left="20" name="currency_action" @@ -109,7 +106,7 @@ height="16" layout="topleft" top_delta="0" - left="222" + left="242" name="currency_label" width="15"> L$ @@ -136,7 +133,7 @@ height="16" layout="topleft" left="20" - top_pad="10" + top="130" name="buying_label" width="210"> For the price @@ -153,7 +150,7 @@ layout="topleft" left="170" name="currency_est" - width="130"> + width="150"> [LOCALAMOUNT] </text> <text @@ -164,8 +161,9 @@ follows="top|left" height="16" layout="topleft" - left="40" - width="100" + top="130" + left="170" + width="150" halign="right" name="getting_data"> Estimating... @@ -173,13 +171,13 @@ <text type="string" font="SansSerifSmall" - top_delta="0" + top="150" length="1" follows="top|left" halign="right" height="16" - left_pad="10" - width="150" + left="150" + width="170" layout="topleft" name="buy_action"> [NAME] L$ [PRICE] @@ -193,6 +191,7 @@ layout="topleft" left="20" name="total_label" + top="170" width="210"> My new balance will be </text> @@ -207,7 +206,7 @@ left="200" halign="right" name="total_amount" - width="100"> + width="120"> L$ [AMT] </text> <text @@ -215,8 +214,10 @@ length="1" follows="top|left" layout="topleft" + top="195" left="20" width="300" + height="30" name="purchase_warning_repurchase"> Confirming this purchase only buys the L$. You'll need to try again. @@ -226,7 +227,10 @@ You'll need to try again. length="1" follows="top|left" layout="topleft" + top="195" left="20" + width="300" + height="30" name="purchase_warning_notenough"> You aren't buying enough L$. Increase the amount to buy. @@ -239,7 +243,7 @@ Increase the amount to buy. layout="topleft" left="151" name="buy_btn" - top="248" + top="242" width="90"/> <button follows="bottom|right" @@ -260,15 +264,23 @@ Increase the amount to buy. <text type="string" font="SansSerifHuge" - left="170" + left="165" width="170" - height="80" - top="30" + height="25" + top="25" name="info_cannot_buy"> - Take your -[SECOND_LIFE] to -the next level... + Unable to Buy </text> + <text + type="string" + width="175" + height="125" + top="60" + left="165" + word_wrap="true" + follows="bottom|right" + name="cannot_buy_message"> + </text> <button follows="bottom|left" height="20" @@ -276,16 +288,6 @@ the next level... layout="topleft" left="170" name="error_web" - top="120" + top="200" width="160"/> - <text - type="string" - width="350" - height="20" - top_pad="92" - left_pad="-300" - follows="bottom|right" - name="cannot_buy_message"> - Continue to the web site and enter payment information - </text> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_buy_land.xml b/indra/newview/skins/default/xui/en/floater_buy_land.xml index 62d40bc45f..6d1c2c1cb9 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_land.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_land.xml @@ -587,7 +587,7 @@ sold with objects width="215" word_wrap="true"> You hold 1309 m² of land. - This parcel is 512 m² of land. +This parcel is 512 m² of land. </text> <locate height="10" diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml index c4a2654403..86c75a3946 100644 --- a/indra/newview/skins/default/xui/en/floater_camera.xml +++ b/indra/newview/skins/default/xui/en/floater_camera.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater can_dock="true" - can_minimize="false" - can_close="false" + can_minimize="true" + can_close="true" center_horiz="true" follows="top" height="110" diff --git a/indra/newview/skins/default/xui/en/floater_font_test.xml b/indra/newview/skins/default/xui/en/floater_font_test.xml index 6f9038df62..66c207603b 100644 --- a/indra/newview/skins/default/xui/en/floater_font_test.xml +++ b/indra/newview/skins/default/xui/en/floater_font_test.xml @@ -199,7 +199,7 @@ bottom_delta="20" follows="left|top|right" font="SansSerif" - font_shadow="hard" + font_shadow="none" height="16" layout="topleft" left="16"> diff --git a/indra/newview/skins/default/xui/en/floater_gesture.xml b/indra/newview/skins/default/xui/en/floater_gesture.xml index 052398bcd3..3d0a969112 100644 --- a/indra/newview/skins/default/xui/en/floater_gesture.xml +++ b/indra/newview/skins/default/xui/en/floater_gesture.xml @@ -2,13 +2,16 @@ <floater can_resize="true" height="465" - layout="topleft" - min_height="200" - min_width="280" name="gestures" help_topic="gestures" - title="Active Gestures" - width="280"> + title="Gestures" + background_visible="true" + follows="all" + label="Places" + layout="topleft" + min_height="350" + min_width="240" + width="313"> <floater.string name="loading"> Loading... @@ -17,31 +20,20 @@ name="playing"> (Playing) </floater.string> - <text - type="string" - length="1" - bottom="30" - follows="top|left" - layout="topleft" - left="15" - name="help_label"> - Double-click a gesture to play. - </text> <scroll_list - bottom_delta="390" + bottom_delta="400" draw_heading="true" - follows="top|left|bottom|right" - height="380" + follows="all" layout="topleft" - left="15" - name="gesture_list" - right="-15"> + left="0" + top="20" + name="gesture_list"> <scroll_list.columns label="Name" name="name" - width="90" /> + width="153" /> <scroll_list.columns - label="Trigger" + label="Chat" name="trigger" width="80" /> <scroll_list.columns @@ -51,29 +43,74 @@ <scroll_list.columns label="Key" name="shortcut" - width="50" /> + width="80" /> </scroll_list> + <panel + background_visible="true" + bevel_style="none" + top_pad="0" + follows="left|right|bottom" + height="30" + label="bottom_panel" + layout="topleft" + left="0" + name="bottom_panel" + width="313"> + <button + follows="bottom|left" + font="SansSerifBigBold" + tool_tip="Change sort and view of Recent Residents list" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + name="recent_viewsort_btn" + picture_style="true" + top="5" + width="18" /> + <button + follows="bottom|left" + font="SansSerifBigBold" + height="18" + image_selected="AddItem_Press" + image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" + layout="topleft" + left_pad="5" + name="new_gesture_btn" + picture_style="true" + tool_tip="Make new Gesture" + top_delta="0" + width="18" /> + <button + follows="bottom|left" + font="SansSerifBigBold" + height="18" + image_selected="TrashItem_Press" + image_unselected="TrashItem_Off" + image_disabled="TrashItem_Disabled" + layout="topleft" + left_pad="230" + name="del_btn" + picture_style="true" + tool_tip="Delete this Gesture" + top_delta="0" + width="18" /> + </panel> <button follows="bottom|right" - height="20" - label="New" - layout="topleft" - left_delta="0" - name="new_gesture_btn" - top_pad="10" - width="83" /> - <button - follows="bottom|right" - height="20" + height="23" label="Edit" layout="topleft" - left_pad="6" + left="6" name="edit_btn" - top_delta="0" + top_pad="5" width="83" /> <button follows="bottom|right" - height="20" + height="23" label="Play" layout="topleft" left_pad="6" @@ -82,7 +119,7 @@ width="83" /> <button follows="bottom|right" - height="20" + height="23" label="Stop" layout="topleft" left_delta="0" @@ -90,4 +127,3 @@ top_delta="0" width="83" /> </floater> - diff --git a/indra/newview/skins/default/xui/en/floater_god_tools.xml b/indra/newview/skins/default/xui/en/floater_god_tools.xml index 615c35e6c3..53d05f3c61 100644 --- a/indra/newview/skins/default/xui/en/floater_god_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_god_tools.xml @@ -23,6 +23,7 @@ layout="topleft" left="1" mouse_opaque="false" + help_topic="godtools_grid_tab" name="grid" top="16" width="398"> @@ -61,6 +62,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="godtools_region_tab" name="region" top_delta="0" width="398"> @@ -483,6 +485,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="godtools_objects_tab" name="objects" top_delta="0" width="398"> @@ -690,6 +693,7 @@ label="Request" layout="topleft" left_delta="0" + help_topic="godtools_request_tab" name="request" top_delta="0" width="398"> diff --git a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml index 70f296b606..c695753ca3 100644 --- a/indra/newview/skins/default/xui/en/floater_hardware_settings.xml +++ b/indra/newview/skins/default/xui/en/floater_hardware_settings.xml @@ -95,7 +95,7 @@ name="(brightness, lower is brighter)" top_delta="2" width="315"> - (brightness, lower = brighter, 0 = default) + (0 = default brightness, lower = brighter) </text> <text type="string" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index a233f7f0fa..611c51ad11 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -11,10 +11,10 @@ can_dock="true" can_minimize="true" visible="true" - width="315"> + width="365"> <layout_stack follows="left|top|right|bottom" height="235" - width="315" + width="365" layout="topleft" orientation="horizontal" name="im_panels" @@ -25,13 +25,13 @@ layout="topleft" top_delta="-3" min_width="96" - width="96" + width="146" height="225" label="IM Control Panel" user_resize="false" /> <layout_panel height="235" width="200" - left_delta="96" + left_delta="146" top="0" user_resize="false"> <button height="12" @@ -62,7 +62,7 @@ width="195" word_wrap="true"> </text_editor> - <line_editor name="chat_editor" height="20" layout="topleft" width="190"> + <line_editor follows="left|right" name="chat_editor" height="20" layout="topleft" width="190"> </line_editor> </layout_panel> </layout_stack> diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml index bdce8fa4fc..95e4247a05 100644 --- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml +++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml @@ -34,7 +34,6 @@ font="SansSerif" height="64" border_visible="false" - hide_scrollbar="true" layout="topleft" left="77" max_length="2147483647" diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index dc6a02efe1..a2b2e1ddf3 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -67,7 +67,6 @@ left="0" name="floater_map_north" right="10" - text="N" text_color="1 1 1 0.7" top="215"> N diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml index 65235da8d5..f82e01dd1f 100644 --- a/indra/newview/skins/default/xui/en/floater_moveview.xml +++ b/indra/newview/skins/default/xui/en/floater_moveview.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater can_dock="true" - can_close="false" - can_minimize="false" + can_close="true" + can_minimize="true" center_horiz="true" follows="bottom" height="110" @@ -50,6 +50,7 @@ follows="left|bottom" height="25" image_selected="Movement_TurnLeft_On" + image_pressed_selected="Movement_TurnLeft_On" image_unselected="Movement_TurnLeft_Off" layout="topleft" left="17" @@ -63,6 +64,7 @@ follows="left|bottom" height="25" image_selected="Movement_TurnRight_On" + image_pressed_selected="Movement_TurnRight_On" image_unselected="Movement_TurnRight_Off" layout="topleft" left_pad="34" @@ -76,6 +78,7 @@ follows="left|bottom" height="25" image_selected="Movement_Up_On" + image_pressed_selected="Movement_Up_On" image_unselected="Movement_Up_Off" layout="topleft" left="10" @@ -89,6 +92,7 @@ follows="left|bottom" height="25" image_selected="Movement_Down_On" + image_pressed_selected="Movement_Down_On" image_unselected="Movement_Down_Off" layout="topleft" left_pad="45" @@ -102,6 +106,7 @@ follows="left|bottom" height="25" image_selected="Movement_Forward_On" + image_pressed_selected="Movement_Forward_On" image_unselected="Movement_Forward_Off" layout="topleft" left="46" @@ -116,6 +121,7 @@ follows="left|bottom" height="25" image_selected="Movement_Backward_On" + image_pressed_selected="Movement_Backward_On" image_unselected="Movement_Backward_Off" layout="topleft" left_delta="0" diff --git a/indra/newview/skins/default/xui/en/floater_my_friends.xml b/indra/newview/skins/default/xui/en/floater_my_friends.xml index a9a18f44c4..0ca4fc825a 100644 --- a/indra/newview/skins/default/xui/en/floater_my_friends.xml +++ b/indra/newview/skins/default/xui/en/floater_my_friends.xml @@ -28,6 +28,7 @@ label="Friends" layout="topleft" left="0" + help_topic="my_friends_friends_tab" name="friends_panel" width="370" /> <panel @@ -36,6 +37,7 @@ label="Groups" layout="topleft" left="0" + help_topic="my_friends_groups_tab" name="groups_panel" width="370" /> </tab_container> diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml index e851710ad8..f1976afb4a 100644 --- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml @@ -31,12 +31,13 @@ name="close_btn"/> </panel> <text_editor + allow_html="true" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" follows="left|top|right|bottom" font="SansSerif" layout="topleft" - height="320" + height="320" max_length="2147483647" name="Chat History Editor" parse_highlights="true" diff --git a/indra/newview/skins/default/xui/en/floater_post_process.xml b/indra/newview/skins/default/xui/en/floater_post_process.xml index aaf7aecd6b..571f4149f0 100644 --- a/indra/newview/skins/default/xui/en/floater_post_process.xml +++ b/indra/newview/skins/default/xui/en/floater_post_process.xml @@ -23,6 +23,7 @@ layout="topleft" left="1" mouse_opaque="false" + help_topic="post_process_color_filter_tab" name="wmiColorFilterPanel" top="0" width="398"> @@ -184,6 +185,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="post_process_night_vision_tab" name="wmiNightVisionPanel" top_delta="-236" width="398"> @@ -279,6 +281,7 @@ label="Bloom" layout="topleft" left_delta="0" + help_topic="post_process_bloom_tab" name="wmiBloomPanel" top_delta="-236" width="398"> @@ -374,6 +377,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="post_process_extras_tab" name="Extras" top_delta="-236" width="398"> diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml index d655c268b2..cf9e3a82fc 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences.xml @@ -52,54 +52,63 @@ filename="panel_preferences_general.xml" label="General" layout="topleft" + help_topic="preferences_general_tab" name="general" /> <panel class="panel_preference" filename="panel_preferences_graphics1.xml" label="Graphics" layout="topleft" + help_topic="preferences_display_tab" name="display" /> <panel class="panel_preference" filename="panel_preferences_im.xml" label="Privacy" layout="topleft" + help_topic="preferences_im_tab" name="im" /> <panel class="panel_preference" filename="panel_preferences_audio.xml" label="Sound" layout="topleft" + help_topic="preferences_audio_tab" name="audio" /> <panel class="panel_preference" filename="panel_preferences_chat.xml" label="Chat" layout="topleft" + help_topic="preferences_chat_tab" name="chat" /> <panel class="panel_preference" filename="panel_preferences_popups.xml" label="Alerts" layout="topleft" + help_topic="preferences_msgs_tab" name="msgs" /> <panel class="panel_preference" filename="panel_preferences_input.xml" label="Setup" layout="topleft" + help_topic="preferences_input_tab" name="input" /> <panel class="panel_preference" filename="panel_preferences_advanced.xml" label="Advanced" layout="topleft" + help_topic="preferences_advanced1_tab" name="advanced1" /> <panel class="panel_preference" filename="panel_preferences_advanced2.xml" label="Move or Kill" layout="topleft" + help_topic="preferences_advanced2_tab" name="advanced2" /> </tab_container> 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 f90f2a81cf..448b0fa6af 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_notecard.xml @@ -86,7 +86,7 @@ follows="left|bottom" height="22" label="Save" - label_selected="Discard" + label_selected="Save" layout="topleft" left="288" name="Save" diff --git a/indra/newview/skins/default/xui/en/floater_preview_texture.xml b/indra/newview/skins/default/xui/en/floater_preview_texture.xml index a243cb399e..e477b6ddb8 100644 --- a/indra/newview/skins/default/xui/en/floater_preview_texture.xml +++ b/indra/newview/skins/default/xui/en/floater_preview_texture.xml @@ -45,22 +45,22 @@ <button follows="left|bottom" height="22" - label="Delete" + label="OK" layout="topleft" left="80" - name="Discard" + name="Keep" top="302" width="100" /> <button follows="left|bottom" height="22" - label="Save" + label="Cancel" layout="topleft" left_pad="5" - name="Keep" + name="Discard" top_delta="0" width="100" /> - <text + <text type="string" length="1" follows="left|bottom" @@ -68,8 +68,66 @@ layout="topleft" left="13" name="dimensions" - top="287" + top="309" width="303"> [WIDTH]px x [HEIGHT]px </text> + <text + type="string" + length="1" + bg_visible="false" + border_drop_shadow_visible="false" + border_visible="false" + top="309" + drop_shadow_visible="true" + enabled="true" + follows="right|bottom" + font="SansSerifSmall" + h_pad="0" + halign="right" + height="14" + left="54" + mouse_opaque="true" + name="aspect_ratio" + v_pad="0" + width="110"> + Preview Aspect Ratio + </text> + <combo_box + allow_text_entry="true" + top="306" + follows="right|bottom" + height="20" + left="176" + max_chars="20" + mouse_opaque="true" + enabled="true" + width="108" + name="combo_aspect_ratio" + tool_tip="Preview at a fixed aspect ratio"> + <combo_item name="Unconstrained" value="Unconstrained"> + Unconstrained + </combo_item> + <combo_item name="1:1" value="1:1" tool_tip="Group Insignia or 1st Life Profile"> + 1:1 + </combo_item> + <combo_item name="4:3" value="4:3" tool_tip="2nd Life Profile"> + 4:3 + </combo_item> + <combo_item name="10:7" value="10:7" tool_tip="Classifieds and search listings, landmarks"> + 10:7 + </combo_item> + <combo_item name="3:2" value="3:2" tool_tip="About land"> + 3:2 + </combo_item> + <combo_item name="16:10" value="16:10"> + 16:10 + </combo_item> + <combo_item name="16:9" value="16:9" tool_tip="Profile Picks"> + 16:9 + </combo_item> + <combo_item name="2:1" value="2:1"> + 2:1 + </combo_item> + </combo_box> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_region_info.xml b/indra/newview/skins/default/xui/en/floater_region_info.xml index e045b811f2..3fadc15616 100644 --- a/indra/newview/skins/default/xui/en/floater_region_info.xml +++ b/indra/newview/skins/default/xui/en/floater_region_info.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater height="512" + help_topic="regioninfo" layout="topleft" name="regioninfo" - help_topic="regioninfo" save_rect="true" title="Region/Estate" - width="280"> + width="480"> <tab_container bottom="512" follows="left|right|top|bottom" diff --git a/indra/newview/skins/default/xui/en/floater_sell_land.xml b/indra/newview/skins/default/xui/en/floater_sell_land.xml index f07b9d3767..652ed96192 100644 --- a/indra/newview/skins/default/xui/en/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/en/floater_sell_land.xml @@ -212,7 +212,7 @@ name="Anyone" value="anyone" /> <combo_box.item - label="Specific user:" + label="Specific person:" name="Specificuser:" value="user" /> </combo_box> diff --git a/indra/newview/skins/default/xui/en/floater_settings_debug.xml b/indra/newview/skins/default/xui/en/floater_settings_debug.xml index e2f4a73ec8..b7779687ec 100644 --- a/indra/newview/skins/default/xui/en/floater_settings_debug.xml +++ b/indra/newview/skins/default/xui/en/floater_settings_debug.xml @@ -23,7 +23,6 @@ <text_editor enabled="false" height="60" - hide_scrollbar="true" layout="topleft" left_delta="0" name="comment_text" diff --git a/indra/newview/skins/default/xui/en/floater_test_widgets.xml b/indra/newview/skins/default/xui/en/floater_test_widgets.xml index 8ed2047a27..cc0fc34dd5 100644 --- a/indra/newview/skins/default/xui/en/floater_test_widgets.xml +++ b/indra/newview/skins/default/xui/en/floater_test_widgets.xml @@ -277,6 +277,7 @@ follows="top|left" label="Spinner" layout="topleft" + label_width="45" name="test_spinner" tool_tip="spinner"/> <text diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index c65206d629..d3ceb67ceb 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -32,7 +32,7 @@ </floater.string> <floater.string name="status_grab"> - Drag to move, Ctrl to lift, Ctrl-Shift to rotate + Drag to move, Ctrl to lift, Ctrl+Shift to rotate </floater.string> <floater.string name="status_place"> @@ -66,8 +66,8 @@ follows="left|top" height="20" image_disabled="Tool_Zoom" - image_disabled_selected="tool_zoom_active.tga" - image_selected="tool_zoom_active.tga" + image_disabled_selected="Tool_Zoom" + image_selected="Tool_Zoom" image_unselected="Tool_Zoom" layout="topleft" left="10" @@ -83,8 +83,8 @@ follows="left|top" height="20" image_disabled="Tool_Grab" - image_disabled_selected="tool_grab_active.tga" - image_selected="tool_grab_active.tga" + image_disabled_selected="Tool_Grab" + image_selected="Tool_Grab" image_unselected="Tool_Grab" layout="topleft" left_pad="8" @@ -100,8 +100,8 @@ follows="left|top" height="20" image_disabled="Tool_Face" - image_disabled_selected="tool_face_active.tga" - image_selected="tool_face_active.tga" + image_disabled_selected="Tool_Face" + image_selected="Tool_Face" image_unselected="Tool_Face" layout="topleft" left_pad="8" @@ -117,8 +117,8 @@ follows="left|top" height="20" image_disabled="Tool_Create" - image_disabled_selected="tool_create_active.tga" - image_selected="tool_create_active.tga" + image_disabled_selected="Tool_Create" + image_selected="Tool_Create" image_unselected="Tool_Create" layout="topleft" left_pad="8" @@ -134,8 +134,8 @@ follows="left|top" height="20" image_disabled="Tool_Dozer" - image_disabled_selected="tool_dozer_active.tga" - image_selected="tool_dozer_active.tga" + image_disabled_selected="Tool_Dozer" + image_selected="Tool_Dozer" image_unselected="Tool_Dozer" layout="topleft" left_pad="8" @@ -148,6 +148,9 @@ parameter="Land" /> </button> <text + height="30" + word_wrap="true" + use_ellipses="true" type="string" text_color="LabelSelectedDisabledColor" length="1" @@ -156,7 +159,7 @@ left="8" name="text status" top_pad="3" - width="280"> + width="275"> Drag to move, shift-drag to copy </text> <radio_group @@ -177,7 +180,7 @@ name="radio orbit" /> <radio_item top_pad="6" - label="Pan (Ctrl-Shift)" + label="Pan (Ctrl+Shift)" layout="topleft" name="radio pan" /> <radio_group.commit_callback @@ -215,7 +218,7 @@ name="radio lift" /> <radio_item top_pad="6" - label="Spin (Ctrl-Shift)" + label="Spin (Ctrl+Shift)" layout="topleft" name="radio spin" /> <radio_group.commit_callback @@ -239,7 +242,7 @@ name="radio rotate" /> <radio_item top_pad="6" - label="Stretch (Ctrl-Shift)" + label="Stretch (Ctrl+Shift)" layout="topleft" name="radio stretch" /> <radio_item @@ -251,39 +254,17 @@ function="BuildTool.commitRadioEdit"/> </radio_group> <check_box - left="10" + left="10" follows="left|top" + height="16" control_name="EditLinkedParts" label="Edit linked" layout="topleft" name="checkbox edit linked parts" > <check_box.commit_callback function="BuildTool.selectComponent"/> - </check_box> - <combo_box - height="19" - left="10" - layout="topleft" - follows="left|top" - top_pad="0" - name="combobox grid mode" - width="120"> - <combo_box.item - label="World ruler" - name="World" - value="World" /> - <combo_box.item - label="Local ruler" - name="Local" - value="Local" /> - <combo_box.item - label="Reference ruler" - name="Reference" - value="Reference" /> - <combo_box.commit_callback - function="BuildTool.gridMode"/> - </combo_box> - <check_box + </check_box> + <check_box control_name="ScaleUniform" height="19" label="Stretch Both Sides" @@ -301,26 +282,51 @@ name="checkbox stretch textures" top_pad="0" width="134" /> - <check_box + <check_box control_name="SnapEnabled" - height="19" + height="20" initial_value="true" - label="Snap to Grid" + label="Snap to grid" layout="topleft" - name="checkbox snap to grid" top_pad="0" + name="checkbox snap to grid" width="134" /> - <button - left="163" - top_pad="0" - image_overlay="Arrow_Right_Off" + <combo_box + height="20" + layout="topleft" + follows="left|top" + top_pad="4" + name="combobox grid mode" + width="108"> + <combo_box.item + label="World grid" + name="World" + value="World" /> + <combo_box.item + label="Local grid" + name="Local" + value="Local" /> + <combo_box.item + label="Reference grid" + name="Reference" + value="Reference" /> + <combo_box.commit_callback + function="BuildTool.gridMode"/> + </combo_box> + <button + left_pad="0" + right="-12" + image_disabled="ForwardArrow_Disabled" + image_selected="ForwardArrow_Press" + image_unselected="ForwardArrow_Off" picture_style="true" label_selected="Options" layout="topleft" name="Options..." - tool_tip="Set the Grid Options" - width="26" - height="22" > + tool_tip="Grid Options" + top_delta="0" + width="18" + height="18" > <button.commit_callback function="BuildTool.gridOptions"/> </button> @@ -328,8 +334,8 @@ follows="left|top" height="20" image_disabled="Object_Cube" - image_disabled_selected="object_cube_active.tga" - image_selected="object_cube_active.tga" + image_disabled_selected="Object_Cube" + image_selected="Object_Cube" image_unselected="Object_Cube" layout="topleft" left="4" @@ -342,8 +348,8 @@ follows="left|top" height="20" image_disabled="Object_Prism" - image_disabled_selected="object_prism_active.tga" - image_selected="object_prism_active.tga" + image_disabled_selected="Object_Prism" + image_selected="Object_Prism" image_unselected="Object_Prism" layout="topleft" left_delta="26" @@ -384,8 +390,8 @@ follows="left|top" height="20" image_disabled="Object_Cylinder" - image_disabled_selected="object_cylinder_active.tga" - image_selected="object_cylinder_active.tga" + image_disabled_selected="Object_Cylinder" + image_selected="Object_Cylinder" image_unselected="Object_Cylinder" layout="topleft" left_delta="26" @@ -398,8 +404,8 @@ follows="left|top" height="20" image_disabled="Object_Hemi_Cylinder" - image_disabled_selected="object_hemi_cylinder_active.tga" - image_selected="object_hemi_cylinder_active.tga" + image_disabled_selected="Object_Hemi_Cylinder" + image_selected="Object_Hemi_Cylinder" image_unselected="Object_Hemi_Cylinder" layout="topleft" left_delta="26" @@ -412,8 +418,8 @@ follows="left|top" height="20" image_disabled="Object_Cone" - image_disabled_selected="object_cone_active.tga" - image_selected="object_cone_active.tga" + image_disabled_selected="Object_Cone" + image_selected="Object_Cone" image_unselected="Object_Cone" layout="topleft" left_delta="26" @@ -426,8 +432,8 @@ follows="left|top" height="20" image_disabled="Object_Hemi_Cone" - image_disabled_selected="object_hemi_cone_active.tga" - image_selected="object_hemi_cone_active.tga" + image_disabled_selected="Object_Hemi_Cone" + image_selected="Object_Hemi_Cone" image_unselected="Object_Hemi_Cone" layout="topleft" left_delta="26" @@ -440,8 +446,8 @@ follows="left|top" height="20" image_disabled="Object_Sphere" - image_disabled_selected="object_sphere_active.tga" - image_selected="object_sphere_active.tga" + image_disabled_selected="Object_Sphere" + image_selected="Object_Sphere" image_unselected="Object_Sphere" layout="topleft" left_delta="26" @@ -454,8 +460,8 @@ follows="left|top" height="20" image_disabled="Object_Hemi_Sphere" - image_disabled_selected="object_hemi_sphere_active.tga" - image_selected="object_hemi_sphere_active.tga" + image_disabled_selected="Object_Hemi_Sphere" + image_selected="Object_Hemi_Sphere" image_unselected="Object_Hemi_Sphere" layout="topleft" left_delta="26" @@ -468,8 +474,8 @@ follows="left|top" height="20" image_disabled="Object_Torus" - image_disabled_selected="object_torus_active.tga" - image_selected="object_torus_active.tga" + image_disabled_selected="Object_Torus" + image_selected="Object_Torus" image_unselected="Object_Torus" layout="topleft" left="4" @@ -482,8 +488,8 @@ follows="left|top" height="20" image_disabled="Object_Tube" - image_disabled_selected="object_tube_active.tga" - image_selected="object_tube_active.tga" + image_disabled_selected="Object_Tube" + image_selected="Object_Tube" image_unselected="Object_Tube" layout="topleft" left_delta="26" @@ -496,8 +502,8 @@ follows="left|top" height="20" image_disabled="Object_Ring" - image_disabled_selected="object_ring_active.tga" - image_selected="object_ring_active.tga" + image_disabled_selected="Object_Ring" + image_selected="Object_Ring" image_unselected="Object_Ring" layout="topleft" left_delta="26" @@ -510,8 +516,8 @@ follows="left|top" height="20" image_disabled="Object_Tree" - image_disabled_selected="object_tree_active.tga" - image_selected="object_tree_active.tga" + image_disabled_selected="Object_Tree" + image_selected="Object_Tree" image_unselected="Object_Tree" layout="topleft" left_delta="26" @@ -524,8 +530,8 @@ follows="left|top" height="20" image_disabled="Object_Grass" - image_disabled_selected="object_grass_active.tga" - image_selected="object_grass_active.tga" + image_disabled_selected="Object_Grass" + image_selected="Object_Grass" image_unselected="Object_Grass" layout="topleft" left_delta="26" @@ -716,25 +722,24 @@ </button> <text type="string" - text_color="LabelSelectedDisabledColor" length="1" - top_pad="4" height="12" follows="left|top" halign="right" layout="topleft" - left="115" + right="-13" name="obj_count" + top_pad="8" width="143"> Objects: [COUNT] </text> <text type="string" - text_color="LabelSelectedDisabledColor" length="1" follows="left|top" halign="right" layout="topleft" + right="-13" name="prim_count" width="143"> Prims: [COUNT] @@ -756,6 +761,7 @@ label="General" layout="topleft" mouse_opaque="false" + help_topic="toolbox_general_tab" name="General" top="16"> <panel.string @@ -827,7 +833,7 @@ name="Object Name" select_on_focus="true" top_delta="0" - width="165" /> + width="170" /> <text type="string" length="1" @@ -849,7 +855,7 @@ name="Object Description" select_on_focus="true" top_delta="0" - width="165" /> + width="170" /> <text type="string" left="10" @@ -884,7 +890,7 @@ width="90"> Owner: </text> -<!--TODO: add person inspector to creator name--> +<!--TODO: add person inspector to owner name--> <text type="string" length="1" @@ -902,41 +908,48 @@ follows="left|top" layout="topleft" left="10" - height="19" + height="18" name="Group:" - width="70"> + top_pad="5" + width="75"> Group: </text> + <button + follows="top|left" + height="10" + image_disabled="Activate_Checkmark" + image_selected="Activate_Checkmark" + image_unselected="Activate_Checkmark" + image_color="White_50" + layout="topleft" + left_pad="0" + top_delta="2" + name="button set group" + picture_style="true" + tab_stop="false" + tool_tip="Choose a group to share this object's permissions" + width="10" /> <name_box follows="left|top" - height="19" + height="18" initial_value="Loading..." layout="topleft" - left_pad="0" + left_pad="4" + top_delta="-1" name="Group Name Proxy" - width="159" /> - <button - follows="left|top" - left_pad="0" - image_overlay="Arrow_Right_Off" - picture_style="true" - layout="topleft" - name="button set group" - tool_tip="Choose a group to share this object's permissions" - width="26" - height="22" /> + width="150" /> <button follows="top|left" font="SansSerifSmall" - height="19" + height="20" label="Deed" label_selected="Deed" layout="topleft" name="button deed" top_pad="0" - left="80" + left="83" tool_tip="Deeding gives this item away with Next Owner permissions. Group shared objects can be deeded by a group officer." - width="90" /> + width="100" /> <check_box height="19" follows="left|top" @@ -944,8 +957,8 @@ layout="topleft" name="checkbox share with group" tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions." - left_pad="5" - width="93" /> + left_pad="3" + width="100" /> <text type="string" length="1" @@ -960,10 +973,10 @@ </text> <combo_box follows="left|top" - height="22" + height="20" layout="topleft" name="clickaction" - width="155" + width="158" left_pad="0"> <combo_box.item label="Touch (default)" @@ -1000,12 +1013,12 @@ layout="topleft" follows="left|top" allow_text_entry="false" - height="22" - width="155" + height="20" + intial_value="2" max_chars="20" mouse_opaque="true" name="sale type" - intial_value="2"> + width="158"> <combo_box.item name="Copy" label="Copy" @@ -1024,21 +1037,23 @@ follows="left|top" decimal_digits="0" increment="1" - top_pad="10" + top_pad="8" + left="100" control_name="Edit Cost" name="Edit Cost" label="Price: L$" - label_width="60" - width="155" + label_width="70" + width="168" min_val="1" - height="19" + height="20" max_val="999999999" /> <check_box - left="107" height="15" width="100" + top_pad="3" label="Show in search" layout="topleft" + left="100" name="search_check" tool_tip="Let people see this object in search results" /> @@ -1090,13 +1105,6 @@ left_pad="0" name="checkbox allow everyone copy" width="90" /> - <check_box - height="19" - label="Use" - layout="topleft" - left_pad="0" - name="allow everyone to use" - width="90" /> <text type="string" follows="left|top" @@ -1133,78 +1141,78 @@ width="90" /> <text type="string" - text_color="EmphasisColor_35" + text_color="EmphasisColor" length="1" top_pad="5" follows="left|top" layout="topleft" - left="18" + left="10" name="B:" height="10" - width="30"> + width="45"> B: </text> <text type="string" - text_color="EmphasisColor_35" + text_color="White" length="1" follows="left|top" layout="topleft" left_pad="0" name="O:" height="10" - width="30"> + width="44"> O: </text> <text type="string" - text_color="EmphasisColor_35" + text_color="EmphasisColor" length="1" follows="left|top" layout="topleft" left_pad="0" name="G:" height="10" - width="30"> + width="43"> G: </text> <text type="string" - text_color="EmphasisColor_35" + text_color="White" length="1" follows="left|top" left_pad="0" layout="topleft" name="E:" height="10" - width="30"> + width="43"> E: </text> <text type="string" - text_color="EmphasisColor_35" + text_color="EmphasisColor" length="1" follows="left|top" layout="topleft" left_pad="0" name="N:" height="10" - width="30"> + width="48"> N: </text> <text type="string" - text_color="EmphasisColor_35" + text_color="White" length="1" follows="left|top" layout="topleft" left_pad="0" name="F:" height="10" - width="30"> + width="50"> F: </text> - </panel> + </panel> </panel> <panel border="false" @@ -1214,6 +1222,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="toolbox_object_tab" name="Object" top="16" width="280"> @@ -2002,6 +2011,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="toolbox_features_tab" name="Features" top_delta="0" width="280"> @@ -2169,18 +2179,18 @@ name="colorswatch" tool_tip="Click to open Color Picker" width="40" /> - <texture_picker - allow_no_texture="true" - top_delta="0" + <texture_picker + allow_no_texture="true" + top_delta="0" can_apply_immediately="true" - default_image_name="Default" - follows="left|top" - height="48" + default_image_name="Default" + follows="left|top" + height="48" label="" - left_delta="57" - mouse_opaque="true" + left_delta="57" + mouse_opaque="true" name="light texture control" - tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)" + tool_tip="Click to choose a projection image (only has effect with deferred rendering enabled)" width="32" /> <spinner follows="left|top" @@ -2239,6 +2249,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="toolbox_texture_tab" name="Texture" top_delta="0" width="280"> @@ -2484,7 +2495,7 @@ name="weave" value="weave" /> </combo_box> - <!-- + <!-- <line_editor bevel_style="in" border_style="line" @@ -2517,7 +2528,7 @@ name="media info set" top_delta="-4" width="120" /> ---> +--> <text type="string" length="1" @@ -2570,16 +2581,16 @@ name="checkbox flip t" top_delta="0" width="70" /> - + <spinner decimal_digits="2" follows="left|top" height="19" increment="1" initial_value="0" - label="Rotation (degrees)" + label="Rotation (degrees)" layout="topleft" - label_width="100" + label_width="100" left="10" max_val="9999" min_val="-9999" @@ -2682,7 +2693,7 @@ name="media_tex" width="100"> Media: - </text> + </text> <line_editor follows="left|top|right" height="18" @@ -2735,7 +2746,7 @@ left_delta="190"> <button.commit_callback function="BuildTool.EditMedia"/> - </button> + </button> </panel> <panel border="false" @@ -2744,6 +2755,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="toolbox_contents_tab" name="Contents" top_delta="0" width="280"> @@ -2822,7 +2834,7 @@ </text> <button follows="left|top" - height="22" + height="20" label="Land profile" label_selected="Land profile" layout="topleft" @@ -2837,17 +2849,18 @@ layout="topleft" left_delta="0" name="checkbox show owners" - tool_tip="Colorize the parcels according to the type of owner" + tool_tip="Colorize the parcels according to the type of owner: Green = Your land Aqua = Your group's land Red = Owned by others Yellow = For sale Purple = For auction Grey = Public" top_pad="8" width="205" /> - <button + <!--TODO: HOOK UP TO HELP VIEWER--> + <!-- <button image_overlay="Arrow_Right_Off" picture_style="true" left_pad="5" name="button show owners help" tool_tip="See an explanation of colors" width="26" - height="22" /> + height="22" />--> <text type="string" length="1" @@ -2863,7 +2876,7 @@ </text> <button follows="left|top" - height="22" + height="20" label="Subdivide" label_selected="Subdivide" layout="topleft" @@ -2873,7 +2886,7 @@ width="112" /> <button follows="left|top" - height="22" + height="20" label="Join" label_selected="Join" layout="topleft" @@ -2896,7 +2909,7 @@ </text> <button follows="left|top" - height="22" + height="20" label="Buy Land" label_selected="Buy Land" layout="topleft" @@ -2906,7 +2919,7 @@ width="112" /> <button follows="left|top" - height="19" + height="20" label="Abandon Land" label_selected="Abandon Land" layout="topleft" @@ -2914,5 +2927,5 @@ name="button abandon land" top_pad="4" width="112" /> - </panel> + </panel> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml index 4ed6787f53..acd770cd38 100644 --- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml @@ -102,7 +102,6 @@ top_delta="0" width="85" /> <button - enabled="false" follows="right|top" height="25" is_toggle="true" @@ -171,6 +170,15 @@ name="export_schema" top_delta="0" width="120" /> + <check_box + follows="left|top" + label="Show Rectangles" + name="show_rectangles" + left_pad="10" + top_delta="0" + height="25" + width="120" /> + <scroll_list bottom="525" column_padding="0" @@ -347,14 +355,22 @@ </panel> <scroll_container follows="top|right|bottom" - height="637" + height="600" layout="topleft" - left_delta="550" + left="750" name="overlap_scroll" reserve_scroll_corner="true" - top_delta="2" + top="20" width="300"> - <panel + <panel + border="true" + name="overlap_dummy_panel" + top="0" + left="0" + width="300" + height="600" + > + <overlap_panel background_opaque="true" background_visible="true" bevel_style="in" @@ -362,14 +378,14 @@ bg_opaque_color="1 1 1 1" border="true" follows="top|right|bottom" - height="637" + height="600" label="Overlap Panel" layout="topleft" - left_delta="0" + left="0" min_width="300" name="overlap_panel" tool_tip="This panel displays the currently-selected element and all of the elements that overlap it, separated by horizontal lines" - top="-607" + top="0" visible="false" width="300" /> <text @@ -380,12 +396,11 @@ height="30" layout="topleft" left="10" - left_delta="10" name="overlap_panel_label" - right="-50" - top="0" + top="10" width="150"> Overlapping Elements: </text> + </panel> </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_water.xml b/indra/newview/skins/default/xui/en/floater_water.xml index febfd1929e..6206ea29c2 100644 --- a/indra/newview/skins/default/xui/en/floater_water.xml +++ b/indra/newview/skins/default/xui/en/floater_water.xml @@ -75,6 +75,7 @@ layout="topleft" left="1" mouse_opaque="false" + help_topic="water_settings_tab" name="Settings" top="60" width="698"> @@ -465,6 +466,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="water_waves_tab" name="Waves" top_delta="44" width="698"> diff --git a/indra/newview/skins/default/xui/en/floater_windlight_options.xml b/indra/newview/skins/default/xui/en/floater_windlight_options.xml index 872bd704d5..2b3bc5f11a 100644 --- a/indra/newview/skins/default/xui/en/floater_windlight_options.xml +++ b/indra/newview/skins/default/xui/en/floater_windlight_options.xml @@ -84,6 +84,7 @@ layout="topleft" left="1" mouse_opaque="false" + help_topic="windlight_atmosphere_tab" name="Atmosphere" top="60" width="698"> @@ -519,6 +520,7 @@ label="Lighting" layout="topleft" left_delta="0" + help_topic="windlight_lighting_tab" name="Lighting" top_delta="4" width="698"> @@ -978,6 +980,7 @@ layout="topleft" left_delta="0" mouse_opaque="false" + help_topic="windlight_clouds_tab" name="Clouds" top_delta="4" width="698"> diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index bd76b10312..8f88366842 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -30,6 +30,7 @@ label="Objects" layout="topleft" left="1" + help_topic="worldmap_objects_tab" name="objects_mapview" top="19" width="540" /> @@ -40,6 +41,7 @@ label="Terrain" layout="topleft" left_delta="0" + help_topic="worldmap_terrain_tab" name="terrain_mapview" top_delta="3" width="540" /> @@ -417,7 +419,8 @@ left_delta="0" name="search_results" top_pad="10" - width="222"> + width="222" + sort_column="1"> <scroll_list.columns label="" name="icon" diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index dec9839d1a..b261281c64 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -150,9 +150,11 @@ comment="Size of large font (points, or 1/72 of an inch)" size="10.0" /> + <!-- Changed Medium size to address menu font size not matching spec. + May want to revert/update after menu font configuration has been enabled. --> <font_size name="Medium" comment="Size of medium font (points, or 1/72 of an inch)" - size="9.0" + size="8.0" /> <font_size name="Small" comment="Size of small font (points, or 1/72 of an inch)" diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml index 1af07c35be..a934e541da 100644 --- a/indra/newview/skins/default/xui/en/inspect_avatar.xml +++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml @@ -148,4 +148,17 @@ right="-10" top="249" width="18" /> + <menu_button + visible="false" + follows="top|left" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + menu_filename="menu_inspect_self_gear.xml" + name="gear_self_btn" + picture_style="true" + right="-10" + top="249" + width="18" /> </floater> diff --git a/indra/newview/skins/default/xui/en/inspect_object.xml b/indra/newview/skins/default/xui/en/inspect_object.xml index 97df28aa30..73a7bef77d 100644 --- a/indra/newview/skins/default/xui/en/inspect_object.xml +++ b/indra/newview/skins/default/xui/en/inspect_object.xml @@ -144,7 +144,7 @@ This is a really long description for an object being as how it is at least 80 c image_disabled="OptionsMenu_Disabled" image_selected="OptionsMenu_Press" image_unselected="OptionsMenu_Off" - menu_filename="menu_inspect_avatar_gear.xml" + menu_filename="menu_inspect_object_gear.xml" name="gear_btn" picture_style="true" right="-10" diff --git a/indra/newview/skins/default/xui/en/menu_bottomtray.xml b/indra/newview/skins/default/xui/en/menu_bottomtray.xml index e98920f8c2..a7abb223ba 100644 --- a/indra/newview/skins/default/xui/en/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/menu_bottomtray.xml @@ -31,7 +31,7 @@ parameter="ShowMoveButton" /> </menu_item_check> <menu_item_check - label="Camera button" + label="View button" layout="topleft" name="ShowCameraButton"> <menu_item_check.on_click @@ -41,4 +41,15 @@ function="CheckControl" parameter="ShowCameraButton" /> </menu_item_check> + <menu_item_check + label="Snapshot button" + layout="topleft" + name="ShowSnapshotButton"> + <menu_item_check.on_click + function="ToggleControl" + parameter="ShowSnapshotButton" /> + <menu_item_check.on_check + function="CheckControl" + parameter="ShowSnapshotButton" /> + </menu_item_check> </menu> diff --git a/indra/newview/skins/default/xui/en/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml index 951cf63c76..be380e11e5 100644 --- a/indra/newview/skins/default/xui/en/menu_favorites.xml +++ b/indra/newview/skins/default/xui/en/menu_favorites.xml @@ -29,7 +29,7 @@ parameter="copy_slurl" /> </menu_item_call> <menu_item_call - label="Show On Map" + label="Show on Map" layout="topleft" name="Show On Map"> <menu_item_call.on_click @@ -55,6 +55,9 @@ <menu_item_call.on_click function="Favorites.DoToSelected" parameter="paste" /> + <menu_item_call.on_enable + function="Favorites.EnableSelected" + parameter="can_paste" /> </menu_item_call> <menu_item_separator diff --git a/indra/newview/skins/default/xui/en/menu_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml index 2029b19c1c..e83d07baec 100644 --- a/indra/newview/skins/default/xui/en/menu_group_plus.xml +++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <menu name="menu_group_plus" left="0" bottom="0" visible="false" - mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true"> + mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false"> <menu_item_call name="item_join" label="Join Group..."> <menu_item_call.on_click function="People.Group.Plus.Action" userdata="join_group" /> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml index 9f5b7f3813..5279f9d141 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml @@ -99,10 +99,11 @@ function="InspectAvatar.VisibleFindOnMap"/>
</menu_item_call>
<menu_item_call
- enabled="false"
label="Zoom In"
layout="topleft"
name="zoom_in">
+ <menu_item_call.on_click
+ function="InspectAvatar.ZoomIn"/>
</menu_item_call>
<menu_item_call
label="Pay"
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml index 1bba8eb264..93c53981f3 100644 --- a/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_inspect_object_gear.xml @@ -105,10 +105,11 @@ function="Object.VisibleMute" /> </menu_item_call> <menu_item_call - enabled="false" label="Zoom In" layout="topleft" name="zoom_in"> + <menu_item_call.on_click + function="InspectObject.ZoomIn" /> </menu_item_call> <menu_item_call label="Remove" diff --git a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml new file mode 100644 index 0000000000..240822e5ca --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?>
+<menu
+ create_jump_keys="true"
+ layout="topleft"
+ mouse_opaque="false"
+ visible="false"
+ name="Gear Menu">
+ <menu_item_call
+ label="Stand Up"
+ layout="topleft"
+ enabled="true"
+ name="stand_up">
+ <menu_item_call.on_click
+ function="Self.StandUp"
+ parameter="" />
+ <menu_item_call.on_visible
+ function="Self.VisibleStandUp" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Appearance"
+ layout="topleft"
+ name="my_appearance">
+ <menu_item_call.on_click
+ function="ShowFloater"
+ parameter="appearance" />
+ <menu_item_call.on_enable
+ function="Edit.EnableCustomizeAvatar" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Profile"
+ layout="topleft"
+ enabled="true"
+ name="my_profile">
+ <menu_item_call.on_click
+ function="ShowAgentProfile"
+ parameter="agent" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Friends"
+ layout="topleft"
+ name="my_friends">
+ <menu_item_call.on_click
+ function="Self.Friends"
+ parameter="" />
+ </menu_item_call>
+ <menu_item_call
+ label="My Groups"
+ layout="topleft"
+ name="my_groups">
+ <menu_item_call.on_click
+ function="Self.Groups" />
+ </menu_item_call>
+</menu>
\ No newline at end of file diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index d3a2b2c66b..8cb0a69906 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -178,7 +178,7 @@ </menu> <menu_item_separator /> <menu_item_call - label="Debug Settings editor" + label="Show Debug Settings" layout="topleft" name="Debug Settings"> <menu_item_call.on_click @@ -239,5 +239,12 @@ function="ShowFloater" parameter="message_critical" /> </menu_item_call> + <menu_item_call + label="Web Browser Test" + name="Web Browser Test"> + <menu_item_call.on_click + function="Advanced.WebBrowserTest" + parameter="http://join.secondlife.com/"/> + </menu_item_call> </menu> </menu_bar> diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml index 6ef1eb9513..3c7b6dad14 100644 --- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <menu name="menu_group_plus" left="0" bottom="0" visible="false" - mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true"> + mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false"> <menu_item_call name="sort_name" label="Sort by Name"> <menu_item_call.on_click function="People.Friends.ViewSort.Action" userdata="sort_name" /> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml index ec8582f5b5..2bec745410 100644 --- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <menu name="menu_group_plus" left="0" bottom="0" visible="false" - mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true"> + mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false"> <menu_item_check label="Display Group Icons" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml index 2b0f029016..f91a961388 100644 --- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <menu name="menu_group_plus" left="0" bottom="0" visible="false" - mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true"> + mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false"> <menu_item_call name="sort_recent" label="Sort by Recent Speakers"> <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="sort_recent" /> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml index d9606de90d..ed03cd467c 100644 --- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml +++ b/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <menu name="menu_group_plus" left="0" bottom="0" visible="false" - mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="true"> + mouse_opaque="false" opaque="true" color="MenuDefaultBgColor" drop_shadow="false"> <menu_item_call name="sort_most" label="Sort by Most Recent"> <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="sort_recent" /> </menu_item_call> diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml new file mode 100644 index 0000000000..6768d7fccb --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<menu + name="Teleport History Gear Context Menu" + left="0" + bottom="0" + visible="false" + mouse_opaque="false" + opaque="true" + color="MenuDefaultBgColor" + drop_shadow="true" > + <menu_item_call + label="Expand all folders" + name="Expand all folders"> + <menu_item_call.on_click + function="TeleportHistory.ExpandAllFolders" /> + </menu_item_call> + <menu_item_call + label="Collapse all folders" + name="Collapse all folders"> + <menu_item_call.on_click + function="TeleportHistory.CollapseAllFolders" /> + </menu_item_call> + <menu_item_separator layout="topleft" /> + <menu_item_call + label="Clear Teleport History" + name="Clear Teleport History"> + <menu_item_call.on_click + function="TeleportHistory.ClearTeleportHistory" /> + </menu_item_call> +</menu> diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml index d9cba27b88..515278c23d 100644 --- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml @@ -23,11 +23,4 @@ <menu_item_call.on_click function="TeleportHistory.Copy" /> </menu_item_call> - <menu_item_call - label="Make Landmark" - layout="topleft" - name="Make Landmark"> - <menu_item_call.on_click - function="TeleportHistory.MakeLandmark" /> - </menu_item_call> </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_url_agent.xml b/indra/newview/skins/default/xui/en/menu_url_agent.xml index 885ebbcd52..fa05dac148 100644 --- a/indra/newview/skins/default/xui/en/menu_url_agent.xml +++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml @@ -12,14 +12,14 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy Name To Clipboard" + label="Copy Name to clipboard" layout="topleft" name="url_copy_label"> <menu_item_call.on_click function="Url.CopyLabel" /> </menu_item_call> <menu_item_call - label="Copy SLurl To Clipboard" + label="Copy SLurl to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_url_group.xml b/indra/newview/skins/default/xui/en/menu_url_group.xml index 68da7a0ced..c5eaf94d22 100644 --- a/indra/newview/skins/default/xui/en/menu_url_group.xml +++ b/indra/newview/skins/default/xui/en/menu_url_group.xml @@ -12,14 +12,14 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy Group To Clipboard" + label="Copy Group to clipboard" layout="topleft" name="url_copy_label"> <menu_item_call.on_click function="Url.CopyLabel" /> </menu_item_call> <menu_item_call - label="Copy SLurl To Clipboard" + label="Copy SLurl to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_url_http.xml b/indra/newview/skins/default/xui/en/menu_url_http.xml index 2503b4a2a3..7a4b1e619b 100644 --- a/indra/newview/skins/default/xui/en/menu_url_http.xml +++ b/indra/newview/skins/default/xui/en/menu_url_http.xml @@ -28,7 +28,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy URL To Clipboard" + label="Copy URL to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_url_objectim.xml b/indra/newview/skins/default/xui/en/menu_url_objectim.xml index d7106da177..6f7e659f48 100644 --- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml +++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml @@ -21,14 +21,14 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy Object Name To Clipboard" + label="Copy Object Name to clipboard" layout="topleft" name="url_copy_label"> <menu_item_call.on_click function="Url.CopyLabel" /> </menu_item_call> <menu_item_call - label="Copy SLurl To Clipboard" + label="Copy SLurl to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_url_parcel.xml b/indra/newview/skins/default/xui/en/menu_url_parcel.xml index cbeb1f8e51..3804f7f780 100644 --- a/indra/newview/skins/default/xui/en/menu_url_parcel.xml +++ b/indra/newview/skins/default/xui/en/menu_url_parcel.xml @@ -12,7 +12,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy SLurl To Clipboard" + label="Copy SLurl to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_url_slapp.xml b/indra/newview/skins/default/xui/en/menu_url_slapp.xml index 3eeef0f47e..6d1060b633 100644 --- a/indra/newview/skins/default/xui/en/menu_url_slapp.xml +++ b/indra/newview/skins/default/xui/en/menu_url_slapp.xml @@ -12,7 +12,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy SLurl To Clipboard" + label="Copy SLurl to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_url_slurl.xml b/indra/newview/skins/default/xui/en/menu_url_slurl.xml index 933f8a4484..58714f1f42 100644 --- a/indra/newview/skins/default/xui/en/menu_url_slurl.xml +++ b/indra/newview/skins/default/xui/en/menu_url_slurl.xml @@ -21,7 +21,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy SLurl To Clipboard" + label="Copy SLurl to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_url_teleport.xml b/indra/newview/skins/default/xui/en/menu_url_teleport.xml index 62c7a2f5a9..ff52d7e109 100644 --- a/indra/newview/skins/default/xui/en/menu_url_teleport.xml +++ b/indra/newview/skins/default/xui/en/menu_url_teleport.xml @@ -3,7 +3,7 @@ layout="topleft" name="Url Popup"> <menu_item_call - label="Teleport To This Location" + label="Teleport to this Location" layout="topleft" name="teleport"> <menu_item_call.on_click @@ -12,7 +12,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Copy SLurl To Clipboard" + label="Copy SLurl to clipboard" layout="topleft" name="url_copy"> <menu_item_call.on_click diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index b0839ce255..93a0b917f9 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -18,23 +18,7 @@ function="Floater.Show" parameter="preferences" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu - label="My Account" - layout="topleft" - name="My Account" - tear_off="true"> - <menu_item_call - label="Account History" - layout="topleft" - name="Account History"> - <menu_item_call.on_click - function="PromptShowURL" - name="AccountHistory_url" - parameter="WebLaunchAccountHistory,http://secondlife.com/account/transactions.php" /> - </menu_item_call> - <menu_item_call + <menu_item_call label="Manage My Account" layout="topleft" name="Manage My Account"> @@ -42,28 +26,7 @@ function="PromptShowURL" name="ManageMyAccount_url" parameter="WebLaunchJoinNow,http://secondlife.com/account/" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="My Land" - layout="topleft" - name="My Land"> - <menu_item_call.on_click - function="ShowFloater" - parameter="land_holdings" /> - </menu_item_call> - <menu_item_call - label="Buy Land" - layout="topleft" - name="Buy Land"> - <menu_item_call.on_click - function="ShowFloater" - parameter="buy land" /> - <menu_item_call.on_enable - function="World.EnableBuyLand" /> - </menu_item_call> - </menu> + </menu_item_call> <menu_item_call label="Buy L$" layout="topleft" @@ -113,15 +76,13 @@ function="ShowFloater" parameter="gestures" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu - label="Status" + label="My Status" layout="topleft" name="Status" tear_off="true"> <menu_item_call - label="Set Away" + label="Away" layout="topleft" name="Set Away"> <menu_item_call.on_click @@ -130,7 +91,7 @@ <menu_item_separator layout="topleft"/> <menu_item_call - label="Set Busy" + label="Busy" layout="topleft" name="Set Busy"> <menu_item_call.on_click @@ -183,7 +144,7 @@ function="World.Chat" /> </menu_item_call--> <menu_item_check - label="Local Chat" + label="Nearby Chat" layout="topleft" name="Nearby Chat" shortcut="control|H"> @@ -246,32 +207,32 @@ layout="topleft" name="World" tear_off="true"> - <menu_item_check - label="Camera Controls" + <menu_item_check + label="Move" layout="topleft" - name="Camera Controls"> + name="Movement Controls"> <menu_item_check.on_check function="Floater.Visible" - parameter="camera" /> + parameter="moveview" /> <menu_item_check.on_click function="Floater.Toggle" - parameter="camera" /> + parameter="moveview" /> </menu_item_check> <menu_item_check - label="Movement Controls" + label="View" layout="topleft" - name="Movement Controls"> + name="Camera Controls"> <menu_item_check.on_check function="Floater.Visible" - parameter="moveview" /> + parameter="camera" /> <menu_item_check.on_click function="Floater.Toggle" - parameter="moveview" /> + parameter="camera" /> </menu_item_check> <menu_item_separator layout="topleft" /> <menu_item_call - label="Place Information" + label="Place Profile" layout="topleft" name="About Land"> <menu_item_call.on_click @@ -286,14 +247,32 @@ function="Floater.Show" parameter="region_info" /> </menu_item_call> + <menu_item_call + label="Buy Land" + layout="topleft" + name="Buy Land"> + <menu_item_call.on_click + function="ShowFloater" + parameter="buy land" /> + <menu_item_call.on_enable + function="World.EnableBuyLand" /> + </menu_item_call> + <menu_item_call + label="My Land" + layout="topleft" + name="My Land"> + <menu_item_call.on_click + function="ShowFloater" + parameter="land_holdings" /> + </menu_item_call> <menu create_jump_keys="true" - label="Land Options" + label="Show" layout="topleft" name="Land" tear_off="true"> <menu_item_check - label="Show Property Lines" + label="Property Lines" layout="topleft" name="Property Lines" shortcut="control|alt|shift|P"> @@ -304,7 +283,7 @@ parameter="ShowPropertyLines" /> </menu_item_check> <menu_item_check - label="Show Land Owners" + label="Land Owners" layout="topleft" name="Land Owners"> <menu_item_check.on_check @@ -314,7 +293,7 @@ parameter="ShowParcelOwners" /> </menu_item_check> <menu_item_check - label="Show Ban Lines" + label="Ban Lines" layout="topleft" name="Ban Lines"> <menu_item_check.on_check @@ -360,19 +339,7 @@ function="World.EnableTeleportHome" /> </menu_item_call> </menu> - <menu_item_check - label="World Map" - layout="topleft" - name="World Map" - shortcut="control|M"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="world_map" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="world_map" /> - </menu_item_check> - <menu_item_check + <menu_item_check label="Mini-Map" layout="topleft" name="Mini-Map" @@ -384,34 +351,45 @@ function="Floater.Toggle" parameter="mini_map" /> </menu_item_check> - <menu_item_separator - layout="topleft" /> - <menu_item_check + <menu_item_check + label="World Map" + layout="topleft" + name="World Map" + shortcut="control|M" + use_mac_ctrl="true"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="world_map" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="world_map" /> + </menu_item_check> + <!-- <menu_item_check label="Show Navigation Bar" layout="topleft" name="ShowNavbarNavigationPanel"> <menu_item_check.on_click function="ToggleControl" - parameter="ShowNavbarNavigationPanel" /> + parameter="ShowNavbarNavigationPanel" /> <menu_item_check.on_check function="CheckControl" parameter="ShowNavbarNavigationPanel" /> - </menu_item_check> - <menu_item_check + </menu_item_check> + <menu_item_check label="Show Favorites Bar" layout="topleft" name="ShowNavbarFavoritesPanel"> <menu_item_check.on_click function="ToggleControl" - parameter="ShowNavbarFavoritesPanel" /> + parameter="ShowNavbarFavoritesPanel" /> <menu_item_check.on_check function="CheckControl" parameter="ShowNavbarFavoritesPanel" /> - </menu_item_check> + </menu_item_check> <menu_item_separator - layout="topleft" /> + layout="topleft" />--> <menu_item_call - label="Take Snapshot" + label="Snapshot" layout="topleft" name="Take Snapshot" shortcut="control|shift|S"> @@ -419,11 +397,9 @@ function="Floater.Show" parameter="snapshot" /> </menu_item_call> - <menu_item_separator - layout="topleft" /> <menu create_jump_keys="true" - label="Sun Settings" + label="Sun" layout="topleft" name="Environment Settings" tear_off="true"> @@ -462,7 +438,7 @@ parameter="midnight" /> </menu_item_call> <menu_item_call - label="Use region settings" + label="Use the Estate Time" layout="topleft" name="Revert to Region Default"> <menu_item_call.on_click @@ -489,7 +465,7 @@ tear_off="true" visible="true"> <menu_item_check - label="Show Build Tools" + label="Build" layout="topleft" name="Show Build Tools" shortcut="control|B"> @@ -825,12 +801,23 @@ function="Tools.EnableToolNotPie" /> </menu_item_check> <menu_item_call - label="Set Default Permissions" + label="Set Default Upload Permissions" layout="topleft" name="perm prefs"> <menu_item_call.on_click function="Floater.Toggle" parameter="perm_prefs" /> + <menu_item_check + label="Show Advanced Permissions" + layout="topleft" + name="DebugPermissions"> + <menu_item_check.on_check + function="CheckControl" + parameter="DebugPermissions" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="DebugPermissions" /> + </menu_item_check> </menu_item_call> <!--menu_item_call label="Show Script Warning/Error Window" @@ -995,6 +982,57 @@ </menu_item_check> </menu> </menu> + <menu + create_jump_keys="true" + label="Select Linked Parts" + layout="topleft" + name="Select Linked Parts" + tear_off="true"> + <menu_item_call + label="Select Next Part" + layout="topleft" + name="Select Next Part" + shortcut="control|."> + <menu_item_call.on_click + function="Tools.SelectNextPart" + parameter="next" /> + <menu_item_call.on_enable + function="Tools.EnableSelectNextPart" /> + </menu_item_call> + <menu_item_call + label="Select Previous Part" + layout="topleft" + name="Select Previous Part" + shortcut="control|,"> + <menu_item_call.on_click + function="Tools.SelectNextPart" + parameter="previous" /> + <menu_item_call.on_enable + function="Tools.EnableSelectNextPart" /> + </menu_item_call> + <menu_item_call + label="Include Next Part" + layout="topleft" + name="Include Next Part" + shortcut="control|shift|."> + <menu_item_call.on_click + function="Tools.SelectNextPart" + parameter="includenext" /> + <menu_item_call.on_enable + function="Tools.EnableSelectNextPart" /> + </menu_item_call> + <menu_item_call + label="Include Previous Part" + layout="topleft" + name="Include Previous Part" + shortcut="control|shift|,"> + <menu_item_call.on_click + function="Tools.SelectNextPart" + parameter="includeprevious" /> + <menu_item_call.on_enable + function="Tools.EnableSelectNextPart" /> + </menu_item_call> + </menu> </menu> <menu label="Help" @@ -1018,19 +1056,10 @@ function="Floater.Show" parameter="hud" /> </menu_item_call> - <menu_item_check - label="Show Quick Tips" - layout="topleft" - name="Show Quick Tips"> - <menu_item_check.on_check - function="Help.CheckShowFirstTimeTip" /> - <menu_item_check.on_click - function="Help.ShowQuickTips" /> - </menu_item_check> <menu_item_separator layout="topleft" /> <menu_item_call - label="Report Abuse..." + label="Report Abuse" layout="topleft" name="Report Abuse"> <menu_item_call.on_click @@ -1054,233 +1083,8 @@ name="Advanced" tear_off="true" visible="false"> - <menu - label="Shortcuts" - layout="topleft" - name="Shortcuts" - tear_off="true" - visible="false"> - <menu_item_check - label="Search" - layout="topleft" - name="Search" - shortcut="control|F"> - <menu_item_check.on_check - function="Floater.Visible" - parameter="search" /> - <menu_item_check.on_click - function="Floater.Toggle" - parameter="search" /> - </menu_item_check> - <menu_item_call - enabled="false" - label="Release Keys" - layout="topleft" - name="Release Keys"> - <menu_item_call.on_click - function="Tools.ReleaseKeys" - parameter="" /> - <menu_item_call.on_enable - function="Tools.EnableReleaseKeys" - parameter="" /> - </menu_item_call> - <menu_item_call - label="Set UI Size to Default" - layout="topleft" - name="Set UI Size to Default"> - <menu_item_call.on_click - function="View.DefaultUISize" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_check - label="Always Run" - layout="topleft" - name="Always Run" - shortcut="control|R"> - <menu_item_check.on_check - function="World.CheckAlwaysRun" /> - <menu_item_check.on_click - function="World.AlwaysRun" /> - </menu_item_check> - <menu_item_check - label="Fly" - layout="topleft" - name="Fly" - shortcut="Home"> - <menu_item_check.on_click - function="Agent.toggleFlying" /> - <menu_item_check.on_enable - function="Agent.enableFlying" /> - </menu_item_check> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Close Window" - layout="topleft" - name="Close Window" - shortcut="control|W"> - <menu_item_call.on_click - function="File.CloseWindow" /> - <menu_item_call.on_enable - function="File.EnableCloseWindow" /> - </menu_item_call> - <menu_item_call - label="Close All Windows" - layout="topleft" - name="Close All Windows" - shortcut="control|shift|W"> - <menu_item_call.on_click - function="File.CloseAllWindows" /> - <menu_item_call.on_enable - function="File.EnableCloseAllWindows" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Snapshot to Disk" - layout="topleft" - name="Snapshot to Disk" - shortcut="control|`" - use_mac_ctrl="true"> - <menu_item_call.on_click - function="File.TakeSnapshotToDisk" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Mouselook" - layout="topleft" - name="Mouselook" - shortcut="M"> - <menu_item_call.on_click - function="View.Mouselook" /> - <menu_item_call.on_enable - function="View.EnableMouselook" /> - </menu_item_call> - <menu_item_check - label="Joystick Flycam" - layout="topleft" - name="Joystick Flycam" - shortcut="alt|shift|F"> - <menu_item_check.on_check - function="View.CheckJoystickFlycam" /> - <menu_item_check.on_click - function="View.JoystickFlycam" /> - <menu_item_check.on_enable - function="View.EnableJoystickFlycam" /> - </menu_item_check> - <menu_item_call - label="Reset View" - layout="topleft" - name="Reset View" - shortcut="Esc"> - <menu_item_call.on_click - function="View.ResetView" /> - </menu_item_call> - <menu_item_call - label="Look at Last Chatter" - layout="topleft" - name="Look at Last Chatter" - shortcut="control|\"> - <menu_item_call.on_click - function="View.LookAtLastChatter" /> - <menu_item_call.on_enable - function="View.EnableLastChatter" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu - create_jump_keys="true" - label="Select Tool" - layout="topleft" - name="Select Tool" - tear_off="true"> - <menu_item_call - label="Focus" - layout="topleft" - name="Focus" - shortcut="control|1"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="focus" /> - </menu_item_call> - <menu_item_call - label="Move" - layout="topleft" - name="Move" - shortcut="control|2"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="move" /> - </menu_item_call> - <menu_item_call - label="Edit" - layout="topleft" - name="Edit" - shortcut="control|3"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="edit" /> - </menu_item_call> - <menu_item_call - label="Create" - layout="topleft" - name="Create" - shortcut="control|4"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="create" /> - </menu_item_call> - <menu_item_call - label="Land" - layout="topleft" - name="Land" - shortcut="control|5"> - <menu_item_call.on_click - function="Tools.SelectTool" - parameter="land" /> - </menu_item_call> - </menu> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Zoom In" - layout="topleft" - name="Zoom In" - shortcut="control|0"> - <menu_item_call.on_click - function="View.ZoomIn" /> - </menu_item_call> - <menu_item_call - label="Zoom Default" - layout="topleft" - name="Zoom Default" - shortcut="control|9"> - <menu_item_call.on_click - function="View.ZoomDefault" /> - </menu_item_call> - <menu_item_call - label="Zoom Out" - layout="topleft" - name="Zoom Out" - shortcut="control|8"> - <menu_item_call.on_click - function="View.ZoomOut" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Toggle Fullscreen" - layout="topleft" - name="Toggle Fullscreen" - shortcut="alt|Enter"> - <menu_item_call.on_click - function="View.Fullscreen" /> - </menu_item_call> - </menu> <menu_item_check - label="Go Away/AFK When Idle" + label="Set Away After 30 Minutes" layout="topleft" name="Go Away/AFK When Idle"> <menu_item_check.on_check @@ -1291,14 +1095,14 @@ parameter="AllowIdleAFK" /> </menu_item_check> <menu_item_call - label="Stop Animating My Avatar" + label="Stop Animating Me" layout="topleft" name="Stop Animating My Avatar"> <menu_item_call.on_click function="Tools.StopAllAnimations" /> </menu_item_call> <menu_item_call - label="Rebake Texture" + label="Rebake Textures" layout="topleft" name="Rebake Texture" shortcut="control|alt|R"> @@ -1363,7 +1167,7 @@ parameter="CompressSnapshotsToDisk" /> </menu_item_check> <menu_item_call - label="Save Texture As..." + label="Save Texture As" layout="topleft" name="Save Texture As"> <menu_item_call.on_click @@ -1399,6 +1203,17 @@ function="Floater.Toggle" parameter="stats" /> </menu_item_check> + <menu_item_check + label="Show Avatar Rendering Cost" + layout="topleft" + name="Avatar Rendering Cost"> + <menu_item_check.on_check + function="Advanced.CheckInfoDisplay" + parameter="shame" /> + <menu_item_check.on_click + function="Advanced.ToggleInfoDisplay" + parameter="shame" /> + </menu_item_check> </menu> <menu create_jump_keys="true" @@ -1407,16 +1222,6 @@ name="Highlighting and Visibility" tear_off="true"> <menu_item_check - label="Highlight Transparent" - layout="topleft" - name="Highlight Transparent" - shortcut="control|alt|T"> - <menu_item_check.on_check - function="View.CheckHighlightTransparent" /> - <menu_item_check.on_click - function="View.HighlightTransparent" /> - </menu_item_check> - <menu_item_check label="Hide Particles" layout="topleft" name="Hide Particles" @@ -1429,16 +1234,6 @@ parameter="hideparticles" /> </menu_item_check> <menu_item_check - label="Show HUD Attachments" - layout="topleft" - name="Show HUD Attachments" - shortcut="alt|shift|H"> - <menu_item_check.on_check - function="View.CheckHUDAttachments" /> - <menu_item_check.on_click - function="View.ShowHUDAttachments" /> - </menu_item_check> - <menu_item_check label="Hide Selected" layout="topleft" name="Hide Selected"> @@ -1450,6 +1245,26 @@ parameter="HideSelectedObjects" /> </menu_item_check> <menu_item_check + label="Highlight Transparent" + layout="topleft" + name="Highlight Transparent" + shortcut="control|alt|T"> + <menu_item_check.on_check + function="View.CheckHighlightTransparent" /> + <menu_item_check.on_click + function="View.HighlightTransparent" /> + </menu_item_check> + <menu_item_check + label="Show HUD Attachments" + layout="topleft" + name="Show HUD Attachments" + shortcut="alt|shift|H"> + <menu_item_check.on_check + function="View.CheckHUDAttachments" /> + <menu_item_check.on_click + function="View.ShowHUDAttachments" /> + </menu_item_check> + <menu_item_check label="Show Mouselook Crosshairs" layout="topleft" name="ShowCrosshairs"> @@ -1460,8 +1275,7 @@ function="ToggleControl" parameter="ShowCrosshairs" /> </menu_item_check> - </menu> - <menu + <!-- <menu create_jump_keys="true" label="Hover Tips" layout="topleft" @@ -1478,9 +1292,9 @@ function="View.ShowHoverTips" /> </menu_item_check> <menu_item_separator - layout="topleft" /> + layout="topleft" />--> <menu_item_check - label="Land Tips" + label="Show Land Tooltips" layout="topleft" name="Land Tips"> <menu_item_check.on_check @@ -1491,8 +1305,8 @@ <menu_item_check.on_enable function="View.CheckShowHoverTips" /> </menu_item_check> - <menu_item_check - label="Tips On All Objects" + <!-- <menu_item_check + label="Show Tips On All Objects" layout="topleft" name="Tips On All Objects"> <menu_item_check.on_check @@ -1503,33 +1317,10 @@ <menu_item_check.on_enable function="View.CheckShowHoverTips" /> </menu_item_check> + </menu>--> + </menu> - <menu_item_separator - layout="topleft" /> - <menu_item_check - label="Run Multiple Threads" - layout="topleft" - name="Run Multiple Threads"> - <menu_item_check.on_check - function="CheckControl" - parameter="RunMultipleThreads" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="RunMultipleThreads" /> - </menu_item_check> - <menu_item_separator - layout="topleft" /> - <menu_item_check - label="Avatar Rendering Cost" - layout="topleft" - name="Avatar Rendering Cost"> - <menu_item_check.on_check - function="Advanced.CheckInfoDisplay" - parameter="shame" /> - <menu_item_check.on_click - function="Advanced.ToggleInfoDisplay" - parameter="shame" /> - </menu_item_check> + <menu create_jump_keys="true" label="Rendering Types" @@ -1573,7 +1364,7 @@ parameter="tree" /> </menu_item_check> <menu_item_check - label="Character" + label="Avatars" layout="topleft" name="Character" shortcut="control|alt|shift|4"> @@ -1796,66 +1587,17 @@ parameter="flexible" /> </menu_item_check> </menu> - <menu_item_separator - layout="topleft" /> - <menu - create_jump_keys="true" - label="Recorder" - layout="topleft" - name="Recorder" - tear_off="true"> - <menu_item_call - label="Start Playback" - layout="topleft" - name="Start Playback"> - <menu_item_call.on_click - function="Advanced.AgentPilot" - parameter="start playback" /> - </menu_item_call> - <menu_item_call - label="Stop Playback" - layout="topleft" - name="Stop Playback"> - <menu_item_call.on_click - function="Advanced.AgentPilot" - parameter="stop playback" /> - </menu_item_call> - <menu_item_check - label="Loop Playback" - layout="topleft" - name="Loop Playback"> - <menu_item_check.on_check - function="Advanced.CheckAgentPilotLoop" - parameter="loopPlayback" /> - <menu_item_check.on_click - function="Advanced.ToggleAgentPilotLoop" /> - </menu_item_check> - <menu_item_call - label="Start Record" - layout="topleft" - name="Start Record"> - <menu_item_call.on_click - function="Advanced.AgentPilot" - parameter="start record" /> - </menu_item_call> - <menu_item_call - label="Stop Record" - layout="topleft" - name="Stop Record"> - <menu_item_call.on_click - function="Advanced.AgentPilot" - parameter="stop record" /> - </menu_item_call> - </menu> - <menu_item_call - label="Dump Scripted Camera" + <menu_item_check + label="Run Multiple Threads" layout="topleft" - name="Dump Scripted Camera"> - <menu_item_call.on_click - function="Advanced.DumpScriptedCamera" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> + name="Run Multiple Threads"> + <menu_item_check.on_check + function="CheckControl" + parameter="RunMultipleThreads" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="RunMultipleThreads" /> + </menu_item_check> <menu_item_call label="Clear Group Cache" layout="topleft" @@ -1863,7 +1605,7 @@ <menu_item_call.on_click function="Advanced.ClearGroupCache" parameter="ClearGroupCache" /> - </menu_item_call> + </menu_item_call> <menu_item_check label="Mouse Smoothing" layout="topleft" @@ -1878,7 +1620,7 @@ <menu_item_separator layout="topleft" /> <menu_item_call - label="Debug Settings editor" + label="Show Debug Settings" layout="topleft" name="Debug Settings"> <menu_item_call.on_click @@ -1886,7 +1628,7 @@ parameter="all" /> </menu_item_call> <menu_item_check - label="Activate Debug Mode (QA)" + label="Show Develop Menu" layout="topleft" name="Debug Mode" shortcut="control|alt|Q"> @@ -1900,9 +1642,9 @@ </menu> <menu create_jump_keys="true" - label="Debug" + label="Develop" layout="topleft" - name="Debug" + name="Develop" tear_off="true" visible="false"> <menu @@ -1915,7 +1657,8 @@ label="Texture Console" layout="topleft" name="Texture Console" - shortcut="control|shift|3"> + shortcut="control|shift|3" + use_mac_ctrl="true"> <menu_item_check.on_check function="Advanced.CheckConsole" parameter="texture" /> @@ -1927,7 +1670,8 @@ label="Debug Console" layout="topleft" name="Debug Console" - shortcut="control|shift|4"> + shortcut="control|shift|4" + use_mac_ctrl="true"> <menu_item_check.on_check function="Advanced.CheckConsole" parameter="debug" /> @@ -1939,7 +1683,8 @@ label="Fast Timers" layout="topleft" name="Fast Timers" - shortcut="control|shift|9"> + shortcut="control|shift|9" + use_mac_ctrl="true"> <menu_item_check.on_check function="Advanced.CheckConsole" parameter="fast timers" /> @@ -1951,7 +1696,8 @@ label="Memory" layout="topleft" name="Memory" - shortcut="control|shift|0"> + shortcut="control|shift|0" + use_mac_ctrl="true"> <menu_item_check.on_check function="Advanced.CheckConsole" parameter="memory view" /> @@ -1963,7 +1709,8 @@ label="Notifications Console" layout="topleft" name="Notifications" - shortcut="control|shift|5"> + shortcut="control|shift|5" + use_mac_ctrl="true"> <menu_item_check.on_check function="Advanced.CheckConsole" parameter="notifications" /> @@ -1997,6 +1744,41 @@ function="Advanced.DumpInfoToConsole" parameter="capabilities" /> </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_check + label="Camera" + layout="topleft" + name="Camera"> + <menu_item_check.on_check + function="Advanced.CheckHUDInfo" + parameter="camera" /> + <menu_item_check.on_click + function="Advanced.ToggleHUDInfo" + parameter="camera" /> + </menu_item_check> + <menu_item_check + label="Wind" + layout="topleft" + name="Wind"> + <menu_item_check.on_check + function="Advanced.CheckHUDInfo" + parameter="wind" /> + <menu_item_check.on_click + function="Advanced.ToggleHUDInfo" + parameter="wind" /> + </menu_item_check> + <menu_item_check + label="FOV" + layout="topleft" + name="FOV"> + <menu_item_check.on_check + function="Advanced.CheckHUDInfo" + parameter="fov" /> + <menu_item_check.on_click + function="Advanced.ToggleHUDInfo" + parameter="fov" /> + </menu_item_check> </menu> <menu create_jump_keys="true" @@ -2051,7 +1833,7 @@ <menu_item_separator layout="topleft" /> <menu_item_check - label="Show Updates to objects" + label="Show Updates to Objects" layout="topleft" name="Show Updates" shortcut="control|alt|shift|U"> @@ -2317,184 +2099,6 @@ parameter="raycast" /> </menu_item_check> </menu> - <menu_item_separator - layout="topleft" /> - <menu - create_jump_keys="true" - label="Network" - layout="topleft" - name="Network" - tear_off="true"> - <menu_item_check - label="Pause Agent" - layout="topleft" - name="AgentPause"> - <menu_item_check.on_check - function="CheckControl" - parameter="AgentPause" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="AgentPause" /> - </menu_item_check> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Enable Message Log" - layout="topleft" - name="Enable Message Log"> - <menu_item_call.on_click - function="Advanced.EnableMessageLog" /> - </menu_item_call> - <menu_item_call - label="Disable Message Log" - layout="topleft" - name="Disable Message Log"> - <menu_item_call.on_click - function="Advanced.DisableMessageLog" /> - </menu_item_call> - <menu_item_separator - layout="topleft" /> - <menu_item_check - label="Velocity Interpolate Objects" - layout="topleft" - name="Velocity Interpolate Objects"> - <menu_item_check.on_check - function="CheckControl" - parameter="VelocityInterpolate" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="VelocityInterpolate" /> - </menu_item_check> - <menu_item_check - label="Ping Interpolate Object Positions" - layout="topleft" - name="Ping Interpolate Object Positions"> - <menu_item_check.on_check - function="CheckControl" - parameter="PingInterpolate" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="PingInterpolate" /> - </menu_item_check> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Drop a Packet" - layout="topleft" - name="Drop a Packet" - shortcut="control|alt|L"> - <menu_item_call.on_click - function="Advanced.DropPacket" /> - </menu_item_call> - </menu> - <menu_item_separator - layout="topleft" /> - <menu_item_call - label="Bumps, Pushes & Hits..." - layout="topleft" - name="Bumps, Pushes &amp; Hits"> - <menu_item_call.on_click - function="Floater.Show" - parameter="bumps" /> - </menu_item_call> - <menu_item_check - label="Output Debug Minidump" - layout="topleft" - name="Output Debug Minidump"> - <menu_item_check.on_check - function="CheckControl" - parameter="SaveMinidump" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="SaveMinidump" /> - </menu_item_check> - <menu_item_check - label="Debug Permissions in Build Tool" - layout="topleft" - name="DebugPermissions"> - <menu_item_check.on_check - function="CheckControl" - parameter="DebugPermissions" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="DebugPermissions" /> - </menu_item_check> - <menu_item_separator - layout="topleft" /> - <menu_item_check - label="View Admin Options" - layout="topleft" - name="View Admin Options"> - <menu_item_check.on_check - function="Advanced.CheckViewAdminOptions" - parameter="ViewAdminOptions" /> - <menu_item_check.on_click - function="Advanced.ToggleViewAdminOptions" /> - </menu_item_check> - <menu_item_call - label="Request Admin Status" - layout="topleft" - name="Request Admin Options" - shortcut="control|alt|G"> - <menu_item_call.on_click - function="Advanced.RequestAdminStatus" /> - </menu_item_call> - <menu_item_call - label="Deactivate Admin Status" - layout="topleft" - name="Leave Admin Options" - shortcut="control|alt|shift|G"> - <menu_item_call.on_click - function="Advanced.LeaveAdminStatus" /> - </menu_item_call> - </menu> - <menu - create_jump_keys="true" - label="Develop" - layout="topleft" - name="Develop" - tear_off="true" - visible="false"> - <menu - create_jump_keys="true" - label="HUD Info" - layout="topleft" - name="HUD Info" - tear_off="true"> - <menu_item_check - label="Camera" - layout="topleft" - name="Camera"> - <menu_item_check.on_check - function="Advanced.CheckHUDInfo" - parameter="camera" /> - <menu_item_check.on_click - function="Advanced.ToggleHUDInfo" - parameter="camera" /> - </menu_item_check> - <menu_item_check - label="Wind" - layout="topleft" - name="Wind"> - <menu_item_check.on_check - function="Advanced.CheckHUDInfo" - parameter="wind" /> - <menu_item_check.on_click - function="Advanced.ToggleHUDInfo" - parameter="wind" /> - </menu_item_check> - <menu_item_check - label="FOV" - layout="topleft" - name="FOV"> - <menu_item_check.on_check - function="Advanced.CheckHUDInfo" - parameter="fov" /> - <menu_item_check.on_click - function="Advanced.ToggleHUDInfo" - parameter="fov" /> - </menu_item_check> - </menu> <menu create_jump_keys="true" label="Rendering" @@ -2587,9 +2191,7 @@ <menu_item_check.on_enable function="Advanced.EnableRenderDeferredGI" /> </menu_item_check> - <menu_item_separator /> - <menu_item_check label="Debug GL" name="Debug GL"> @@ -2679,6 +2281,367 @@ parameter="RenderHighlightEnable" /> </menu_item_check> </menu> + + <menu + create_jump_keys="true" + label="Network" + layout="topleft" + name="Network" + tear_off="true"> + <menu_item_check + label="Pause Agent" + layout="topleft" + name="AgentPause"> + <menu_item_check.on_check + function="CheckControl" + parameter="AgentPause" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="AgentPause" /> + </menu_item_check> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Enable Message Log" + layout="topleft" + name="Enable Message Log"> + <menu_item_call.on_click + function="Advanced.EnableMessageLog" /> + </menu_item_call> + <menu_item_call + label="Disable Message Log" + layout="topleft" + name="Disable Message Log"> + <menu_item_call.on_click + function="Advanced.DisableMessageLog" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_check + label="Velocity Interpolate Objects" + layout="topleft" + name="Velocity Interpolate Objects"> + <menu_item_check.on_check + function="CheckControl" + parameter="VelocityInterpolate" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="VelocityInterpolate" /> + </menu_item_check> + <menu_item_check + label="Ping Interpolate Object Positions" + layout="topleft" + name="Ping Interpolate Object Positions"> + <menu_item_check.on_check + function="CheckControl" + parameter="PingInterpolate" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="PingInterpolate" /> + </menu_item_check> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Drop a Packet" + layout="topleft" + name="Drop a Packet" + shortcut="control|alt|L"> + <menu_item_call.on_click + function="Advanced.DropPacket" /> + </menu_item_call> + </menu> + <menu_item_call + label="Dump Scripted Camera" + layout="topleft" + name="Dump Scripted Camera"> + <menu_item_call.on_click + function="Advanced.DumpScriptedCamera" /> + </menu_item_call> + <menu_item_call + label="Bumps, Pushes & Hits" + layout="topleft" + name="Bumps, Pushes &amp; Hits"> + <menu_item_call.on_click + function="Floater.Show" + parameter="bumps" /> + </menu_item_call> + + <menu + create_jump_keys="true" + label="Recorder" + layout="topleft" + name="Recorder" + tear_off="true"> + <menu_item_call + label="Start Playback" + layout="topleft" + name="Start Playback"> + <menu_item_call.on_click + function="Advanced.AgentPilot" + parameter="start playback" /> + </menu_item_call> + <menu_item_call + label="Stop Playback" + layout="topleft" + name="Stop Playback"> + <menu_item_call.on_click + function="Advanced.AgentPilot" + parameter="stop playback" /> + </menu_item_call> + <menu_item_check + label="Loop Playback" + layout="topleft" + name="Loop Playback"> + <menu_item_check.on_check + function="Advanced.CheckAgentPilotLoop" + parameter="loopPlayback" /> + <menu_item_check.on_click + function="Advanced.ToggleAgentPilotLoop" /> + </menu_item_check> + <menu_item_call + label="Start Record" + layout="topleft" + name="Start Record"> + <menu_item_call.on_click + function="Advanced.AgentPilot" + parameter="start record" /> + </menu_item_call> + <menu_item_call + label="Stop Record" + layout="topleft" + name="Stop Record"> + <menu_item_call.on_click + function="Advanced.AgentPilot" + parameter="stop record" /> + </menu_item_call> + </menu> + <menu + label="Shortcuts" + layout="topleft" + name="Shortcuts" + tear_off="true" + visible="false"> + <menu_item_check + label="Search" + layout="topleft" + name="Search" + shortcut="control|F"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="search" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="search" /> + </menu_item_check> + <menu_item_call + enabled="false" + label="Release Keys" + layout="topleft" + name="Release Keys"> + <menu_item_call.on_click + function="Tools.ReleaseKeys" + parameter="" /> + <menu_item_call.on_enable + function="Tools.EnableReleaseKeys" + parameter="" /> + </menu_item_call> + <menu_item_call + label="Set UI Size to Default" + layout="topleft" + name="Set UI Size to Default"> + <menu_item_call.on_click + function="View.DefaultUISize" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_check + label="Always Run" + layout="topleft" + name="Always Run" + shortcut="control|R"> + <menu_item_check.on_check + function="World.CheckAlwaysRun" /> + <menu_item_check.on_click + function="World.AlwaysRun" /> + </menu_item_check> + <menu_item_check + label="Fly" + layout="topleft" + name="Fly" + shortcut="Home"> + <menu_item_check.on_click + function="Agent.toggleFlying" /> + <menu_item_check.on_enable + function="Agent.enableFlying" /> + </menu_item_check> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Close Window" + layout="topleft" + name="Close Window" + shortcut="control|W"> + <menu_item_call.on_click + function="File.CloseWindow" /> + <menu_item_call.on_enable + function="File.EnableCloseWindow" /> + </menu_item_call> + <menu_item_call + label="Close All Windows" + layout="topleft" + name="Close All Windows" + shortcut="control|shift|W"> + <menu_item_call.on_click + function="File.CloseAllWindows" /> + <menu_item_call.on_enable + function="File.EnableCloseAllWindows" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Snapshot to Disk" + layout="topleft" + name="Snapshot to Disk" + shortcut="control|`" + use_mac_ctrl="true"> + <menu_item_call.on_click + function="File.TakeSnapshotToDisk" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Mouselook" + layout="topleft" + name="Mouselook" + shortcut="M"> + <menu_item_call.on_click + function="View.Mouselook" /> + <menu_item_call.on_enable + function="View.EnableMouselook" /> + </menu_item_call> + <menu_item_check + label="Joystick Flycam" + layout="topleft" + name="Joystick Flycam" + shortcut="alt|shift|F"> + <menu_item_check.on_check + function="View.CheckJoystickFlycam" /> + <menu_item_check.on_click + function="View.JoystickFlycam" /> + <menu_item_check.on_enable + function="View.EnableJoystickFlycam" /> + </menu_item_check> + <menu_item_call + label="Reset View" + layout="topleft" + name="Reset View" + shortcut="Esc"> + <menu_item_call.on_click + function="View.ResetView" /> + </menu_item_call> + <menu_item_call + label="Look at Last Chatter" + layout="topleft" + name="Look at Last Chatter" + shortcut="control|\"> + <menu_item_call.on_click + function="View.LookAtLastChatter" /> + <menu_item_call.on_enable + function="View.EnableLastChatter" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu + create_jump_keys="true" + label="Select Build Tool" + layout="topleft" + name="Select Tool" + tear_off="true"> + <menu_item_call + label="Focus Tool" + layout="topleft" + name="Focus" + shortcut="control|1"> + <menu_item_call.on_click + function="Tools.SelectTool" + parameter="focus" /> + </menu_item_call> + <menu_item_call + label="Move Tool" + layout="topleft" + name="Move" + shortcut="control|2"> + <menu_item_call.on_click + function="Tools.SelectTool" + parameter="move" /> + </menu_item_call> + <menu_item_call + label="Edit Tool" + layout="topleft" + name="Edit" + shortcut="control|3"> + <menu_item_call.on_click + function="Tools.SelectTool" + parameter="edit" /> + </menu_item_call> + <menu_item_call + label="Create Tool" + layout="topleft" + name="Create" + shortcut="control|4"> + <menu_item_call.on_click + function="Tools.SelectTool" + parameter="create" /> + </menu_item_call> + <menu_item_call + label="Land Tool" + layout="topleft" + name="Land" + shortcut="control|5"> + <menu_item_call.on_click + function="Tools.SelectTool" + parameter="land" /> + </menu_item_call> + </menu> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Zoom In" + layout="topleft" + name="Zoom In" + shortcut="control|0"> + <menu_item_call.on_click + function="View.ZoomIn" /> + </menu_item_call> + <menu_item_call + label="Zoom Default" + layout="topleft" + name="Zoom Default" + shortcut="control|9"> + <menu_item_call.on_click + function="View.ZoomDefault" /> + </menu_item_call> + <menu_item_call + label="Zoom Out" + layout="topleft" + name="Zoom Out" + shortcut="control|8"> + <menu_item_call.on_click + function="View.ZoomOut" /> + </menu_item_call> + <menu_item_separator + layout="topleft" /> + <menu_item_call + label="Toggle Fullscreen" + layout="topleft" + name="Toggle Fullscreen" + > + <!-- Note: shortcut="alt|Enter" was deleted from the preceding node--> + <menu_item_call.on_click + function="View.Fullscreen" /> + </menu_item_call> + </menu> + <menu create_jump_keys="true" label="World" @@ -2732,7 +2695,7 @@ layout="topleft" name="UI" tear_off="true"> - <menu_item_check + <!-- <menu_item_check label="New Bottom Bar" layout="topleft" name="New Bottom Bar"> @@ -2742,21 +2705,14 @@ <menu_item_check.on_click function="ToggleControl" parameter="BottomPanelNew" /> - </menu_item_check> + </menu_item_check>--> <menu_item_call label="Web Browser Test" layout="topleft" name="Web Browser Test"> <menu_item_call.on_click - function="Advanced.WebBrowserTest" /> - </menu_item_call> - <menu_item_call - label="UI/Color Settings" - layout="topleft" - name="UI/Color Settings"> - <menu_item_call.on_click - function="Advanced.ShowDebugSettings" - parameter="skin" /> + function="Advanced.WebBrowserTest" + parameter="http://secondlife.com/app/search/slurls.html"/> </menu_item_call> <menu_item_call label="Dump SelectMgr" @@ -2773,6 +2729,12 @@ function="Advanced.DumpInventory" /> </menu_item_call> <menu_item_call + label="Dump Timers" + name="Dump Timers"> + <menu_item_call.on_click + function="Advanced.DumpTimers" /> + </menu_item_call> + <menu_item_call label="Dump Focus Holder" layout="topleft" name="Dump Focus Holder" @@ -2815,8 +2777,8 @@ function="ToggleControl" parameter="DoubleClickAutoPilot" /> </menu_item_check> - <menu_item_separator - layout="topleft" /> + + <menu_item_separator /> <menu_item_check label="Debug SelectMgr" layout="topleft" @@ -2952,7 +2914,7 @@ </menu> <menu create_jump_keys="true" - label="Character" + label="Avatar" layout="topleft" name="Character" tear_off="true"> @@ -3226,7 +3188,18 @@ function="Advanced.CompressImage" /> </menu_item_call> <menu_item_check - label="Console Window" + label="Output Debug Minidump" + layout="topleft" + name="Output Debug Minidump"> + <menu_item_check.on_check + function="CheckControl" + parameter="SaveMinidump" /> + <menu_item_check.on_click + function="ToggleControl" + parameter="SaveMinidump" /> + </menu_item_check> + <menu_item_check + label="Console Window on next Run" layout="topleft" name="Console Window"> <menu_item_check.on_check @@ -3236,6 +3209,34 @@ function="ToggleControl" parameter="ShowConsoleWindow" /> </menu_item_check> + <menu_item_separator + layout="topleft" /> + <menu_item_check + label="Show Admin Menu" + layout="topleft" + name="View Admin Options"> + <menu_item_check.on_check + function="Advanced.CheckViewAdminOptions" + parameter="ViewAdminOptions" /> + <menu_item_check.on_click + function="Advanced.ToggleViewAdminOptions" /> + </menu_item_check> + <menu_item_call + label="Request Admin Status" + layout="topleft" + name="Request Admin Options" + shortcut="control|alt|G"> + <menu_item_call.on_click + function="Advanced.RequestAdminStatus" /> + </menu_item_call> + <menu_item_call + label="Leave Admin Status" + layout="topleft" + name="Leave Admin Options" + shortcut="control|alt|shift|G"> + <menu_item_call.on_click + function="Advanced.LeaveAdminStatus" /> + </menu_item_call> </menu> <menu create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f141a909a8..95dd8677b4 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -485,6 +485,20 @@ You do not have enough L$ to join this group. <notification icon="alertmodal.tga" + name="CreateGroupCost" + type="alertmodal"> +Creating this group will cost L$100. +Groups need more than one member, or they are deleted forever. +Please invite members within 48 hours. + <usetemplate + canceltext="Cancel" + name="okcancelbuttons" + notext="Cancel" + yestext="Create group for L$100"/> + </notification> + + <notification + icon="alertmodal.tga" name="LandBuyPass" type="alertmodal"> For L$[COST] you can enter this land ('[PARCEL_NAME]') for [TIME] hours. Buy a pass? @@ -493,7 +507,7 @@ For L$[COST] you can enter this land ('[PARCEL_NAME]') for [TIME] hour notext="Cancel" yestext="OK"/> </notification> - + <notification icon="alertmodal.tga" name="SalePriceRestriction" @@ -650,7 +664,7 @@ Scripts must be allowed to run for weapons to work. icon="alertmodal.tga" name="MultipleFacesSelected" type="alertmodal"> - Multiple faces are currently selected. +Multiple faces are currently selected. If you continue this action, separate instances of media will be set on multiple faces of the object. To place the media on only one face, choose Select Texture and click on the desired face of that object then click Add. <usetemplate @@ -3468,7 +3482,7 @@ You can click 'Change Preference' to raise your maturity Rating prefer icon="alertmodal.tga" name="TooManyPrimsSelected" type="alertmodal"> - "There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again" +There are too many prims selected. Please select [MAX_PRIM_COUNT] or fewer prims and try again <usetemplate name="okbutton" yestext="OK"/> @@ -3742,7 +3756,7 @@ Default: Disallow label="Disable Scripts" name="HelpRegionDisableScripts" type="alertmodal"> -When sim performance is poor, a script may be to blame. Open the Statistics Bar (Ctrl-Shift-1). Look at the Simulator Physics FPS. +When sim performance is poor, a script may be to blame. Open the Statistics Bar (Ctrl+Shift+1). Look at the Simulator Physics FPS. If it is lower than 45, open the Time panel located at the bottom of the Stats Bar. If Script Time reads 25 ms or higher, click the Get Top Scripts button. You will be given the name and location of scripts that may be causing poor performance. Checking the Disable Scripts box and then pressing the Apply button will temporarily disable all scripts in this region. You may need to do this in order to travel to the location of a noted 'top script'. Once you have arrived at the location, investigate the script to determine if it is causing the problem. You may want to contact the owner of the script or delete or return the object. @@ -3757,7 +3771,7 @@ Default: off name="HelpRegionDisableCollisions" type="alertmodal"> When sim performance is poor, physical objects may be to blame. -Open the Statistics Bar (Ctrl-Shift-1). Look at the Simulator Physics FPS. If it is lower than 45, open the Time panel located at the bottom of the Stats Bar. If Sim Time (Physics) reads 20 ms or higher, click the Get Top Colliders button. +Open the Statistics Bar (Ctrl+Shift+1). Look at the Simulator Physics FPS. If it is lower than 45, open the Time panel located at the bottom of the Stats Bar. If Sim Time (Physics) reads 20 ms or higher, click the Get Top Colliders button. You will be given the name and location of physical objects that may be causing poor performance. Checking the Disable Collisions box and then pressing the Apply button will temporarily disable object-object collisions. You may need to do this in order to travel to the location of a noted 'top collider'. Once you have arrived at the location, investigate the object - is it constantly colliding with other objects? You may want to contact the owner of the object or delete or return the object. @@ -4418,7 +4432,7 @@ Are you sure you want to delete your travel, web, and search history? <usetemplate name="okcancelbuttons" notext="Cancel" - yestext="Yes"/> + yestext="OK"/> </notification> <notification @@ -5014,347 +5028,349 @@ The string [STRING_NAME] is missing from strings.xml icon="notifytip.tga" name="SystemMessageTip" type="notifytip"> - [MESSAGE] +[MESSAGE] </notification> <notification icon="notifytip.tga" name="Cancelled" type="notifytip"> - Cancelled +Cancelled </notification> <notification icon="notifytip.tga" name="CancelledSit" type="notifytip"> - Cancelled Sit +Cancelled Sit </notification> <notification icon="notifytip.tga" name="CancelledAttach" type="notifytip"> - Cancelled Attach +Cancelled Attach </notification> <notification icon="notifytip.tga" name="ReplacedMissingWearable" type="notifytip"> - Replaced missing clothing/body part with default. +Replaced missing clothing/body part with default. </notification> <notification icon="groupnotify" name="GroupNotice" type="groupnotify"> - Topic: [SUBJECT], Message: [MESSAGE] +Topic: [SUBJECT], Message: [MESSAGE] </notification> <notification icon="notifytip.tga" name="FriendOnline" type="notifytip"> - [FIRST] [LAST] is Online +[FIRST] [LAST] is Online </notification> <notification icon="notifytip.tga" name="FriendOffline" type="notifytip"> - [FIRST] [LAST] is Offline +[FIRST] [LAST] is Offline </notification> <notification icon="notifytip.tga" name="AddSelfFriend" type="notifytip"> - Although you're very nice, you can't add yourself as a friend. +Although you're very nice, you can't add yourself as a friend. </notification> <notification icon="notifytip.tga" name="UploadingAuctionSnapshot" type="notifytip"> - Uploading in-world and web site snapshots... - (Takes about 5 minutes.) +Uploading in-world and web site snapshots... +(Takes about 5 minutes.) </notification> <notification icon="notify.tga" name="UploadPayment" type="notify"> - You paid L$[AMOUNT] to upload. +You paid L$[AMOUNT] to upload. </notification> <notification icon="notifytip.tga" name="UploadWebSnapshotDone" type="notifytip"> - Web site snapshot upload done. +Web site snapshot upload done. </notification> <notification icon="notifytip.tga" name="UploadSnapshotDone" type="notifytip"> - In-world snapshot upload done +In-world snapshot upload done </notification> <notification icon="notifytip.tga" name="TerrainDownloaded" type="notifytip"> - Terrain.raw downloaded +Terrain.raw downloaded </notification> <notification icon="notifytip.tga" name="GestureMissing" type="notifytip"> - Hmm. Gesture [NAME] is missing from the database. +Hmm. Gesture [NAME] is missing from the database. </notification> <notification icon="notifytip.tga" name="UnableToLoadGesture" type="notifytip"> - Unable to load gesture [NAME]. - Please try again. +Unable to load gesture [NAME]. +Please try again. </notification> <notification icon="notifytip.tga" name="LandmarkMissing" type="notifytip"> - Landmark is missing from database. +Landmark is missing from database. </notification> <notification icon="notifytip.tga" name="UnableToLoadLandmark" type="notifytip"> - Unable to load landmark. Please try again. +Unable to load landmark. Please try again. </notification> <notification icon="notifytip.tga" name="CapsKeyOn" type="notifytip"> - Your Caps Lock key is on. - This might affect your password. +Your Caps Lock key is on. +This might affect your password. </notification> <notification icon="notifytip.tga" name="NotecardMissing" type="notifytip"> - Notecard is missing from database. +Notecard is missing from database. </notification> <notification icon="notifytip.tga" name="NotecardNoPermissions" type="notifytip"> - You don't have permission to view this notecard. +You don't have permission to view this notecard. </notification> <notification icon="notifytip.tga" name="RezItemNoPermissions" type="notifytip"> - Insufficient permissions to rez object. +Insufficient permissions to rez object. </notification> <notification icon="notifytip.tga" name="UnableToLoadNotecard" type="notifytip"> - Unable to load notecard. - Please try again. +Unable to load notecard. +Please try again. </notification> <notification icon="notifytip.tga" name="ScriptMissing" type="notifytip"> - Script is missing from database. +Script is missing from database. </notification> <notification icon="notifytip.tga" name="ScriptNoPermissions" type="notifytip"> - Insufficient permissions to view script. +Insufficient permissions to view script. </notification> <notification icon="notifytip.tga" name="UnableToLoadScript" type="notifytip"> - Unable to load script. Please try again. +Unable to load script. Please try again. </notification> <notification icon="notifytip.tga" name="IncompleteInventory" type="notifytip"> - The complete contents you are offering are not yet locally available. Please try offering those items again in a minute. +The complete contents you are offering are not yet locally available. Please try offering those items again in a minute. </notification> <notification icon="notifytip.tga" name="CannotModifyProtectedCategories" type="notifytip"> - You cannot modify protected categories. +You cannot modify protected categories. </notification> <notification icon="notifytip.tga" name="CannotRemoveProtectedCategories" type="notifytip"> - You cannot remove protected categories. +You cannot remove protected categories. </notification> <notification icon="notifytip.tga" name="OfferedCard" type="notifytip"> - You have offered a calling card to [FIRST] [LAST] +You have offered a calling card to [FIRST] [LAST] </notification> <notification icon="notifytip.tga" name="UnableToBuyWhileDownloading" type="notifytip"> - Unable to buy while downloading object data. - Please try again. +Unable to buy while downloading object data. +Please try again. </notification> <notification icon="notifytip.tga" name="UnableToLinkWhileDownloading" type="notifytip"> - Unable to link while downloading object data. - Please try again. +Unable to link while downloading object data. +Please try again. </notification> <notification icon="notifytip.tga" name="CannotBuyObjectsFromDifferentOwners" type="notifytip"> - You can only buy objects from one owner at a time. - Please select a single object. +You can only buy objects from one owner at a time. +Please select a single object. </notification> <notification icon="notifytip.tga" name="ObjectNotForSale" type="notifytip"> - This object is not for sale. +This object is not for sale. </notification> <notification icon="notifytip.tga" name="EnteringGodMode" type="notifytip"> - Entering god mode, level [LEVEL] +Entering god mode, level [LEVEL] </notification> <notification icon="notifytip.tga" name="LeavingGodMode" type="notifytip"> - Now leaving god mode, level [LEVEL] +Now leaving god mode, level [LEVEL] </notification> <notification icon="notifytip.tga" name="CopyFailed" type="notifytip"> - You don't have permission to copy this. +You don't have permission to copy this. </notification> <notification icon="notifytip.tga" name="InventoryAccepted" type="notifytip"> - [NAME] accepted your inventory offer. +[NAME] accepted your inventory offer. </notification> <notification icon="notifytip.tga" name="InventoryDeclined" type="notifytip"> - [NAME] declined your inventory offer. +[NAME] declined your inventory offer. </notification> <notification icon="notifytip.tga" name="ObjectMessage" type="notifytip"> - [NAME]: [MESSAGE] +[NAME]: [MESSAGE] </notification> <notification icon="notifytip.tga" name="CallingCardAccepted" type="notifytip"> - Your calling card was accepted. +Your calling card was accepted. </notification> <notification icon="notifytip.tga" name="CallingCardDeclined" type="notifytip"> - Your calling card was declined. +Your calling card was declined. </notification> <notification icon="notifytip.tga" name="TeleportToLandmark" type="notifytip"> - Now that you have reached the mainland, you can teleport to locations like '[NAME]' by clicking on the Inventory button on the bottom right of your screen, and then select the Landmarks folder. - Double click on the landmark and click on Teleport to travel there. +You can teleport to locations like '[NAME]' by opening the Places panel on the right side of your screen, and then select the Landmarks tab. +Click on any landmark to select it, then click 'Teleport' at the bottom of the panel. +(You can also double-click on the landmark, or right-click it and choose 'Teleport'.) </notification> <notification icon="notifytip.tga" name="TeleportToPerson" type="notifytip"> - Now that you have reached the mainland, you can contact residents like '[NAME]' by clicking on the Inventory button on the bottom right of your screen, and then select the Calling Cards folder. - Double click on the card, click on Instant Message, and type a message. +You can contact residents like '[NAME]' by opening the People panel on the right side of your screen. +Select the resident from the list, then click 'IM' at the bottom of the panel. +(You can also double-click on their name in the list, or right-click and choose 'IM'). </notification> <notification icon="notifytip.tga" name="CantSelectLandFromMultipleRegions" type="notifytip"> - Can't select land across server boundaries. - Try selecting a smaller piece of land. +Can't select land across server boundaries. +Try selecting a smaller piece of land. </notification> <notification icon="notifytip.tga" name="SearchWordBanned" type="notifytip"> - Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. +Some terms in your search query were excluded due to content restrictions as clarified in the Community Standards. </notification> <notification icon="notifytip.tga" name="NoContentToSearch" type="notifytip"> - Please select at least one type of content to search (PG, Mature, or Adult). +Please select at least one type of content to search (PG, Mature, or Adult). </notification> <notification icon="notify.tga" name="GroupVote" type="notify"> - [NAME] has proposed to vote on: - [MESSAGE] +[NAME] has proposed to vote on: +[MESSAGE] <form name="form"> <button index="0" @@ -5371,17 +5387,17 @@ The string [STRING_NAME] is missing from strings.xml icon="notify.tga" name="SystemMessage" type="notify"> - [MESSAGE] +[MESSAGE] </notification> <notification icon="notify.tga" name="EventNotification" type="notify"> - Event Notification: +Event Notification: - [NAME] - [DATE] +[NAME] +[DATE] <form name="form"> <button index="0" @@ -5402,9 +5418,9 @@ The string [STRING_NAME] is missing from strings.xml icon="notify.tga" name="TransferObjectsHighlighted" type="notify"> - All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted. +All objects on this parcel that will transfer to the purchaser of this parcel are now highlighted. - * Trees and grasses that will transfer are not highlighted. +* Trees and grasses that will transfer are not highlighted. <form name="form"> <button index="0" @@ -5417,79 +5433,79 @@ The string [STRING_NAME] is missing from strings.xml icon="notify.tga" name="DeactivatedGesturesTrigger" type="notify"> - Deactivated gestures with same trigger: - [NAMES] +Deactivated gestures with same trigger: +[NAMES] </notification> <notification icon="notify.tga" name="NoQuickTime" type="notify"> - Apple's QuickTime software does not appear to be installed on your system. - If you want to view streaming media on parcels that support it you should go to the QuickTime site (http://www.apple.com/quicktime) and install the QuickTime Player. +Apple's QuickTime software does not appear to be installed on your system. +If you want to view streaming media on parcels that support it you should go to the QuickTime site (http://www.apple.com/quicktime) and install the QuickTime Player. </notification> <notification icon="notify.tga" name="NoPlugin" type="notify"> - No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable. +No Media Plugin was found to handle the "[MIME_TYPE]" mime type. Media of this type will be unavailable. </notification> <notification icon="alertmodal.tga" name="MediaPluginFailed" type="alertmodal"> - The following Media Plugin has failed: +The following Media Plugin has failed: [PLUGIN] Please re-install the plugin or contact the vendor if you continue to experience problems. <form name="form"> <ignore name="ignore" - text="When a Media Plugin fails"/> + text="A Media Plugin fails to run"/> </form> </notification> <notification icon="notify.tga" name="OwnedObjectsReturned" type="notify"> - The objects you own on the selected parcel of land have been returned back to your inventory. +The objects you own on the selected parcel of land have been returned back to your inventory. </notification> <notification icon="notify.tga" name="OtherObjectsReturned" type="notify"> - The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory. +The objects on the selected parcel of land that is owned by [FIRST] [LAST] have been returned to his or her inventory. </notification> <notification icon="notify.tga" name="OtherObjectsReturned2" type="notify"> - The objects on the selected parcel of land owned by the resident '[NAME]' have been returned to their owner. +The objects on the selected parcel of land owned by the resident '[NAME]' have been returned to their owner. </notification> <notification icon="notify.tga" name="GroupObjectsReturned" type="notify"> - The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner's inventory. - Transferable deeded objects have been returned to their previous owners. - Non-transferable objects that are deeded to the group have been deleted. +The objects on the selected parcel of land shared with the group [GROUPNAME] have been returned back to their owner's inventory. +Transferable deeded objects have been returned to their previous owners. +Non-transferable objects that are deeded to the group have been deleted. </notification> <notification icon="notify.tga" name="UnOwnedObjectsReturned" type="notify"> - The objects on the selected parcel that are NOT owned by you have been returned to their owners. +The objects on the selected parcel that are NOT owned by you have been returned to their owners. </notification> <notification icon="notify.tga" name="NotSafe" type="notify"> - This land has damage enabled. - You can be hurt here. If you die, you will be teleported to your home location. +This land has damage enabled. +You can be hurt here. If you die, you will be teleported to your home location. <unique/> </notification> @@ -5497,8 +5513,8 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="NoFly" type="notify"> - This area has flying disabled. - You can't fly here. +This area has flying disabled. +You can't fly here. <unique/> </notification> @@ -5506,7 +5522,7 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="PushRestricted" type="notify"> - This area does not allow pushing. You can't push others here unless you own the land. +This area does not allow pushing. You can't push others here unless you own the land. <unique/> </notification> @@ -5514,7 +5530,7 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="NoVoice" type="notify"> - This area has voice chat disabled. You won't be able to hear anyone talking. +This area has voice chat disabled. You won't be able to hear anyone talking. <unique/> </notification> @@ -5522,7 +5538,7 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="NoBuild" type="notify"> - This area has building disabled. You can't build or rez objects here. +This area has building disabled. You can't build or rez objects here. <unique/> </notification> @@ -5530,232 +5546,232 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="ScriptsStopped" type="notify"> - An administrator has temporarily stopped scripts in this region. +An administrator has temporarily stopped scripts in this region. </notification> <notification icon="notify.tga" name="ScriptsNotRunning" type="notify"> - This region is not running any scripts. +This region is not running any scripts. </notification> <notification icon="notify.tga" name="NoOutsideScripts" type="notify"> - This land has outside scripts disabled. +This land has outside scripts disabled. - No scripts will work here except those belonging to the land owner. +No scripts will work here except those belonging to the land owner. </notification> <notification icon="notify.tga" name="ClaimPublicLand" type="notify"> - You can only claim public land in the Region you're in. +You can only claim public land in the Region you're in. </notification> <notification icon="notify.tga" name="RegionTPAccessBlocked" type="notify"> - You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. +You aren't allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer. - Please go to the Knowledge Base for details on accessing areas with this maturity Rating. +Please go to the Knowledge Base for details on accessing areas with this maturity Rating. </notification> <notification icon="notify.tga" name="URBannedFromRegion" type="notify"> - You are banned from the region. +You are banned from the region. </notification> <notification icon="notify.tga" name="NoTeenGridAccess" type="notify"> - Your account cannot connect to this teen grid region. +Your account cannot connect to this teen grid region. </notification> <notification icon="notify.tga" name="NoHelpIslandTP" type="notify"> - You cannot teleport back to Help Island. - Go to 'Help Island Public' to repeat the tutorial. +You cannot teleport back to Help Island. +Go to 'Help Island Public' to repeat the tutorial. </notification> <notification icon="notify.tga" name="ImproperPaymentStatus" type="notify"> - You do not have proper payment status to enter this region. +You do not have proper payment status to enter this region. </notification> <notification icon="notify.tga" name="MustGetAgeRgion" type="notify"> - You must be age-verified to enter this region. +You must be age-verified to enter this region. </notification> <notification icon="notify.tga" name="MustGetAgeParcel" type="notify"> - You must be age-verified to enter this parcel. +You must be age-verified to enter this parcel. </notification> <notification icon="notify.tga" name="NoDestRegion" type="notify"> - No destination region found. +No destination region found. </notification> <notification icon="notify.tga" name="NotAllowedInDest" type="notify"> - You are not allowed into the destination. +You are not allowed into the destination. </notification> <notification icon="notify.tga" name="RegionParcelBan" type="notify"> - Cannot region cross into banned parcel. Try another way. +Cannot region cross into banned parcel. Try another way. </notification> <notification icon="notify.tga" name="TelehubRedirect" type="notify"> - You have been redirected to a telehub. +You have been redirected to a telehub. </notification> <notification icon="notify.tga" name="CouldntTPCloser" type="notify"> - Could not teleport closer to destination. +Could not teleport closer to destination. </notification> <notification icon="notify.tga" name="TPCancelled" type="notify"> - Teleport cancelled. +Teleport cancelled. </notification> <notification icon="notify.tga" name="FullRegionTryAgain" type="notify"> - The region you are attempting to enter is currently full. - Please try again in a few moments. +The region you are attempting to enter is currently full. +Please try again in a few moments. </notification> <notification icon="notify.tga" name="GeneralFailure" type="notify"> - General failure. +General failure. </notification> <notification icon="notify.tga" name="RoutedWrongRegion" type="notify"> - Routed to wrong region. Please try again. +Routed to wrong region. Please try again. </notification> <notification icon="notify.tga" name="NoValidAgentID" type="notify"> - No valid agent id. +No valid agent id. </notification> <notification icon="notify.tga" name="NoValidSession" type="notify"> - No valid session id. +No valid session id. </notification> <notification icon="notify.tga" name="NoValidCircuit" type="notify"> - No valid circuit code. +No valid circuit code. </notification> <notification icon="notify.tga" name="NoValidTimestamp" type="notify"> - No valid timestamp. +No valid timestamp. </notification> <notification icon="notify.tga" name="NoPendingConnection" type="notify"> - Unable to create pending connection. +Unable to create pending connection. </notification> <notification icon="notify.tga" name="InternalUsherError" type="notify"> - Internal error attempting to connect agent usher. +Internal error attempting to connect agent usher. </notification> <notification icon="notify.tga" name="NoGoodTPDestination" type="notify"> - Unable to find a good teleport destination in this region. +Unable to find a good teleport destination in this region. </notification> <notification icon="notify.tga" name="InternalErrorRegionResolver" type="notify"> - Internal error attempting to activate region resolver. +Internal error attempting to activate region resolver. </notification> <notification icon="notify.tga" name="NoValidLanding" type="notify"> - A valid landing point could not be found. +A valid landing point could not be found. </notification> <notification icon="notify.tga" name="NoValidParcel" type="notify"> - No valid parcel could be found. +No valid parcel could be found. </notification> <notification icon="notify.tga" name="ObjectGiveItem" type="notify"> - An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECTTYPE] named [OBJECTNAME]. +An object named [OBJECTFROMNAME] owned by [FIRST] [LAST] has given you a [OBJECTTYPE] named [OBJECTNAME]. <form name="form"> <button index="0" name="Keep" - text="Keep"/> + text="OK"/> <button index="1" name="Discard" - text="Discard"/> + text="Cancel"/> <button index="2" name="Mute" @@ -5767,16 +5783,16 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="ObjectGiveItemUnknownUser" type="notify"> - An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a [OBJECTTYPE] named [OBJECTNAME]. +An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you a [OBJECTTYPE] named [OBJECTNAME]. <form name="form"> <button index="0" name="Keep" - text="Keep"/> + text="OK"/> <button index="1" name="Discard" - text="Discard"/> + text="Cancel"/> <button index="2" name="Mute" @@ -5788,16 +5804,16 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="UserGiveItem" type="notify"> - [NAME] has given you a [OBJECTTYPE] named '[OBJECTNAME]'. +[NAME] has given you a [OBJECTTYPE] named '[OBJECTNAME]'. <form name="form"> <button index="0" name="Keep" - text="Keep"/> + text="OK"/> <button index="1" name="Discard" - text="Discard"/> + text="Cancel"/> <button index="2" name="Mute" @@ -5809,15 +5825,15 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="GodMessage" type="notify"> - [NAME] - [MESSAGE] +[NAME] +[MESSAGE] </notification> <notification icon="notify.tga" name="JoinGroup" type="notify"> - [MESSAGE] +[MESSAGE] <form name="form"> <button index="0" @@ -5838,9 +5854,9 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="TeleportOffered" type="notify"> - [NAME] has offered to teleport you to their location: +[NAME] has offered to teleport you to their location: - [MESSAGE] +[MESSAGE] <form name="form"> <button index="0" @@ -5857,8 +5873,8 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="GotoURL" type="notify"> - [MESSAGE] - [URL] +[MESSAGE] +[URL] <form name="form"> <button index="0" @@ -5875,11 +5891,11 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="OfferFriendship" type="notify"> - [NAME] is offering friendship. +[NAME] is offering friendship. - [MESSAGE] +[MESSAGE] - (By default, you will be able to see each other's online status.) +(By default, you will be able to see each other's online status.) <form name="form"> <button index="0" @@ -5896,9 +5912,9 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="OfferFriendshipNoMessage" type="notify"> - [NAME] is offering friendship. +[NAME] is offering friendship. - (By default, you will be able to see each other's online status.) +(By default, you will be able to see each other's online status.) <form name="form"> <button index="0" @@ -5915,22 +5931,22 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="FriendshipAccepted" type="notify"> - [NAME] accepted your friendship offer. +[NAME] accepted your friendship offer. </notification> <notification icon="notify.tga" name="FriendshipDeclined" type="notify"> - [NAME] declined your friendship offer. +[NAME] declined your friendship offer. </notification> <notification icon="notify.tga" name="OfferCallingCard" type="notify"> - [FIRST] [LAST] is offering their calling card. - This will add a bookmark in your inventory so you can quickly IM this resident. +[FIRST] [LAST] is offering their calling card. +This will add a bookmark in your inventory so you can quickly IM this resident. <form name="form"> <button index="0" @@ -5949,8 +5965,8 @@ Please re-install the plugin or contact the vendor if you continue to experience priority="high" sound="UISndAlert" type="notify"> - This region will restart in [MINUTES] minutes. - If you stay in this region you will be logged out. +This region will restart in [MINUTES] minutes. +If you stay in this region you will be logged out. </notification> <notification @@ -5959,19 +5975,19 @@ Please re-install the plugin or contact the vendor if you continue to experience priority="high" sound="UISndAlert" type="notify"> - This region will restart in [SECONDS] seconds. - If you stay in this region you will be logged out. +This region will restart in [SECONDS] seconds. +If you stay in this region you will be logged out. </notification> <notification icon="notify.tga" name="LoadWebPage" type="notify"> - Load web page [URL]? +Load web page [URL]? - [MESSAGE] +[MESSAGE] - From object: [OBJECTNAME], owner: [NAME]? +From object: [OBJECTNAME], owner: [NAME]? <form name="form"> <button index="0" @@ -5988,31 +6004,31 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="FailedToFindWearableUnnamed" type="notify"> - Failed to find [TYPE] in database. +Failed to find [TYPE] in database. </notification> <notification icon="notify.tga" name="FailedToFindWearable" type="notify"> - Failed to find [TYPE] named [DESC] in database. +Failed to find [TYPE] named [DESC] in database. </notification> <notification icon="notify.tga" name="InvalidWearable" type="notify"> - The item you are trying to wear uses a feature that your Viewer can't read. Please upgrade your version of [APP_NAME] to wear this item. +The item you are trying to wear uses a feature that your Viewer can't read. Please upgrade your version of [APP_NAME] to wear this item. </notification> <notification icon="notify.tga" name="ScriptQuestion" type="notify"> - '[OBJECTNAME]', an object owned by '[NAME]', would like to: +'[OBJECTNAME]', an object owned by '[NAME]', would like to: - [QUESTIONS] - Is this OK? +[QUESTIONS] +Is this OK? <form name="form"> <button index="0" @@ -6034,12 +6050,12 @@ Please re-install the plugin or contact the vendor if you continue to experience name="ScriptQuestionCaution" priority="high" type="notify"> - An object named '[OBJECTNAME]', owned by '[NAME]' would like to: +An object named '[OBJECTNAME]', owned by '[NAME]' would like to: - [QUESTIONS] - If you do not trust this object and its creator, you should deny the request. +[QUESTIONS] +If you do not trust this object and its creator, you should deny the request. - Grant this request? +Grant this request? <form name="form"> <button index="0" @@ -6061,8 +6077,8 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="ScriptDialog" type="notify"> - [FIRST] [LAST]'s '[TITLE]' - [MESSAGE] +[FIRST] [LAST]'s '[TITLE]' +[MESSAGE] <form name="form"> <button index="-1" @@ -6075,8 +6091,8 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="ScriptDialogGroup" type="notify"> - [GROUPNAME]'s '[TITLE]' - [MESSAGE] +[GROUPNAME]'s '[TITLE]' +[MESSAGE] <form name="form"> <button index="-1" @@ -6089,41 +6105,41 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="FirstBalanceIncrease" type="notify"> - You just received L$[AMOUNT]. - Your L$ balance is shown in the upper-right. +You just received L$[AMOUNT]. +Your L$ balance is shown in the upper-right. </notification> <notification icon="notify.tga" name="FirstBalanceDecrease" type="notify"> - You just paid L$[AMOUNT]. - Your L$ balance is shown in the upper-right. +You just paid L$[AMOUNT]. +Your L$ balance is shown in the upper-right. </notification> <notification icon="notify.tga" name="FirstSit" type="notify"> - You are sitting. - Use your arrow keys (or AWSD) to look around. - Click the 'Stand Up' button to stand. +You are sitting. +Use your arrow keys (or AWSD) to look around. +Click the 'Stand Up' button to stand. </notification> <notification icon="notify.tga" name="FirstMap" type="notify"> - Click and drag the map to look around. - Double-click to teleport. - Use the controls on the right to find things and display different backgrounds. +Click and drag the map to look around. +Double-click to teleport. +Use the controls on the right to find things and display different backgrounds. </notification> <notification icon="notify.tga" name="FirstBuild" type="notify"> - You have opened the Build Tools. Every object you see around you was created using these tools. +You have opened the Build Tools. Every object you see around you was created using these tools. </notification> <!-- @@ -6140,24 +6156,24 @@ Please re-install the plugin or contact the vendor if you continue to experience icon="notify.tga" name="FirstTeleport" type="notify"> - You can only teleport to certain areas in this region. The arrow points to your specific destination. Click the arrow to dismiss it. +You can only teleport to certain areas in this region. The arrow points to your specific destination. Click the arrow to dismiss it. </notification> <notification icon="notify.tga" name="FirstOverrideKeys" type="notify"> - Your movement keys are now being handled by an object. - Try the arrow keys or AWSD to see what they do. - Some objects (like guns) require you to go into mouselook to use them. - Press 'M' to do this. +Your movement keys are now being handled by an object. +Try the arrow keys or AWSD to see what they do. +Some objects (like guns) require you to go into mouselook to use them. +Press 'M' to do this. </notification> <notification icon="notify.tga" name="FirstAppearance" type="notify"> - You are editing your Appearance. +You are editing your Appearance. Use the arrow keys to look around. When you are done, press 'Save All'. </notification> @@ -6166,38 +6182,38 @@ When you are done, press 'Save All'. icon="notify.tga" name="FirstInventory" type="notify"> - This is your Inventory, which contains items you own. +This is your Inventory, which contains items you own. - * To wear something, drag it onto yourself. - * To rez something inworld, drag it onto the ground. - * To read a notecard, double-click it. +* To wear something, drag it onto yourself. +* To rez something inworld, drag it onto the ground. +* To read a notecard, double-click it. </notification> <notification icon="notify.tga" name="FirstSandbox" type="notify"> - This is a sandbox area, and is meant to help Residents learn how to build. +This is a sandbox area, and is meant to help Residents learn how to build. - Things you build here will be deleted after you leave, so don't forget to right-click and choose 'Take' to move your creation to your Inventory. +Things you build here will be deleted after you leave, so don't forget to right-click and choose 'Take' to move your creation to your Inventory. </notification> <notification icon="notify.tga" name="FirstFlexible" type="notify"> - This object is flexible. Flexis must be phantom and not physical. +This object is flexible. Flexis must be phantom and not physical. </notification> <notification icon="notify.tga" name="FirstDebugMenus" type="notify"> - You opened the Advanced menu. +You opened the Advanced menu. - To toggle this menu, - Windows: Ctrl-Alt-D - Mac: ⌘-Opt-D +To toggle this menu, + Windows: Ctrl+Alt+D + Mac: ⌥⌘D </notification> @@ -6205,7 +6221,7 @@ When you are done, press 'Save All'. icon="notify.tga" name="FirstSculptedPrim" type="notify"> - You are editing a Sculpted prim. Sculpties require a special texture to define their shape. +You are editing a Sculpted prim. Sculpties require a special texture to define their shape. </notification> <!--notification @@ -6219,7 +6235,7 @@ When you are done, press 'Save All'. icon="notifytip.tga" name="MaxListSelectMessage" type="notifytip"> - You may only select up to [MAX_SELECT] items from this list. +You may only select up to [MAX_SELECT] items from this list. </notification> <notification @@ -6348,7 +6364,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="VoiceChannelFull" type="notifytip"> - The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later. +The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6358,7 +6374,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="ProximalVoiceChannelFull" type="notifytip"> - We're sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area. +We're sorry. This area has reached maximum capacity for voice conversations. Please try to use voice in another area. <unique/> </notification> @@ -6366,7 +6382,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="VoiceChannelDisconnected" type="notifytip"> - You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to spatial voice chat. +You have been disconnected from [VOICE_CHANNEL_NAME]. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6376,7 +6392,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="VoiceChannelDisconnectedP2P" type="notifytip"> - [VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to spatial voice chat. +[VOICE_CHANNEL_NAME] has ended the call. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6386,7 +6402,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="P2PCallDeclined" type="notifytip"> - [VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to spatial voice chat. +[VOICE_CHANNEL_NAME] has declined your call. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6396,7 +6412,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="P2PCallNoAnswer" type="notifytip"> - [VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to spatial voice chat. +[VOICE_CHANNEL_NAME] is not available to take your call. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6406,7 +6422,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="VoiceChannelJoinFailed" type="notifytip"> - Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to spatial voice chat. +Failed to connect to [VOICE_CHANNEL_NAME], please try again later. You will now be reconnected to spatial voice chat. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6417,7 +6433,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="VoiceLoginRetry" type="notifytip"> - We are creating a voice channel for you. This may take up to one minute. +We are creating a voice channel for you. This may take up to one minute. <unique/> </notification> @@ -6425,28 +6441,28 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="Cannot enter parcel: not a group member" type="notifytip"> - Only members of a certain group can visit this area. +Only members of a certain group can visit this area. </notification> <notification icon="notifytip.tga" name="Cannot enter parcel: banned" type="notifytip"> - Cannot enter parcel, you have been banned. +Cannot enter parcel, you have been banned. </notification> <notification icon="notifytip.tga" name="Cannot enter parcel: not on access list" type="notifytip"> - Cannot enter parcel, you are not on the access list. +Cannot enter parcel, you are not on the access list. </notification> <notification icon="notifytip.tga" name="VoiceNotAllowed" type="notifytip"> - You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. +You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME]. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6456,7 +6472,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block icon="notifytip.tga" name="VoiceCallGenericError" type="notifytip"> - An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later. +An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME]. Please try again later. <unique> <context key="VOICE_CHANNEL_NAME"/> </unique> @@ -6468,7 +6484,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block name="ServerVersionChanged" priority="high" type="notifytip"> - You just entered a region using a different server version, which may affect performance. Click to see the release notes. +You just entered a region using a different server version, which may affect performance. Click to see the release notes. </notification> <notification @@ -6476,33 +6492,19 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block name="UnsupportedCommandSLURL" priority="high" type="notifytip"> - The SLurl you clicked on is not supported. +The SLurl you clicked on is not supported. </notification> <notification name="IMToast" type="notifytoast"> - [MESSAGE] +[MESSAGE] <form name="form"> <button index="0" name="respondbutton" text="Respond"/> </form> </notification> - - <notification - icon="alertmodal.tga" - name="CreateGroupCost" - type="alertmodal"> - Creating this group will cost L$100. - Groups need more than one member, or they are deleted forever. - Please invite members within 48 hours. - <usetemplate - canceltext="Cancel" - name="okcancelbuttons" - notext="Cancel" - yestext="Create group for L$100"/> - </notification> <notification icon="notifytip.tga" name="AttachmentSaved" type="notifytip"> - Attachment has been saved. +Attachment has been saved. </notification> <notification @@ -6523,6 +6525,17 @@ Server Error: Media update or get failed. yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="ConfirmClearTeleportHistory" + type="alertmodal"> +Are you sure you want to delete your teleport history? + <usetemplate + name="okcancelbuttons" + notext="Cancel" + yestext="OK"/> + </notification> + <global name="UnsupportedCPU"> - Your CPU speed does not meet the minimum requirements. </global> diff --git a/indra/newview/skins/default/xui/en/panel_audio_device.xml b/indra/newview/skins/default/xui/en/panel_audio_device.xml index 4329982209..546f46205f 100644 --- a/indra/newview/skins/default/xui/en/panel_audio_device.xml +++ b/indra/newview/skins/default/xui/en/panel_audio_device.xml @@ -81,7 +81,6 @@ enabled="false" height="60" border_visible="false" - hide_scrollbar="true" layout="topleft" left_delta="10" max_length="65535" diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index c3ae2d953a..f7f08b9b6a 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -47,7 +47,7 @@ top="4" use_ellipses="true" value="Unknown" - width="180" /> + width="162" /> <text follows="right" font="SansSerif" @@ -85,4 +85,19 @@ picture_style="true" top="2" width="18" /> + <button + follows="right" + font="SansSerifBigBold" + height="18" + image_disabled="profile_chevron_btn.tga" + image_disabled_selected="profile_chevron_btn.tga" + image_hover_selected="profile_chevron_btn_active.tga" + image_selected="profile_chevron_btn_active.tga" + image_unselected="profile_chevron_btn.tga" + layout="topleft" + left_pad="2" + name="profile_btn" + picture_style="true" + top="2" + width="18" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml index 34b4736979..e4f6e7bd44 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_tag.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_tag.xml @@ -61,7 +61,6 @@ font="SansSerifSmall" read_only="true" bg_readonly_color="0 0 0 0" - hide_scrollbar="true" word_wrap="true" mouse_opaque="true" name="msg_text" > diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index cd7e340ff1..b4847368b2 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -83,7 +83,7 @@ top="6" width="70"> <button.init_callback - function="Button.SetFloaterToggle" + function="Button.SetDockableFloaterToggle" parameter="moveview" /> </button> </layout_panel> @@ -105,10 +105,10 @@ height="28" layout="topleft" min_height="28" - min_width="150" + min_width="100" name="cam_panel" top_delta="-10" - width="150"> + width="100"> <button follows="right" height="20" @@ -121,7 +121,7 @@ name="camera_btn" width="70"> <button.init_callback - function="Button.SetFloaterToggle" + function="Button.SetDockableFloaterToggle" parameter="camera" /> </button> <button @@ -136,15 +136,28 @@ image_selected="toggle_button_selected" image_unselected="toggle_button_off"> <button.init_callback - function="Button.SetFloaterToggle" + function="Button.SetDockableFloaterToggle" parameter="camera_presets" /> </button> + </layout_panel> + <layout_panel + mouse_opaque="false" + auto_resize="false" + follows="right" + height="28" + layout="topleft" + min_height="28" + min_width="35" + name="snapshot_panel" + top_delta="-10" + width="35"> <split_button arrow_position="right" follows="right" height="18" - left_pad="4" + left="0" + layout="topleft" name="snapshots" top="6" width="35"> @@ -160,19 +173,8 @@ image_unselected="camera_presets/camera_presets_snapshot.png" name="snapshot" tool_tip="Take Snapshot" /> - </split_button> + </split_button> </layout_panel> - <icon - auto_resize="false" - color="0 0 0 0" - follows="left|right" - height="10" - image_name="spacer24.tga" - layout="topleft" - left="0" - name="DUMMY" - top="0" - width="5"/> <layout_panel mouse_opaque="false" follows="left|right" diff --git a/indra/newview/skins/default/xui/en/panel_chat_item.xml b/indra/newview/skins/default/xui/en/panel_chat_item.xml index 713c3a41a2..78f53562cd 100644 --- a/indra/newview/skins/default/xui/en/panel_chat_item.xml +++ b/indra/newview/skins/default/xui/en/panel_chat_item.xml @@ -16,7 +16,7 @@ /> <text width="130" top="25" left="40" height="20" follows="left|right|top" - font="SansSerifBigBold" text_color="white" word_wrap="true" + font="SansSerifBigBold" text_color="white" word_wrap="false" use_ellipses="true" mouse_opaque="true" name="sender_name" > Jerry Knight </text> diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index 5dd03656c6..453e1319a6 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -2,13 +2,13 @@ <panel background_visible="true" bevel_style="in" - height="420" + height="570" label="Edit Pick" layout="topleft" left="0" name="panel_edit_pick" top="0" - width="255"> + width="333"> <text type="string" length="1" @@ -36,34 +36,26 @@ <scroll_container color="DkGray2" follows="left|top|right|bottom" - height="300" + height="470" layout="topleft" - left="0" + left="10" + top_pad="10" name="profile_scroll" reserve_scroll_corner="true" opaque="true" - width="255"> + width="313"> <panel name="scroll_content_panel" follows="left|top|right" layout="topleft" top="0" left="0" - width="240" - height="575"> - <panel - background_visible="true" - bg_alpha_color="DkGray2" - width="220" - follows="left|right|top|bottom" - height="560" - layout="topleft" - left="0" - top="0"> + width="298" + height="555"> <texture_picker follows="left|top|right" - height="190" - width="220" + height="197" + width="280" layout="topleft" top="20" left="10" @@ -101,7 +93,7 @@ max_length="63" name="pick_name" text_color="black" - width="220" /> + width="280" /> <text type="string" length="1" @@ -119,8 +111,8 @@ <text_editor follows="left|top|right" height="100" - width="220" - hide_scrollbar="true" + width="280" + hide_scrollbar="false" layout="topleft" left="10" top_pad="2" @@ -153,7 +145,7 @@ right="-10" top_pad="2" text_color="white" - width="250" + width="280" word_wrap="true"> loading... </text> @@ -166,7 +158,6 @@ name="set_to_curr_location_btn" width="200" /> </panel> - </panel> </scroll_container> <panel follows="left|right|bottom" diff --git a/indra/newview/skins/default/xui/en/panel_edit_profile.xml b/indra/newview/skins/default/xui/en/panel_edit_profile.xml index b13058f40a..0202323dcf 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_profile.xml @@ -14,7 +14,8 @@ width="255"> <string name="CaptionTextAcctInfo"> - [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION] + [ACCTTYPE] +[PAYMENTINFO] [AGEVERIFICATION] </string> <string name="AcctTypeResident" @@ -138,6 +139,7 @@ layout="topleft" left="120" top="30" + max_length="511" name="sl_description_edit" width="115" word_wrap="true"> @@ -193,6 +195,7 @@ layout="topleft" left="120" top="195" + max_length="254" name="fl_description_edit" width="115" word_wrap="true"> @@ -294,7 +297,7 @@ width="100"/> <text follows="left|top|right" - height="15" + height="20" layout="topleft" left="10" name="acc_status_text" diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml index a9363df259..be38492c82 100644 --- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml +++ b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml @@ -1,31 +1,27 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="panel_im_control_panel" - width="96" - height="215" - border="false"> - <avatar_list - width="90" - column_padding="0" - draw_heading="true" - draw_stripes="false" - follows="left|top|bottom|right" - layout="topleft" - left="3" - name="speakers_list" - search_column="1" - sort_column="2" - top="10" - height="150" /> - - <button name="group_info_btn" - label="Group Info" - left_delta="3" - width="90" - height="20" /> - - <button name="call_btn" - label="Call" - width="90" - height="20" /> - +<panel + name="panel_im_control_panel" + width="146" + height="215" + border="false"> + <avatar_list_tmp + color="DkGray2" + follows="left|top|right|bottom" + height="150" + layout="topleft" + left="3" + name="speakers_list" + top="10" + width="140"/> + <button + name="group_info_btn" + label="Group Info" + left_delta="3" + width="90" + height="20" /> + <button + name="call_btn" + label="Call" + width="90" + height="20" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml index 03e2d35b9f..6f01202680 100644 --- a/indra/newview/skins/default/xui/en/panel_group_general.xml +++ b/indra/newview/skins/default/xui/en/panel_group_general.xml @@ -12,9 +12,7 @@ width="280"> <panel.string name="help_text"> - The General tab contains general information about -this group, a list of Owners and visible Members, -general Group Preferences and member options. + The General tab contains general information about this group, a list of members, general Group Preferences and member options. Hover your mouse over the options for more help. </panel.string> @@ -45,7 +43,6 @@ Hover your mouse over the options for more help. follows="left|top" left="5" height="75" - hide_scrollbar="true" layout="topleft" max_length="511" name="charter" @@ -114,7 +111,7 @@ Hover your mouse over the options for more help. layout="topleft" left_delta="0" name="active_title" - tool_tip="Sets the title that appears in your avatar's name tag when this group is active." + tool_tip="Sets the title that appears in your avatar's name tag when this group is active." top_pad="0" width="240" /> <check_box @@ -124,7 +121,7 @@ Hover your mouse over the options for more help. layout="topleft" left_delta="0" name="receive_notices" - tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you." + tool_tip="Sets whether you want to receive Notices from this group. Uncheck this box if this group is spamming you." top_pad="5" width="240" /> <check_box @@ -180,7 +177,7 @@ Hover your mouse over the options for more help. max_val="99999" top_pad="5" name="spin_enrollment_fee" - tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked." + tool_tip="New members must pay this fee to join the group when Enrollment Fee is checked." top_delta="-2" width="75" /> <check_box @@ -202,7 +199,7 @@ Hover your mouse over the options for more help. top_pad="10" width="240"> <combo_box.item - label="Select Mature -" + label="- Select Mature -" name="select_mature" value="Select" /> <combo_box.item @@ -215,4 +212,4 @@ Hover your mouse over the options for more help. value="Not Mature" /> </combo_box> </panel> -</panel>
\ No newline at end of file +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml index 999aa814b1..d61fcf529a 100644 --- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml @@ -259,6 +259,7 @@ label="Planning" layout="topleft" left="1" + help_topic="group_money_planning_tab" name="group_money_planning_tab" top="5" width="265"> @@ -284,6 +285,7 @@ label="Details" layout="topleft" left_delta="0" + help_topic="group_money_details_tab" name="group_money_details_tab" top_delta="0" width="265"> @@ -329,6 +331,7 @@ label="Sales" layout="topleft" left_delta="0" + help_topic="group_money_sales_tab" name="group_money_sales_tab" top_delta="-1" width="265"> diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index ffc2f279bc..82a3c98dd9 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -187,7 +187,6 @@ the General tab. </text> <text_editor height="75" - hide_scrollbar="true" layout="topleft" left_pad="3" max_length="511" @@ -344,7 +343,6 @@ the General tab. <text_editor enabled="false" height="150" - hide_scrollbar="true" layout="topleft" left="10" max_length="511" diff --git a/indra/newview/skins/default/xui/en/panel_group_notify.xml b/indra/newview/skins/default/xui/en/panel_group_notify.xml index f97daf922f..bd98996ae1 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notify.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notify.xml @@ -7,13 +7,13 @@ 4 </string> <panel follows="top" background_visible="true" bevel_style="in" bg_alpha_color="black" - height="50" label="header" layout="topleft" left="0" name="header" + height="30" label="header" layout="topleft" left="0" name="header" top="0" width="350"> - <icon follows="left|top|right|bottom" height="40" width="40" layout="topleft" + <icon follows="left|top|right|bottom" height="20" width="20" layout="topleft" top="5" left="5" mouse_opaque="true" name="group_icon"/> <text type="string" length="1" follows="left|top|right|bottom" - font="SansSerifBigBold" height="20" layout="topleft" left="60" name="title" - text_color="GroupNotifyTextColor" top="20" width="275" use_ellipses="true"> + font="SansSerifBigBold" height="20" layout="topleft" left_pad="10" name="title" + text_color="GroupNotifyTextColor" top="5" width="275" use_ellipses="true"> Sender Name / Group Name </text> </panel> @@ -65,7 +65,7 @@ follows="left|bottom|right" height="15" width="15" layout="topleft" bottom="122" left="25" mouse_opaque="true" name="attachment_icon" visible="true" /> - <text font="SansSerif" font.style="UNDERLINE" font_shadow="hard" + <text font="SansSerif" font.style="UNDERLINE" font_shadow="none" type="string" length="1" follows="left|bottom|right" layout="topleft" left="45" bottom="122" height="15" width="280" name="attachment" text_color="GroupNotifyTextColor" visible="true"> diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index 7b8bd8b337..bf861af4f2 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -174,6 +174,7 @@ label="Members" layout="topleft" left="1" + help_topic="roles_members_tab" name="members_sub_tab" tool_tip="Members" top="17" @@ -283,6 +284,7 @@ clicking on their names. label="Roles" layout="topleft" left_delta="0" + help_topic="roles_roles_tab" name="roles_sub_tab" class="panel_group_roles_subtab" top="17" @@ -400,6 +402,7 @@ including the Everyone and Owner Roles. label="Abilities" layout="topleft" left_delta="0" + help_topic="roles_actions_tab" name="actions_sub_tab" class="panel_group_actions_subtab" top="17" @@ -625,7 +628,6 @@ things in this group. There's a broad variety of Abilities. type="string" halign="left" height="48" - hide_scrollbar="true" layout="topleft" left="135" max_length="254" @@ -723,7 +725,6 @@ things in this group. There's a broad variety of Abilities. enabled="false" halign="left" height="48" - hide_scrollbar="true" layout="topleft" left_delta="0" max_length="512" diff --git a/indra/newview/skins/default/xui/en/panel_instant_message.xml b/indra/newview/skins/default/xui/en/panel_instant_message.xml index 7db1b9e916..00ede1fb2c 100644 --- a/indra/newview/skins/default/xui/en/panel_instant_message.xml +++ b/indra/newview/skins/default/xui/en/panel_instant_message.xml @@ -80,7 +80,8 @@ use_ellipses="true" value="MESSAGE" width="330" - word_wrap="true" /> + word_wrap="true" + max_length="350" /> <button follows="bottom" font="SansSerifBigBold" diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml index aeeb884036..afe00271f7 100644 --- a/indra/newview/skins/default/xui/en/panel_login.xml +++ b/indra/newview/skins/default/xui/en/panel_login.xml @@ -164,7 +164,7 @@ control_name="RememberPassword" follows="left|bottom" height="16" - label="Remember me" + label="Remember password" layout="topleft" left_pad="10" name="remember_check" diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml index f1e2560356..c725334fc0 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml @@ -196,7 +196,7 @@ left="30" width="340" enabled="false" - name="meida_setting_note"> + name="media_setting_note"> Note: Residents can override this setting </text> diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml index 1178d75b2c..00100693cc 100644 --- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml @@ -4,7 +4,7 @@ background_visible="true" bg_opaque_color="MouseGray" follows="left|top|right" - height="60" + height="65" layout="topleft" name="navigation_bar" width="600"> @@ -64,13 +64,13 @@ left_pad="7" name="home_btn" picture_style="true" - tool_tip="Teleport to your home location" + tool_tip="Teleport to my home location" top_delta="0" width="32" /> <location_input follows="left|right|top" halign="right" - height="22" + height="23" label="Location" layout="topleft" left_pad="7" @@ -133,7 +133,7 @@ follows="left|right|top" height="25" layout="topleft" - left="5" + left="0" name="favorite" image_drag_indication="Arrow_Down" chevron_button_tool_tip="Show more of My Favorites" diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml index 4088d96ebf..3c8bf31e13 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml @@ -18,18 +18,31 @@ left_delta="7" left="0" name="chat_box" - tool_tip="Press Enter to say, Ctrl-Enter to shout." + tool_tip="Press Enter to say, Ctrl+Enter to shout." top="3" width="250" /> + <output_monitor + auto_update="true" + follows="right" + draw_border="false" + halign="left" + height="16" + layout="topleft" + left_pad="-24" + mouse_opaque="true" + name="chat_zone_indicator" + top="4" + visible="true" + width="20" /> <button - follows="right" - width="45" - top="3" - layout="topleft" - left_pad="5" - label="Log" - height="20"> - <button.commit_callback function="Floater.Toggle" parameter="nearby_chat"/> + follows="right" + width="45" + top="3" + layout="topleft" + left_pad="5" + label="Log" + height="20"> + <button.commit_callback function="Floater.Toggle" parameter="nearby_chat"/> </button> <chiclet_talk follows="right" diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml index 2056ec14d5..5333dfa2f5 100644 --- a/indra/newview/skins/default/xui/en/panel_notes.xml +++ b/indra/newview/skins/default/xui/en/panel_notes.xml @@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - bevel_style="in" - follows="left|top|right|bottom" - height="460" + follows="all" + height="535" label="Notes & Privacy" layout="topleft" left="0" name="panel_notes" top="0" - width="313"> + width="313" +> <layout_stack name="layout" orientation="vertical" @@ -16,34 +16,28 @@ layout="topleft" left="0" top="0" - height="430" - width="313" + height="517" border_size="0"> <panel name="notes_stack" follows="all" layout="topleft" top="0" - left="0" - height="390" - width="313"> + left="0"> <scroll_container color="DkGray2" - follows="left|top|right|bottom" - height="390" + follows="all" layout="topleft" left="0" name="profile_scroll" opaque="true" - top="0" - width="313"> + top="0"> <panel - height="350" - layout="topleft" - name="profile_scroll_panel" - top="0" - left="0" - width="293"> + layout="topleft" + name="profile_scroll_panel" + top="0" + left="0" + width="303"> <text follows="left|top" font="SansSerifBold" @@ -52,18 +46,17 @@ left="10" name="status_message" text_color="white" - top="5" + top="20" value="My private notes:" width="293" /> <text_editor follows="left|top" - height="200" - hide_scrollbar="true" + height="120" layout="topleft" left="10" max_length="1000" name="notes_edit" - text_color="black" + text_color="DkGray" top_pad="10" width="280" word_wrap="true" /> @@ -75,70 +68,91 @@ left="10" name="status_message2" text_color="white" - top_pad="10" - value="Let this person:" + top_pad="30" + value="Allow this person to:" width="293" /> <check_box enabled="false" - height="20" + height="16" label="See my online status" layout="topleft" left="20" name="status_check" - top_pad="0" width="293" /> <check_box enabled="false" - height="20" + height="16" label="See me on the map" layout="topleft" left="20" name="map_check" - top_pad="0" width="293" /> <check_box enabled="false" - height="20" + height="16" label="Edit, delete or take my objects" layout="topleft" left="20" name="objects_check" - top_pad="0" width="293" /> </panel> </scroll_container> </panel> <panel - follows="bottom" + follows="bottom|left" height="30" layout="topleft" - left="10" + left="0" name="notes_buttons_panel" - top_pad="5" - width="280" auto_resize="false"> - <button - enabled="false" - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Teleport" - layout="topleft" - left="0" - name="teleport_btn" - top="0" - width="75" /> - <button - enabled="false" - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Map" - layout="topleft" - name="show_on_map_btn" - top="0" - left_pad="5" - width="85" /> + <button + follows="bottom|left" + height="19" + label="Add" + layout="topleft" + left="0" + mouse_opaque="false" + name="add_friend" + top="5" + width="55" /> + <button + follows="bottom|left" + height="19" + label="IM" + layout="topleft" + name="im" + top="5" + left_pad="5" + width="40" /> + <button + enabled="false" + follows="bottom|left" + height="19" + label="Call" + layout="topleft" + name="call" + left_pad="5" + top="5" + width="55" /> + <button + enabled="false" + follows="bottom|left" + height="19" + label="Map" + layout="topleft" + name="show_on_map_btn" + top="5" + left_pad="5" + width="50" /> + <button + follows="bottom|left" + height="19" + label="Teleport" + layout="topleft" + name="teleport" + left_pad="5" + top="5" + width="90" /> </panel> </layout_stack> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml index 786c39c5e9..b51d53a1b4 100644 --- a/indra/newview/skins/default/xui/en/panel_people.xml +++ b/indra/newview/skins/default/xui/en/panel_people.xml @@ -60,6 +60,7 @@ color="DkGray" label="Nearby" layout="topleft" left="0" + help_topic="people_nearby_tab" name="nearby_panel" top="0" width="313"> @@ -109,6 +110,7 @@ color="DkGray" top="0" label="Friends" layout="topleft" + help_topic="people_friends_tab" name="friends_panel" width="313"> <accordion @@ -214,6 +216,7 @@ color="DkGray" label="Groups" top="0" layout="topleft" + help_topic="people_groups_tab" name="groups_panel" width="313"> <group_list @@ -301,6 +304,7 @@ color="DkGray" height="390" label="Recent" layout="topleft" + help_topic="people_recent_tab" name="recent_panel" width="313"> <avatar_list diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index 9edd14ce49..7d5ae3d78a 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -31,8 +31,8 @@ <scroll_container color="DkGray2" opaque="true" - follows="left|top|bottom" - height="490" + follows="all" + height="470" layout="topleft" left="10" top_pad="10" @@ -41,14 +41,14 @@ width="313"> <panel name="scroll_content_panel" - follows="left|top|right|bottom" + follows="left|top" min_height="300" layout="topleft" top="0" background_visible="false" - height="488" + height="470" left="0" - width="311"> + width="295"> <texture_picker enabled="false" follows="left|top" @@ -57,11 +57,11 @@ left="10" name="pick_snapshot" top="20" - width="290" /> + width="280" /> <text follows="left|top|right" height="20" - width="291" + width="280" layout="topleft" font="SansSerifBig" font.style="BOLD" @@ -77,16 +77,16 @@ layout="topleft" left="10" name="pick_location" - width="291" + width="280" word_wrap="true" value="[loading...]" /> <text follows="left|top|right" - height="400" + height="280" layout="topleft" left="10" name="pick_desc" - width="290" + width="280" value="[description]" word_wrap="true" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml index 1bd1953397..2869ec78f4 100644 --- a/indra/newview/skins/default/xui/en/panel_picks.xml +++ b/indra/newview/skins/default/xui/en/panel_picks.xml @@ -1,16 +1,16 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel - follows="left|top|right|bottom" - height="555" + follows="all" + height="535" label="Picks" layout="topleft" left="0" name="panel_picks" top="0" width="313"> - <flat_list_view + <flat_list_view color="DkGray2" - follows="left|top|right|bottom" + follows="all" height="465" layout="topleft" left="0" @@ -18,14 +18,14 @@ opaque="true" top="0" width="313" /> - <panel + <panel background_visible="true" bevel_style="none" enabled="false" auto_resize="false" follows="bottom" left="0" - height="23" + height="18" label="bottom_panel" layout="topleft" name="edit_panel" @@ -34,26 +34,24 @@ <button enabled="false" follows="bottom|left" - font="SansSerifBigBold" height="18" image_selected="OptionsMenu_Press" image_unselected="OptionsMenu_Off" image_disabled="OptionsMenu_Disabled" layout="topleft" - left="10" + left="0" name="gear_menu_btn" picture_style="true" top="5" width="18" /> <button follows="bottom|left" - font="SansSerifBigBold" height="18" image_disabled="AddItem_Disabled" image_selected="AddItem_Press" image_unselected="AddItem_Off" layout="topleft" - left="35" + left_pad="15" name="new_btn" picture_style="true" tool_tip="Create New Pick at Current Location" @@ -61,7 +59,6 @@ width="18" /> <button follows="bottom|right" - font="SansSerifBigBold" height="18" image_disabled="TrashItem_Disabled" image_selected="TrashItem_Press" @@ -77,17 +74,56 @@ follows="bottom" auto_resize="false" layout="topleft" - height="30" + height="19" name="buttons_cucks" width="313"> - <button - enabled="false" - follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Map" - layout="topleft" - name="show_on_map_btn" - width="85" /> + <button + follows="bottom|left" + height="19" + label="Add" + layout="topleft" + left="0" + mouse_opaque="false" + name="add_friend" + top="5" + width="55" /> + <button + follows="bottom|left" + height="19" + label="IM" + layout="topleft" + name="im" + top="5" + left_pad="5" + width="40" /> + <button + enabled="false" + follows="bottom|left" + height="19" + label="Call" + layout="topleft" + name="call" + left_pad="5" + top="5" + width="55" /> + <button + enabled="false" + follows="bottom|left" + height="19" + label="Map" + layout="topleft" + name="show_on_map_btn" + top="5" + left_pad="5" + width="50" /> + <button + follows="bottom|left" + height="19" + label="Teleport" + layout="topleft" + name="teleport" + left_pad="5" + top="5" + width="90" /> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 696e0b3c33..1ea6e1149d 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -41,6 +41,7 @@ height="326" layout="topleft" left="0" + help_topic="places_info_tab" name="panel_place_info" top="30" visible="false" /> @@ -48,6 +49,7 @@ height="25" layout="topleft" left="0" + help_topic="places_button_tab" name="button_panel" top_pad="10" width="313"> @@ -60,7 +62,7 @@ left="5" name="teleport_btn" top="0" - width="70" /> + width="77" /> <button follows="bottom|left" font="SansSerifSmallBold" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml index 06ecfdc995..f7d7d52b68 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml @@ -217,7 +217,7 @@ My Avatar: width="237" top_pad="0"/> <check_box - control_name="TapTapHoldtoRun" + control_name="AllowTapTapHoldRun" height="20" label="Tap-tap-hold to run" layout="topleft" @@ -225,36 +225,15 @@ My Avatar: name="tap_tap_hold_to_run" width="237" top_pad="0"/> - <!--menu_item_check - label="Tap-Tap-Hold to Run" - layout="topleft" - name="Tap-Tap-Hold to Run"> - <menu_item_check.on_check - function="Advanced.CheckAllowTapTapHoldRun" - parameter="TapTapHoldRun" /> - <menu_item_check.on_click - function="Advanced.ToggleAllowTapTapHoldRun" /> - </menu_item_check--> <check_box - control_name="EnableLipSync" + control_name="LipSyncEnabled" height="20" - label="Move my avatar's lips when speaking" + label="Move avatar lips when speaking" layout="topleft" left_delta="0" name="enable_lip_sync" width="237" top_pad="0" /> - <!--menu_item_check - label="Enable Lip Sync(Beta)" - layout="topleft" - name="Enable Lip Sync(Beta)"> - <menu_item_check.on_check - function="CheckControl" - parameter="LipSyncEnabled" /> - <menu_item_check.on_click - function="ToggleControl" - parameter="LipSyncEnabled" /> - </menu_item_check--> <check_box control_name="test" height="20" @@ -293,4 +272,4 @@ My Avatar: </radio_group> -</panel>
\ No newline at end of file +</panel> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index ecfb0048a3..84fcf21623 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -48,41 +48,36 @@ length="1" enabled="true" name="640x480" - value="640 x 480"> - 640x480 - </combo_box.item> + value="640 x 480" + label="640x480"/> <combo_box.item type="string" length="1" enabled="true" name="800x600" - value="800 x 600"> - 800x600 - </combo_box.item> + value="800 x 600" + label="800x600"/> <combo_box.item type="string" length="1" enabled="true" name="720x480" - value="720 x 480"> - 720x480 (NTSC) - </combo_box.item> + value="720 x 480" + label="720x480 (NTSC)"/> <combo_box.item type="string" length="1" enabled="true" name="768x576" - value="768 x 576"> - 768x576 (PAL) - </combo_box.item> + value="768 x 576" + label="768x576 (PAL)"/> <combo_box.item type="string" length="1" enabled="true" name="1024x768" - value="1024 x 768"> - 1024x768 - </combo_box.item> + value="1024 x 768" + label="1024x768"/> <combo_box.commit_callback function="Pref.setControlFalse" parameter="FullScreenAutoDetectAspectRatio" /> diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml index 9cf699ad46..ba933683e3 100644 --- a/indra/newview/skins/default/xui/en/panel_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_profile.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel follows="all" - height="560" + height="535" label="Profile" layout="topleft" left="0" @@ -10,7 +10,8 @@ width="313"> <string name="CaptionTextAcctInfo"> - [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION] + [ACCTTYPE] +[PAYMENTINFO] [AGEVERIFICATION] </string> <string name="payment_update_link_url"> @@ -26,33 +27,31 @@ <string name="no_partner_text" value="None" /> - <scroll_container + <scroll_container color="DkGray2" - follows="left|top|right|bottom" - height="500" + follows="all" + height="485" min_height="300" layout="topleft" name="profile_scroll" reserve_scroll_corner="true" opaque="true" - top="0" - width="313"> - <panel - name="scroll_content_panel" - follows="left|top|right" - layout="topleft" - top="0" - left="0" - width="300" - height="700"> + top="0"> + <panel + name="scroll_content_panel" + follows="left|top|right" + layout="topleft" + top="0" + left="0" + width="313"> <panel - follows="left|top" - height="117" - layout="topleft" - left="10" - name="second_life_image_panel" - top="10" - width="285"> + follows="left|top" + height="117" + layout="topleft" + left="10" + name="second_life_image_panel" + top="0" + width="285"> <texture_picker allow_no_texture="true" default_image_name="None" @@ -66,7 +65,6 @@ width="102" /> <text follows="left|top|right" - font="SansSerifSmall" font.style="BOLD" height="15" layout="topleft" @@ -81,9 +79,9 @@ height="90" layout="topleft" name="sl_description_edit" - width="170" + width="173" expanded_bg_visible="true" - expanded_bg_color="black"> + expanded_bg_color="DkGray"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </expandable_text> </panel> @@ -107,7 +105,6 @@ width="102" /> <text follows="left|top|right" - font="SansSerifSmall" font.style="BOLD" height="15" layout="topleft" @@ -116,7 +113,7 @@ text_color="white" top_delta="0" value="Real World:" - width="175" /> + width="173" /> <expandable_text follows="left|top|right" height="90" @@ -124,7 +121,7 @@ name="fl_description_edit" width="170" expanded_bg_visible="true" - expanded_bg_color="black"> + expanded_bg_color="DkGray"> Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </expandable_text> </panel> @@ -138,7 +135,7 @@ left="10" name="me_homepage_text" text_color="white" - top_pad="10" + top_pad="0" width="280"> Homepage: </text> @@ -148,19 +145,21 @@ layout="topleft" left="10" name="homepage_edit" + top_pad="0" value="http://librarianavengers.org" - width="280" - word_wrap="false" /> + width="290" + word_wrap="false" + use_elipsis="true" + /> <text follows="left|top" - font="SansSerifSmall" font.style="BOLD" - height="15" + height="10" layout="topleft" left="10" name="title_member_text" text_color="white" - top_pad="20" + top_pad="10" value="Member Since:" width="280" /> <text @@ -169,20 +168,18 @@ layout="topleft" left="10" name="register_date" - top_pad="5" value="05/31/1976" width="280" word_wrap="true" /> <text follows="left|top" - font="SansSerifSmall" font.style="BOLD" height="15" layout="topleft" left="10" name="title_acc_status_text" text_color="white" - top_pad="15" + top_pad="10" value="Account Status:" width="280" /> <!-- <text @@ -198,24 +195,23 @@ width="100"/> --> <text follows="left|top" - height="15" + height="20" layout="topleft" left="10" name="acc_status_text" - top_pad="5" + top_pad="0" value="Resident. No payment info on file." - width="280" + width="295" word_wrap="true" /> <text follows="left|top" - font="SansSerifSmall" font.style="BOLD" height="15" layout="topleft" left="10" name="title_partner_text" text_color="white" - top_pad="15" + top_pad="10" value="Partner:" width="280" /> <panel @@ -224,11 +220,11 @@ layout="topleft" left="10" name="partner_data_panel" - top_pad="5" + top_pad="0" width="280"> <text follows="left|top" - height="15" + height="10" layout="topleft" left="0" name="partner_text" @@ -239,14 +235,13 @@ </panel> <text follows="left|top" - font="SansSerifSmall" font.style="BOLD" height="15" layout="topleft" left="10" name="title_groups_text" text_color="white" - top_pad="15" + top_pad="10" value="Groups:" width="280" /> <text @@ -255,91 +250,93 @@ layout="topleft" left="10" name="sl_groups" - top_pad="5" - width="280" - word_wrap="true"> + top_pad="0" + width="290" + word_wrap="true" + use_elipsis="true"> Lorem ipsum dolor sit amet, consectetur adlkjpiscing elit moose moose. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet. adipiscing elit. Aenean rigviverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet sorbet ipsum. adipiscing elit. Aenean viverra orci et justo sagittis aliquet. Nullam malesuada mauris sit amet ipsum. </text> </panel> - </scroll_container> - - <panel + </scroll_container> + <panel follows="bottom|left" layout="topleft" left="0" name="profile_buttons_panel" - top_pad="0" - height="25" - width="313"> + top_pad="2" + bottom="10" + height="19"> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" - label="Add Friend" + height="19" + label="Add" layout="topleft" left="0" mouse_opaque="false" name="add_friend" - top="0" - width="90" /> + top="5" + width="55" /> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" + height="19" label="IM" layout="topleft" name="im" - top="0" - left_pad="0" + top="5" + left_pad="5" width="40" /> <button enabled="false" follows="bottom|left" - font="SansSerifSmallBold" - height="25" + height="19" label="Call" layout="topleft" name="call" - left_pad="0" - top="0" + left_pad="5" + top="5" + width="55" /> + <button + enabled="false" + follows="bottom|left" + height="19" + label="Map" + layout="topleft" + name="show_on_map_btn" + top="5" + left_pad="5" width="50" /> <button follows="bottom|left" - font="SansSerifSmallBold" - height="25" + height="19" label="Teleport" layout="topleft" name="teleport" - left_pad="0" - top="0" - width="75" /> - </panel> - <panel + left_pad="5" + top="5" + width="90" /> + </panel> + <panel follows="bottom|left" layout="topleft" left="0" name="profile_me_buttons_panel" - top_pad="0" + top_pad="-3" visible="false" - height="25" - width="313"> + height="19"> <button - follows="bottom|left" - height="23" + follows="bottom|right" + height="19" + left="10" label="Edit Profile" - layout="topleft" - left="0" name="edit_profile_btn" - top="0" width="130" /> <button - follows="bottom|left" - height="23" + follows="bottom|right" + height="19" label="Edit Appearance" - layout="topleft" - left_pad="5" + left_pad="10" name="edit_appearance_btn" - top="0" + right="-10" width="130" /> - </panel> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index 606535115d..8a48574440 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -5,7 +5,6 @@ height="570" layout="topleft" min_height="350" - min_width="240" name="panel_target_profile" width="333"> <string @@ -16,65 +15,69 @@ name="status_offline"> Offline </string> + <button + follows="top|right" + height="23" + image_overlay="BackArrow_Off" + layout="topleft" + name="back" + picture_style="true" + left="10" + tab_stop="false" + top="2" + width="23" /> <text follows="top|left|right" font="SansSerifHugeBold" - height="20" + height="26" layout="topleft" - left="10" + left_pad="10" name="user_name" text_color="white" top="0" value="(Loading...)" - width="250" /> + use_elipsis="true" + width="275" /> <text follows="top|left" - height="16" + height="13" layout="topleft" - left="10" + left="45" name="status" text_color="LtGray_50" - top_pad="5" value="Online" - width="100" /> - <button - follows="top|right" - height="25" - image_overlay="BackArrow_Off" - layout="topleft" - name="back" - picture_style="true" - right="-10" - tab_stop="false" - top="0" - width="25" /> + width="150" /> <tab_container - follows="left|top|right|bottom" - height="560" + follows="all" + height="535" layout="topleft" left="10" name="tabs" - tab_min_width="75" + tab_min_width="95" + tab_height="30" tab_position="top" - top_pad="15" - width="285"> + top_pad="10" + width="313"> <panel class="panel_profile" filename="panel_profile.xml" label="Profile" layout="topleft" + help_topic="profile_profile_tab" name="panel_profile" /> <panel class="panel_picks" filename="panel_picks.xml" label="Picks" layout="topleft" + help_topic="profile_picks_tab" name="panel_picks" /> <panel class="panel_notes" filename="panel_notes.xml" label="Notes & Privacy" layout="topleft" + help_topic="profile_notes_tab" name="panel_notes" /> </tab_container> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 9abaf29f57..a312e4cf13 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -62,7 +62,7 @@ <text follows="left|right|top" font="SansSerifHuge" - font_shadow="hard" + font_shadow="none" halign="left" height="20" layout="topleft" @@ -74,7 +74,7 @@ <text follows="left|right|top" font="SansSerif" - font_shadow="hard" + font_shadow="none" halign="left" height="20" layout="topleft" @@ -96,7 +96,7 @@ <text follows="left|right|top|bottom" font="SansSerifLarge" - font_shadow="hard" + font_shadow="none" halign="left" height="100" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_region_covenant.xml b/indra/newview/skins/default/xui/en/panel_region_covenant.xml index 01fbc81c32..b3147f5e6b 100644 --- a/indra/newview/skins/default/xui/en/panel_region_covenant.xml +++ b/indra/newview/skins/default/xui/en/panel_region_covenant.xml @@ -2,13 +2,13 @@ <panel border="true" follows="top|left" - height="350" + height="320" label="Covenant" layout="topleft" left="0" name="Covenant" top="320" - width="280"> + width="480"> <panel.string name="can_resell"> Purchased land in this region may be resold. @@ -45,14 +45,14 @@ mouse_opaque="false" name="estate_name_lbl" top_pad="5" - width="75"> + width="100"> Name: </text> <text follows="left|top" height="20" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="estate_name_text" top_delta="0" @@ -67,41 +67,40 @@ mouse_opaque="false" name="estate_owner_lbl" top_pad="5" - width="75"> + width="100"> Owner: </text> <text follows="left|top" height="20" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="estate_owner_text" top_delta="0" width="150"> (none) </text> - - <text + <text follows="left|top" - height="20" + height="20" layout="topleft" left="10" - mouse_opaque="false" - name="estate_cov_lbl" + mouse_opaque="false" + name="estate_cov_lbl" top_pad="5" - width="75"> + width="100"> Covenant: </text> <text follows="left|top" height="20" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="covenant_timestamp_text" top_delta="0" - width="167"> + width="308"> Last Modified Wed Dec 31 16:00:00 1969 </text> <button @@ -120,12 +119,12 @@ follows="left|top" height="100" layout="topleft" - left="80" + left="110" max_length="65535" name="covenant_editor" top_delta="30" handle_edit_keys_directly="true" - width="193" + width="340" word_wrap="true"> There is no Covenant provided for this Estate. </text_editor> @@ -135,7 +134,7 @@ height="18" label="Reset" layout="topleft" - left_delta="75" + left_delta="250" name="reset_covenant" top_pad="5" width="90" /> @@ -144,12 +143,11 @@ follows="left|top" height="20" layout="topleft" - left="85" + left="120" name="covenant_help_text" top_pad="10" - width="190"> - Changes to the covenant will show -on all parcels in the estate. + width="460"> + Changes to the covenant will show on all parcels in the estate. </text> <text follows="left|top" @@ -157,10 +155,10 @@ on all parcels in the estate. layout="topleft" left_delta="0" name="covenant_instructions" - top_pad="15" - width="190"> + top_pad="5" + width="465"> Drag and drop a notecard to change -the Covenant for this Estate. + the Covenant for this Estate. </text> <text @@ -171,7 +169,7 @@ the Covenant for this Estate. left="5" mouse_opaque="false" name="region_section_lbl" - top_pad="10" + top_pad="5" width="100"> Region </text> @@ -183,19 +181,19 @@ the Covenant for this Estate. mouse_opaque="false" name="region_name_lbl" top_pad="5" - width="75"> + width="100"> Name: </text> <text follows="left|top" height="20" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="region_name_text" top_delta="0" width="150"> - leyla + Erica </text> <text follows="left|top" @@ -205,14 +203,14 @@ the Covenant for this Estate. mouse_opaque="false" name="region_landtype_lbl" top_pad="5" - width="75"> + width="100"> Type: </text> <text follows="left|top" height="20" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="region_landtype_text" top_delta="0" @@ -227,14 +225,14 @@ the Covenant for this Estate. mouse_opaque="false" name="region_maturity_lbl" top_pad="5" - width="75"> + width="100"> Rating: </text> <text follows="left|top" height="20" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="region_maturity_text" top_delta="0" @@ -249,20 +247,19 @@ the Covenant for this Estate. mouse_opaque="false" name="resellable_lbl" top_pad="5" - width="75"> + width="100"> Resale: </text> <text follows="left|top" height="20" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="resellable_clause" top_delta="0" - width="190"> - Land in this region may not be -resold. + width="330"> + Land in this region may not be resold. </text> <text follows="left|top" @@ -271,21 +268,20 @@ resold. left="10" mouse_opaque="false" name="changeable_lbl" - top_pad="10" - width="75"> + top_pad="5" + width="100"> Subdivide: </text> <text follows="left|top" height="30" layout="topleft" - left_pad="0" + left_pad="10" mouse_opaque="false" name="changeable_clause" top_delta="0" - width="190"> - Land in this region may not be -joined/subdivided. + width="330"> + Land in this region may not be joined/subdivided. </text> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_debug.xml b/indra/newview/skins/default/xui/en/panel_region_debug.xml index 54664bb6b9..78e5678455 100644 --- a/indra/newview/skins/default/xui/en/panel_region_debug.xml +++ b/indra/newview/skins/default/xui/en/panel_region_debug.xml @@ -8,7 +8,7 @@ left="0" name="Debug" top="320" - width="280"> + width="480"> <text follows="left|top" font="SansSerif" @@ -28,7 +28,7 @@ left_delta="50" name="region_text" top_delta="0" - width="220"> + width="400"> unknown </text> <check_box @@ -91,15 +91,16 @@ <button enabled="false" follows="left|top" - height="20" font="SansSerifSmall" + height="20" label="Apply" layout="topleft" left="60" name="apply_btn" top="100" - width="80" /> + width="100" /> <text + follows="left|top" height="20" layout="topleft" @@ -110,16 +111,18 @@ Object Return </text> <text + follows="left|top" height="20" layout="topleft" - left="20" + left="30" name="resident_text_lbl" top="175" width="60"> Resident: </text> <line_editor + border_style="line" border_thickness="1" enabled="false" @@ -130,7 +133,7 @@ mouse_opaque="false" name="target_avatar_name" top_delta="-2" - width="115"> + width="180"> (none) </line_editor> <button @@ -143,17 +146,17 @@ name="choose_avatar_btn" top_delta="0" width="70" /> - <text + <text follows="left|top" height="20" layout="topleft" - left="20" + left="30" name="options_text_lbl" top="198" width="60"> Options: </text> - <check_box + <check_box height="20" label="With scripts" layout="topleft" @@ -192,15 +195,15 @@ width="80" /> <button follows="left|top" - height="20" font="SansSerifSmall" + height="20" label="Get Top Colliders..." layout="topleft" left="10" name="top_colliders_btn" tool_tip="List of objects experiencing the most potential collisions" top="313" - width="130" /> + width="150" /> <button follows="left|top" font="SansSerifSmall" @@ -213,15 +216,15 @@ width="18" /> <button follows="left|top" - height="20" font="SansSerifSmall" + height="20" label="Get Top Scripts..." layout="topleft" left="10" name="top_scripts_btn" tool_tip="List of objects spending the most time running scripts" top_pad="5" - width="130" /> + width="150" /> <button follows="left|top" font="SansSerifSmall" @@ -234,15 +237,15 @@ width="18" /> <button follows="left|top" - height="20" font="SansSerifSmall" + height="20" label="Restart Region" layout="topleft" left="10" name="restart_btn" tool_tip="Give 2 minute countdown and restart region" top_pad="5" - width="110" /> + width="130" /> <button follows="left|top" font="SansSerifSmall" @@ -255,13 +258,13 @@ width="18" /> <button follows="left|top" - height="20" font="SansSerifSmall" + height="20" label="Delay Restart" layout="topleft" left="10" name="cancel_restart_btn" tool_tip="Delay region restart by one hour" top_pad="5" - width="110" /> + width="130" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml index 6e837bcfee..afcefcbd3b 100644 --- a/indra/newview/skins/default/xui/en/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml @@ -2,474 +2,518 @@ <panel border="false" follows="top|left" - height="512" - top="0" - left="0" - name="EstateWrapper" + height="320" label="Estate" layout="topleft" - width="313"> - <panel - follows="top|left" - height="950" - label="Estate" + left="0" + name="Estate" + top="320" + width="480"> + <panel.string + name="email_unsupported"> + Feature unsupported + </panel.string> + <text + type="string" + length="1" + follows="left|top" + height="32" layout="topleft" - name="Estate" + left="10" + name="estate_help_text" + top="14" width="313"> - <panel.string - name="email_unsupported"> - Feature unsupported - </panel.string> - <text - type="string" - length="1" - follows="left|top" - height="32" - layout="topleft" - left="0" - name="estate_help_text" - top="5" - width="313"> Changes to settings on this tab will affect all - regions in the estate. - </text> - <text - type="string" - length="1" - follows="left|top" - - layout="topleft" - name="estate_text" - top_pad="5" - width="313"> +regions in the estate. + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="estate_text" + top_pad="2" + width="80"> Estate: - </text> - <text - type="string" - length="1" - follows="left|top" - layout="topleft" - name="estate_name" - top_pad="5" - width="313"> + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="estate_name" + top_delta="16" + width="150"> (unknown) - </text> - <text - type="string" - length="1" - follows="left|top" - layout="topleft" - left_delta="0" - name="owner_text" - top_pad="5" - width="313"> - Estate Owner: - </text> - <text - type="string" - length="1" - follows="left|top" - layout="topleft" - name="estate_owner" - top_pad="5" - width="313"> + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="owner_text" + top_pad="2" + width="80"> + Estate owner: + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="0" + name="estate_owner" + top_delta="16" + width="150"> (unknown) - </text> - <check_box - height="23" - label="Use Global Time" - layout="topleft" - left="12" - name="use_global_time_check" - top="102" - width="200" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="20" - name="use_global_time_help" - top_delta="2" - width="18" /> - <check_box - height="23" - label="Fixed Sun" - layout="topleft" - left="12" - name="fixed_sun_check" - top_pad="10" - width="100" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="120" - name="fixed_sun_help" - top_delta="2" - width="18" /> - <icon - height="23" - image_name="icon_day_cycle.tga" - layout="topleft" - left="47" - name="daycycle" - top_pad="10" - width="165" /> - <slider - follows="left|top" - height="23" - increment="0.001" - label="Phase" - layout="topleft" - left="12" - max_val="30" - min_val="6" - name="sun_hour_slider" - show_text="false" - top_pad="10" - width="200" /> - <check_box - height="23" - label="Allow Public Access" - layout="topleft" - left_delta="0" - name="externally_visible_check" - top_pad="10" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="20" - name="externally_visible_help" - top_delta="2" - width="18" /> - <text - type="string" - length="1" - follows="top|left" - height="16" - layout="topleft" - left="32" - name="Only Allow" - top_pad="5" - width="278"> + </text> + <view_border + bevel_style="in" + follows="top|left" + height="290" + layout="topleft" + left_delta="-4" + top_pad="5" + width="250" /> + <check_box + height="20" + label="Use Global Time" + layout="topleft" + left="12" + name="use_global_time_check" + top="132" + width="200" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="20" + name="use_global_time_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Fixed Sun" + layout="topleft" + left="12" + name="fixed_sun_check" + top="152" + width="100" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="120" + name="fixed_sun_help" + top_delta="2" + width="18" /> + <icon + height="20" + image_name="icon_day_cycle.tga" + layout="topleft" + left="47" + name="daycycle" + top="177" + width="165" /> + <slider + follows="left|top" + height="20" + increment="0.001" + label="Phase" + layout="topleft" + left="12" + max_val="30" + min_val="6" + name="sun_hour_slider" + show_text="false" + top="202" + width="200" /> + <check_box + height="20" + label="Allow Public Access" + layout="topleft" + left_delta="0" + name="externally_visible_check" + top_pad="6" + width="200" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="20" + name="externally_visible_help" + top_delta="2" + width="18" /> + <text + type="string" + length="1" + follows="top|left" + height="16" + layout="topleft" + left="32" + name="Only Allow" + top="250" + width="278"> Restrict Access To: - </text> - <check_box - follows="top|left" - height="16" - label="Residents with payment info on file" - layout="topleft" - left_delta="0" - name="limit_payment" - tool_tip="Ban unidentified residents." - top_pad="2" - width="278" /> - <check_box - follows="top|left" - height="16" - label="Age-verified adults" - layout="topleft" - left_delta="0" - name="limit_age_verified" - tool_tip="Ban residents who have not verified their age. See the [SUPPORT_SITE] for more information." - top_pad="2" - width="278" /> - <check_box - height="23" - label="Allow Voice Chat" - layout="topleft" - left="12" - name="voice_chat_check" - top_pad="5" - width="200" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="20" - name="voice_chat_help" - top_delta="2" - width="18" /> - <check_box - height="23" - label="Allow Direct Teleport" - layout="topleft" - left="12" - name="allow_direct_teleport" - top_pad="0" - width="80" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="140" - name="allow_direct_teleport_help" - top_delta="2" - width="18" /> - <text - type="string" - length="1" - follows="left|top" - height="23" - layout="topleft" - left="10" - name="abuse_email_text" - top_pad="5" - width="313"> + </text> + <check_box + follows="top|left" + height="16" + label="Residents with payment info on file" + layout="topleft" + left_delta="0" + name="limit_payment" + tool_tip="Ban unidentified residents." + top_pad="2" + width="278" /> + <check_box + follows="top|left" + height="16" + label="Age-verified adults" + layout="topleft" + left_delta="0" + name="limit_age_verified" + tool_tip="Ban residents who have not verified their age. See the [SUPPORT_SITE] for more information." + top_pad="2" + width="278" /> + <check_box + height="20" + label="Allow Voice Chat" + layout="topleft" + left="12" + name="voice_chat_check" + top="304" + width="200" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="20" + name="voice_chat_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Allow Direct Teleport" + layout="topleft" + left="12" + name="allow_direct_teleport" + top_pad="4" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="140" + name="allow_direct_teleport_help" + top_delta="2" + width="18" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="abuse_email_text" + top_pad="5" + width="180"> Abuse email address: - </text> - <line_editor - follows="top|left" - height="19" - layout="topleft" - left="15" - name="abuse_email_address" - top_pad="0" - width="250" /> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_pad="12" - name="abuse_email_address_help" - top_delta="0" - width="18" /> - <button - enabled="false" - follows="left|top" - height="23" - label="Apply" - layout="topleft" - name="apply_btn" - right="250" - top_pad="4" - width="90" /> - <button - follows="left|top" - height="23" - label="Send Message To Estate..." - layout="topleft" - left="8" - name="message_estate_btn" - top_pad="5" - width="250" /> - <button - follows="left|top" - height="23" - label="Kick User from Estate..." - layout="topleft" - left="8" - name="kick_user_from_estate_btn" - top_pad="5" - width="250" /> - <text - type="string" - length="1" - top="490" - follows="left|top" - height="23" - layout="topleft" - name="estate_manager_label" - left="8" - width="200"> + </text> + <line_editor + follows="top|left" + height="19" + layout="topleft" + left="15" + name="abuse_email_address" + top_pad="5" + width="205" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="12" + name="abuse_email_address_help" + top_dekta="0" + width="18" /> + <button + enabled="false" + follows="left|top" + height="20" + label="Apply" + layout="topleft" + name="apply_btn" + right="250" + top_pad="4" + width="90" /> + <button + follows="left|top" + height="20" + label="Send Message To Estate..." + layout="topleft" + left="8" + name="message_estate_btn" + top_pad="5" + width="250" /> + <button + follows="left|top" + height="20" + label="Kick User from Estate..." + layout="topleft" + left="8" + name="kick_user_from_estate_btn" + top_pad="5" + width="250" /> + + <text + type="string" + length="1" + bottom="34" + follows="left|top" + height="20" + layout="topleft" + name="estate_manager_label" + right="470" + width="200"> Estate Managers: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="estate_manager_help" - top_delta="-1" - width="18" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left="8" - multi_select="true" - name="estate_manager_name_list" - top_pad="0" - width="300" /> - <button - follows="left|top" - height="23" - label="Add..." - layout="topleft" - left="8" - name="add_estate_manager_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="23" - label="Remove..." - layout="topleft" - name="remove_estate_manager_btn" - left_pad="70" - top_delta="0" - width="90" /> - <text - type="string" - length="1" - follows="left|top" - height="23" - layout="topleft" - left="8" - name="allow_resident_label" - top_pad="5" - width="200"> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="182" + name="estate_manager_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + right="470" + top_pad="5" + width="200" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="estate_manager_name_list" + top_delta="0" + width="200" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_estate_manager_btn" + right="470" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left_delta="-110" + name="add_estate_manager_btn" + top_delta="0" + width="90" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_delta="0" + name="allow_resident_label" + top_pad="5" + width="200"> Allowed Residents: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="allow_resident_help" - top_delta="-1" - width="18" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left="8" - multi_select="true" - name="allowed_avatar_name_list" - top_pad="0" - width="300" /> - <button - follows="left|top" - height="23" - label="Add..." - layout="topleft" - left="8" - name="add_allowed_avatar_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="23" - label="Remove..." - layout="topleft" - name="remove_allowed_avatar_btn" - left_pad="70" - top_delta="0" - width="90" /> - <text - type="string" - length="1" - follows="left|top" - height="23" - layout="topleft" - left="8" - name="allow_group_label" - top_pad="5" - width="200"> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="182" + name="allow_resident_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + right="470" + top_pad="5" + width="200" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="allowed_avatar_name_list" + top_delta="0" + width="200" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_allowed_avatar_btn" + right="470" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left_delta="-110" + name="add_allowed_avatar_btn" + top_delta="0" + width="90" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_delta="0" + name="allow_group_label" + top_pad="5" + width="200"> Allowed Groups: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="allow_group_help" - top_delta="-1" - width="18" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left="8" - multi_select="true" - name="allowed_group_name_list" - top_pad="0" - width="300" /> - <button - follows="left|top" - height="23" - label="Add..." - layout="topleft" - left="8" - name="add_allowed_group_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="23" - label="Remove..." - layout="topleft" - name="remove_allowed_group_btn" - left_pad="70" - top_delta="0" - width="90" /> - <text - type="string" - length="1" - follows="left|top" - height="23" - layout="topleft" - left="8" - name="ban_resident_label" - top_pad="5" - width="200"> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="182" + name="allow_group_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + right="470" + top_pad="5" + width="200" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="allowed_group_name_list" + top_delta="0" + width="200" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_allowed_group_btn" + right="470" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left_delta="-110" + name="add_allowed_group_btn" + top_delta="0" + width="90" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_delta="0" + name="ban_resident_label" + top_pad="5" + width="200"> Banned Residents: - </text> - <button - follows="left|top" - font="SansSerifSmall" - height="18" - label="?" - layout="topleft" - left_delta="232" - name="ban_resident_help" - top_delta="-1" - width="18" /> - <name_list - follows="left|top" - height="60" - layout="topleft" - left="8" - multi_select="true" - name="banned_avatar_name_list" - top_pad="0" - width="300" /> - <button - follows="left|top" - height="23" - label="Add..." - layout="topleft" - left="8" - name="add_banned_avatar_btn" - top_pad="5" - width="90" /> - <button - follows="left|top" - height="23" - label="Remove..." - layout="topleft" - name="remove_banned_avatar_btn" - left_pad="70" - top_delta="0" - width="90" /> - </panel> + </text> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_delta="182" + name="ban_resident_help" + top_delta="-1" + width="18" /> + <view_border + bevel_style="none" + follows="top|left" + height="60" + layout="topleft" + right="470" + top_pad="5" + width="200" /> + <name_list + follows="left|top" + height="60" + layout="topleft" + left_delta="0" + multi_select="true" + name="banned_avatar_name_list" + top_delta="0" + width="200" /> + <button + follows="left|top" + height="20" + label="Remove..." + layout="topleft" + name="remove_banned_avatar_btn" + right="470" + top_pad="5" + width="90" /> + <button + follows="left|top" + height="20" + label="Add..." + layout="topleft" + left_delta="-110" + name="add_banned_avatar_btn" + top_delta="0" + width="90" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml index 9b9c62dbf9..160ae96fc4 100644 --- a/indra/newview/skins/default/xui/en/panel_region_general.xml +++ b/indra/newview/skins/default/xui/en/panel_region_general.xml @@ -2,13 +2,13 @@ <panel border="true" follows="top|left" - height="360" + height="320" label="Region" layout="topleft" left="0" name="General" - top="360" - width="280"> + top="320" + width="480"> <text follows="left|top" font="SansSerif" @@ -28,7 +28,7 @@ left_delta="50" name="region_text" top_delta="0" - width="200"> + width="400"> unknown </text> <text @@ -279,7 +279,7 @@ label="PG" name="PG" value="13" /> - </combo_box> + </combo_box> <button follows="left|top" font="SansSerifSmall" @@ -300,10 +300,10 @@ name="apply_btn" top="320" width="100"> - <button.commit_callback + <button.commit_callback function="RegionInfo.Cancel" /> </button> - <button + <button follows="left|top" height="20" label="Teleport Home One User..." @@ -335,8 +335,8 @@ height="20" label="Manage Telehub..." layout="topleft" - left_delta="0" + left="250" name="manage_telehub_btn" - top_pad="20" - width="150" /> + top="70" + width="150" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_region_general_layout.xml b/indra/newview/skins/default/xui/en/panel_region_general_layout.xml new file mode 100644 index 0000000000..9b9c62dbf9 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_region_general_layout.xml @@ -0,0 +1,342 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + border="true" + follows="top|left" + height="360" + label="Region" + layout="topleft" + left="0" + name="General" + top="360" + width="280"> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left="10" + name="region_text_lbl" + top="10" + width="100"> + Region: + </text> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="50" + name="region_text" + top_delta="0" + width="200"> + unknown + </text> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left="10" + name="version_channel_text_lbl" + top="30" + width="100"> + Version: + </text> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="50" + name="version_channel_text" + top_delta="0" + width="200"> + unknown + </text> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left="10" + name="region_type_lbl" + top="50" + width="100"> + Type: + </text> + <text + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="50" + name="region_type" + top_delta="0" + width="200"> + unknown + </text> + <check_box + height="20" + label="Block Terraform" + layout="topleft" + left="10" + name="block_terraform_check" + top="70" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="115" + name="terraform_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Block Fly" + layout="topleft" + left="10" + name="block_fly_check" + top="90" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="115" + name="fly_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Allow Damage" + layout="topleft" + left="10" + name="allow_damage_check" + top="110" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="115" + name="damage_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Restrict Pushing" + layout="topleft" + left="10" + name="restrict_pushobject" + top="130" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="115" + name="restrict_pushobject_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Allow Land Resell" + layout="topleft" + left="10" + name="allow_land_resell_check" + top="160" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="115" + name="land_resell_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Allow Land Join/Divide" + layout="topleft" + left="10" + name="allow_parcel_changes_check" + top="180" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="115" + name="parcel_changes_help" + top_delta="2" + width="18" /> + <check_box + height="20" + label="Block Land Show in Search" + layout="topleft" + left="10" + name="block_parcel_search_check" + tool_tip="Let people see this region and its parcels in search results" + top="200" + width="80" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="115" + name="parcel_search_help" + top_delta="2" + width="18" /> + <spinner + follows="left|top" + height="20" + increment="1" + label="Agent Limit" + label_width="97" + layout="topleft" + left="10" + max_val="100" + min_val="1" + name="agent_limit_spin" + top="240" + width="170" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="25" + name="agent_limit_help" + top_delta="2" + width="18" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Object Bonus" + label_width="97" + layout="topleft" + left="10" + max_val="10" + min_val="1" + name="object_bonus_spin" + top="260" + width="170" /> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="25" + name="object_bonus_help" + top_delta="2" + width="18" /> + <text + follows="left|top" + height="20" + label="Maturity" + layout="topleft" + left="10" + name="access_text" + top="290" + width="100"> + Rating: + </text> + <combo_box + height="20" + label="Mature" + layout="topleft" + left_delta="100" + name="access_combo" + top_delta="0" + width="85"> + <combo_box.item + label="Adult" + name="Adult" + value="42" /> + <combo_box.item + label="Mature" + name="Mature" + value="21" /> + <combo_box.item + label="PG" + name="PG" + value="13" /> + </combo_box> + <button + follows="left|top" + font="SansSerifSmall" + height="18" + label="?" + layout="topleft" + left_pad="10" + name="access_help" + top_delta="2" + width="18" /> + <button + enabled="false" + follows="left|top" + height="20" + label="Apply" + layout="topleft" + left="108" + name="apply_btn" + top="320" + width="100"> + <button.commit_callback + function="RegionInfo.Cancel" /> + </button> + <button + follows="left|top" + height="20" + label="Teleport Home One User..." + layout="topleft" + left="10" + name="kick_btn" + top_pad="10" + width="250" /> + <button + follows="left|top" + height="20" + label="Teleport Home All Users..." + layout="topleft" + left_delta="0" + name="kick_all_btn" + top_pad="3" + width="250" /> + <button + follows="left|top" + height="20" + label="Send Message To Region..." + layout="topleft" + left_delta="0" + name="im_btn" + top_pad="20" + width="200" /> + <button + follows="left|top" + height="20" + label="Manage Telehub..." + layout="topleft" + left_delta="0" + name="manage_telehub_btn" + top_pad="20" + width="150" /> +</panel> 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 a78a1ea98c..148d9500bb 100644 --- a/indra/newview/skins/default/xui/en/panel_region_terrain.xml +++ b/indra/newview/skins/default/xui/en/panel_region_terrain.xml @@ -2,13 +2,13 @@ <panel border="true" follows="top|left" - height="340" + height="320" label="Terrain" layout="topleft" left="0" name="Terrain" top="320" - width="280"> + width="480"> <text follows="left|top" font="SansSerif" @@ -28,7 +28,7 @@ left_delta="50" name="region_text" top_delta="0" - width="200"> + width="400"> unknown </text> <spinner @@ -101,9 +101,9 @@ height="20" label="Use Estate Sun" layout="topleft" - left="15" + left="250" name="use_estate_sun_check" - top="105" + top="35" width="100" /> <button follows="left|top" @@ -111,7 +111,7 @@ height="18" label="?" layout="topleft" - left_pad="85" + left_pad="70" name="use_estate_sun_help" top_delta="2" width="18" /> @@ -119,9 +119,9 @@ height="20" label="Fixed Sun" layout="topleft" - left="15" + left="250" name="fixed_sun_check" - top_pad="0" + top="55" width="100" /> <button follows="left|top" @@ -129,7 +129,7 @@ height="18" label="?" layout="topleft" - left_pad="85" + left_pad="70" name="fixed_sun_help" top_delta="2" width="18" /> @@ -137,9 +137,9 @@ height="20" image_name="icon_day_cycle.tga" layout="topleft" - left="50" + left="285" name="daycycle" - top_delta="25" + top="80" width="165" /> <slider follows="left|top" @@ -147,12 +147,12 @@ increment="0.001" label="Phase" layout="topleft" - left="15" + left="250" max_val="30" min_val="6" name="sun_hour_slider" show_text="false" - top_delta="30" + top="105" width="200" /> <button enabled="false" @@ -160,18 +160,18 @@ height="20" label="Apply" layout="topleft" - left="130" + left="350" name="apply_btn" - top_delta="30" + top="135" width="90" /> <view_border bevel_style="none" follows="top|left" - height="210" + height="130" layout="topleft" left="8" top="30" - width="240" /> + width="460" /> <button follows="left|top" height="20" @@ -180,7 +180,7 @@ left_delta="2" name="download_raw_btn" tool_tip="Available only to estate owners, not managers" - top_pad="15" + top_pad="60" width="170" /> <button follows="left|top" @@ -200,7 +200,7 @@ left="10" name="upload_raw_btn" tool_tip="Available only to estate owners, not managers" - top_pad="0" + top="243" width="170" /> <button follows="left|top" @@ -220,7 +220,7 @@ left="10" name="bake_terrain_btn" tool_tip="Set current terrain as mid-point for raise/lower limits" - top_pad="15" + top="283" width="100" /> <button follows="left|top" diff --git a/indra/newview/skins/default/xui/en/panel_region_texture.xml b/indra/newview/skins/default/xui/en/panel_region_texture.xml index 404e1b8907..5089064c07 100644 --- a/indra/newview/skins/default/xui/en/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_region_texture.xml @@ -2,231 +2,235 @@ <panel border="true" follows="top|left" - height="512" - name="TextureWrapper" + height="320" label="Ground Textures" layout="topleft" - width="280"> - <scroll_container - follows="top|left|right|bottom" - height="508" - name="container1" - layout="topleft" - width="280"> - <panel - follows="top|left" - height="575" - label="Ground Textures" + left="0" + name="Textures" + top="320" + width="480"> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" layout="topleft" - name="Textures" - width="258"> - <text - follows="left|top" - font="SansSerif" - height="20" - layout="topleft" - left="10" - name="region_text_lbl" - top="10" - width="100"> + left="10" + name="region_text_lbl" + top="10" + width="100"> Region: - </text> - <text - follows="left|top" - font="SansSerif" - height="20" - layout="topleft" - left_delta="50" - name="region_text" - top_delta="0" - width="200"> + </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="20" + layout="topleft" + left_delta="50" + name="region_text" + top_delta="0" + width="400"> unknown - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left="10" - name="detail_texture_text" - top="36" - width="300"> - Terrain Textures - (requires 512x512, 24 bit .tga files) - </text> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left_delta="0" - name="texture_detail_0" - top_delta="30" - width="100" /> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left_pad="10" - name="texture_detail_1" - top_delta="0" - width="100" /> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left="10" - name="texture_detail_2" - top_delta="105" - width="100" /> - <texture_picker - follows="left|top" - height="100" - layout="topleft" - left_pad="10" - name="texture_detail_3" - top_delta="0" - width="100" /> - <text - follows="left|top" - height="20" - layout="topleft" - left="10" - name="height_text_lbl" - top="157" - width="65"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="detail_texture_text" + top="36" + width="300"> + Terrain Textures (requires 512x512, 24 bit .tga files) + </text> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left_delta="0" + name="texture_detail_0" + top_delta="20" + width="100" /> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left_pad="10" + name="texture_detail_1" + top_delta="0" + width="100" /> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left_pad="10" + name="texture_detail_2" + top_delta="0" + width="100" /> + <texture_picker + follows="left|top" + height="100" + layout="topleft" + left_pad="10" + name="texture_detail_3" + top_delta="0" + width="100" /> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl" + top="146" + width="65"> 1 (Low) - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left_pad="45" - name="height_text_lbl2" - top_delta="0" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="45" + name="height_text_lbl2" + top_delta="0" + width="100"> 2 - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left="10" - name="height_text_lbl3" - top_delta="105" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl3" + top_delta="0" + width="100"> 3 - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left_pad="10" - name="height_text_lbl4" - top_delta="0" - width="100"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl4" + top_delta="0" + width="100"> 4 (High) - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left="10" - name="height_text_lbl5" - top_delta="25" - width="300"> + </text> + <text + type="string" + length="1" + follows="left|top" + height="20" + layout="topleft" + left="10" + name="height_text_lbl5" + top="186" + width="300"> Texture Elevation Ranges - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left="51" - name="height_text_lbl6" - top_delta="20" - width="100"> + </text> + <text + follows="left|top" + height="20" + layout="topleft" + left="51" + name="height_text_lbl6" + top="201" + width="100"> Southwest - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left_pad="10" - name="height_text_lbl7" - top_delta="0" - width="100"> + </text> + <text + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl7" + top_delta="0" + width="100"> Northwest - </text> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="Low" - label_width="37" - layout="topleft" - left="10" - max_val="500" - min_val="-500" - name="height_start_spin_0" - top_delta="20" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="Low" - label_width="37" - layout="topleft" - left_pad="10" - max_val="500" - min_val="-500" - name="height_start_spin_1" - top_delta="0" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="High" - label_width="37" - layout="topleft" - left="10" - max_val="500" - min_val="-500" - name="height_range_spin_0" - top_delta="20" - width="100" /> - <spinner - follows="left|top" - height="20" - increment="0.5" - label="High" - label_width="37" - layout="topleft" - left_pad="10" - max_val="500" - min_val="-500" - name="height_range_spin_1" - top_delta="0" - width="100" /> - <text - follows="left|top" - height="20" - layout="topleft" - left="51" - name="height_text_lbl8" - top_delta="30" - width="100"> + </text> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left="10" + max_val="500" + min_val="-500" + name="height_start_spin_0" + top_delta="20" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="Low" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_start_spin_1" + top_delta="0" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left="10" + max_val="500" + min_val="-500" + name="height_range_spin_0" + top_delta="20" + width="100" /> + <spinner + follows="left|top" + height="20" + increment="0.5" + label="High" + label_width="37" + layout="topleft" + left_pad="10" + max_val="500" + min_val="-500" + name="height_range_spin_1" + top_delta="0" + width="100" /> + <text + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl8" + top_delta="0" + width="100"> Southeast - </text> - <text - follows="left|top" - height="20" - layout="topleft" - left_pad="10" - name="height_text_lbl9" - top_delta="0" - width="100"> + </text> + <text + follows="left|top" + height="20" + layout="topleft" + left_pad="10" + name="height_text_lbl9" + top_delta="0" + width="100"> Northeast - </text> + </text> <spinner follows="left|top" height="20" @@ -303,17 +307,14 @@ and the HIGH value is the MINIMUM height of Texture #4. </text> - - <button - enabled="false" - follows="left|bottom" - height="20" - label="Apply" - layout="topleft" - left="120" - name="apply_btn" - top_delta="60" - width="100" /> - </panel> - </scroll_container> + <button + enabled="false" + follows="left|bottom" + height="20" + label="Apply" + layout="topleft" + left="350" + name="apply_btn" + top="290" + width="100" /> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml index d172154d49..d3d45640cb 100644 --- a/indra/newview/skins/default/xui/en/panel_side_tray.xml +++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml @@ -74,7 +74,7 @@ help_topic="sidebar_places" tab_title="Places" label="Places" - description="Find places to go and places you've been." + description="Find places to go and places you've visited before." image="TabIcon_Places_Off" mouse_opaque="false" background_visible="true" @@ -93,7 +93,7 @@ name="sidebar_me" help_topic="sidebar_me" tab_title="Me" - description="Change your profile, your look and quick links to your outfits." + description="Edit your public profile and Picks." image="TabIcon_Me_Off" mouse_opaque="false" background_visible="true" @@ -111,7 +111,7 @@ name="sidebar_appearance" help_topic="sidebar_appearance" tab_title="Appearance" - description="Change your looks and appearance." + description="Change your appearance and current look." image="TabIcon_Appearance_Off" mouse_opaque="false" background_opaque="false" diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml index d379c60aed..e991861e94 100644 --- a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml +++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel background_visible="true" - bevel_style="in" - follows="left|top|right|bottom" - height="420" + bevel_style="out" + follows="all" + height="560" label="home_tab" layout="topleft" name="home_tab" @@ -13,37 +13,36 @@ bg_alpha_color="DkGray2" class="panel_sidetray_home_info" follows="left|top|right" - height="130" + height="120" layout="topleft" - left="10" + left="15" + top="17" name="sidebar_people" - width="313"> + width="303"> <text follows="left|right|top" font="SansSerifBigBold" height="30" layout="topleft" - left="5" + left="10" mouse_opaque="false" name="tab_name" - text_color="white" + text_color="EmphasisColor" top="10" value="People" width="200" word_wrap="true" /> <icon - color="DkGray" follows="top|right" height="20" layout="topleft" name="tab_icon" right="-10" top="10" - image_name="TabIcon_Home_Selected" + image_name="TabIcon_People_Selected" width="20" /> <text follows="left|right|bottom" - font="SansSerifBold" height="120" layout="topleft" left="10" @@ -53,7 +52,7 @@ text_color="white" top="40" word_wrap="true"> - Find your friends, contacts and people nearby. + Find your friends, your groups, contacts and people nearby. </text> </panel> <panel @@ -61,37 +60,36 @@ bg_alpha_color="DkGray2" class="panel_sidetray_home_info" follows="left|top|right" - height="130" + height="120" layout="topleft" - left="10" + left="15" + top_pad="15" name="sidebar_places" - width="313"> + width="303"> <text follows="left|right|top" font="SansSerifBigBold" height="30" layout="topleft" - left="5" + left="10" mouse_opaque="false" name="tab_name" - text_color="white" + text_color="EmphasisColor" top="10" value="Places" width="200" word_wrap="true" /> <icon - color="DkGray" follows="top|right" height="20" layout="topleft" name="tab_icon" right="-10" top="10" - width="20" + width="20" image_name="TabIcon_Places_Selected"/> <text - follows="left|right|bottom|top" - font="SansSerifBold" + follows="all" height="120" layout="topleft" left="10" @@ -101,7 +99,7 @@ text_color="white" top="40" word_wrap="true"> - Find your friends, contacts and people nearby. + Find places to go and places you've visited before. </text> </panel> <panel @@ -109,37 +107,36 @@ bg_alpha_color="DkGray2" class="panel_sidetray_home_info" follows="left|top|right" - height="130" + height="120" layout="topleft" - left="10" + left="15" + top_pad="15" name="sidebar_me" - width="313"> + width="303"> <text follows="left|right|top" font="SansSerifBigBold" height="30" layout="topleft" - left="5" + left="10" mouse_opaque="false" name="tab_name" - text_color="white" + text_color="EmphasisColor" top="10" value="My Profile" width="200" word_wrap="true" /> <icon - color="DkGray" follows="top|right" height="20" layout="topleft" name="tab_icon" right="-10" top="10" - width="20" + width="20" image_name="TabIcon_Me_Selected"/> <text - follows="left|right|bottom|top" - font="SansSerifBold" + follows="all" height="120" layout="topleft" left="10" @@ -149,7 +146,7 @@ text_color="white" top="40" word_wrap="true"> - Change your profile. + Edit your public profile. </text> </panel> <panel @@ -157,37 +154,36 @@ bg_alpha_color="DkGray2" class="panel_sidetray_home_info" follows="left|top|right" - height="130" + height="120" layout="topleft" - left="10" + left="15" + top_pad="15" name="sidebar_appearance" - width="313"> + width="303"> <text follows="left|right|top" font="SansSerifBigBold" height="30" layout="topleft" - left="5" + left="10" mouse_opaque="false" name="tab_name" - text_color="white" + text_color="EmphasisColor" top="10" value="My Appearance" width="200" word_wrap="true" /> <icon - color="DkGray" follows="top|right" height="20" layout="topleft" name="tab_icon" right="-10" top="10" - width="20" - image_name="TabIcon_Things_Selected"/> + width="20" + image_name="TabIcon_Appearance_Selected"/> <text - follows="left|right|bottom|top" - font="SansSerifBold" + follows="all" height="120" layout="topleft" left="10" @@ -197,7 +193,7 @@ text_color="white" top="40" word_wrap="true"> - Change your apperance and looks. + Change your appearance and current look. </text> </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml index 07f0806ccb..fc61ce9683 100644 --- a/indra/newview/skins/default/xui/en/panel_status_bar.xml +++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml @@ -41,7 +41,7 @@ </panel.string> <button auto_resize="true" - halign="left" + halign="right" follows="right|bottom" font="SansSerifSmall" image_color="White_05" @@ -49,10 +49,11 @@ image_overlay="BuyArrow_Over" height="18" layout="topleft" - left="-210" + left="-225" name="buycurrency" + pad_right="23px" picture_style="true" - tool_tip="My Balance / Buy L$" + tool_tip="My Balance: Click to buy more L$" top="0" width="117" /> <text @@ -64,7 +65,7 @@ height="16" top="3" layout="topleft" - left_pad="5" + left_pad="20" name="TimeText" text_color="TimeTextColor" tool_tip="Current Time (Pacific)" @@ -103,7 +104,7 @@ bg_visible="false" text_readonly_color="HealthTextColor" follows="rsight|bottom" - font_shadow="hard" + font_shadow="none" height="16" layout="topleft" left_pad="18" diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml index aa95a2baef..b0cd75117f 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml @@ -1,16 +1,24 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <panel name="Teleport History" bottom="0" height="326" left="0" width="380" border="true" follows="left|top|right|bottom"> + <string + name="cant_create_lm_here" + value="Please teleport to selected location before creating Landmark. " /> + <string + name="create_landmark" + value="Create Landmark" /> + <string + name="open_landmark" + value="Open Landmark panel" /> <accordion follows="left|top|right|bottom" - height="326" + height="300" layout="topleft" left="0" top="0" name="history_accordion" width="380"> - - <accordion_tab + <accordion_tab can_resize="false" layout="topleft" name="today" @@ -24,9 +32,8 @@ name="today_items" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -41,9 +48,8 @@ name="yesterday_items" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -58,9 +64,8 @@ name="2_days_ago" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -75,9 +80,8 @@ name="3_days_ago" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -92,9 +96,8 @@ name="4_days_ago" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -109,9 +112,8 @@ name="5_days_ago_items" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -126,9 +128,8 @@ name="6_days_and_older_items" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -143,9 +144,8 @@ name="1_month_and_older_items" top="0" width="380"> - </flat_list_view> - </accordion_tab> - + </flat_list_view> + </accordion_tab> <accordion_tab can_resize="false" layout="topleft" @@ -160,7 +160,47 @@ name="6_months_and_older_items" top="0" width="380"> - </flat_list_view> - </accordion_tab> + </flat_list_view> + </accordion_tab> </accordion> + <panel + background_visible="true" + bevel_style="none" + top_pad="0" + follows="left|right|bottom" + height="30" + label="bottom_panel" + layout="topleft" + left="0" + name="bottom_panel" + width="380"> + <button + follows="bottom|left" + font="SansSerifBigBold" + tool_tip="" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + name="gear_btn" + picture_style="true" + top="5" + width="18" /> + <button + follows="bottom|left" + font="SansSerifBigBold" + height="18" + image_selected="Favorite_Star_Active" + image_disabled="Favorite_Star_Off" + image_unselected="Favorite_Star_Press" + layout="topleft" + left_pad="5" + name="star_btn" + picture_style="true" + tool_tip="" + top_delta="0" + width="18" /> + </panel> </panel> diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml index d640d3ad88..63c2d4538e 100644 --- a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml +++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml @@ -42,7 +42,7 @@ height="20" layout="topleft" left_pad="5" - use_ellipsis="true" + use_ellipses="true" name="region" text_color="white" top="4" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index d124a4cdfa..2a616d8e2f 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -14,7 +14,10 @@ <!-- starting up --> <string name="StartupDetectingHardware">Detecting hardware...</string> <string name="StartupLoading">Loading</string> + + <!-- Legacy strings, almost never used --> <string name="Fullbright">Fullbright (Legacy)</string> + <!-- Login --> <string name="LoginInProgress">Logging in. [APP_NAME] may appear frozen. Please wait.</string> <string name="LoginInProgressNoFrozen">Logging in...</string> @@ -59,8 +62,8 @@ <string name="TooltipFlagNoScripts">No Scripts</string> <string name="TooltipLand">Land:</string> <string name="TooltipMustSingleDrop">Only a single item can be dragged here</string> - <string name="TooltipAltLeft">Alt-Left arrow for previous tab</string> - <string name="TooltipAltRight">Alt-Right arrow for next tab</string> + <string name="TooltipAltLeft">Alt+← for previous tab</string> + <string name="TooltipAltRight">Alt+→ for next tab</string> <!-- tooltips for Urls --> <string name="TooltipHttpUrl">Click to view this web page</string> @@ -75,8 +78,8 @@ <string name="TooltipSLAPP">Click to run the secondlife:// command</string> <!-- ButtonToolTips, llfloater.cpp --> - <string name="BUTTON_CLOSE_DARWIN">Close (⌘-W)</string> - <string name="BUTTON_CLOSE_WIN">Close (Ctrl-W)</string> + <string name="BUTTON_CLOSE_DARWIN">Close (⌘W)</string> + <string name="BUTTON_CLOSE_WIN">Close (Ctrl+W)</string> <string name="BUTTON_RESTORE">Restore</string> <string name="BUTTON_MINIMIZE">Minimize</string> <string name="BUTTON_TEAR_OFF">Tear Off</string> @@ -230,8 +233,10 @@ <string name="anim_yes_happy">Yes (Happy)</string> <string name="anim_yes_head">Yes</string> + <!-- world map --> <string name="texture_loading">Loading...</string> <string name="worldmap_offline">Offline</string> + <string name="worldmap_results_none_found">None found.</string> <!-- animations uploading status codes --> <string name="Ok">OK</string> @@ -2110,6 +2115,15 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh <string name="AddLandmarkNavBarMenu">Add Landmark...</string> <string name="EditLandmarkNavBarMenu">Edit Landmark...</string> + <!-- menu accelerators --> + <string name="accel-mac-control">⌃</string> + <string name="accel-mac-command">⌘</string> + <string name="accel-mac-option">⌥</string> + <string name="accel-mac-shift">⇧</string> + <string name="accel-win-control">Ctrl+</string> + <string name="accel-win-alt">Alt+</string> + <string name="accel-win-shift">Shift+</string> + <!-- Previews --> <string name="FileSaved">File Saved</string> <string name="Receiving">Receiving</string> @@ -2225,9 +2239,8 @@ Running in window. <string name="MBPixelFmtErr">Can't find suitable pixel format</string> <string name="MBPixelFmtDescErr">Can't get pixel format description</string> <string name="MBTrueColorWindow"> - [APP_NAME] requires True Color (32-bit) to run in a window. -Please go to Control Panels > Display > Settings and set the screen to 32-bit color. -Alternately, if you choose to run fullscreen, [APP_NAME] will automatically adjust the screen each time it runs. + [APP_NAME] requires True Color (32-bit) to run. +Please go to your computer's display settings and set the color mode to 32-bit. </string> <string name="MBAlpha"> [APP_NAME] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues. @@ -2246,14 +2259,14 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <!-- Avatar Shape Information --> <string name="5 O'Clock Shadow">5 O'Clock Shadow</string> -<string name="5 O'Clock Shadow bump">5 O'Clock Shadow bump</string> + <string name="All White">All White</string> <string name="Anime Eyes">Anime Eyes</string> <string name="Arced">Arced</string> <string name="Arm Length">Arm Length</string> <string name="Attached">Attached</string> <string name="Attached Earlobes">Attached Earlobes</string> -<string name="BELLY">BELLY</string> + <string name="Back Bangs">Back Bangs</string> <string name="Back Bangs Down">Back Bangs Down</string> <string name="Back Bangs Up">Back Bangs Up</string> @@ -2270,9 +2283,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Big">Big</string> <string name="Big Butt">Big Butt</string> <string name="Big Eyeball">Big Eyeball</string> -<string name="Big Hair Back">Big Hair Back</string> -<string name="Big Hair Front">Big Hair Front</string> -<string name="Big Hair Top">Big Hair Top</string> +<string name="Big Hair Back">Big Hair: Back</string> +<string name="Big Hair Front">Big Hair: Front</string> +<string name="Big Hair Top">Big Hair: Top</string> <string name="Big Head">Big Head</string> <string name="Big Pectorals">Big Pectorals</string> <string name="Big Spikes">Big Spikes</string> @@ -2291,7 +2304,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Bottom">Bottom</string> <string name="Bottom Left">Bottom Left</string> <string name="Bottom Right">Bottom Right</string> -<string name="Bottom bump">Bottom bump</string> + <string name="Bow Legged">Bow Legged</string> <string name="Breast Buoyancy">Breast Buoyancy</string> <string name="Breast Cleavage">Breast Cleavage</string> @@ -2303,12 +2316,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Bugged Eyes">Bugged Eyes</string> <string name="Bulbous">Bulbous</string> <string name="Bulbous Nose">Bulbous Nose</string> -<string name="Bump base">Bump base</string> -<string name="Bump upperdef">Bump upperdef</string> + + <string name="Bushy Eyebrows">Bushy Eyebrows</string> <string name="Bushy Hair">Bushy Hair</string> <string name="Butt Size">Butt Size</string> -<string name="CHEST">CHEST</string> +<string name="bustle skirt">Bustle Skirt</string> +<string name="no bustle">No Bustle</string> +<string name="more bustle">More Bustle</string> + <string name="Center">Center</string> <string name="Center 2">Center 2</string> <string name="Chaplin">Chaplin</string> @@ -2319,7 +2335,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Chin Angle">Chin Angle</string> <string name="Chin Cleft">Chin Cleft</string> <string name="Chin Curtains">Chin Curtains</string> -<string name="Chin Curtains bump">Chin Curtains bump</string> + <string name="Chin Depth">Chin Depth</string> <string name="Chin Heavy">Chin Heavy</string> <string name="Chin In">Chin In</string> @@ -2335,13 +2351,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Closed Right">Closed Right</string> <string name="Coin Purse">Coin Purse</string> <string name="Collar Back">Collar Back</string> -<string name="Collar Back Height Cloth">Collar Back Height Cloth</string> -<string name="Collar Back Shadow Height">Collar Back Shadow Height</string> -<string name="Collar Back bump">Collar Back bump</string> + + + <string name="Collar Front">Collar Front</string> -<string name="Collar Front Height Cloth">Collar Front Height Cloth</string> -<string name="Collar Front Shadow Height">Collar Front Shadow Height</string> -<string name="Collar Front bump">Collar Front bump</string> + + + <string name="Corner Down">Corner Down</string> <string name="Corner Normal">Corner Normal</string> <string name="Corner Up">Corner Up</string> @@ -2375,11 +2391,11 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Eyeball Size">Eyeball Size</string> <string name="Eyebrow Arc">Eyebrow Arc</string> <string name="Eyebrow Density">Eyebrow Density</string> -<string name="Eyebrow Density Bump">Eyebrow Density Bump</string> + <string name="Eyebrow Height">Eyebrow Height</string> <string name="Eyebrow Points">Eyebrow Points</string> <string name="Eyebrow Size">Eyebrow Size</string> -<string name="Eyebrow Size Bump">Eyebrow Size Bump</string> + <string name="Eyelash Length">Eyelash Length</string> <string name="Eyeliner">Eyeliner</string> <string name="Eyeliner Color">Eyeliner Color</string> @@ -2429,21 +2445,21 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Full Sides">Full Sides</string> <string name="Glossy">Glossy</string> <string name="Glove Fingers">Glove Fingers</string> -<string name="Glove Fingers bump">Glove Fingers bump</string> + <string name="Glove Length">Glove Length</string> -<string name="Glove Length bump">Glove Length bump</string> -<string name="HEAD">HEAD</string> + + <string name="Hair">Hair</string> -<string name="Hair Back">Hair Back</string> -<string name="Hair Front">Hair Front</string> -<string name="Hair Sides">Hair Sides</string> +<string name="Hair Back">Hair: Back</string> +<string name="Hair Front">Hair: Front</string> +<string name="Hair Sides">Hair: Sides</string> <string name="Hair Sweep">Hair Sweep</string> -<string name="Hair Thickess">Hair Thickess</string> +<string name="Hair Thickess">Hair Thickness</string> <string name="Hair Thickness">Hair Thickness</string> <string name="Hair Tilt">Hair Tilt</string> <string name="Hair Tilted Left">Hair Tilted Left</string> <string name="Hair Tilted Right">Hair Tilted Right</string> -<string name="Hair Volume">Hair Volume</string> +<string name="Hair Volume">Hair: Volume</string> <string name="Hand Size">Hand Size</string> <string name="Handlebars">Handlebars</string> <string name="Head Length">Head Length</string> @@ -2462,15 +2478,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Hip Length">Hip Length</string> <string name="Hip Width">Hip Width</string> <string name="In">In</string> -<string name="In Shdw Color">In Shdw Color</string> -<string name="In Shdw Opacity">In Shdw Opacity</string> +<string name="In Shdw Color">Inner Shadow Color</string> +<string name="In Shdw Opacity">Inner Shadow Opacity</string> <string name="Inner Eye Corner">Inner Eye Corner</string> <string name="Inner Eye Shadow">Inner Eye Shadow</string> <string name="Inner Shadow">Inner Shadow</string> -<string name="Jacket Collar Back bump">Jacket Collar Back bump</string> -<string name="Jacket Collar Front bump">Jacket Collar Front bump</string> + + <string name="Jacket Length">Jacket Length</string> -<string name="Jacket Sleeve Length bump">Jacket Sleeve Length bump</string> + <string name="Jacket Wrinkles">Jacket Wrinkles</string> <string name="Jaw Angle">Jaw Angle</string> <string name="Jaw Jut">Jaw Jut</string> @@ -2534,11 +2550,11 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Long Torso">Long Torso</string> <string name="Long arms">Long arms</string> <string name="Longcuffs">Longcuffs</string> -<string name="Loose Lower Clothing">Loose Lower Clothing</string> + <string name="Loose Pants">Loose Pants</string> <string name="Loose Shirt">Loose Shirt</string> <string name="Loose Sleeves">Loose Sleeves</string> -<string name="Loose Upper Clothing">Loose Upper Clothing</string> + <string name="Love Handles">Love Handles</string> <string name="Low">Low</string> <string name="Low Heels">Low Heels</string> @@ -2548,7 +2564,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Lower">Lower</string> <string name="Lower Bridge">Lower Bridge</string> <string name="Lower Cheeks">Lower Cheeks</string> -<string name="Lower Clothes Shading">Lower Clothes Shading</string> + <string name="Male">Male</string> <string name="Middle Part">Middle Part</string> <string name="More">More</string> @@ -2574,14 +2590,14 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="More Volume">More Volume</string> <string name="More soul">More soul</string> <string name="Moustache">Moustache</string> -<string name="Moustache bump">Moustache bump</string> + <string name="Mouth">Mouth</string> <string name="Mouth Corner">Mouth Corner</string> <string name="Mouth Position">Mouth Position</string> <string name="Mowhawk">Mowhawk</string> <string name="Muscular">Muscular</string> <string name="Mutton Chops">Mutton Chops</string> -<string name="NECK">NECK</string> + <string name="Nail Polish">Nail Polish</string> <string name="Nail Polish Color">Nail Polish Color</string> <string name="Narrow">Narrow</string> @@ -2616,7 +2632,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Nose Width">Nose Width</string> <string name="Nostril Division">Nostril Division</string> <string name="Nostril Width">Nostril Width</string> -<string name="NotHair">NotHair</string> + <string name="Old">Old</string> <string name="Opaque">Opaque</string> <string name="Open">Open</string> @@ -2626,21 +2642,21 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Open Right">Open Right</string> <string name="Orange">Orange</string> <string name="Out">Out</string> -<string name="Out Shdw Color">Out Shdw Color</string> -<string name="Out Shdw Opacity">Out Shdw Opacity</string> +<string name="Out Shdw Color">Outer Shadow Color</string> +<string name="Out Shdw Opacity">Outer Shadow Opacity</string> <string name="Outer Eye Corner">Outer Eye Corner</string> <string name="Outer Eye Shadow">Outer Eye Shadow</string> <string name="Outer Shadow">Outer Shadow</string> <string name="Overbite">Overbite</string> -<string name="PELVIS">PELVIS</string> + <string name="Package">Package</string> <string name="Painted Nails">Painted Nails</string> <string name="Pale">Pale</string> <string name="Pants Crotch">Pants Crotch</string> <string name="Pants Fit">Pants Fit</string> <string name="Pants Length">Pants Length</string> -<string name="Pants Length Cloth">Pants Length Cloth</string> -<string name="Pants Length Shadow">Pants Length Shadow</string> + + <string name="Pants Waist">Pants Waist</string> <string name="Pants Wrinkles">Pants Wrinkles</string> <string name="Part">Part</string> @@ -2707,12 +2723,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Shift Mouth">Shift Mouth</string> <string name="Shift Right">Shift Right</string> <string name="Shirt Bottom">Shirt Bottom</string> -<string name="Shirt Bottom Cloth">Shirt Bottom Cloth</string> + <string name="Shirt Fit">Shirt Fit</string> -<string name="Shirt Shadow Bottom">Shirt Shadow Bottom</string> + <string name="Shirt Wrinkles">Shirt Wrinkles</string> <string name="Shoe Height">Shoe Height</string> -<string name="Shoe Height bump">Shoe Height bump</string> + <string name="Short">Short</string> <string name="Short Arms">Short Arms</string> <string name="Short Legs">Short Legs</string> @@ -2728,7 +2744,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Side Bangs Up">Side Bangs Up</string> <string name="Side Fringe">Side Fringe</string> <string name="Sideburns">Sideburns</string> -<string name="Sideburns bump">Sideburns bump</string> + <string name="Sides Hair">Sides Hair</string> <string name="Sides Hair Down">Sides Hair Down</string> <string name="Sides Hair Up">Sides Hair Up</string> @@ -2739,24 +2755,24 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Skull">Skull</string> <string name="Slanted Forehead">Slanted Forehead</string> <string name="Sleeve Length">Sleeve Length</string> -<string name="Sleeve Length Cloth">Sleeve Length Cloth</string> -<string name="Sleeve Length Shadow">Sleeve Length Shadow</string> -<string name="Sleeve Length bump">Sleeve Length bump</string> + + + <string name="Sleeve Looseness">Sleeve Looseness</string> -<string name="Slit Back">Slit Back</string> -<string name="Slit Front">Slit Front</string> -<string name="Slit Left">Slit Left</string> -<string name="Slit Right">Slit Right</string> +<string name="Slit Back">Slit: Back</string> +<string name="Slit Front">Slit: Front</string> +<string name="Slit Left">Slit: Left</string> +<string name="Slit Right">Slit: Right</string> <string name="Small">Small</string> <string name="Small Hands">Small Hands</string> <string name="Small Head">Small Head</string> <string name="Smooth">Smooth</string> <string name="Smooth Hair">Smooth Hair</string> <string name="Socks Length">Socks Length</string> -<string name="Socks Length bump">Socks Length bump</string> + <string name="Some">Some</string> <string name="Soulpatch">Soulpatch</string> -<string name="Soulpatch bump">Soulpatch bump</string> + <string name="Sparse">Sparse</string> <string name="Spiked Hair">Spiked Hair</string> <string name="Spine">Spine</string> @@ -2809,13 +2825,13 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Upper Bridge">Upper Bridge</string> <string name="Upper Cheeks">Upper Cheeks</string> <string name="Upper Chin Cleft">Upper Chin Cleft</string> -<string name="Upper Clothes Shading">Upper Clothes Shading</string> + <string name="Upper Eyelid Fold">Upper Eyelid Fold</string> <string name="Upturned">Upturned</string> <string name="Very Red">Very Red</string> <string name="Waist Height">Waist Height</string> -<string name="Waist Height Cloth">Waist Height Cloth</string> -<string name="Waist Height Shadow">Waist Height Shadow</string> + + <string name="Well-Fed">Well-Fed</string> <string name="White Hair">White Hair</string> <string name="Wide">Wide</string> @@ -2825,11 +2841,6 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="Wild">Wild</string> <string name="Wrinkles">Wrinkles</string> - <!-- Favorites Bar --> - <string name="location_ctrl_add_landmark">Add to My Landmarks</string> - <string name="location_ctrl_edit_landmark">Edit My Landmark</string> - <string name="favorite_landmark_loading_tooltip">(Loading...)</string> - <!-- Strings used by the (currently Linux) auto-updater app --> <string name="UpdaterWindowTitle"> [APP_NAME] Update @@ -2887,6 +2898,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="no_ability_error"> You do not have that ability. </string> + <string name="no_ability"> + You do not have that ability. + </string> <string name="not_a_mod_error"> You are not a session moderator. </string> diff --git a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml index df5ea24c73..3ff0b3062a 100644 --- a/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml +++ b/indra/newview/skins/default/xui/en/widgets/accordion_tab.xml @@ -1,6 +1,12 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <accordion_tab + header_bg_color="0.68 0.68 0.68 1" + header_txt_color="0.68 0.68 0.68 1" header_collapse_img="Accordion_ArrowClosed_Off" header_collapse_img_pressed="Accordion_ArrowClosed_Press" header_expand_img="Accordion_ArrowOpened_Off" - header_expand_img_pressed="Accordion_ArrowOpened_Press" /> + header_expand_img_pressed="Accordion_ArrowOpened_Press" + header_image="Accordion_Off.png" + header_image_over="Accordion_Over" + header_image_pressed="Accordion_Press" + /> diff --git a/indra/newview/skins/default/xui/en/widgets/combo_box.xml b/indra/newview/skins/default/xui/en/widgets/combo_box.xml index 0dbca318b6..8b23b72c2d 100644 --- a/indra/newview/skins/default/xui/en/widgets/combo_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/combo_box.xml @@ -7,7 +7,7 @@ label="" hover_glow_amount="0.15" font="SansSerifSmall" - scale_image="true" + scale_image="false" image_unselected="ComboButton_Off" image_selected="ComboButton_Selected" image_disabled="ComboButton_Disabled" /> @@ -15,7 +15,7 @@ label="" hover_glow_amount="0.15" font="SansSerifSmall" - scale_image="true" + scale_image="false" pad_right="24" image_unselected="DropDown_Off" image_selected="DropDown_Selected" @@ -23,7 +23,11 @@ <combo_box.combo_list bg_writeable_color="MenuDefaultBgColor" background_visible="true" /> + <!-- Text is "tentative" if you have typed in a string that does not match + any item in the list, but we usually don't care, so use the same color + as normal text. --> <combo_box.combo_editor name="Combo Text Entry" select_on_focus="true" - font="SansSerifSmall" /> + font="SansSerifSmall" + text_tentative_color="TextFgColor" /> </combo_box> diff --git a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml index 6381dce1d6..319beac291 100644 --- a/indra/newview/skins/default/xui/en/widgets/expandable_text.xml +++ b/indra/newview/skins/default/xui/en/widgets/expandable_text.xml @@ -5,11 +5,12 @@ more_label="More" follows="left|top" name="text" + allow_scroll="true" use_ellipses="true" word_wrap="true" tab_stop="true" - v_pad="2" - h_pad="3" > + v_pad="3" + h_pad="4" > </textbox> <scroll name="scroll" diff --git a/indra/newview/skins/default/xui/en/widgets/location_input.xml b/indra/newview/skins/default/xui/en/widgets/location_input.xml index df8a9431d7..d86103aedc 100644 --- a/indra/newview/skins/default/xui/en/widgets/location_input.xml +++ b/indra/newview/skins/default/xui/en/widgets/location_input.xml @@ -18,10 +18,12 @@ max_chars="20" follows="left|top" allow_new_values="true" + add_landmark_tool_tip="Add this to My Landmarks" + edit_landmark_tool_tip="Edit My Landmark" > <info_button name="Place Information" label="" - tool_tip="About current location" + tool_tip="See more info about the current location" width="16" height="16" follows="left|top" @@ -35,11 +37,12 @@ hover_glow_amount="0.15" image_hover_selected="Favorite_Star_Over" image_hover_unselected="Favorite_Star_Over" - width="16" - height="16" - tool_tip="Add to My Landmarks" + width="18" + height="18" follows="right|top" - scale_image="false" /> + scale_image="false" + top="19" + left="-3" /> <combo_button name="Location History" label="" pad_right="0" diff --git a/indra/newview/skins/default/xui/en/widgets/menu.xml b/indra/newview/skins/default/xui/en/widgets/menu.xml index 58543338f6..53034afa61 100644 --- a/indra/newview/skins/default/xui/en/widgets/menu.xml +++ b/indra/newview/skins/default/xui/en/widgets/menu.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <menu bg_color="MenuDefaultBgColor" bg_visible="true" - drop_shadow="true" + drop_shadow="false" tear_off="false" shortcut_pad="15"> </menu> diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml index e998635d20..a054b4ee60 100644 --- a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml +++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml @@ -5,11 +5,13 @@ show_text_as_tentative="false" dropdown_button_visible="false" max_chars="256" + name="parent" allow_new_values="true" background_image="TextField_Search_Off" background_image_disabled="TextField_Search_Disabled" background_image_focused="TextField_Search_Active"> <combo_editor + name="child1" select_on_focus="true" text_pad_left="20" tool_tip="Search" @@ -18,9 +20,11 @@ background_image_focused="TextField_Search_Active"/> <combo_list multi_select="false" + name="child2" page_lines="10" scroll_bar_bg_visible="true" /> <search_button label="" + name="child3" top_pad="4" left_pad="4" width="13" diff --git a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml index 8ace7b96bc..bb46ec0954 100644 --- a/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml +++ b/indra/newview/skins/default/xui/en/widgets/simple_text_editor.xml @@ -5,7 +5,7 @@ font="SansSerifSmall" max_length="255" embedded_items="false" - hide_scrollbar="false" + allow_scroll="true" border_visible="false" word_wrap="false" ignore_tab="true" @@ -15,8 +15,8 @@ default_color="TextDefaultColor" text_color="TextFgColor" text_readonly_color="TextFgReadOnlyColor" - h_pad="5" - v_pad="3" + h_pad="6" + v_pad="4" bg_visible="true" bg_readonly_color="TextBgReadOnlyColor" bg_writeable_color="TextBgWriteableColor" diff --git a/indra/newview/skins/default/xui/en/widgets/tab_container.xml b/indra/newview/skins/default/xui/en/widgets/tab_container.xml index 6dfb6ecf9c..25d85899a1 100644 --- a/indra/newview/skins/default/xui/en/widgets/tab_container.xml +++ b/indra/newview/skins/default/xui/en/widgets/tab_container.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <tab_container tab_min_width="60" tab_max_width="150" + tab_height="16" tab_top_image_unselected="TabTop_Middle_Off" tab_top_image_selected="TabTop_Middle_Selected" tab_bottom_image_unselected="Toolbar_Left_Off" diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml index 5914c21b2b..5dd09e663b 100644 --- a/indra/newview/skins/default/xui/en/widgets/text.xml +++ b/indra/newview/skins/default/xui/en/widgets/text.xml @@ -1,15 +1,14 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <text allow_html="true" - clip_to_rect="false" mouse_opaque="false" name="text_box" font="SansSerifSmall" - font_shadow="soft" + font_shadow="none" tab_stop="false" halign="left" hover_color="LabelSelectedColor" - h_pad="-1" - hide_scrollbar="true" + h_pad="0" + allow_scroll="false" text_readonly_color="LabelDisabledColor" bg_writeable_color="FloaterDefaultBackgroundColor" border_color="DefaultHighlightLight" @@ -18,5 +17,5 @@ border_visible="false" hover="false" text_color="LabelTextColor" - v_pad="-1" + v_pad="0" max_length="4096"/> diff --git a/indra/newview/skins/default/xui/en/widgets/textbase.xml b/indra/newview/skins/default/xui/en/widgets/textbase.xml index c352abca3b..e5dc022633 100644 --- a/indra/newview/skins/default/xui/en/widgets/textbase.xml +++ b/indra/newview/skins/default/xui/en/widgets/textbase.xml @@ -1,4 +1,4 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<textbase clip_to_rect="true" - h_pad="4" - v_pad="4"/> +<textbase allow_scroll="true" + h_pad="5" + v_pad="5"/> diff --git a/indra/newview/skins/default/xui/es/floater_sell_land.xml b/indra/newview/skins/default/xui/es/floater_sell_land.xml index 6d1122a771..bce13c1e33 100644 --- a/indra/newview/skins/default/xui/es/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/es/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="sell land" title="Vender el terreno"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Parcela: </text> @@ -57,4 +59,6 @@ de propietario. </text> <button label="Poner el terreno en venta" name="sell_btn"/> <button label="Cancelar" name="cancel_btn"/> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index c3c4c55027..da842d22c6 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -159,7 +159,7 @@ </combo_box> <panel name="perms_build"> <text name="perm_modify"> - Puede modificar este objeto. + Puede modificar este objeto </text> <text name="B:"> B: @@ -187,28 +187,28 @@ <check_box name="checkbox next owner can transfer" left_delta="67"/> </panel> <string name="text modify info 1"> - Puede modificar este objeto. + Puede modificar este objeto </string> <string name="text modify info 2"> - Puede modificar estos objetos. + Puede modificar estos objetos </string> <string name="text modify info 3"> - No puede modificar este objeto. + No puede modificar este objeto </string> <string name="text modify info 4"> - No puede modificar estos objetos. + No puede modificar estos objetos </string> <string name="text modify warning"> - Debe seleccionar todo el objeto para definir los permisos. + Debe seleccionar todo el objeto para definir los permisos </string> <string name="Cost Default"> - Precio: L$ + Precio: L$ </string> <string name="Cost Total"> - Precio total: L$ + Precio total: L$ </string> <string name="Cost Per Unit"> - Precio por: L$ + Precio por: L$ </string> <string name="Cost Mixed"> Precio variable @@ -502,7 +502,7 @@ </panel> <panel label="Contenido " name="Contents"> <button label="Script nuevo" label_selected="Script nuevo" name="button new script"/> - <button label="Permisos..." name="button permissions"/> + <button label="Permisos" name="button permissions"/> </panel> </tab_container> <panel name="land info panel"> @@ -516,18 +516,18 @@ Superficie: [AREA] m² </text> <button label="Acerca del terreno..." label_selected="Acerca del terreno..." name="button about land" width="140"/> - <check_box label="Mostrar los propietarios" name="checkbox show owners" tool_tip="El color de las parcelas es según su propietario"/> + <check_box label="Mostrar los propietarios" name="checkbox show owners" tool_tip="El color de las parcelas es según su propietario: Verde = Su terreno Agua = Terreno de sus grupos Rojo = Propiedad de otros Amarillo = En venta Morado = Para subasta Gris = Público"/> <button label="?" label_selected="?" name="button show owners help" left_delta="150"/> <text name="label_parcel_modify"> Modificar la parcela </text> - <button label="Subdividir..." label_selected="Subdividir..." name="button subdivide land" width="140"/> - <button label="Unir..." label_selected="Unir..." name="button join land" width="140"/> + <button label="Subdividir" label_selected="Subdividir" name="button subdivide land" width="140"/> + <button label="Unir" label_selected="Unir" name="button join land" width="140"/> <text name="label_parcel_trans"> Transacciones de terreno </text> - <button label="Comprar terreno..." label_selected="Comprar terreno..." name="button buy land" width="140"/> - <button label="Abandonar el terreno..." label_selected="Abandonar el terreno..." name="button abandon land" width="140"/> + <button label="Comprar terreno" label_selected="Comprar terreno" name="button buy land" width="140"/> + <button label="Abandonar el terreno" label_selected="Abandonar el terreno" name="button abandon land" width="140"/> </panel> <floater.string name="status_rotate"> Arrastre las bandas de color para girar el objeto diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml index e418de3929..86f3f1f125 100644 --- a/indra/newview/skins/default/xui/es/notifications.xml +++ b/indra/newview/skins/default/xui/es/notifications.xml @@ -1760,7 +1760,7 @@ Si se marca esta opción, los compradores podrán revender el terreno que compre Por defecto: Deshabilitado </notification> <notification label="Desactivar los scripts" name="HelpRegionDisableScripts"> - Cuando el rendimiento de un sim es pobre, el culpable puede ser un script. Abra Estadísticas (Ctrl-May-1). Mire Simulator Physics FPS. Si es menor de 45, abre el panel Time, en la parte inferior de las Estadísticas. Si ve que Script Time está en 25 ms o más alto, pulse el botón Listar los scripts según su uso, y verá el nombre y la posición de los scripts que pueden estar causando el bajo rendimiento. + Cuando el rendimiento de un sim es pobre, el culpable puede ser un script. Abra Estadísticas (Ctrl+May+1). Mire Simulator Physics FPS. Si es menor de 45, abre el panel Time, en la parte inferior de las Estadísticas. Si ve que Script Time está en 25 ms o más alto, pulse el botón Listar los scripts según su uso, y verá el nombre y la posición de los scripts que pueden estar causando el bajo rendimiento. Marcando la casilla Desactivar los scripts y pulsando el botón Aplicar, se desactivarán temporalmente en esta región todos los scripts. Debe hacer esto para viajar a la posición que ha visto en la Lista de scripts según su uso. Cuando llegue, investigue el script para determinar si es él quien causa el problema. Deberá contactar con el propietario del script, o borrar o devolver el objeto. @@ -1769,7 +1769,7 @@ Desmarque la casilla Desactivar los scripts y pulse Aplicar para reactivar los s Por defecto: off </notification> <notification label="Desactivar las colisiones" name="HelpRegionDisableCollisions"> - Cuando el rendimiento de un sim es pobre, la culpa puede estar en los objetos físicos. Abra Estadísticas (Ctrl-May-1). Mire Simulator Physics FPS. Si es menor de 45, abre el panel Time, en la parte inferior de las Estadísticas. Si ve que Sim Time (Physics) está en 20 ms o más alto, pulse el botón Listar los objetos que colisionan, y verá el nombre y la posición de los objetos que pueden estar causando el bajo rendimiento. + Cuando el rendimiento de un sim es pobre, la culpa puede estar en los objetos físicos. Abra Estadísticas (Ctrl+May+1). Mire Simulator Physics FPS. Si es menor de 45, abre el panel Time, en la parte inferior de las Estadísticas. Si ve que Sim Time (Physics) está en 20 ms o más alto, pulse el botón Listar los objetos que colisionan, y verá el nombre y la posición de los objetos que pueden estar causando el bajo rendimiento. Marcando la casilla Desactivar las colisiones y pulsando el botón Aplicar, se desactivarán temporalmente las colisiones entre objetos. Debe hacer esto para viajar a la localización que se ha avisado en la Lista de objetos que colisionan. Cuando llegue, investigue el objeto: @@ -1993,9 +1993,9 @@ Dado que estos objetos tienen scripts, moverlos a su inventario puede provocar u <usetemplate ignoretext="Cuando mueva objetos con script 'no copiables' del inventario" name="okcancelignore" notext="Cancelar" yestext="OK"/> </notification> <notification name="ClickActionNotPayable"> - Atención: la acción Pagar al objeto al pulsar ha sido marcada, pero sólo funcionará si se añade un script con un evento money(). + Atención: la acción 'Pagar al objeto' al pulsar ha sido marcada, pero sólo funcionará si se añade un script con un evento money(). <form name="form"> - <ignore name="ignore" text="Cuando configure 'Pagar' en objetos sin el evento money()"/> + <ignore name="ignore" text="Cuando configure 'Pagar al objeto' sin el evento money()"/> </form> </notification> <notification name="OpenObjectCannotCopy"> @@ -2917,7 +2917,7 @@ Los objetos flexibles no pueden ser materiales, y serán inmateriales hasta que <notification name="FirstDebugMenus"> Ha activado el menú Avanzado. Contiene herramientas útiles para los desarrolladores que trabajan mejorando [SECOND_LIFE]. -Para pasar este menú a una ventana, pulse Ctrl-Alt-D. En un Mac, pulse ⌘-Opt-D. +Para pasar este menú a una ventana, pulse Ctrl+Alt+D. En un Mac, pulse ⌥⌘D. </notification> <notification name="FirstSculptedPrim"> Está editando un prim 'sculpted'. diff --git a/indra/newview/skins/default/xui/es/panel_edit_profile.xml b/indra/newview/skins/default/xui/es/panel_edit_profile.xml new file mode 100644 index 0000000000..bcf4128e01 --- /dev/null +++ b/indra/newview/skins/default/xui/es/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Residente" />
+ <string name="AcctTypeTrial"
+ value="Prueba" />
+ <string name="AcctTypeCharterMember"
+ value="Miembro fundador" />
+ <string name="AcctTypeEmployee"
+ value="Empleado de Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Ha usado una forma de pago" />
+ <string name="PaymentInfoOnFile"
+ value="Hay infor. de la forma de pago" />
+ <string name="NoPaymentInfoOnFile"
+ value="Sin infor. de la forma de pago" />
+ <string name="AgeVerified"
+ value="Edad verificada" />
+ <string name="NotAgeVerified"
+ value="Edad no verificada" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=es
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Compañero/a:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Mensaje en el estado ocupado:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_group_general.xml b/indra/newview/skins/default/xui/es/panel_group_general.xml index 0c98889d32..4fd5685b7d 100644 --- a/indra/newview/skins/default/xui/es/panel_group_general.xml +++ b/indra/newview/skins/default/xui/es/panel_group_general.xml @@ -1,9 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="General" name="general_tab"> <string name="help_text"> - La pestaña General contiene información global de este grupo, -la lista de propietarios y miembros visibles, -las preferencias generales del grupo, y las opciones de los miembros. + La pestaña General contiene información global de este grupo, la lista de propietarios y miembros visibles, las preferencias generales del grupo, y las opciones de los miembros. Ponga su ratón sobre las opciones para más información. </string> @@ -47,7 +45,7 @@ Ponga su ratón sobre las opciones para más información. <panel name="preferences_container"> <check_box label="Mostrar en la búsqueda" name="show_in_group_list" tool_tip="Dejar que la gente vea este grupo en los resultados de la búsqueda."/> <check_box label="Inscripción libre" name="open_enrollement" tool_tip="Definir si se admiten al grupo nuevos miembros sin que sea preciso invitárseles."/> - <check_box label="Cuota de inscripción en L$:" name="check_enrollment_fee" tool_tip="Define si se requiere una cuota para entrar al grupo."/> + <check_box label="Cuota de inscripción:" name="check_enrollment_fee" tool_tip="Define si se requiere una cuota para entrar al grupo."/> <spinner width="60" left_delta="130" name="spin_enrollment_fee" tool_tip="Cuando está marcado 'Cuota de inscripción', los miembros nuevos deben pagar esta cuota para entrar al grupo."/> <combo_box bottom_delta="-38" width="150" name="group_mature_check" tool_tip="Establece si la información de su grupo es 'mature'."> <combo_box.item name="select_mature" label="- Elegir Calificación -"/> diff --git a/indra/newview/skins/default/xui/es/panel_group_land_money.xml b/indra/newview/skins/default/xui/es/panel_group_land_money.xml index b4ea0dbeda..bccc114624 100644 --- a/indra/newview/skins/default/xui/es/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/es/panel_group_land_money.xml @@ -48,8 +48,11 @@ <string name="land_contrib_error"> No se ha podido defininir su contribución de terreno. </string> + <text name="your_contribution_units"> + ( m² ) + </text> <text name="your_contribution_max_value"> - m² ([AMOUNT] máx.) + ([AMOUNT] máx.) </text> <text name="group_over_limit_text"> Los miembros del grupo deben contribuir con más créditos de terreno diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml index 2f2aab5448..2b813a18bf 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml @@ -33,10 +33,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="'PG', 'Mature' y 'Adult'"/> <combo_box.item name="Desired_Mature" label="'PG' y 'Mature'"/> - <combo_box.item name="Desired_PG" label="sólo 'PG'"/> + <combo_box.item name="Desired_PG" label="'PG'"/> </combo_box> <text name="maturity_desired_textbox"> - sólo 'PG' + 'PG' </text> <text name="start_location_textbox"> Posición inicial: diff --git a/indra/newview/skins/default/xui/es/panel_region_estate.xml b/indra/newview/skins/default/xui/es/panel_region_estate.xml index 653dc32a24..f16ec89cb0 100644 --- a/indra/newview/skins/default/xui/es/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/es/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Estado" name="Estate"> +<panel label="Estado" name="Estate"> <text name="estate_help_text"> Los cambios en las configuraciones de esta pestaña afectarán a todas las regiones del estado. @@ -68,6 +66,4 @@ pestaña afectarán a todas las regiones del estado. <button label="?" name="ban_resident_help" right="476"/> <button label="Quitar..." name="remove_banned_avatar_btn"/> <button label="Añadir..." name="add_banned_avatar_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_region_texture.xml b/indra/newview/skins/default/xui/es/panel_region_texture.xml index 879fb87be2..5540358f97 100644 --- a/indra/newview/skins/default/xui/es/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/es/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Texturas del terreno" name="Textures"> +<panel label="Texturas del terreno" name="Textures"> <text name="region_text_lbl"> Región: </text> @@ -56,6 +54,4 @@ y el valor ALTA es la altura MÍNIMA de la textura #4. </text> <button label="Aplicar" name="apply_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 0735bb0082..294e407278 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -498,16 +498,16 @@ Si aun así persiste este mensaje, reinicie su ordenador. Si sigue recibiendo este mensaje, contacte con el [SUPPORT_SITE]. </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Alt- + ⌥ </string> <string name="accel-mac-shift"> - Mayús- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -615,6 +615,9 @@ Si sigue recibiendo este mensaje, contacte con el [SUPPORT_SITE]. <string name="no_ability_error"> Usted no tiene esa capacidad. </string> + <string name="no_ability"> + Usted no tiene esa capacidad. + </string> <string name="not_a_mod_error"> Usted no es un moderador de la sesión. </string> @@ -633,4 +636,31 @@ Si sigue recibiendo este mensaje, contacte con el [SUPPORT_SITE]. <string name="close_on_no_ability"> Usted ya no tendrá más la capacidad de estar en la sesión de chat. </string> + <string name="AcctTypeResident"> + Residente + </string> + <string name="AcctTypeTrial"> + Prueba + </string> + <string name="AcctTypeCharterMember"> + Miembro fundador + </string> + <string name="AcctTypeEmployee"> + Empleado de Linden Lab + </string> + <string name="PaymentInfoUsed"> + Ha usado una forma de pago + </string> + <string name="PaymentInfoOnFile"> + Hay infor. de la forma de pago + </string> + <string name="NoPaymentInfoOnFile"> + Sin infor. de la forma de pago + </string> + <string name="AgeVerified"> + Edad verificada + </string> + <string name="NotAgeVerified"> + Edad no verificada + </string> </strings> diff --git a/indra/newview/skins/default/xui/fr/floater_sell_land.xml b/indra/newview/skins/default/xui/fr/floater_sell_land.xml index 6ef12fab4a..643a9435db 100644 --- a/indra/newview/skins/default/xui/fr/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/fr/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="sell land" title="Vendre terrain"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Parcelle : </text> @@ -59,4 +61,6 @@ de propriétaire. </text> <button label="Mettre le terrain en vente" name="sell_btn" width="165"/> <button label="Annuler" name="cancel_btn"/> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml index 03ab397ea1..e8db326e15 100644 --- a/indra/newview/skins/default/xui/fr/floater_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_tools.xml @@ -149,7 +149,7 @@ </combo_box> <panel name="perms_build"> <text name="perm_modify"> - Vous pouvez modifier cet objet. + Vous pouvez modifier cet objet </text> <text name="B:"> B : @@ -177,28 +177,28 @@ <check_box name="checkbox next owner can transfer"/> </panel> <string name="text modify info 1"> - Vous pouvez modifier cet objet. + Vous pouvez modifier cet objet </string> <string name="text modify info 2"> - Vous pouvez modifier ces objets. + Vous pouvez modifier ces objets </string> <string name="text modify info 3"> - Vous ne pouvez pas modifier cet objet. + Vous ne pouvez pas modifier cet objet </string> <string name="text modify info 4"> - Vous ne pouvez pas modifier ces objets. + Vous ne pouvez pas modifier ces objets </string> <string name="text modify warning"> - Sélectionnez l'objet en entier. + Sélectionnez l'objet en entier </string> <string name="Cost Default"> - Prix : L$ + Prix : L$ </string> <string name="Cost Total"> - Prix total : L$ + Prix total : L$ </string> <string name="Cost Per Unit"> - Prix par : L$ + Prix par : L$ </string> <string name="Cost Mixed"> Prix mixte @@ -443,8 +443,8 @@ <button label="Ajuster" label_selected="Ajuster" left="150" name="button align"/> </panel> <panel label="Contenu" name="Contents"> - <button label="Nouveau script" label_selected="Nouveau script..." name="button new script"/> - <button label="Droits..." name="button permissions"/> + <button label="Nouveau script" label_selected="Nouveau script" name="button new script"/> + <button label="Droits" name="button permissions"/> </panel> </tab_container> <panel name="land info panel"> @@ -458,18 +458,18 @@ Surface : [AREA] m² </text> <button label="À propos du terrain..." label_selected="À propos du terrain..." name="button about land" width="142"/> - <check_box label="Afficher les propriétaires" name="checkbox show owners" tool_tip="Colorie les parcelles en fonction de leur propriétaire"/> + <check_box label="Afficher les propriétaires" name="checkbox show owners" tool_tip="Colorie les parcelles en fonction de leur propriétaire : Vert = votre terrain Turquoise = le terrain de votre groupe Rouge = appartenant à d'autres Jaune = en vente Mauve = aux enchères Gris = public"/> <button label="?" label_selected="?" name="button show owners help" left_delta="154"/> <text name="label_parcel_modify"> Modifier la parcelle </text> - <button label="Diviser..." label_selected="Diviser..." name="button subdivide land" width="142"/> - <button label="Fusionner..." label_selected="Fusionner..." name="button join land" width="142"/> + <button label="Diviser" label_selected="Diviser" name="button subdivide land" width="142"/> + <button label="Fusionner" label_selected="Fusionner" name="button join land" width="142"/> <text name="label_parcel_trans"> Transactions </text> - <button label="Acheter le terrain..." label_selected="Acheter le terrain..." name="button buy land" width="142"/> - <button label="Abandonner le terrain..." label_selected="Abandonner le terrain..." name="button abandon land" width="142"/> + <button label="Acheter le terrain" label_selected="Acheter le terrain" name="button buy land" width="142"/> + <button label="Abandonner le terrain" label_selected="Abandonner le terrain" name="button abandon land" width="142"/> </panel> <floater.string name="status_rotate"> Pour faire tourner l'objet, faîtes glisser les bandes de couleur. diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml index 3255cdb728..a38cf858e0 100644 --- a/indra/newview/skins/default/xui/fr/notifications.xml +++ b/indra/newview/skins/default/xui/fr/notifications.xml @@ -1682,7 +1682,7 @@ Si cette option est cochée, les propriétaires sont libres de revendre leur par Valeur par défaut : désactivé </notification> <notification label="Désactiver les scripts" name="HelpRegionDisableScripts"> - Lorsque la performance d'une région est faible, cela peut venir d'un script. Ouvrez la section Statistiques (Ctrl-Maj-1) et vérifiez le FPS Physique (Physics FPS) de la section Simulateur. + Lorsque la performance d'une région est faible, cela peut venir d'un script. Ouvrez la section Statistiques (Ctrl+Maj+1) et vérifiez le FPS Physique (Physics FPS) de la section Simulateur. Si le FPS est en dessous de 45, ouvrez la section Time située en fin de liste. Si le Script Time est au dessus de 25ms, cliquez sur le bouton Afficher les objets scriptés les plus consommateurs. Vous verrez le nom et l'emplacement des scripts éventuellement à l'origine du problème. Si vous cochez la case Désactiver les scripts et que vous appuyez sur Appliquer, tous les scripts de cette région seront temporairement désactivés. Vous devrez peut-être faire cela le temps d'arriver à l'endroit su script en cause. Une fois sur place, assurez-vous que le script est bien à l'origine du problème. Pour cela, vous devrez peut-être contacter le propriétaire du script ou bien supprimer ou renvoyer l'objet. @@ -1692,7 +1692,7 @@ Valeur par défaut : désactivé </notification> <notification label="Désactiver les collisions" name="HelpRegionDisableCollisions"> Des objets physiques peuvent fortement réduire les performances d'une région. -Ouvrez la barre de statistiques (Ctrl-Maj-1) et vérifiez le FPS Physique (Physics FPS) de la section Simulateur. +Ouvrez la barre de statistiques (Ctrl+Maj+1) et vérifiez le FPS Physique (Physics FPS) de la section Simulateur. Si le FPS est en dessous de 45, ouvrez la section Time située en fin de liste. Si le Script Time est au dessus de 25ms, cliquez sur le bouton Afficher les collisions les plus consommatrices. Vous verrez le nom et l'emplacement des objets physiques éventuellement à l'origine du problème. @@ -1913,7 +1913,7 @@ Déplacer les objets de l'inventaire ? <usetemplate ignoretext="Lors du transfert d'un inventaire non copiable depuis des objets scriptés" name="okcancelignore" notext="Annuler" yestext="OK"/> </notification> <notification name="ClickActionNotPayable"> - Avertissement : l'action du clic Payer l'objet a été défini mais ne fonctionnera que si un script est ajouté avec l'event money(). + Avertissement : l'action du clic 'Payer l'objet' a été défini mais ne fonctionnera que si un script est ajouté avec l'event money(). <form name="form"> <ignore name="ignore" text="Lors du paramétrage de la fonction Payer sur des objets sans événement monétaire"/> </form> @@ -2333,8 +2333,8 @@ Voulez-vous aller sur le site de [SECOND_LIFE] pour enregistrer ces informations Vous ne pouvez pas devenir ami avec vous-même. </notification> <notification name="UploadingAuctionSnapshot"> - Importation de photos SL et Web en cours -(prend environ 5 minutes…) + Importation de photos SL et Web en cours... +(prend environ 5 minutes.) </notification> <notification name="UploadPayment"> Le chargement a coûté [AMOUNT] L$. @@ -2842,7 +2842,7 @@ Les objets flexibles ne peuvent pas avoir de propriétés physiques et doivent r <notification name="FirstDebugMenus"> Vous avez activé le menu Avancé. Ce menu contient des fonctionnalités utiles pour les développeurs qui travaillent sur [SECOND_LIFE]. -Pour activer/désactiver ce menu sous Windows, appuyez sur Ctrl-Alt-D. Sur un Mac, appuyez sur ⌘-Opt-Maj-D +Pour activer/désactiver ce menu sous Windows, appuyez sur Ctrl+Alt+D. Sur un Mac, appuyez sur ⌥⌘D </notification> <notification name="FirstSculptedPrim"> Vous êtes en train d'éditer un sculptie. diff --git a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml new file mode 100644 index 0000000000..f62ea7c80f --- /dev/null +++ b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Résident" />
+ <string name="AcctTypeTrial"
+ value="Essai" />
+ <string name="AcctTypeCharterMember"
+ value="Membre originaire" />
+ <string name="AcctTypeEmployee"
+ value="Employé(e) de Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Infos de paiement utilisées" />
+ <string name="PaymentInfoOnFile"
+ value="Infos de paiement enregistrées" />
+ <string name="NoPaymentInfoOnFile"
+ value="Aucune info de paiement" />
+ <string name="AgeVerified"
+ value="Âge vérifié" />
+ <string name="NotAgeVerified"
+ value="Âge non vérifié" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=fr
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partenaire :"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Réponse si occupé(e) :
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_group_general.xml b/indra/newview/skins/default/xui/fr/panel_group_general.xml index f89c90e508..9afc4ae11d 100644 --- a/indra/newview/skins/default/xui/fr/panel_group_general.xml +++ b/indra/newview/skins/default/xui/fr/panel_group_general.xml @@ -43,7 +43,7 @@ <panel name="preferences_container"> <check_box label="Afficher dans la recherche" name="show_in_group_list" tool_tip="Afficher ce groupe dans les résultats de recherche."/> <check_box label="Inscription libre" name="open_enrollement" tool_tip="Indique si une invitation est nécessaire pour devenir membre de ce groupe."/> - <check_box label="Frais d'inscription : L$" name="check_enrollment_fee" tool_tip="Indique s'il y a des frais d'inscription pour devenir membre."/> + <check_box label="Frais d'inscription :" name="check_enrollment_fee" tool_tip="Indique s'il y a des frais d'inscription pour devenir membre."/> <spinner name="spin_enrollment_fee" tool_tip="Si la case Frais d'inscription est cochée, cela signifie qu'il faut payer des frais pour devenir membre."/> <combo_box name="group_mature_check" tool_tip="Indique si les informations sur votre groupe sont classées Mature." width="195"> <combo_box.item name="select_mature" label="- Type de public -"/> diff --git a/indra/newview/skins/default/xui/fr/panel_group_land_money.xml b/indra/newview/skins/default/xui/fr/panel_group_land_money.xml index 551d11d588..29259e2e42 100644 --- a/indra/newview/skins/default/xui/fr/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/fr/panel_group_land_money.xml @@ -49,8 +49,11 @@ financières de ce groupe. <string name="land_contrib_error"> Impossible de définir votre don de terre. </string> + <text name="your_contribution_units"> + ( m² ) + </text> <text name="your_contribution_max_value"> - m² ([AMOUNT] max.) + ([AMOUNT] max.) </text> <text name="group_over_limit_text"> Une contribution supplémentaire du groupe est requise pour prendre en diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml index f3a1a0c0e2..1ed3cafbc3 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml @@ -34,10 +34,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="PG, Mature et Adult"/> <combo_box.item name="Desired_Mature" label="PG et Mature"/> - <combo_box.item name="Desired_PG" label="PG uniquement"/> + <combo_box.item name="Desired_PG" label="PG"/> </combo_box> <text name="maturity_desired_textbox"> - PG uniquement + PG </text> <text name="start_location_textbox"> Lieu de départ : diff --git a/indra/newview/skins/default/xui/fr/panel_region_estate.xml b/indra/newview/skins/default/xui/fr/panel_region_estate.xml index b592d29711..425f273790 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Domaine" name="Estate"> +<panel label="Domaine" name="Estate"> <text name="estate_help_text" bottom="-34"> Les changements apportés aux paramètres de cet onglet auront des répercussions sur @@ -77,6 +75,4 @@ toutes les régions du domaine. <button label="Supprimer..." name="remove_banned_avatar_btn"/> <button label="Envoyer un message au domaine..." name="message_estate_btn"/> <button label="Éjecter le résident du domaine..." name="kick_user_from_estate_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/fr/panel_region_texture.xml b/indra/newview/skins/default/xui/fr/panel_region_texture.xml index da800dc6bd..d312646788 100644 --- a/indra/newview/skins/default/xui/fr/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/fr/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Textures du sol" name="Textures"> +<panel label="Textures du sol" name="Textures"> <text name="region_text_lbl"> Région : </text> @@ -71,6 +69,4 @@ et la valeur HAUTE correspond à la hauteur MINIMUM de la Texture #4. </text> <button label="Appliquer" name="apply_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml index 6bdee836d9..070d2cd1a5 100644 --- a/indra/newview/skins/default/xui/fr/strings.xml +++ b/indra/newview/skins/default/xui/fr/strings.xml @@ -488,16 +488,16 @@ Choisir le répertoire </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Maj- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -604,6 +604,9 @@ <string name="no_ability_error"> Vous n'avez pas ce pouvoir. </string> + <string name="no_ability"> + Vous n'avez pas ce pouvoir. + </string> <string name="not_a_mod_error"> Vous n'êtes pas modérateur de session. </string> @@ -622,4 +625,31 @@ <string name="close_on_no_ability"> Vous ne pouvez plus participer à la session de chat. </string> + <string name="AcctTypeResident"> + Résident + </string> + <string name="AcctTypeTrial"> + Essai + </string> + <string name="AcctTypeCharterMember"> + Membre originaire + </string> + <string name="AcctTypeEmployee"> + Employé(e) de Linden Lab + </string> + <string name="PaymentInfoUsed"> + Infos de paiement utilisées + </string> + <string name="PaymentInfoOnFile"> + Infos de paiement enregistrées + </string> + <string name="NoPaymentInfoOnFile"> + Aucune info de paiement + </string> + <string name="AgeVerified"> + Âge vérifié + </string> + <string name="NotAgeVerified"> + Âge non vérifié + </string> </strings> diff --git a/indra/newview/skins/default/xui/it/floater_sell_land.xml b/indra/newview/skins/default/xui/it/floater_sell_land.xml index d9cf612d33..79dd2c5abf 100644 --- a/indra/newview/skins/default/xui/it/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/it/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="sell land" title="Vendi terra"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Terreno: </text> @@ -58,4 +60,6 @@ cambieranno proprietario. </text> <button label="Metti la terra in vendita" name="sell_btn"/> <button label="Annulla" name="cancel_btn"/> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index d4d70f3367..8fc1818ccc 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -160,7 +160,7 @@ </combo_box> <panel name="perms_build"> <text name="perm_modify"> - Puoi modificare questo oggetto. + Puoi modificare questo oggetto </text> <text name="B:"> B: @@ -188,28 +188,28 @@ <check_box name="checkbox next owner can transfer" left_delta="67"/> </panel> <string name="text modify info 1"> - Puoi modificare questo oggetto. + Puoi modificare questo oggetto </string> <string name="text modify info 2"> - Puoi modificare questi oggetti. + Puoi modificare questi oggetti </string> <string name="text modify info 3"> - Non puoi modificare questo oggetto. + Non puoi modificare questo oggetto </string> <string name="text modify info 4"> - Non puoi modificare questi oggetti. + Non puoi modificare questi oggetti </string> <string name="text modify warning"> - Devi selezionare l'intero oggetto per impostare i permessi. + Devi selezionare l'intero oggetto per impostare i permessi </string> <string name="Cost Default"> - Prezzo: L$ + Prezzo: L$ </string> <string name="Cost Total"> - Prezzo totale: L$ + Prezzo totale: L$ </string> <string name="Cost Per Unit"> - Prezzo per: L$ + Prezzo per: L$ </string> <string name="Cost Mixed"> Prezzo misto @@ -502,8 +502,8 @@ <button label="Allinea" label_selected="Allinea" name="button align" left="160"/> </panel> <panel label="Contenuto" name="Contents"> - <button label="Nuovo Script" label_selected="Nuovo script..." name="button new script"/> - <button label="Permessi..." name="button permissions"/> + <button label="Nuovo Script" label_selected="Nuovo script" name="button new script"/> + <button label="Permessi" name="button permissions"/> <panel name="ContentsInventory" width="272" /> </panel> </tab_container> @@ -518,18 +518,18 @@ Area: [AREA] m² </text> <button label="Informazioni sul terreno..." label_selected="Informazioni sul terreno..." name="button about land" width="156"/> - <check_box label="Mostra i proprietari" name="checkbox show owners" tool_tip="Colora i terreni in base ai loro proprietari"/> + <check_box label="Mostra i proprietari" name="checkbox show owners" tool_tip="Colora i terreni in base ai loro proprietari: Verde = il tuo terreno Acqua = la terra del tuo gruppo Rosso = posseduta da altri Giallo = in vendita Viola = in asta Grigia = pubblica"/> <button label="?" label_selected="?" name="button show owners help" left_delta="120"/> <text name="label_parcel_modify"> Modifica il terreno </text> - <button label="Suddividi..." label_selected="Suddividi..." name="button subdivide land" width="156"/> - <button label="Unisci..." label_selected="Unisci..." name="button join land" width="156"/> + <button label="Suddividi" label_selected="Suddividi" name="button subdivide land" width="156"/> + <button label="Unisci" label_selected="Unisci" name="button join land" width="156"/> <text name="label_parcel_trans"> Transazioni del territorio </text> - <button label="Acquista il terreno..." label_selected="Acquista il terreno..." name="button buy land" width="156"/> - <button label="Abbandona il terreno..." label_selected="Abbandona il terreno..." name="button abandon land" width="156"/> + <button label="Acquista il terreno" label_selected="Acquista il terreno" name="button buy land" width="156"/> + <button label="Abbandona il terreno" label_selected="Abbandona il terreno" name="button abandon land" width="156"/> </panel> <floater.string name="status_rotate"> Sposta le fasce colorate per ruotare l'oggetto diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index d85dd7732a..8f8a969ace 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -1747,7 +1747,7 @@ Se questa opzione è selezionato i compratori possono rivendere i loro terreni i Impostazione base: Non consentire </notification> <notification label="Disabilita gli script" name="HelpRegionDisableScripts"> - Se le prestazioni di una sim sono basse, probabilmente è colpa di uno script. Apri la 'Barra delle statistiche' (Ctrl-Shift-1). Controlla il FPS della fisica del simulatore. + Se le prestazioni di una sim sono basse, probabilmente è colpa di uno script. Apri la 'Barra delle statistiche' (Ctrl+Shift+1). Controlla il FPS della fisica del simulatore. Se è più basso di 45, apri il pannello 'Time' (Tempi) collocato ln fondo alla 'Barra delle statistiche' Se il tempo per gli script è di 25 ms o più alto, clicca sul bottone 'Visualizza l'elenco degli script più pesanti...'. Ti verrà dato il nome e l'ubicazione degli script che probabilmente causano una cattiva prestazione. @@ -1758,7 +1758,7 @@ Impostazione base: spento </notification> <notification label="Disabilita le collisioni" name="HelpRegionDisableCollisions"> Quando le prestazioni della sim sono basse, può darsi che la colpa sia di oggetti fisici. -Apri la 'Barra delle statistiche' (Ctrl-Shift-1). +Apri la 'Barra delle statistiche' (Ctrl+Shift+1). Controlla il FPS della fisica del simulatore. Se è più basso di 45, apri il pannello 'Time' (Tempi) collocato in fondo alla 'Barra delle statistiche'. Se il tempo della sim (fisica) risulta 20 ms o più, clicca sul bottone 'mostra gli oggetti che collidono di più'. @@ -1987,9 +1987,9 @@ Trasferisci gli elementi nell'inventario? <usetemplate ignoretext="Quando si trasferiscono oggetti scriptati non copiabili nell'inventario." name="okcancelignore" notext="Annulla" yestext="OK"/> </notification> <notification name="ClickActionNotPayable"> - Attenzione: L'azione di pagamento automatico al click è stata impostata, ma funzionerà solo se aggiungi uno script con un evento money(). + Attenzione: L'azione 'Paga l'oggetto' al click è stata impostata, ma funzionerà solo se aggiungi uno script con un evento money(). <form name="form"> - <ignore name="ignore" text="Quando imposti il 'Pagamento' di oggetti senza l'evento money()"/> + <ignore name="ignore" text="Quando imposti il 'Paga l'oggetto' senza l'evento money()"/> </form> </notification> <notification name="OpenObjectCannotCopy"> @@ -2923,7 +2923,7 @@ Gli oggetti flessibili non possono essere fisici e devano essere fantasma fino a <notification name="FirstDebugMenus"> Hai attivato il menu Avanzato. Questo menu contiene funzioni utili per gli sviluppatori per il debug di [SECOND_LIFE]. -Per attivare o disattivare questo menu su Windows premere Ctrl-Alt-D. Su Mac premere ⌘-Opt-D. +Per attivare o disattivare questo menu su Windows premere Ctrl+Alt+D. Su Mac premere ⌥⌘D. </notification> <notification name="FirstSculptedPrim"> Si sta modificando uno sculpted prim. diff --git a/indra/newview/skins/default/xui/it/panel_edit_profile.xml b/indra/newview/skins/default/xui/it/panel_edit_profile.xml new file mode 100644 index 0000000000..0eba7bf3b6 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Residente" />
+ <string name="AcctTypeTrial"
+ value="Prova" />
+ <string name="AcctTypeCharterMember"
+ value="Membro privilegiato" />
+ <string name="AcctTypeEmployee"
+ value="Impiegato della Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Info. di pagamento usate" />
+ <string name="PaymentInfoOnFile"
+ value="Info. di pagamento in archivio" />
+ <string name="NoPaymentInfoOnFile"
+ value="Nessuna info. di pagamento" />
+ <string name="AgeVerified"
+ value="Età verificata" />
+ <string name="NotAgeVerified"
+ value="Età non verificata" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=it
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Risposta agli IM quando sono in 'Occupato':
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_group_general.xml b/indra/newview/skins/default/xui/it/panel_group_general.xml index 08d6268f5b..2bc4d82082 100644 --- a/indra/newview/skins/default/xui/it/panel_group_general.xml +++ b/indra/newview/skins/default/xui/it/panel_group_general.xml @@ -1,9 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="Generale" name="general_tab"> <string name="help_text"> - Il pannello 'Generale' contiene informazioni generali riguardanti il -gruppo, un elenco dei proprietari e i membri visibili, -le preferenze generali di gruppo e le opzioni dei membri. + Il pannello 'Generale' contiene informazioni generali riguardanti il gruppo, un elenco dei proprietari e i membri visibili, le preferenze generali di gruppo e le opzioni dei membri. Passa il mouse sulle opzioni per un aiuto aggiuntivo. </string> @@ -47,7 +45,7 @@ Passa il mouse sulle opzioni per un aiuto aggiuntivo. <panel name="preferences_container"> <check_box label="Mostra nella ricerca" name="show_in_group_list" tool_tip="Lascia che i residenti vedano questo gruppo nella ricerca."/> <check_box label="Iscrizione libera" name="open_enrollement" tool_tip="Imposta se questo gruppo permette ai nuovi membri di unirsi senza essere invitati."/> - <check_box label="Tassa di iscrizione: L$" name="check_enrollment_fee" tool_tip="Imposta se richiedere una tassa di iscrizione per unirsi al gruppo."/> + <check_box label="Tassa di iscrizione:" name="check_enrollment_fee" tool_tip="Imposta se richiedere una tassa di iscrizione per unirsi al gruppo."/> <spinner width="60" left_delta="136" name="spin_enrollment_fee" tool_tip="I nuovi membri devono pagare questa tassa per unirsi al gruppo. La tassa di iscrizione è selezionata."/> <combo_box name="group_mature_check" tool_tip="Imposta se le informazioni sul tuo gruppo sono da considerarsi Mature."> <combo_box.item name="select_mature" label="- Seleziona -"/> diff --git a/indra/newview/skins/default/xui/it/panel_group_land_money.xml b/indra/newview/skins/default/xui/it/panel_group_land_money.xml index 5f54d8cd25..3e6684ed06 100644 --- a/indra/newview/skins/default/xui/it/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/it/panel_group_land_money.xml @@ -47,8 +47,11 @@ <string name="land_contrib_error"> Non è possibile impostare i tuoi contributi in terra. </string> + <text name="your_contribution_units"> + ( m² ) + </text> <text name="your_contribution_max_value"> - m² ([AMOUNT] massimo) + ([AMOUNT] massimo) </text> <text name="group_over_limit_text"> I membri del gruppo devono contribuire con più crediti per mantenere diff --git a/indra/newview/skins/default/xui/it/panel_preferences_general.xml b/indra/newview/skins/default/xui/it/panel_preferences_general.xml index 4c6a7d8eb3..e6cd6e67b2 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_general.xml @@ -33,10 +33,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="PG, Mature e Adult"/> <combo_box.item name="Desired_Mature" label="PG e Mature"/> - <combo_box.item name="Desired_PG" label="solo PG"/> + <combo_box.item name="Desired_PG" label="PG"/> </combo_box> <text name="maturity_desired_textbox"> - solo PG + PG </text> <text name="start_location_textbox"> Punto di partenza: diff --git a/indra/newview/skins/default/xui/it/panel_region_estate.xml b/indra/newview/skins/default/xui/it/panel_region_estate.xml index 345e8c532c..5b95b7378b 100644 --- a/indra/newview/skins/default/xui/it/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/it/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Proprietà immobiliari" name="Estate"> +<panel label="Proprietà immobiliari" name="Estate"> <text name="estate_help_text"> I cambiamenti alle impostazioni in questa finestra avranno effetto su tutte le regioni della proprietà. @@ -68,6 +66,4 @@ avranno effetto su tutte le regioni della proprietà. <button label="?" name="ban_resident_help"/> <button label="Rimuovi..." name="remove_banned_avatar_btn"/> <button label="Aggiungi..." name="add_banned_avatar_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_region_texture.xml b/indra/newview/skins/default/xui/it/panel_region_texture.xml index 976a93abb8..254700e9f1 100644 --- a/indra/newview/skins/default/xui/it/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/it/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Texture del terreno" name="Textures"> +<panel label="Texture del terreno" name="Textures"> <text name="region_text_lbl"> Regione: </text> @@ -56,6 +54,4 @@ Texture #1, e il valore più ALTO all'altezza MINIMA della Texture #4. </text> <button label="Applica" name="apply_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 67b946e1de..bc3cc38a40 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -484,16 +484,16 @@ Scegli la cartella </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Shift- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -600,6 +600,9 @@ <string name="no_ability_error"> Non hai questa abilitazione. </string> + <string name="no_ability"> + Non hai questa abilitazione. + </string> <string name="not_a_mod_error"> Non sei un moderatore. </string> @@ -618,4 +621,31 @@ <string name="close_on_no_ability"> Non hai più le abilitazioni per rimanere nella sessione chat. </string> + <string name="AcctTypeResident"> + Residente + </string> + <string name="AcctTypeTrial"> + Prova + </string> + <string name="AcctTypeCharterMember"> + Membro privilegiato + </string> + <string name="AcctTypeEmployee"> + Impiegato della Linden Lab + </string> + <string name="PaymentInfoUsed"> + Info. di pagamento usate + </string> + <string name="PaymentInfoOnFile"> + Info. di pagamento in archivio + </string> + <string name="NoPaymentInfoOnFile"> + Nessuna info. di pagamento + </string> + <string name="AgeVerified"> + Età verificata + </string> + <string name="NotAgeVerified"> + Età non verificata + </string> </strings> diff --git a/indra/newview/skins/default/xui/ja/floater_sell_land.xml b/indra/newview/skins/default/xui/ja/floater_sell_land.xml index 3860c599fb..5193e5bba1 100644 --- a/indra/newview/skins/default/xui/ja/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/ja/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="sell land" title="土地を販売" height="496" min_height="496" > + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> 区画: </text> @@ -63,4 +65,6 @@ </text> <button label="販売を決定" name="sell_btn" bottom="-489"/> <button label="取り消し" name="cancel_btn" /> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml index 36aec17f9a..5840773dbd 100644 --- a/indra/newview/skins/default/xui/ja/floater_tools.xml +++ b/indra/newview/skins/default/xui/ja/floater_tools.xml @@ -192,13 +192,13 @@ 権限を設定するには、オブジェクト全体を選択する必要があります。 </string> <string name="Cost Default"> - 価格: L$ + 価格: L$ </string> <string name="Cost Total"> - 合計価格: L$ + 合計価格: L$ </string> <string name="Cost Per Unit"> - 単価: L$ + 単価: L$ </string> <string name="Cost Mixed"> 混合価格 @@ -442,7 +442,7 @@ </panel> <panel label="中身" name="Contents"> <button label="新しいスクリプト" label_selected="新しいスクリプト" name="button new script" width="120"/> - <button label="権限..." name="button permissions" left_delta="130" width="80"/> + <button label="権限" name="button permissions" left_delta="130" width="80"/> </panel> </tab_container> <panel name="land info panel"> @@ -456,18 +456,18 @@ 面積:[AREA]平方メートル </text> <button label="土地情報..." label_selected="土地情報..." name="button about land"/> - <check_box label="オーナーを表示" name="checkbox show owners" tool_tip="所有権別に区画を色分けします"/> + <check_box label="オーナーを表示" name="checkbox show owners" tool_tip="所有権別に区画を色分けします: 緑 = あなたの土地 アクア = あなたのグループ所有地 赤 = 他人が所有する土地 黄色 = 売り出し中 紫 = オークション グレー = パブリック"/> <button label="?" label_selected="?" name="button show owners help" left_delta="114"/> <text name="label_parcel_modify"> 区画の編集 </text> - <button label="再分割..." label_selected="再分割..." name="button subdivide land"/> - <button label="統合する..." label_selected="統合する..." name="button join land"/> + <button label="再分割" label_selected="再分割" name="button subdivide land"/> + <button label="統合する" label_selected="統合する" name="button join land"/> <text name="label_parcel_trans"> 土地取引 </text> - <button label="土地を購入..." label_selected="土地を購入..." name="button buy land"/> - <button label="土地を放棄..." label_selected="土地を放棄..." name="button abandon land"/> + <button label="土地を購入" label_selected="土地を購入" name="button buy land"/> + <button label="土地を放棄" label_selected="土地を放棄" name="button abandon land"/> </panel> <floater.string name="status_rotate"> 色の付いたバンドをドラッグしてオブジェクトを回転 diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 5c22fbf474..4d067d2823 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -1809,7 +1809,7 @@ L$[AMOUNT]で、このクラシファイド広告を今すぐ公開しますか </notification> <notification label="スクリプトを無効化" name="HelpRegionDisableScripts"> スクリプトが原因でシムの状況が悪くなる場合があります。 -統計グラフをだして(Ctrl-Shift-1)、 +統計グラフをだして(Ctrl+Shift+1)、 シミュレーターフィジックスFPSを見てください。 45より数が低ければ、一番下に位置しているタイムパネルを開いてください。 スクリプト時間が25ms以上であれば、 @@ -1828,7 +1828,7 @@ L$[AMOUNT]で、このクラシファイド広告を今すぐ公開しますか <notification label="衝突を無効化" name="HelpRegionDisableCollisions"> 物理的オブジェクトが原因で、 シムの処理が重くなることがあります。 -統計グラフを開いて(Ctrl-Shift-1)、 +統計グラフを開いて(Ctrl+Shift+1)、 シミュレーターフィジックスFPSを見てください。 数値が45より低ければ、統計バーの下に位置しているタイムパネルを開いてください。 もしシムタイム(物理的作用)が20 msより長い場合は、 @@ -3128,8 +3128,8 @@ Mキーを押して変更します。 [SECOND_LIFE] をデバッグするデベロッパーにとって 有用な機能があります。 このメニューを切り替えるには、 -WindowsではCtrl-Alt-Dを押します。 -Macの場合は、⌘-Opt-Shift-Dを押してください。 +WindowsではCtrl+Alt+Dを押します。 +Macの場合は、⌥⌘Dを押してください。 </notification> <notification name="FirstSculptedPrim"> スカルプトプリムを編集しています。 diff --git a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml new file mode 100644 index 0000000000..ca4ab3e773 --- /dev/null +++ b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="住人" />
+ <string name="AcctTypeTrial"
+ value="トライアル" />
+ <string name="AcctTypeCharterMember"
+ value="特権メンバー" />
+ <string name="AcctTypeEmployee"
+ value="Linden Lab従業員" />
+ <string name="PaymentInfoUsed"
+ value="支払い情報登録済" />
+ <string name="PaymentInfoOnFile"
+ value="支払い情報登録済み" />
+ <string name="NoPaymentInfoOnFile"
+ value="支払い情報未登録" />
+ <string name="AgeVerified"
+ value="年齢確認済み" />
+ <string name="NotAgeVerified"
+ value="年齢未確認" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=ja
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="パートナー:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ 取り込み中応答メッセージ:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_group_general.xml b/indra/newview/skins/default/xui/ja/panel_group_general.xml index 266937e216..43e3ca69ef 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_general.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_general.xml @@ -47,7 +47,7 @@ <panel name="preferences_container"> <check_box label="検索に表示" name="show_in_group_list" tool_tip="このグループを検索結果に表示させます"/> <check_box label="会員募集" name="open_enrollement" tool_tip="招待状なしに自由にこのグループに加入することを許可するかどうかを指定します"/> - <check_box label="入会費:L$" name="check_enrollment_fee" tool_tip="このグループへの参加に入会費を必須とするかどうかを指定します"/> + <check_box label="入会費:" name="check_enrollment_fee" tool_tip="このグループへの参加に入会費を必須とするかどうかを指定します"/> <spinner name="spin_enrollment_fee" tool_tip="「入会費」がチェックされている場合、新規会員は入会時にここに指定された金額を支払う必要があります"/> <combo_box name="group_mature_check" tool_tip="グループ情報がMature向けかどうかの設定をします。"> <combo_box.item name="select_mature" label="- Matureの選択 -"/> diff --git a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml index 019d42c40a..595d315cf9 100644 --- a/indra/newview/skins/default/xui/ja/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/ja/panel_group_land_money.xml @@ -48,8 +48,11 @@ <string name="land_contrib_error"> 土地の出資設定を行うことができませんでした。 </string> + <text name="your_contribution_units"> + (平方メートル) + </text> <text name="your_contribution_max_value"> - 平方メートル ([AMOUNT]最大) + ([AMOUNT]最大) </text> <text name="group_over_limit_text"> 使用中の土地をサポートするには、グループ・メンバーがさらに多 diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml index 6c3ad93d4f..584fcd6164 100644 --- a/indra/newview/skins/default/xui/ja/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/ja/panel_preferences_general.xml @@ -33,10 +33,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="PG、Mature、Adult"/> <combo_box.item name="Desired_Mature" label="PGとMature"/> - <combo_box.item name="Desired_PG" label="PG限定"/> + <combo_box.item name="Desired_PG" label="PG"/> </combo_box> <text name="maturity_desired_textbox"> - PG限定 + PG </text> <text name="start_location_textbox"> ログイン位置: diff --git a/indra/newview/skins/default/xui/ja/panel_region_estate.xml b/indra/newview/skins/default/xui/ja/panel_region_estate.xml index ce4f3c19b2..186820f00a 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="不動産" name="Estate"> +<panel label="不動産" name="Estate"> <text name="estate_help_text"> このタブの設定を変更するとこの不動産内 の全ての地域に影響を与えます。 @@ -77,6 +75,4 @@ <button label="メッセージを不動産へ送信..." name="message_estate_btn" /> <button label="土地からユーザーを追い出す..." name="kick_user_from_estate_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/ja/panel_region_texture.xml b/indra/newview/skins/default/xui/ja/panel_region_texture.xml index 19326c82b6..6527f0fbe6 100644 --- a/indra/newview/skins/default/xui/ja/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/ja/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="地面テクスチャー" name="Textures"> +<panel label="地面テクスチャー" name="Textures"> <text name="region_text_lbl"> 地域: </text> @@ -56,6 +54,4 @@ そして「高」の値はテクスチャー#4の高さの下限となります。 </text> <button label="適用" name="apply_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml index 7b21146651..0eb26754cf 100644 --- a/indra/newview/skins/default/xui/ja/strings.xml +++ b/indra/newview/skins/default/xui/ja/strings.xml @@ -488,16 +488,16 @@ 参照 </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Shift- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -603,6 +603,9 @@ <string name="no_ability_error"> あなたにはその能力がありません。 </string> + <string name="no_ability"> + あなたにはその能力がありません。 + </string> <string name="not_a_mod_error"> あなたはセッション・モデレータではありません。 </string> @@ -621,4 +624,31 @@ <string name="close_on_no_ability"> このチャット・セッションを継続することはできません </string> + <string name="AcctTypeResident"> + 住人 + </string> + <string name="AcctTypeTrial"> + トライアル + </string> + <string name="AcctTypeCharterMember"> + 特権メンバー + </string> + <string name="AcctTypeEmployee"> + Linden Lab従業員 + </string> + <string name="PaymentInfoUsed"> + 支払い情報登録済 + </string> + <string name="PaymentInfoOnFile"> + 支払い情報登録済み + </string> + <string name="NoPaymentInfoOnFile"> + 支払い情報未登録 + </string> + <string name="AgeVerified"> + 年齢確認済み + </string> + <string name="NotAgeVerified"> + 年齢未確認 + </string> </strings> diff --git a/indra/newview/skins/default/xui/nl/floater_sell_land.xml b/indra/newview/skins/default/xui/nl/floater_sell_land.xml index ed5cd50165..3981f3ccc2 100644 --- a/indra/newview/skins/default/xui/nl/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/nl/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="sell land" title="Verkoop land"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Perceel: </text> @@ -58,4 +60,6 @@ zullen van eigenaar veranderen. </text> <button label="Zet het land te koop" name="sell_btn"/> <button label="Annuleren" name="cancel_btn"/> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/nl/floater_tools.xml b/indra/newview/skins/default/xui/nl/floater_tools.xml index 0d2c009dc6..cb0c1ad89a 100644 --- a/indra/newview/skins/default/xui/nl/floater_tools.xml +++ b/indra/newview/skins/default/xui/nl/floater_tools.xml @@ -159,7 +159,7 @@ </combo_box> <panel name="perms_build"> <text name="perm_modify"> - U kunt dit object wijzigen. + U kunt dit object wijzigen </text> <text name="B:"> B: @@ -187,28 +187,28 @@ <check_box name="checkbox next owner can transfer" left_delta="67"/> </panel> <string name="text modify info 1"> - U kunt dit object wijzigen. + U kunt dit object wijzigen </string> <string name="text modify info 2"> - U kunt deze objecten wijzigen. + U kunt deze objecten wijzigen </string> <string name="text modify info 3"> - U kunt dit object niet wijzigen. + U kunt dit object niet wijzigen </string> <string name="text modify info 4"> - U kunt deze objecten niet wijzigen. + U kunt deze objecten niet wijzigen </string> <string name="text modify warning"> - U moet het hele object selecteren om permissies in te stellen. + U moet het hele object selecteren om permissies in te stellen </string> <string name="Cost Default"> - Prijs: L$ + Prijs: L$ </string> <string name="Cost Total"> - Totale Prijs: L$ + Totale Prijs: L$ </string> <string name="Cost Per Unit"> - Prijs per: L$ + Prijs per: L$ </string> <string name="Cost Mixed"> Gemengde prijs @@ -499,8 +499,8 @@ <button label="Uitlijnen" label_selected="Uitlijnen" name="button align" left="155" /> </panel> <panel label="Inhoud" name="Contents"> - <button label="Nieuw script" label_selected="Nieuw script..." name="button new script"/> - <button label="Permissies..." name="button permissions"/> + <button label="Nieuw script" label_selected="Nieuw script" name="button new script"/> + <button label="Permissies" name="button permissions"/> <panel name="ContentsInventory" width="272" /> </panel> </tab_container> @@ -515,18 +515,18 @@ Gebied: [AREA] m². </text> <button label="Over land..." label_selected="Over land..." name="button about land"/> - <check_box label="Toon Eigenaren" name="checkbox show owners" tool_tip="Kleur percelen op basis van hun eigendom"/> + <check_box label="Toon Eigenaren" name="checkbox show owners" tool_tip="Kleur percelen op basis van hun eigendom: Groen = Uw land Aqua = Land van uw groep Rood = Eigendom van anderen Geel = Te koop Paars = Ter veiling Grijs = Openbaar"/> <button label="?" label_selected="?" name="button show owners help" left_delta="105"/> <text name="label_parcel_modify"> Wijzig Perceel </text> - <button label="Opdelen..." label_selected="Opdelen..." name="button subdivide land"/> - <button label="Samenvoegen..." label_selected="Samenvoegen..." name="button join land"/> + <button label="Opdelen" label_selected="Opdelen" name="button subdivide land"/> + <button label="Samenvoegen" label_selected="Samenvoegen" name="button join land"/> <text name="label_parcel_trans"> Landtransacties </text> - <button label="Koop land..." label_selected="Koop land..." name="button buy land"/> - <button label="Land Afstaan..." label_selected="Land Afstaan..." name="button abandon land"/> + <button label="Koop land" label_selected="Koop land" name="button buy land"/> + <button label="Land Afstaan" label_selected="Land Afstaan" name="button abandon land"/> </panel> <floater.string name="status_rotate"> Sleep de gekleurde banden om het object te roteren diff --git a/indra/newview/skins/default/xui/nl/notifications.xml b/indra/newview/skins/default/xui/nl/notifications.xml index b47e92b682..9a83eaea61 100644 --- a/indra/newview/skins/default/xui/nl/notifications.xml +++ b/indra/newview/skins/default/xui/nl/notifications.xml @@ -1756,7 +1756,7 @@ Indien deze optie is aan gevinkt, kunnen kopers hun land in deze regio verkopen. Standaard: Niet toestaan </notification> <notification label="Scripts Uitschakelen" name="HelpRegionDisableScripts"> - Indien de sim prestaties slecht zijn, kan een script de oorzaak zijn. Open de Statistieken balk (Ctrl-Shift-1). Kijk naar de Simulator Fysieke FPS. Indien het lager is dan 45, open dan het Tijd paneel onderaan de Statistieken balk. Indien de Script Tijd 25 ms of hoger is, klik dan op de Top Scripts knop. U krijgt dan een naam en lokatie van scripts die mogelijk de slechte prestaties veroorzaken. + Indien de sim prestaties slecht zijn, kan een script de oorzaak zijn. Open de Statistieken balk (Ctrl+Shift+1). Kijk naar de Simulator Fysieke FPS. Indien het lager is dan 45, open dan het Tijd paneel onderaan de Statistieken balk. Indien de Script Tijd 25 ms of hoger is, klik dan op de Top Scripts knop. U krijgt dan een naam en lokatie van scripts die mogelijk de slechte prestaties veroorzaken. Het aan vinken van Scripts Uitschakelen en vervolgens op de Toepassen knop drukken, zal tijdelijk alle scripts in deze regio uitschakelen. U zult dit mogelijk moeten doen om naar de lokatie te gaan van het 'top script'. Eenmaal aangekomen, onderzoek dan of het script het probleem veroorzaakt. U zult mogelijk de eigenaar willen contacteren of het object willen retourneren c.q. verwijderen. Verwijder het vinkje van Scripts Uitschakelen en klik op Toepassen om scripts weer te reactiveren in de regio. @@ -1764,7 +1764,7 @@ Verwijder het vinkje van Scripts Uitschakelen en klik op Toepassen om scripts we Standaard: Uitgeschakeld </notification> <notification label="Botsingen Uitschakelen" name="HelpRegionDisableCollisions"> - Indien de sim prestaties slecht zijn, kunnen fysieke objecten de oorzaak zijn. Open de Statistieken balk (Ctrl-Shift-1). Kijk naar de Simulator Fysieke FPS. Indien het lager is dan 45, open dan het Tijd paneel onderaan de Statistieken balk. Indien de Sim Tijd (Fysiek) 20 ms of hoger is, klik dan op de Toon Top Botsingen knop. U krijgt dan een naam en lokatie van de fysieke objecten die mogelijk de slecht prestaties veroorzaken. + Indien de sim prestaties slecht zijn, kunnen fysieke objecten de oorzaak zijn. Open de Statistieken balk (Ctrl+Shift+1). Kijk naar de Simulator Fysieke FPS. Indien het lager is dan 45, open dan het Tijd paneel onderaan de Statistieken balk. Indien de Sim Tijd (Fysiek) 20 ms of hoger is, klik dan op de Toon Top Botsingen knop. U krijgt dan een naam en lokatie van de fysieke objecten die mogelijk de slecht prestaties veroorzaken. Het aan vinken van de Botsingen Uitschakelen knop en vervolgens op de Toepassen knop drukken, zal tijdelijk object-object botsingen uitschakelen. U zult dit mogelijk moeten doen om naar de lokatie te gaan van de 'top botsingen'. Eenmaal aangekomen, onderzoek dan het object. Botst het constant met andere objecten? U zult mogelijk de eigenaar willen contacteren of het object willen retourneren c.q. verwijderen. Verwijder het vinkje van Botsingen Uitschakelen en klik op Toepassen om botsingen weer te reactiveren in de regio. @@ -1991,7 +1991,7 @@ inventaris item(s) verplaatsen? <usetemplate ignoretext="Indien verplaatsen 'niet kopieerbare' inventaris van gescripte objecten" name="okcancelignore" notext="Annuleren" yestext="OK"/> </notification> <notification name="ClickActionNotPayable"> - Waarschuwing: Het Betaal Object aan klik actie is ingesteld, maar het zal alleen werken als er een script is toegevoegd met een money() event. + Waarschuwing: Het 'Betaal object' aan klik actie is ingesteld, maar het zal alleen werken als er een script is toegevoegd met een money() event. <form name="form"> <ignore name="ignore" text="Indien instellen 'Betaal' op objecten zonder money() events"/> </form> @@ -2916,7 +2916,7 @@ Flexibele objecten mogen niet fysiek zijn en moeten fantoom zijn tot de 'fl <notification name="FirstDebugMenus"> U heeft het menu Geavanceerd geactiveerd. Dit menu bevat opties die handig zijn voor ontwikkelaars tijdens het debuggen van [SECOND_LIFE]. -Om dit menu in en uit te schakelen drukt u binnen Windows Ctrl-Alt-D. Met een Mac drukt u ⌘-Opt-D. +Om dit menu in en uit te schakelen drukt u binnen Windows Ctrl+Alt+D. Met een Mac drukt u ⌥⌘D. </notification> <notification name="FirstSculptedPrim"> U bent een sculpted prim aan het bewerken. diff --git a/indra/newview/skins/default/xui/nl/panel_edit_profile.xml b/indra/newview/skins/default/xui/nl/panel_edit_profile.xml new file mode 100644 index 0000000000..00f8c087de --- /dev/null +++ b/indra/newview/skins/default/xui/nl/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Inwoner" />
+ <string name="AcctTypeTrial"
+ value="Proef" />
+ <string name="AcctTypeCharterMember"
+ value="Charter lid" />
+ <string name="AcctTypeEmployee"
+ value="Linden Lab werknemer" />
+ <string name="PaymentInfoUsed"
+ value="Betalingsinformatie gebruikt" />
+ <string name="PaymentInfoOnFile"
+ value="Betalingsinformatie aanwezig" />
+ <string name="NoPaymentInfoOnFile"
+ value="Geen betalingsinfo aanwezig" />
+ <string name="AgeVerified"
+ value="Leeftijd geverifieerd" />
+ <string name="NotAgeVerified"
+ value="Leeftijd niet geverifieerd" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=nl
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Antwoord bij Niet Storen:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/nl/panel_group_general.xml b/indra/newview/skins/default/xui/nl/panel_group_general.xml index d92d41bcb3..2a0fe03232 100644 --- a/indra/newview/skins/default/xui/nl/panel_group_general.xml +++ b/indra/newview/skins/default/xui/nl/panel_group_general.xml @@ -45,7 +45,7 @@ Laat uw muis boven de opties zweven voor meer help. <panel name="preferences_container"> <check_box label="Toon in zoeken" name="show_in_group_list" tool_tip="Stelt in of deze groep zichtbaar is in de zoekresultaten."/> <check_box label="Vrije toegang" name="open_enrollement" tool_tip="Stelt in of deze groep toestaat dat nieuwe leden lid kunnen worden zonder uitgenodigd te zijn."/> - <check_box label="Contributiebijdrage: L$" name="check_enrollment_fee" tool_tip="Stelt in of er een contributiebijdrage vereist is om lid te worden van de groep."/> + <check_box label="Contributiebijdrage:" name="check_enrollment_fee" tool_tip="Stelt in of er een contributiebijdrage vereist is om lid te worden van de groep."/> <spinner name="spin_enrollment_fee" tool_tip="Nieuwe leden moeten deze bijdrage betalen om deel te nemen aan de groep wanneer "Contributie bijdrage" is aangevinkt." width="58" left_delta="142"/> <combo_box name="group_mature_check" tool_tip="Stelt in of uw groepsinformatie als mature beschouwd wordt."> <combo_box.item name="select_mature" label="- Selecteer -"/> diff --git a/indra/newview/skins/default/xui/nl/panel_region_estate.xml b/indra/newview/skins/default/xui/nl/panel_region_estate.xml index 3a8096ce5f..7a5fa801d9 100644 --- a/indra/newview/skins/default/xui/nl/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/nl/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Estate" name="Estate"> +<panel label="Estate" name="Estate"> <text name="estate_help_text"> Wijzigingen van instellingen op dit tabblad zullen alle regio's in de estate beïnvloeden. @@ -69,6 +67,4 @@ zullen alle regio's in de estate beïnvloeden. <button label="?" name="ban_resident_help"/> <button label="Verwijderen..." name="remove_banned_avatar_btn"/> <button label="Toevoegen..." name="add_banned_avatar_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/nl/panel_region_texture.xml b/indra/newview/skins/default/xui/nl/panel_region_texture.xml index da40926ce2..ff10e20b7c 100644 --- a/indra/newview/skins/default/xui/nl/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/nl/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Grond texturen" name="Textures"> +<panel label="Grond texturen" name="Textures"> <text name="region_text_lbl"> Regio: </text> @@ -56,6 +54,4 @@ en de HIGH waarde is de MINIMUM hoogte van textuur #4. </text> <button label="Toepassen" name="apply_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/nl/strings.xml b/indra/newview/skins/default/xui/nl/strings.xml index bb073f735d..49ebcd319c 100644 --- a/indra/newview/skins/default/xui/nl/strings.xml +++ b/indra/newview/skins/default/xui/nl/strings.xml @@ -487,16 +487,16 @@ Kies folder </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Shift- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -604,6 +604,9 @@ <string name="no_ability_error"> U beschikt niet over die mogelijkheid. </string> + <string name="no_ability"> + U beschikt niet over die mogelijkheid. + </string> <string name="not_a_mod_error"> U bent geen sessie moderateur </string> @@ -622,4 +625,31 @@ <string name="close_on_no_ability"> U heeft niet langer de mogelijkheid om in deze chatsessie te zijn. </string> + <string name="AcctTypeResident"> + Inwoner + </string> + <string name="AcctTypeTrial"> + Proef + </string> + <string name="AcctTypeCharterMember"> + Charter lid + </string> + <string name="AcctTypeEmployee"> + Linden Lab werknemer + </string> + <string name="PaymentInfoUsed"> + Betalingsinformatie gebruikt + </string> + <string name="PaymentInfoOnFile"> + Betalingsinformatie aanwezig + </string> + <string name="NoPaymentInfoOnFile"> + Geen betalingsinfo aanwezig + </string> + <string name="AgeVerified"> + Leeftijd geverifieerd + </string> + <string name="NotAgeVerified"> + Leeftijd niet geverifieerd + </string> </strings> diff --git a/indra/newview/skins/default/xui/pl/floater_sell_land.xml b/indra/newview/skins/default/xui/pl/floater_sell_land.xml index 70451fb5f6..579dcd6745 100755 --- a/indra/newview/skins/default/xui/pl/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater name="sell land" title="Sell Land"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Posiadłość: </text> @@ -55,4 +57,6 @@ </text> <button label="Wystaw Ziemię na Sprzedaż" name="sell_btn" /> <button label="Anuluj" name="cancel_btn" /> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml index ad03e6e9f0..c9e7a7e9eb 100755 --- a/indra/newview/skins/default/xui/pl/floater_tools.xml +++ b/indra/newview/skins/default/xui/pl/floater_tools.xml @@ -191,28 +191,28 @@ <check_box name="checkbox next owner can transfer"/> </panel> <string name="text modify info 1"> - Możesz modyfikować ten obiekt. + Możesz modyfikować ten obiekt </string> <string name="text modify info 2"> - Możesz modyfikować te obiekty. + Możesz modyfikować te obiekty </string> <string name="text modify info 3"> - Nie możesz modyfikować tego obiektu. + Nie możesz modyfikować tego obiektu </string> <string name="text modify info 4"> - Nie możesz modyfikować tych obieków. + Nie możesz modyfikować tych obieków </string> <string name="text modify warning"> - Musisz zaznaczyć cały obiekt by ustawić prawa. + Musisz zaznaczyć cały obiekt by ustawić prawa </string> <string name="Cost Default"> - Cena: L$ + Cena: L$ </string> <string name="Cost Total"> - Cena Całości: L$ + Cena Całości: L$ </string> <string name="Cost Per Unit"> - Cena Za: L$ + Cena Za: L$ </string> <string name="Cost Mixed"> Cena Mieszana @@ -511,8 +511,8 @@ <button label="Dopasuj" label_selected="Dopasuj" name="button align" left="160"/> </panel> <panel label="Treść" name="Contents"> - <button label="Nowy Skrypt" label_selected="Nowy Skrypt..." name="button new script"/> - <button label="Prawa..." name="button permissions"/> + <button label="Nowy Skrypt" label_selected="Nowy Skrypt" name="button new script"/> + <button label="Prawa" name="button permissions"/> </panel> </tab_container> <panel name="land info panel"> @@ -526,18 +526,18 @@ Obszar: [AREA] m </text> <button label="O Posiadłości..." label_selected="O Posiadłości..." name="button about land"/> - <check_box label="Pokaż Właścicieli" name="checkbox show owners" tool_tip="Pokoloruj posiadłości zgodnie z przynależnością do właściciela"/> + <check_box label="Pokaż Właścicieli" name="checkbox show owners" tool_tip="Pokoloruj posiadłości zgodnie z przynależnością do właściciela: Zielony = Twoja Posiadłość Morski = Posiadłość Twojej Grupy Czerwony = Posiadłości Innych Żółty = Na Sprzedaż Fioletowy = Na Aukcję Szary = Publiczna"/> <button label="?" label_selected="?" name="button show owners help" left_delta="120"/> <text name="label_parcel_modify"> Modyfikuj Posiadłość </text> - <button label="Podziel..." label_selected="Podziel..." name="button subdivide land"/> - <button label="Złącz..." label_selected="Złącz..." name="button join land"/> + <button label="Podziel" label_selected="Podziel" name="button subdivide land"/> + <button label="Złącz" label_selected="Złącz" name="button join land"/> <text name="label_parcel_trans"> Transakcje na posiadłości </text> - <button label="Kup..." label_selected="Kup..." name="button buy land"/> - <button label="Anuluj..." label_selected="Anuluj..." name="button abandon land"/> + <button label="Kup" label_selected="Kup" name="button buy land"/> + <button label="Anuluj" label_selected="Anuluj" name="button abandon land"/> </panel> <floater.string name="status_rotate"> Przeciągaj kolorowe pierścienie żeby obracać obiekt diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index ef5dad8786..3cf9be507d 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -1713,7 +1713,7 @@ Jeżeli ta opcja jest wybrana kupujący będą mogli odsprzedać posiadłości w Domyślinie: nie pozwalaj </notification> <notification label="Wyłącz Skrypty" name="HelpRegionDisableScripts"> - Słaba wydajność / prędkość symulatora może być spowodowana przez skrypt. Otwórz panel Statystyki (Ctrl-Shift-1). Sprawdź ilość klatek na sekundę (FPS) w Fizyce Symulatora. Jeżeli jest mniej niż 45 wybierz panel Czas znajdujący się na dole panelu Statystyki. Jeżeli Czas Skryptów wynosi 25 ms lub więcej kliknij na Główne Skrypty. Zobaczysz listę nazw i lokacji skryptów które mogą być odpowiedzialne za pogorszenie wydajności. + Słaba wydajność / prędkość symulatora może być spowodowana przez skrypt. Otwórz panel Statystyki (Ctrl+Shift+1). Sprawdź ilość klatek na sekundę (FPS) w Fizyce Symulatora. Jeżeli jest mniej niż 45 wybierz panel Czas znajdujący się na dole panelu Statystyki. Jeżeli Czas Skryptów wynosi 25 ms lub więcej kliknij na Główne Skrypty. Zobaczysz listę nazw i lokacji skryptów które mogą być odpowiedzialne za pogorszenie wydajności. Wybranie opcji Wyłącz Skrypty i naciśnięcie Zastosuj tymczasowo wyłączy wszystkie skrypty w tym regionie. Wybranie tej opcji może być niezbędne w celu umożliwienia podróży do lokacji wymienionego Głównego Skryptu. Po przebyciu na miejsce zobacz skrypt i sprawdź czy jest on źródłem problemu. W razie potrzeby skontaktuj się z właścicielem skryptu albo usuń lub zwróć obiekt. @@ -1722,7 +1722,7 @@ Wyłączenie opcji Wyłącz Skrypty i naciśnięcie Zastosuj ponownie włączy s Domyślnie: nie wybrana </notification> <notification label="Wyłącz Kolizje" name="HelpRegionDisableCollisions"> - Słaba wydajność / prędkość symulatora może być spowodowana przez fizyczne obiekty. Otwórz panel Statystyki (Ctrl-Shift-1). Sprawdź ilość klatek na sekundę (FPS) w Fizyce Symulatora. Jeżeli jest mniej niż 45 wybierz panel Czas znajdujący się na dole panelu Statystyki. Jeżeli Czas Symulatora (Fizyka) wynosi 20 ms lub więcej kliknij na Główne Kolizje. Zobaczysz listę nazw i lokacji fizycznych obiektów które mogą być odpowiedzialne za pogorszenie wydajności. + Słaba wydajność / prędkość symulatora może być spowodowana przez fizyczne obiekty. Otwórz panel Statystyki (Ctrl+Shift+1). Sprawdź ilość klatek na sekundę (FPS) w Fizyce Symulatora. Jeżeli jest mniej niż 45 wybierz panel Czas znajdujący się na dole panelu Statystyki. Jeżeli Czas Symulatora (Fizyka) wynosi 20 ms lub więcej kliknij na Główne Kolizje. Zobaczysz listę nazw i lokacji fizycznych obiektów które mogą być odpowiedzialne za pogorszenie wydajności. Wybranie opcji Wyłącz Kolizje i naciśnięcie Zastosuj tymczasowo wyłączy kolizje obiektów. Wybranie tej opcji może być niezbędne w celu umożliwienia podróży do lokacji wymienionych Główneych Kolizji. Po przebyciu na miejsce zobacz obiekt i sprawdź czy jest on źródłem kolizji z innymi obiektami. W razie potrzeby skontaktuj się z właścicielem obiektu albo usuń lub zwróć obiekt. @@ -1936,7 +1936,7 @@ Przenieść obiekty szafy? <usetemplate ignoretext="Przenosząc szafę bez praw kopiowania ze skryptowanych obiektów" name="okcancelignore" notext="Anuluj" yestext="OK"/> </notification> <notification name="ClickActionNotPayable"> - Uwaga: Opcja Zapłać Obiektowi została wybrana, ale żeby ta opcja działała musi być dodany skrypt z funkcją money(). + Uwaga: Opcja 'Zapłać Obiektowi' została wybrana, ale żeby ta opcja działała musi być dodany skrypt z funkcją money(). <form name="form"> <ignore name="ignore" text="Wybierając opcję Zapłać Obiektowi dla obiektów bez funkcji money()"/> </form> @@ -2867,7 +2867,7 @@ Obiekty elastyczne nie mogą być fizyczne i muszą być typu fantom. <notification name="FirstDebugMenus"> Zaawansowane menu zostało włączone. To menu zawiera funkcje użyteczne dla programistów analizujących [SECOND_LIFE]. -To menu jest aktywowane dzięki kombinacji klawiszy Ctrl-Alt-D (Windows) lub ⌘-Opt-D (Mac). +To menu jest aktywowane dzięki kombinacji klawiszy Ctrl+Alt+D (Windows) lub ⌥⌘D (Mac). </notification> <notification name="FirstSculptedPrim"> Edytujesz sculpt. diff --git a/indra/newview/skins/default/xui/pl/panel_edit_profile.xml b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml new file mode 100644 index 0000000000..e449a92d7e --- /dev/null +++ b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Rezydent" />
+ <string name="AcctTypeTrial"
+ value="Próbne" />
+ <string name="AcctTypeCharterMember"
+ value="Członek-zalożyciel" />
+ <string name="AcctTypeEmployee"
+ value="Pracownik Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Dane Konta Używane" />
+ <string name="PaymentInfoOnFile"
+ value="Dane Konta Dostępne" />
+ <string name="NoPaymentInfoOnFile"
+ value="Brak Danych Konta" />
+ <string name="AgeVerified"
+ value="Wiek Zweryfikowany" />
+ <string name="NotAgeVerified"
+ value="Brak Weryfikacji Wieku" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=pl
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Partner:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Pracuś Mówi:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_group_general.xml b/indra/newview/skins/default/xui/pl/panel_group_general.xml index 5d19485634..d09ff72226 100755 --- a/indra/newview/skins/default/xui/pl/panel_group_general.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_general.xml @@ -1,9 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <panel label="Ogólne" name="general_tab"> <string name="help_text"> - Zakładka Ogólne zawiera informacje na temat tej grupy, -listę właścicieli, widocznych członków, -ustawienia grupy oraz opcje członkostwa. + Zakładka Ogólne zawiera informacje na temat tej grupy, listę właścicieli, widocznych członków, ustawienia grupy oraz opcje członkostwa. </string> <string name="group_info_unchanged"> Ogólne informacje na temat grupy uległy zmianie. @@ -45,7 +43,7 @@ ustawienia grupy oraz opcje członkostwa. <panel name="preferences_container"> <check_box label="Wyświetlaj w wyszukiwarce" name="show_in_group_list" tool_tip="Udostępnij info o grupie w wyszukiwarce"/> <check_box label="Wolny Wstęp" name="open_enrollement" tool_tip="Sprawdź czy grupa oferuje wolny wstęp i nie wymaga zaproszenia."/> - <check_box label="Opłata Wstępu: L$" name="check_enrollment_fee" tool_tip="Ustaw opłatę za przyłączenie się do grupy."/> + <check_box label="Opłata Wstępu:" name="check_enrollment_fee" tool_tip="Ustaw opłatę za przyłączenie się do grupy."/> <spinner name="spin_enrollment_fee" tool_tip="Nowi członkowie grupy muszą zapłacić wymaganą opłatę by dołączyć do grupy."/> <combo_box name="group_mature_check" tool_tip="Wybierz jeżeli uważasz, iż Twoja grupa klasyfikowana jest jako 'Mature'."> <combo_box.item name="select_mature" label="- Wybierz Treść -"/> diff --git a/indra/newview/skins/default/xui/pl/panel_group_land_money.xml b/indra/newview/skins/default/xui/pl/panel_group_land_money.xml index 5080b0963a..dbfa8e3122 100755 --- a/indra/newview/skins/default/xui/pl/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/pl/panel_group_land_money.xml @@ -48,8 +48,11 @@ <string name="land_contrib_error"> Nie można ustalić Twoich kontrybucji. </string> + <text name="your_contribution_units"> + ( m ) + </text> <text name="your_contribution_max_value"> - metrów ([AMOUNT] maksimum) + ([AMOUNT] maksimum) </text> <text name="group_over_limit_text"> Członkowie Grupy muszą zwiększyć kredyt na używanie Posiadłości. diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml index a7654ef2ff..97b4975f29 100755 --- a/indra/newview/skins/default/xui/pl/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/pl/panel_preferences_general.xml @@ -34,10 +34,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="'PG', 'Mature' oraz 'Adult'"/> <combo_box.item name="Desired_Mature" label="'PG' i 'Mature'"/> - <combo_box.item name="Desired_PG" label="tylko 'PG'"/> + <combo_box.item name="Desired_PG" label="'PG'"/> </combo_box> <text name="maturity_desired_textbox"> - tylko 'PG' + 'PG' </text> <text name="start_location_textbox"> Miejsce Startu: diff --git a/indra/newview/skins/default/xui/pl/panel_region_estate.xml b/indra/newview/skins/default/xui/pl/panel_region_estate.xml index 4447de517b..4275f3f647 100755 --- a/indra/newview/skins/default/xui/pl/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Majątek" name="Estate"> +<panel label="Majątek" name="Estate"> <text name="estate_help_text"> Zmiany ustawień na tej zakładce odnoszą się do wszystkich Regionów w tym Majątku. @@ -73,6 +71,4 @@ do wszystkich Regionów w tym Majątku. <name_list name="banned_avatar_name_list"/> <button label="Usuń..." name="remove_banned_avatar_btn"/> <button label="Dodaj..." name="add_banned_avatar_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/pl/panel_region_texture.xml b/indra/newview/skins/default/xui/pl/panel_region_texture.xml index ac43f0b2cc..d24579fc75 100755 --- a/indra/newview/skins/default/xui/pl/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/pl/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Tekstury Gruntu" name="Textures"> +<panel label="Tekstury Gruntu" name="Textures"> <text name="region_text_lbl"> Region: </text> @@ -56,6 +54,4 @@ a wartość GÓRA to MINIMALNY poziom dla tekstury #4. </text> <button label="Zastosuj" name="apply_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml index 294353ee03..1f67944f86 100755 --- a/indra/newview/skins/default/xui/pl/strings.xml +++ b/indra/newview/skins/default/xui/pl/strings.xml @@ -487,16 +487,16 @@ Wybierz Katalog </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Shift- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -603,6 +603,9 @@ <string name="no_ability_error"> Nie posiadesz tego przywileju. </string> + <string name="no_ability"> + Nie posiadesz tego przywileju. + </string> <string name="not_a_mod_error"> Nie jesteś moderatorem konferencji. </string> @@ -621,4 +624,31 @@ <string name="close_on_no_ability"> Nie posiadasz praw by uczestniczyć w tej konferencji. </string> + <string name="AcctTypeResident"> + Rezydent + </string> + <string name="AcctTypeTrial"> + Próbne + </string> + <string name="AcctTypeCharterMember"> + Członek-zalożyciel + </string> + <string name="AcctTypeEmployee"> + Pracownik Linden Lab + </string> + <string name="PaymentInfoUsed"> + Dane Konta Używane + </string> + <string name="PaymentInfoOnFile"> + Dane Konta Dostępne + </string> + <string name="NoPaymentInfoOnFile"> + Brak Danych Konta + </string> + <string name="AgeVerified"> + Wiek Zweryfikowany + </string> + <string name="NotAgeVerified"> + Brak Weryfikacji Wieku + </string> </strings> diff --git a/indra/newview/skins/default/xui/pt/floater_sell_land.xml b/indra/newview/skins/default/xui/pt/floater_sell_land.xml index 20f9972c73..d3581405ff 100644 --- a/indra/newview/skins/default/xui/pt/floater_sell_land.xml +++ b/indra/newview/skins/default/xui/pt/floater_sell_land.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> <floater name="sell land" title="Vender terreno"> + <scroll_container name="profile_scroll"> + <panel name="scroll_content_panel"> <text name="info_parcel_label"> Lote: </text> @@ -58,4 +60,6 @@ lote irão mudar de propriedade. </text> <button label="Definir Terra para Venda" name="sell_btn"/> <button label="Cancelar" name="cancel_btn"/> + </panel> + </scroll_container> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index 7302c1c8f8..d7227deacc 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -159,7 +159,7 @@ </combo_box> <panel name="perms_build"> <text name="perm_modify"> - Você pode modificar este objeto. + Você pode modificar este objeto </text> <text name="B:"> B: @@ -187,28 +187,28 @@ <check_box name="checkbox next owner can transfer" left_delta="67"/> </panel> <string name="text modify info 1"> - Você pode modificar este objeto. + Você pode modificar este objeto </string> <string name="text modify info 2"> - Você pode modificar estes objetos. + Você pode modificar estes objetos </string> <string name="text modify info 3"> - Você não pode modificar este objeto. + Você não pode modificar este objeto </string> <string name="text modify info 4"> - Você não pode modificar estes objetos. + Você não pode modificar estes objetos </string> <string name="text modify warning"> - Você precisa selecionar o objeto todo para ajustar as permissões. + Você precisa selecionar o objeto todo para ajustar as permissões </string> <string name="Cost Default"> - Preço: L$ + Preço: L$ </string> <string name="Cost Total"> - Preço Total: L$ + Preço Total: L$ </string> <string name="Cost Per Unit"> - Preço Por: L$ + Preço Por: L$ </string> <string name="Cost Mixed"> Preço Misturado @@ -498,8 +498,8 @@ <button label="Alinhar" label_selected="Alinhar" name="button align"/> </panel> <panel label="Conteúdo" name="Contents"> - <button label="Novo Script" label_selected="Novo Script..." name="button new script"/> - <button label="Permissões..." name="button permissions"/> + <button label="Novo Script" label_selected="Novo Script" name="button new script"/> + <button label="Permissões" name="button permissions"/> <panel name="ContentsInventory" width="272" /> </panel> </tab_container> @@ -514,18 +514,18 @@ Área: [AREA] m². </text> <button label="Sobre a Terra..." label_selected="Sobre a Terra..." name="button about land"/> - <check_box label="Mostrar donos" name="checkbox show owners" tool_tip="Colorir lotes de acordo com seus donos"/> + <check_box label="Mostrar donos" name="checkbox show owners" tool_tip="Colorir lotes de acordo com seus donos: Green = Sua terra Aqua = Terra do seu grupo Red = Possuída por outros Yellow = À venda Purple = A leilão Grey = Pública"/> <button label="?" label_selected="?" name="button show owners help" left_delta="100"/> <text name="label_parcel_modify"> Modificar Lote </text> - <button label="Sub-Dividir..." label_selected="Sub-Dividir..." name="button subdivide land"/> - <button label="Unir..." label_selected="Unir..." name="button join land"/> + <button label="Sub-Dividir" label_selected="Sub-Dividir" name="button subdivide land"/> + <button label="Unir" label_selected="Unir" name="button join land"/> <text name="label_parcel_trans"> Transações com a Terra </text> - <button label="Comprar Terra..." label_selected="Comprar Terra.." name="button buy land"/> - <button label="Abandonar Terra..." label_selected="Abandonar Terra..." name="button abandon land"/> + <button label="Comprar Terra" label_selected="Comprar Terra" name="button buy land"/> + <button label="Abandonar Terra" label_selected="Abandonar Terra" name="button abandon land"/> </panel> <floater.string name="status_rotate"> Arrastar as bandas coloridas para girar o objeto diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index 1f15feef49..0ee2c5cb84 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -1730,10 +1730,10 @@ Se esta opção estiver marcada, compradores podem vender seus terrenos nesta re Padrão: Desabilitada. </notification> <notification label="Desabilitar Scripts" name="HelpRegionDisableScripts"> - Quando a performance do simulador está ruim, um script pode ser o culpado. Abra a Barra de Estatísticas (Ctrl-Shift-1). Olhe no Simulador de Física FPS. Se estiver abaixo de 45, então abra o painel 'Tempo' localizado na parte de baixo da Barra de Estatísticas. Se o Tempo de Script indicar 25 ms ou mais, clique no botão 'Get Top CScripts'. Será dado o nome e a localização do script que pode estar causando uma performance ruim. Marque a caixa 'Desabilitar Scripts' e aperte o botão 'Aplicar'. Isto temporariamente desabilitará todos os scripts nesta região. Uma vez que você chegar ao local, investigue o script para determinar se ele está causando o problema. Você pode querer entrar em contato com o proprietário do script, excluir ou devolver o objeto. Desmarque a caixa 'Desabilitar Script' e então clique em 'Aplicar' para reativar os scripts na região. Padrão: desligado. + Quando a performance do simulador está ruim, um script pode ser o culpado. Abra a Barra de Estatísticas (Ctrl+Shift+1). Olhe no Simulador de Física FPS. Se estiver abaixo de 45, então abra o painel 'Tempo' localizado na parte de baixo da Barra de Estatísticas. Se o Tempo de Script indicar 25 ms ou mais, clique no botão 'Get Top CScripts'. Será dado o nome e a localização do script que pode estar causando uma performance ruim. Marque a caixa 'Desabilitar Scripts' e aperte o botão 'Aplicar'. Isto temporariamente desabilitará todos os scripts nesta região. Uma vez que você chegar ao local, investigue o script para determinar se ele está causando o problema. Você pode querer entrar em contato com o proprietário do script, excluir ou devolver o objeto. Desmarque a caixa 'Desabilitar Script' e então clique em 'Aplicar' para reativar os scripts na região. Padrão: desligado. </notification> <notification label="Desabilitar Colisões" name="HelpRegionDisableCollisions"> - Quando a performance do simulador é pobre, os objetos físicos podem ser os culpados.Abra a a Barra de Estatísticas (Ctrl-Shift-1). + Quando a performance do simulador é pobre, os objetos físicos podem ser os culpados.Abra a a Barra de Estatísticas (Ctrl+Shift+1). Olhe a taxa de quadros por segundos (FPS) dos objetos físicos. Se ela estiver abaixo de 45, abra o painel de Tempo, localizado na parte inferior da Barra de Estatísticas. Se o Tempo (Físicos) do Simulador mostrar 20 ms ou mais, clique o botão 'Pegue os Maiores Colidentes'. Será fornecido a você o nome e a localidade dos objetos físicos que podem estar causando uma performance pobre. @@ -1954,7 +1954,7 @@ Mover para o inventário o(s) item(s)? <usetemplate ignoretext="Quando movendo objetos com scripts não copiáveis ao inventário" name="okcancelignore" notext="Não mover" yestext="Mover"/> </notification> <notification name="ClickActionNotPayable"> - Aviso: A ação de Pagar ao Objeto com clique foi definida, mas funcionará apenas se for adicionado um script com o evento money(). + Aviso: A ação de 'Pagar Objeto' com clique foi definida, mas funcionará apenas se for adicionado um script com o evento money(). <form name="form"> <ignore name="ignore" text="Quando Definindo 'Pagar' em objetos sem eventos money()"/> </form> @@ -2875,7 +2875,7 @@ Objetos flexíveis não podem ser físicos e devem ser fantasmas até que a caix <notification name="FirstDebugMenus"> Você ativou o menu Avançado. Este menu contém funcionalidades úteis para desenvolvedores debugarem o [SECOND_LIFE]. -Para mostrar esse menu no Windows pressione Ctrl-Alt-D. No Mac pressione ⌘-Opt-D. +Para mostrar esse menu no Windows pressione Ctrl+Alt+D. No Mac pressione ⌥⌘D. </notification> <notification name="FirstSculptedPrim"> Você está editando uma primitiva esculpida. diff --git a/indra/newview/skins/default/xui/pt/panel_edit_profile.xml b/indra/newview/skins/default/xui/pt/panel_edit_profile.xml new file mode 100644 index 0000000000..e97e77cfe6 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_edit_profile.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel name="edit_profile_panel">
+ <string name="CaptionTextAcctInfo">
+ [ACCTTYPE] [PAYMENTINFO] [AGEVERIFICATION]
+ </string>
+ <string name="AcctTypeResident"
+ value="Residente" />
+ <string name="AcctTypeTrial"
+ value="Teste" />
+ <string name="AcctTypeCharterMember"
+ value="Estatuto do membro" />
+ <string name="AcctTypeEmployee"
+ value="Contratado da Linden Lab" />
+ <string name="PaymentInfoUsed"
+ value="Infor. de pagamento utilizadas" />
+ <string name="PaymentInfoOnFile"
+ value="Infor. de pagamento no arquivo" />
+ <string name="NoPaymentInfoOnFile"
+ value="Sem infor. de pagamento no arquivo" />
+ <string name="AgeVerified"
+ value="Idade Verificada" />
+ <string name="NotAgeVerified"
+ value="Idade não Verificada" />
+ <string name="partner_edit_link_url">
+ http://www.secondlife.com/account/partners.php?lang=pt
+ </string>
+ <panel name="scroll_content_panel">
+ <panel name="data_panel" >
+ <panel name="lifes_images_panel">
+ <panel name="second_life_image_panel">
+ <text name="second_life_photo_title_text">
+ [SECOND_LIFE]:
+ </text>
+ </panel>
+ </panel>
+ <text name="title_partner_text" value="Parceiro:"/>
+ <panel name="partner_data_panel">
+ <text name="partner_text" value="[FIRST] [LAST]"/>
+ </panel>
+ <text name="text_box3">
+ Resposta no Modo Ocupado:
+ </text>
+ </panel>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_group_general.xml b/indra/newview/skins/default/xui/pt/panel_group_general.xml index bdaa0e72f5..226011c138 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_general.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_general.xml @@ -43,7 +43,7 @@ <panel name="preferences_container"> <check_box label="Mostre na busca" name="show_in_group_list" tool_tip="Deixe as pessoas verem este grupo nos resultados de busca."/> <check_box label="Adesão aberta" name="open_enrollement" tool_tip="Definir se este grupo permite que novos membros entrem sem serem convidados"/> - <check_box label="Taxa de adesão: L$" name="check_enrollment_fee" tool_tip="Define se é necessária uma taxa de adesão para se unir ao grupo."/> + <check_box label="Taxa de adesão:" name="check_enrollment_fee" tool_tip="Define se é necessária uma taxa de adesão para se unir ao grupo."/> <spinner width="60" left_delta="120" name="spin_enrollment_fee" tool_tip="Os novos membros devem pagar esta taxa para se unir ao grupo quando a Taxa de Adesão está marcada."/> <combo_box width="170" name="group_mature_check" tool_tip="Define se a informação do seu grupo é considerada mature."> <combo_box.item name="select_mature" label="- Selecionar Maturidade -"/> diff --git a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml index 103da6d67d..5b09363e3c 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml @@ -47,8 +47,11 @@ <string name="land_contrib_error"> Não é possível definir sua contribuição para o terreno. </string> + <text name="your_contribution_units"> + ( m² ) + </text> <text name="your_contribution_max_value"> - m² ([AMOUNT] máxima) + ([AMOUNT] máxima) </text> <text name="group_over_limit_text"> Membros do grupo precisam contribuir com mais créditos de Terra para diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml index e50713c0c8..8bde39545c 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml @@ -33,10 +33,10 @@ <combo_box name="maturity_desired_combobox"> <combo_box.item name="Desired_Adult" label="PG, Mature e Adult"/> <combo_box.item name="Desired_Mature" label="PG e Mature"/> - <combo_box.item name="Desired_PG" label="apenas PG"/> + <combo_box.item name="Desired_PG" label="PG"/> </combo_box> <text name="maturity_desired_textbox"> - apenas PG + PG </text> <text name="start_location_textbox"> Posição Inicial: diff --git a/indra/newview/skins/default/xui/pt/panel_region_estate.xml b/indra/newview/skins/default/xui/pt/panel_region_estate.xml index e62ba85763..f43402be15 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_estate.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_estate.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<panel name="EstateWrapper"> - <scroll_container name="container1"> - <panel label="Propriedade" name="Estate"> +<panel label="Propriedade" name="Estate"> <text name="estate_help_text"> Mudanças nas definições nesta guia irão afetar todas as regiões desta propriedade. @@ -68,6 +66,4 @@ todas as regiões desta propriedade. <button label="?" name="ban_resident_help"/> <button label="Remover..." name="remove_banned_avatar_btn"/> <button label="Adicionar..." name="add_banned_avatar_btn"/> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_region_texture.xml b/indra/newview/skins/default/xui/pt/panel_region_texture.xml index 2fdba79807..4787b59a8d 100644 --- a/indra/newview/skins/default/xui/pt/panel_region_texture.xml +++ b/indra/newview/skins/default/xui/pt/panel_region_texture.xml @@ -1,7 +1,5 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<panel name="TextureWrapper"> - <scroll_container name="container1"> - <panel label="Texturas de Chão" name="Textures"> +<panel label="Texturas de Chão" name="Textures"> <text name="region_text_lbl"> Região: </text> @@ -56,6 +54,4 @@ e o valor Alto é a altura Mínima da Textura #4. </text> <button label="Aplicar" name="apply_btn" /> - </panel> - </scroll_container> </panel> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index b6788567e2..2d3514e5fe 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -484,16 +484,16 @@ Escolher Diretório </string> <string name="accel-mac-control"> - Ctrl- + ⌃ </string> <string name="accel-mac-command"> - Cmd- + ⌘ </string> <string name="accel-mac-option"> - Opt- + ⌥ </string> <string name="accel-mac-shift"> - Shift- + ⇧ </string> <string name="accel-win-control"> Ctrl+ @@ -599,6 +599,9 @@ <string name="no_ability_error"> Você não possui esta habilidade. </string> + <string name="no_ability"> + Você não possui esta habilidade. + </string> <string name="not_a_mod_error"> Você não é um moderador de sessão. </string> @@ -617,4 +620,31 @@ <string name="close_on_no_ability"> Você não possui mais a habilidade de estar na sessão de bate-papo. </string> + <string name="AcctTypeResident"> + Residente + </string> + <string name="AcctTypeTrial"> + Teste + </string> + <string name="AcctTypeCharterMember"> + Estatuto do membro + </string> + <string name="AcctTypeEmployee"> + Contratado da Linden Lab + </string> + <string name="PaymentInfoUsed"> + Infor. de pagamento utilizadas + </string> + <string name="PaymentInfoOnFile"> + Infor. de pagamento no arquivo + </string> + <string name="NoPaymentInfoOnFile"> + Sem infor. de pagamento no arquivo + </string> + <string name="AgeVerified"> + Idade Verificada + </string> + <string name="NotAgeVerified"> + Idade não Verificada + </string> </strings> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f2e89ef062..06eb1e1265 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -786,20 +786,30 @@ class Linux_i686Manifest(LinuxManifest): #self.path("secondlife-i686.supp") if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"): - #self.path("libkdu_v42R.so", "libkdu.so") - self.path("libfmod-3.75.so") self.path("libapr-1.so.0") self.path("libaprutil-1.so.0") self.path("libdb-4.2.so") self.path("libcrypto.so.0.9.7") self.path("libexpat.so.1") self.path("libssl.so.0.9.7") - self.path("libuuid.so.1", "libuuid.so.1") + self.path("libuuid.so.1") self.path("libSDL-1.2.so.0") self.path("libELFIO.so") self.path("libopenjpeg.so.1.3.0", "libopenjpeg.so.1.3") self.path("libalut.so") self.path("libopenal.so", "libopenal.so.1") + try: + self.path("libkdu_v42R.so", "libkdu.so") + pass + except: + print "Skipping libkdu_v42R.so - not found" + pass + try: + self.path("libfmod-3.75.so") + pass + except: + print "Skipping libkdu_v42R.so - not found" + pass self.end_prefix("lib") # Vivox runtimes diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 6a93537a38..381197d812 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -29,67 +29,39 @@ include_directories( ) set(test_SOURCE_FILES - common.cpp - inventory.cpp io.cpp # llapp_tut.cpp # Temporarily removed until thread issues can be solved - llbase64_tut.cpp - llbbox_tut.cpp - llbboxlocal_tut.cpp llblowfish_tut.cpp llbuffer_tut.cpp - lldate_tut.cpp lldependencies_tut.cpp lldoubledispatch_tut.cpp - llerror_tut.cpp llevents_tut.cpp - llhost_tut.cpp llhttpdate_tut.cpp llhttpclient_tut.cpp llhttpnode_tut.cpp llinventoryparcel_tut.cpp lliohttpserver_tut.cpp - lljoint_tut.cpp - llmime_tut.cpp llmessageconfig_tut.cpp - llmodularmath_tut.cpp - llnamevalue_tut.cpp llpermissions_tut.cpp llpipeutil.cpp - llquaternion_tut.cpp - llrandom_tut.cpp - llrect_tut.cpp llsaleinfo_tut.cpp llscriptresource_tut.cpp llsdmessagebuilder_tut.cpp llsdmessagereader_tut.cpp llsd_new_tut.cpp - llsdserialize_tut.cpp llsdutil_tut.cpp llservicebuilder_tut.cpp llstreamtools_tut.cpp - llstring_tut.cpp lltemplatemessagebuilder_tut.cpp lltimestampcache_tut.cpp - lltiming_tut.cpp lltranscode_tut.cpp - lltreeiterators_tut.cpp lltut.cpp - lluri_tut.cpp lluuidhashmap_tut.cpp llxfer_tut.cpp - math.cpp message_tut.cpp reflection_tut.cpp stringize_tut.cpp test.cpp - v2math_tut.cpp - v3color_tut.cpp - v3dmath_tut.cpp - v3math_tut.cpp - v4color_tut.cpp - v4coloru_tut.cpp - v4math_tut.cpp ) set(test_HEADER_FILES diff --git a/indra/test/lltut.h b/indra/test/lltut.h index ba3791cbd4..6322753253 100644 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -74,7 +74,7 @@ namespace tut inline void ensure_memory_matches(const char* msg,const void* actual, U32 actual_len, const void* expected,U32 expected_len) { if((expected_len != actual_len) || - (memcmp(actual, expected, actual_len) != 0)) + (std::memcmp(actual, expected, actual_len) != 0)) { std::stringstream ss; ss << (msg?msg:"") << (msg?": ":"") << "not equal"; diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 721e9da917..7dfe8f40b7 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -148,24 +148,24 @@ public: private: void run_completed_(std::ostream &stream) { + stream << "\tTotal Tests:\t" << mTotalTests << std::endl; + stream << "\tPassed Tests:\t" << mPassedTests; + if (mPassedTests == mTotalTests) + { + stream << "\tYAY!! \\o/"; + } stream << std::endl; - stream << "Total Tests: " << mTotalTests << std::endl; - stream << "Passed Tests: " << mPassedTests << std::endl; - stream << std::endl; - stream << "Total Tests: " << mTotalTests << std::endl; - stream << "Passed Tests: " << mPassedTests << std::endl; - if (mSkippedTests > 0) { - stream << "Skipped known failures: " << mSkippedTests + stream << "\tSkipped known failures:\t" << mSkippedTests << std::endl; } if(mFailedTests > 0) { stream << "*********************************" << std::endl; - stream << "Failed Tests: " << mFailedTests << std::endl; + stream << "Failed Tests:\t" << mFailedTests << std::endl; stream << "Please report or fix the problem." << std::endl; stream << "*********************************" << std::endl; } |