diff --git a/README_BUILD_FIRESTORM_LINUX.txt b/README_BUILD_FIRESTORM_LINUX.txt index 3416b7ba48..8c7bdb61ad 100755 --- a/README_BUILD_FIRESTORM_LINUX.txt +++ b/README_BUILD_FIRESTORM_LINUX.txt @@ -18,9 +18,9 @@ mailing list. We've created a non-KDU build target to make this easier. Everywhe Available premade firestorm-specific build targets: - ReleaseFS (includes KDU, FMOD) - ReleaseFS_open (no KDU, no FMOD) - RelWithDebInfoFS_open (no KDU, no FMOD) + ReleaseFS (includes KDU, FMOD) + ReleaseFS_open (no KDU, no FMOD) + RelWithDebInfoFS_open (no KDU, no FMOD) To build firestorm: @@ -41,10 +41,7 @@ Typical LL autobuild configure options should also work, as long as they don't d already doing. Logs: - Look for logs in build-linux-i686/logs Output: - Look for output in build-linux-i686/newview/Release - diff --git a/README_BUILD_FIRESTORM_MACOSX.txt b/README_BUILD_FIRESTORM_MACOSX.txt index 529bba70d5..c44631128e 100755 --- a/README_BUILD_FIRESTORM_MACOSX.txt +++ b/README_BUILD_FIRESTORM_MACOSX.txt @@ -32,16 +32,15 @@ build, using openjpeg instead of KDU. Available premade firestorm-specific build targets: - ReleaseFS (includes KDU, FMOD) - ReleaseFS_open (no KDU, no FMOD) - RelWithDebInfo_open (no KDU, no FMOD) + ReleaseFS (includes KDU, FMOD) + ReleaseFS_open (no KDU, no FMOD) + RelWithDebInfo_open (no KDU, no FMOD) To build firestorm: autobuild build -c ReleaseFS Other examples: - autobuild configure -c ReleaseFS # basic configuration step, don't build, just configure autobuild configure -c ReleaseFS -- --clean # clean the output area first, then configure autobuild configure -c ReleaseFS -- --chan Private-Yourname # configure with a custom channel diff --git a/README_BUILD_FIRESTORM_WIN32.txt b/README_BUILD_FIRESTORM_WIN32.txt index aaf4c73734..a9690dcd64 100755 --- a/README_BUILD_FIRESTORM_WIN32.txt +++ b/README_BUILD_FIRESTORM_WIN32.txt @@ -2,7 +2,7 @@ Before you start configuring your Windows build system, be aware of our tested c Memory: You will need at least 2GB RAM, 4GB strongly recommended. CPU: Multiple CPUs are strongly recommended. A build can take over an hour. - Visual Studio 2010. + Visual Studio 2010 SP1. Ensure you can build a stock viewer-development try as described in the SL wiki. Before asking for any help compiling Firestorm, make sure you can build viewer-development first. If you try and skip this step, you may @@ -32,9 +32,9 @@ After launching the VS2010 cmd shell and navigating to your firestorm code repo: Other build targets you may use are: - ReleaseFS (includes KDU, FMOD) - ReleaseFS_open (no KDU, no FMOD) - RelWithDebInfoFS_open (no KDU, no FMOD) + ReleaseFS (includes KDU, FMOD) + ReleaseFS_open (no KDU, no FMOD) + RelWithDebInfoFS_open (no KDU, no FMOD) Other examples: autobuild configure -c ReleaseFS # basic configuration step, don't build, just configure diff --git a/README_BUILD_FIRESTORM_WIN64.txt b/README_BUILD_FIRESTORM_WIN64.txt index 6995ad2313..5e48852ac3 100755 --- a/README_BUILD_FIRESTORM_WIN64.txt +++ b/README_BUILD_FIRESTORM_WIN64.txt @@ -1,7 +1,7 @@ This is WIP. Please change/expand when seeing fit. 1.1 Visual Studio 2010 Pro or better with installed 64 bit compiler. -1.2 Or Visual Studio Express and 'Microsoft Windows SDK for Windows 7 and .NET Framework 4'. Make sure to install at least the header and compiler. +1.2 Or Visual Studio Express and 'Microsoft Windows SDK for Windows 7 and .NET Framework 4'. Make sure to install at least the header and compiler with all the latest service packs. 2. autobuild from https://bitbucket.org/NickyD/autobuild 3. FMOD, if you want sound, please see https://bitbucket.org/NickyD/3p-fmodex diff --git a/autobuild.xml b/autobuild.xml index 63b94f26c2..d56d26c371 100755 --- a/autobuild.xml +++ b/autobuild.xml @@ -1872,9 +1872,9 @@ archive hash - 4a98d727561cd1f4ac5ee02907411df1 + 3c2b6be4c78b2479c3fae612e1053d37 url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20120228.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/Darwin/installer/llqtwebkit-4.7.1-darwin-20141015.tar.bz2 name darwin @@ -1884,9 +1884,9 @@ archive hash - f50e5f0cc880c55b3f0f7e67dc8f7221 + d31358176b9ba8c676458cc061767c0b url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/Linux/installer/llqtwebkit-4.7.1-linux-20120228.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/Linux/installer/llqtwebkit-4.7.1-linux-20141015.tar.bz2 name linux @@ -1908,9 +1908,9 @@ archive hash - 5e3cd6af397e853a963a6de40d440ff4 + bb4e8c8006c8a7aef6d3e3c36a8cebbf url - http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llqtwebkit/rev/250147/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20120228.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/canonical_3p-llqtwebkit2/rev/295522/arch/CYGWIN/installer/llqtwebkit-4.7.1-windows-20141015.tar.bz2 name windows @@ -2404,9 +2404,9 @@ archive hash - 6849432c00ee2db495016c45f0f30122 + 7dde5d6bfa45124a4c7b342a7a4f3f77 url - http://downloads.phoenixviewer.com/slplugin_x86-1.0-darwin-20140630.tar.bz2 + http://downloads.phoenixviewer.com/slplugin_x86-4.6.9.42958-darwin-20141122.tar.bz2 name darwin diff --git a/indra/Version b/indra/Version index 4cfc99d299..53e12f7c5c 100644 --- a/indra/Version +++ b/indra/Version @@ -1 +1 @@ -VERSION_VIEWER=4.6.8 +VERSION_VIEWER=4.7.0 diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 7c56bb6995..270cb42215 100755 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -251,13 +251,6 @@ elseif(DARWIN) libgrowl++.dylib ) - # libllqtwebkit.dylib comes from a prebuild slplugin. It needs to be fetched from somewhere else - # when building x64/universal. Probably it's best to copy it in fs_viewer_manifest.py for those cases. - if( NOT ND_BUILD64BIT_ARCH ) - set(release_files ${release_files} libllqtwebkit.dylib ) - endif( NOT ND_BUILD64BIT_ARCH ) - # - # We only ever need google breakpad when crash reporting is used if(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) set(release_files ${release_files} "libexception_handler.dylib") diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake index 02c8f388ea..769bd89764 100755 --- a/indra/cmake/WebKitLibPlugin.cmake +++ b/indra/cmake/WebKitLibPlugin.cmake @@ -53,8 +53,12 @@ if (WINDOWS) ) elseif (DARWIN) set(WEBKIT_PLUGIN_LIBRARIES - optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - debug ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.a + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtWebKit.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtOpenGL.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtNetwork.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtGui.4.dylib + ${ARCH_PREBUILT_DIRS_RELEASE}/libQtCore.4.dylib ) elseif (LINUX) # FIRE-6108, add missing if clause for standalone builds - TL @@ -74,7 +78,7 @@ elseif (LINUX) QtGui QtCore jpeg - jscore +# jscore fontconfig X11 Xrender diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h index 742f6abbd4..7bb2384938 100755 --- a/indra/llmath/llcalcparser.h +++ b/indra/llmath/llcalcparser.h @@ -89,6 +89,14 @@ struct LLCalcParser : grammar (str_p("ASIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_asin)(self,arg1)]) | (str_p("ACOS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_acos)(self,arg1)]) | (str_p("ATAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_atan)(self,arg1)]) | + // FIRE-14618: Provide radian-based functions + (str_p("SINR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sinr)(self,arg1)]) | + (str_p("COSR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_cosr)(self,arg1)]) | + (str_p("TANR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_tanr)(self,arg1)]) | + (str_p("ASINR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_asinr)(self,arg1)]) | + (str_p("ACOSR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_acosr)(self,arg1)]) | + (str_p("ATANR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_atanr)(self,arg1)]) | + // (str_p("SQRT") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sqrt)(self,arg1)]) | (str_p("LOG") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_log)(self,arg1)]) | (str_p("EXP") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_exp)(self,arg1)]) | @@ -169,9 +177,17 @@ private: F32 _sin(const F32& a) const { return sin(DEG_TO_RAD * a); } F32 _cos(const F32& a) const { return cos(DEG_TO_RAD * a); } F32 _tan(const F32& a) const { return tan(DEG_TO_RAD * a); } - F32 _asin(const F32& a) const { return asin(a * RAD_TO_DEG); } - F32 _acos(const F32& a) const { return acos(a * RAD_TO_DEG); } - F32 _atan(const F32& a) const { return atan(a * RAD_TO_DEG); } + F32 _asin(const F32& a) const { return asin(a) * RAD_TO_DEG; } + F32 _acos(const F32& a) const { return acos(a) * RAD_TO_DEG; } + F32 _atan(const F32& a) const { return atan(a) * RAD_TO_DEG; } + // FIRE-14618: Provide radian-based functions + F32 _sinr(const F32& a) const { return sin(a); } + F32 _cosr(const F32& a) const { return cos(a); } + F32 _tanr(const F32& a) const { return tan(a); } + F32 _asinr(const F32& a) const { return asin(a); } + F32 _acosr(const F32& a) const { return acos(a); } + F32 _atanr(const F32& a) const { return atan(a); } + // F32 _sqrt(const F32& a) const { return sqrt(a); } F32 _log(const F32& a) const { return log(a); } F32 _exp(const F32& a) const { return exp(a); } diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 34beef6a6b..07d142c226 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -87,6 +87,7 @@ LLShaderFeatures::LLShaderFeatures() , mIndexedTextureChannels(0) , disableTextureIndex(false) , hasAlphaMask(false) + , attachNothing(false) { } @@ -119,28 +120,31 @@ struct LLGLSLShaderCompareTimeElapsed }; //static -void LLGLSLShader::finishProfile() +void LLGLSLShader::finishProfile(bool emit_report) { sProfileEnabled = false; - std::vector sorted; - - for (std::set::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + if (emit_report) { - sorted.push_back(*iter); - } + std::vector sorted; - std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); + for (std::set::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + { + sorted.push_back(*iter); + } - for (std::vector::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) - { - (*iter)->dumpStats(); - } + std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); + for (std::vector::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) + { + (*iter)->dumpStats(); + } + LL_INFOS() << "-----------------------------------" << LL_ENDL; LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed/1000000.f) << LL_ENDL; LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn/1000000.f) << LL_ENDL; LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn/1000000.f) << LL_ENDL; + } } void LLGLSLShader::clearStats() @@ -175,7 +179,7 @@ void LLGLSLShader::dumpStats() } } LL_INFOS() << "=============================================" << LL_ENDL; - + F32 ms = mTimeElapsed/1000000.f; F32 seconds = ms/1000.f; @@ -210,7 +214,7 @@ void LLGLSLShader::startProfile() //static void LLGLSLShader::stopProfile(U32 count, U32 mode) { - if (sProfileEnabled) + if (sProfileEnabled && sCurBoundShaderPtr) { sCurBoundShaderPtr->readProfileQuery(count, mode); } @@ -221,6 +225,7 @@ void LLGLSLShader::placeProfileQuery() #if !LL_DARWIN if (mTimerQuery == 0) { + glGenQueriesARB(1, &mSamplesQuery); glGenQueriesARB(1, &mTimerQuery); } @@ -257,7 +262,7 @@ void LLGLSLShader::placeProfileQuery() } - glBeginQueryARB(GL_SAMPLES_PASSED, 1); + glBeginQueryARB(GL_SAMPLES_PASSED, mSamplesQuery); glBeginQueryARB(GL_TIME_ELAPSED, mTimerQuery); #endif } @@ -275,7 +280,7 @@ void LLGLSLShader::readProfileQuery(U32 count, U32 mode) //U64 samples_passed = 0; GLuint64 samples_passed = 0; - glGetQueryObjectui64v(1, GL_QUERY_RESULT, &samples_passed); + glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed); sTotalTimeElapsed += time_elapsed; mTimeElapsed += time_elapsed; @@ -310,14 +315,15 @@ LLGLSLShader::LLGLSLShader() mShaderLevel(0), mShaderGroup(SG_DEFAULT), mUniformsDirty(FALSE), - mTimerQuery(0) + mTimerQuery(0), + mSamplesQuery(0) + { } LLGLSLShader::~LLGLSLShader() { - } void LLGLSLShader::unload() @@ -352,6 +358,18 @@ void LLGLSLShader::unload() mProgramObject = 0; } + if (mTimerQuery) + { + glDeleteQueriesARB(1, &mTimerQuery); + mTimerQuery = 0; + } + + if (mSamplesQuery) + { + glDeleteQueriesARB(1, &mSamplesQuery); + mSamplesQuery = 0; + } + //hack to make apple not complain glGetError(); diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 7b2f5f04c2..5abddf274b 100755 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -51,6 +51,7 @@ public: S32 mIndexedTextureChannels; bool disableTextureIndex; bool hasAlphaMask; + bool attachNothing; // char numLights; @@ -80,7 +81,7 @@ public: static bool sNoFixedFunction; static void initProfile(); - static void finishProfile(); + static void finishProfile(bool emit_report = true); static void startProfile(); static void stopProfile(U32 count, U32 mode); @@ -184,6 +185,7 @@ public: //statistcis for profiling shader performance U32 mTimerQuery; + U32 mSamplesQuery; U64 mTimeElapsed; static U64 sTotalTimeElapsed; U32 mTrianglesDrawn; diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 45592ee077..a62b24c0ab 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -192,7 +192,10 @@ protected: protected: LLGLTextureState mTextureState ; - +// ND> Expose mipmap generation so we can check it for texture memory tax +public: + bool getUseMipMaps() const { return mUseMipMaps; } +// }; #endif // LL_GL_TEXTURE_H diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 955ea450c1..cd484b4fe9 100755 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -388,6 +388,7 @@ void LLRenderTarget::release() // if (mFBO && (mTex.size() > 1)) { + glBindFramebuffer(GL_FRAMEBUFFER, mFBO); S32 z; for (z = mTex.size() - 1; z >= 1; z--) { diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index ef855e293d..35da8ab2c4 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -73,7 +73,11 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) { llassert_always(shader != NULL); LLShaderFeatures *features = & shader->mFeatures; - + + if (features->attachNothing) + { + return TRUE; + } ////////////////////////////////////// // Attach Vertex Shader Features First ////////////////////////////////////// diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp index 698f3d5e3f..b0550be5db 100755 --- a/indra/llui/llchatentry.cpp +++ b/indra/llui/llchatentry.cpp @@ -53,6 +53,7 @@ LLChatEntry::LLChatEntry(const Params& p) mCurrentHistoryLine = mLineHistory.begin(); mAutoIndent = false; + keepSelectionOnReturn(true); } LLChatEntry::~LLChatEntry() @@ -185,15 +186,6 @@ BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask) { BOOL handled = FALSE; - // In the case of a chat entry, pressing RETURN when something is selected - // should NOT erase the selection (unlike a notecard, for example) - if (key == KEY_RETURN) - { - endOfDoc(); - startSelection(); - endSelection(); - } - LLTextEditor::handleSpecialKey(key, mask); switch(key) diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index edd26fb1a1..7840b84d8b 100755 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -937,7 +937,10 @@ void LLComboBox::updateSelection() mTextEntry->setTentative(FALSE); mLastSelectedIndex = mList->getFirstSelectedIndex(); } - else if (mList->selectItemByPrefix(left_wstring, FALSE)) + // Allow fulltext search in comboboxes + //else if (mList->selectItemByPrefix(left_wstring, FALSE)) + else if (!LLControlGroup::getInstance("Global")->getBOOL("FSComboboxSubstringSearch") && mList->selectItemByPrefix(left_wstring, FALSE)) + // { LLWString selected_item = utf8str_to_wstring(getSelectedItemLabel()); LLWString wtext = left_wstring + selected_item.substr(left_wstring.size(), selected_item.size()); @@ -948,6 +951,18 @@ void LLComboBox::updateSelection() mHasAutocompletedText = TRUE; mLastSelectedIndex = mList->getFirstSelectedIndex(); } + // Allow fulltext search in comboboxes + else if (LLControlGroup::getInstance("Global")->getBOOL("FSComboboxSubstringSearch") && mList->selectItemBySubstring(left_wstring, FALSE)) + { + LLWString selected_item = utf8str_to_wstring(getSelectedItemLabel()); + mTextEntry->setText(wstring_to_utf8str(left_wstring) + " (" + getSelectedItemLabel() + ")"); + mTextEntry->setSelection(left_wstring.size(), mTextEntry->getWText().size()); + mTextEntry->endSelection(); + mTextEntry->setTentative(FALSE); + mHasAutocompletedText = TRUE; + mLastSelectedIndex = mList->getFirstSelectedIndex(); + } + // else // no matching items found { mList->deselectAllItems(); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index da7b830aec..897c85f923 100755 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2429,7 +2429,10 @@ void LLFloaterView::restoreAll() for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { LLFloater* floaterp = (LLFloater*)*child_it; - floaterp->setMinimized(FALSE); + if (floaterp) // Possible fix for crash on disconnect + { + floaterp->setMinimized(FALSE); + } } // *FIX: make sure dependents are restored diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index de10a5a665..ace64311bf 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -275,6 +275,24 @@ BOOL LLFolderViewItem::passedFilter(S32 filter_generation) return getViewModelItem()->passedFilter(filter_generation); } +BOOL LLFolderViewItem::isPotentiallyVisible(S32 filter_generation) +{ + // Item should be visible if: + // 1. item passed current filter + // 2. item was updated (gen < 0) but has descendants that passed filter + // 3. item was recently updated and was visible before update + + LLFolderViewModelItem* model = getViewModelItem(); + if (model->getLastFilterGeneration() < 0 && !getFolderViewModel()->getFilter().isModified()) + { + return model->descendantsPassedFilter(filter_generation) || getVisible(); + } + else + { + return model->passedFilter(filter_generation); + } +} + void LLFolderViewItem::refresh() { LLFolderViewModelItem& vmi = *getViewModelItem(); @@ -722,7 +740,7 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L // const S32 TOP_PAD = default_params.item_top_pad; - if (hasVisibleChildren() || getViewModelItem()->hasChildren()) + if (hasVisibleChildren()) { LLUIImage* arrow_image = default_params.folder_arrow_image; gl_draw_scaled_rotated_image( @@ -1077,7 +1095,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) getRoot()->getFolderViewModel()->sort(this); LL_RECORD_BLOCK_TIME(FTM_ARRANGE); - + // evaluate mHasVisibleChildren mHasVisibleChildren = false; if (getViewModelItem()->descendantsPassedFilter()) @@ -1088,7 +1106,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit) { LLFolderViewItem* itemp = (*iit); - found = itemp->passedFilter(); + found = itemp->isPotentiallyVisible(); if (found) break; } @@ -1098,7 +1116,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit) { LLFolderViewFolder* folderp = (*fit); - found = folderp->passedFilter(); + found = folderp->isPotentiallyVisible(); if (found) break; } @@ -1131,7 +1149,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit) { LLFolderViewFolder* folderp = (*fit); - folderp->setVisible(folderp->passedFilter()); // passed filter or has descendants that passed filter + folderp->setVisible(folderp->isPotentiallyVisible()); if (folderp->getVisible()) { @@ -1150,7 +1168,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) iit != mItems.end(); ++iit) { LLFolderViewItem* itemp = (*iit); - itemp->setVisible(itemp->passedFilter()); + itemp->setVisible(itemp->isPotentiallyVisible()); if (itemp->getVisible()) { diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index af835054db..4f3f26934f 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -263,6 +263,7 @@ public: S32 getIndentation() { return mIndentation; } virtual BOOL passedFilter(S32 filter_generation = -1); + virtual BOOL isPotentiallyVisible(S32 filter_generation = -1); // refresh information from the object being viewed. virtual void refresh(); diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 0f2d2fbee9..3531c2cf50 100755 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -49,8 +49,7 @@ LLLayoutPanel::Params::Params() : expanded_min_dim("expanded_min_dim", 0), min_dim("min_dim", -1), user_resize("user_resize", false), - auto_resize("auto_resize", true), - force_resize_bar("force_resize_bar", false) // FIRE-5141: Add option to force display of a resize handle + auto_resize("auto_resize", true) { addSynonym(min_dim, "min_width"); addSynonym(min_dim, "min_height"); @@ -69,8 +68,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p) mFractionalSize(0.f), mTargetDim(0), mIgnoreReshape(false), - mOrientation(LLLayoutStack::HORIZONTAL), - mForceResizeBar(p.force_resize_bar) // FIRE-5141: Add option to force display of a resize handle + mOrientation(LLLayoutStack::HORIZONTAL) { // panels initialized as hidden should not start out partially visible if (!getVisible()) @@ -476,10 +474,7 @@ void LLLayoutStack::updateLayout() if (panelp->mAutoResize && !panelp->mCollapsed - // FIRE-5141: Add option to force display of a resize handle - //&& panelp->getVisible()) - && (panelp->getVisible() || panelp->mForceResizeBar)) - // + && panelp->getVisible()) { S32 space_for_panel = remaining_space > 0 ? 1 : -1; panelp->mTargetDim += space_for_panel; @@ -792,10 +787,7 @@ bool LLLayoutStack::animatePanels() // BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - // FIRE-5141: Add option to force display of a resize handle - //if (panelp->getVisible()) - if (panelp->getVisible() || panelp->mForceResizeBar) - // + if (panelp->getVisible()) { if (mAnimate && panelp->mVisibleAmt < 1.f) { @@ -896,10 +888,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& if (panelp->mAutoResize) { old_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim()); - // FIRE-5141: Add option to force display of a resize handle - //if (panelp->getVisible() && !panelp->mCollapsed) - if ((panelp->getVisible() || panelp->mForceResizeBar) && !panelp->mCollapsed) - // + if (panelp->getVisible() && !panelp->mCollapsed) { total_visible_fraction += panelp->mFractionalSize; } @@ -910,10 +899,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& other_resize_panel = following_panel; } - // FIRE-5141: Add option to force display of a resize handle - //if (panelp->getVisible() && !panelp->mCollapsed) - if ((panelp->getVisible() || panelp->mForceResizeBar) && !panelp->mCollapsed) - // + if (panelp->getVisible() && !panelp->mCollapsed) { following_panel = panelp; } @@ -948,10 +934,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect& BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) { - // FIRE-5141: Add option to force display of a resize handle - //if (!panelp->getVisible() || panelp->mCollapsed) - if ((!panelp->getVisible() && !panelp->mForceResizeBar) || panelp->mCollapsed) - // + if (!panelp->getVisible() || panelp->mCollapsed) { if (panelp->mAutoResize) { @@ -1059,10 +1042,7 @@ void LLLayoutStack::updateResizeBarLimits() LLLayoutPanel* previous_visible_panelp = NULL; BOOST_REVERSE_FOREACH(LLLayoutPanel* visible_panelp, mPanels) { - // FIRE-5141: Add option to force display of a resize handle - //if (!visible_panelp->getVisible() || visible_panelp->mCollapsed) - if ((!visible_panelp->getVisible() && !visible_panelp->mForceResizeBar) || visible_panelp->mCollapsed) - // + if (!visible_panelp->getVisible() || visible_panelp->mCollapsed) { visible_panelp->mResizeBar->setVisible(FALSE); continue; diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index bc61a3cd65..316d05834d 100755 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -151,9 +151,6 @@ public: Optional user_resize, auto_resize; - // FIRE-5141: Add option to force display of a resize handle - Optional force_resize_bar; - Params(); }; @@ -223,9 +220,6 @@ protected: LLView::EOrientation mOrientation; class LLResizeBar* mResizeBar; - // FIRE-5141: Add option to force display of a resize handle - bool mForceResizeBar; - // Add callback for reshaping reshape_panel_callback_t mReshapePanelCallback; }; diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 421cdbbf2f..a0524ccc55 100755 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -934,6 +934,34 @@ void LLLineEditor::removeChar() } } +// Ctrl-Backspace remove word +// Remove a word (set of characters up to next space/punctuation) from the text +void LLLineEditor::removeWord(bool prev) +{ + const U32 pos(getCursor()); + if (prev ? pos > 0 : static_cast(pos) < getLength()) + { + U32 new_pos(prev ? prevWordPos(pos) : nextWordPos(pos)); + if (new_pos == pos) // Other character we don't jump over + new_pos = prev ? prevWordPos(new_pos-1) : nextWordPos(new_pos+1); + + const U32 diff(labs(pos - new_pos)); + if (prev) + { + mText.erase(new_pos, diff); + setCursor(new_pos); + } + else + { + mText.erase(pos, diff); + } + } + else + { + LLUI::reportBadKeystroke(); + } +} +// void LLLineEditor::addChar(const llwchar uni_char) { @@ -1382,7 +1410,13 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) else if( 0 < getCursor() ) { - removeChar(); + // Ctrl-Backspace remove word + //removeChar(); + if (mask == MASK_CONTROL) + removeWord(true); + else + removeChar(); + // } else { @@ -1392,6 +1426,16 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask) handled = TRUE; break; + // Ctrl-Backspace remove word + case KEY_DELETE: + if (!mReadOnly && mask == MASK_CONTROL) + { + removeWord(false); + handled = true; + } + break; + // + case KEY_PAGE_UP: case KEY_HOME: if (!mIgnoreArrowKeys) diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 1ab5d25346..0b1d593219 100755 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -285,6 +285,8 @@ private: void pasteHelper(bool is_primary); void removeChar(); + // Ctrl-Backspace remove word + void removeWord(bool prev); void addChar(const llwchar c); void setCursorAtLocalPos(S32 local_mouse_x); S32 findPixelNearestPos(S32 cursor_offset = 0) const; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 353c30996c..d45591c838 100755 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1318,6 +1318,13 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const std::string& target, BOOL case_s // Selects first enabled item that has a name where the name's first part matched the target string. // Returns false if item not found. BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sensitive) +// Allow selection by substring match +{ + return selectItemByStringMatch(target, true, case_sensitive); +} + +BOOL LLScrollListCtrl::selectItemByStringMatch(const LLWString& target, bool prefix_match, BOOL case_sensitive) +// { BOOL found = FALSE; @@ -1369,7 +1376,18 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen LLWString trimmed_label = item_label; LLWStringUtil::trim(trimmed_label); - BOOL select = item->getEnabled() && trimmed_label.compare(0, target_trimmed.size(), target_trimmed) == 0; + // Allow selection by substring match + //BOOL select = item->getEnabled() && trimmed_label.compare(0, target_trimmed.size(), target_trimmed) == 0; + BOOL select; + if (prefix_match) + { + select = item->getEnabled() && trimmed_label.compare(0, target_trimmed.size(), target_trimmed) == 0; + } + else + { + select = item->getEnabled() && trimmed_label.find(target_trimmed) != std::string::npos; + } + // if (select) { @@ -1391,6 +1409,19 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen return found; } +// Allow selection by substring match +BOOL LLScrollListCtrl::selectItemBySubstring(const std::string& target, BOOL case_sensitive) +{ + return selectItemBySubstring(utf8str_to_wstring(target), case_sensitive); +} + +// Returns false if item not found. +BOOL LLScrollListCtrl::selectItemBySubstring(const LLWString& target, BOOL case_sensitive) +{ + return selectItemByStringMatch(target, false, case_sensitive); +} +// + const std::string LLScrollListCtrl::getSelectedItemLabel(S32 column) const { LLScrollListItem* item; diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index f6e9e7c947..9aa5e5380f 100755 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -249,6 +249,11 @@ public: BOOL selectItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); // FALSE if item not found BOOL selectItemByPrefix(const std::string& target, BOOL case_sensitive = TRUE); BOOL selectItemByPrefix(const LLWString& target, BOOL case_sensitive = TRUE); + // Allow selection by substring match + BOOL selectItemBySubstring(const std::string& target, BOOL case_sensitive = TRUE); + BOOL selectItemBySubstring(const LLWString& target, BOOL case_sensitive = TRUE); + BOOL selectItemByStringMatch(const LLWString& target, bool prefix_match, BOOL case_sensitive = TRUE); + // LLScrollListItem* getItemByLabel( const std::string& item, BOOL case_sensitive = TRUE, S32 column = 0 ); const std::string getSelectedItemLabel(S32 column = 0) const; LLSD getSelectedValue(); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 2fb3a0601e..6562c091c0 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -302,6 +302,9 @@ LLTextBase::~LLTextBase() { mSegments.clear(); delete mURLClickSignal; + // Properly free the signals + delete mIsFriendSignal; + // } void LLTextBase::initFromParams(const LLTextBase::Params& p) diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 5c3b0fe383..85a89dad84 100755 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -264,7 +264,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) : mContextMenu(NULL), mShowContextMenu(p.show_context_menu), mEnableTooltipPaste(p.enable_tooltip_paste), - mPassDelete(FALSE) + mPassDelete(FALSE), + mKeepSelectionOnReturn(false) { mSourceID.generate(); @@ -1122,6 +1123,35 @@ void LLTextEditor::removeChar() } } +// Ctrl-Backspace remove word +// Remove a word (set of characters up to next space/punctuation) from the text +void LLTextEditor::removeWord(bool prev) +{ + const U32 pos(mCursorPos); + if (prev ? pos > 0 : static_cast(pos) < getLength()) + { + U32 new_pos(prev ? prevWordPos(pos) : nextWordPos(pos)); + if (new_pos == pos) // Other character we don't jump over + new_pos = prev ? prevWordPos(new_pos-1) : nextWordPos(new_pos+1); + + const U32 diff(labs(pos - new_pos)); + if (prev) + { + remove(new_pos, diff, false); + setCursorPos(new_pos); + } + else + { + remove(pos, diff, false); + } + } + else + { + LLUI::reportBadKeystroke(); + } +} +// + // Add a single character to the text S32 LLTextEditor::addChar(S32 pos, llwchar wc) { @@ -1717,7 +1747,13 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask) else if( 0 < mCursorPos ) { - removeCharOrTab(); + // Ctrl-Backspace remove word + //removeCharOrTab(); + if (mask == MASK_CONTROL) + removeWord(true); + else + removeCharOrTab(); + // } else { @@ -1725,11 +1761,23 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask) } break; + // Ctrl-Backspace remove word + case KEY_DELETE: + if (getEnabled() && mask == MASK_CONTROL) + { + removeWord(false); + } + else + { + handled = false; + } + break; + // case KEY_RETURN: if (mask == MASK_NONE) { - if( hasSelection() ) + if( hasSelection() && !mKeepSelectionOnReturn ) { deleteSelection(FALSE); } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index d0d3b1e404..bbc3db5b5e 100755 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -262,6 +262,8 @@ protected: S32 overwriteChar(S32 pos, llwchar wc); void removeChar(); S32 removeChar(S32 pos); + // Ctrl-Backspace remove word + void removeWord(bool prev); S32 insert(S32 pos, const LLWString &wstr, bool group_with_next_op, LLTextSegmentPtr segment); S32 remove(S32 pos, S32 length, bool group_with_next_op); @@ -303,6 +305,7 @@ protected: /*virtual*/ void updateSegments(); void updateLinkSegments(); + void keepSelectionOnReturn(bool keep) { mKeepSelectionOnReturn = keep; } private: // @@ -346,6 +349,7 @@ private: bool mParseOnTheFly; bool mEnableTooltipPaste; bool mPassDelete; + bool mKeepSelectionOnReturn; // disabling of removing selected text after pressing of Enter LLUUID mSourceID; diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 5e1f12996e..bb7f615d51 100755 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -476,9 +476,9 @@ void LLToolTipMgr::show(const std::string& msg) void LLToolTipMgr::show(const LLToolTip::Params& params) { - if (!params.styled_message.isProvided() - && (!params.message.isProvided() || params.message().empty())) return; - + if (!params.styled_message.isProvided() + && (!params.message.isProvided() || params.message().empty()) + && !params.image.isProvided()) return; // fill in default tooltip params from tool_tip.xml LLToolTip::Params params_with_defaults(params); params_with_defaults.fillFrom(LLUICtrlFactory::instance().getDefaultParams()); diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 1b08067cbf..85a700d736 100755 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -227,7 +227,10 @@ void LLUrlAction::blockObject(std::string url) std::string object_name = getObjectName(url); if (LLUUID::validate(object_id)) { - executeSLURL("secondlife:///app/agent/" + object_id + "/block/" + object_name); + // FIRE-14987: Cannot mute objects with slashes in their name via V1 chat history + //executeSLURL("secondlife:///app/agent/" + object_id + "/block/" + object_name); + executeSLURL("secondlife:///app/agent/" + object_id + "/block/" + LLURI::escape(object_name)); + // } } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 9f2bcacbf5..6d4ca3dc78 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -238,7 +238,10 @@ void callFocus() void callFocusLost() { - gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + if (gWindowImplementation) + { + gWindowImplementation->getCallbacks()->handleFocusLost(gWindowImplementation); + } } void callRightMouseDown(float *pos, MASK mask) diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt index 0c1c3d800e..1aa70d4e3b 100755 --- a/indra/media_plugins/webkit/CMakeLists.txt +++ b/indra/media_plugins/webkit/CMakeLists.txt @@ -121,12 +121,12 @@ if (DARWIN) ) # copy the webkit dylib to the build directory - add_custom_command( - TARGET media_plugin_webkit POST_BUILD -# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib - COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ - DEPENDS media_plugin_webkit ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib - ) +# add_custom_command( +# TARGET media_plugin_webkit POST_BUILD +# # OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllqtwebkit.dylib +# COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +# DEPENDS media_plugin_webkit ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib +# ) endif (DARWIN) diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 26d21766ee..26b8a6794d 100755 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -160,7 +160,10 @@ private: checkEditState(); - if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) + // FIRE-14935; Make sure to load URI even if state changes are happing rapidly + // if(mInitState == INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + // { if(!mInitialNavigateURL.empty()) { @@ -458,7 +461,10 @@ private: // virtual void onNavigateBegin(const EventType& event) { - if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + // FIRE-14935; Do not switch URI if there is still a saved URI to load + // if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE) + if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE && !mInitialNavigateURL.empty() ) + // { LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin"); message.setValue("uri", event.getEventUri()); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3a2241dd73..1aececf0da 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -208,6 +208,7 @@ set(viewer_SOURCE_FILES lggcontactsets.cpp lfsimfeaturehandler.cpp llpanelopenregionsettings.cpp + fsfloatervramusage.cpp llaccountingcostmanager.cpp llaisapi.cpp @@ -342,6 +343,7 @@ set(viewer_SOURCE_FILES llfloatergesture.cpp llfloatergodtools.cpp llfloatergotoline.cpp + llfloatergroupbulkban.cpp llfloatergroupinvite.cpp llfloatergroups.cpp llfloaterhandler.cpp @@ -516,6 +518,8 @@ set(viewer_SOURCE_FILES llpanelface.cpp llpanelgenerictip.cpp llpanelgroup.cpp + llpanelgroupbulk.cpp + llpanelgroupbulkban.cpp llpanelgroupgeneral.cpp llpanelgroupinvite.cpp llpanelgrouplandmoney.cpp @@ -924,6 +928,7 @@ set(viewer_HEADER_FILES lggbeamscolors.h lggcontactsets.h lfsimfeaturehandler.h + fsfloatervramusage.h llaccountingcostmanager.h llaisapi.h @@ -1059,6 +1064,7 @@ set(viewer_HEADER_FILES llfloatergesture.h llfloatergodtools.h llfloatergotoline.h + llfloatergroupbulkban.h llfloatergroupinvite.h llfloatergroups.h llfloaterhandler.h @@ -1226,6 +1232,9 @@ set(viewer_HEADER_FILES llpanelface.h llpanelgenerictip.h llpanelgroup.h + llpanelgroupbulk.h + llpanelgroupbulkimpl.h + llpanelgroupbulkban.h llpanelgroupgeneral.h llpanelgroupinvite.h llpanelgrouplandmoney.h diff --git a/indra/newview/NACLantispam.cpp b/indra/newview/NACLantispam.cpp index d083d1226c..eb2e9f792a 100644 --- a/indra/newview/NACLantispam.cpp +++ b/indra/newview/NACLantispam.cpp @@ -470,7 +470,7 @@ bool NACLAntiSpamRegistry::checkNewlineFlood(EAntispamQueue queue, const LLUUID& } return false; } - return false; + return true; } bool NACLAntiSpamRegistry::isBlockedOnQueue(EAntispamQueue queue, const LLUUID& source) @@ -656,8 +656,11 @@ void NACLAntiSpamRegistry::processObjectPropertiesFamily(LLMessageSystem* msg) { AntispamObjectData data = found->second; - data.mName = LLSLURL("objectim", id, "").getSLURLString() + "?name=" + LLURI::escape(name) + "&owner=" + owner_id.asString(); - notify(data); + if (!isBlockedOnQueue(data.mQueue, owner_id)) + { + data.mName = LLSLURL("objectim", id, "").getSLURLString() + "?name=" + LLURI::escape(name) + "&owner=" + owner_id.asString(); + notify(data); + } mObjectData.erase(found); } diff --git a/indra/newview/NACLfloaterexploresounds.cpp b/indra/newview/NACLfloaterexploresounds.cpp index 7c9026ab28..7ae9bf9ee7 100644 --- a/indra/newview/NACLfloaterexploresounds.cpp +++ b/indra/newview/NACLfloaterexploresounds.cpp @@ -88,7 +88,7 @@ BOOL NACLFloaterExploreSounds::postBuild() void NACLFloaterExploreSounds::handleSelection() { - S32 num_selected = mHistoryScroller->getAllSelected().size(); + size_t num_selected = mHistoryScroller->getAllSelected().size(); bool multiple = (num_selected > 1); childSetEnabled("look_at_btn", (num_selected && !multiple)); childSetEnabled("play_locally_btn", num_selected); diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index d3acad0593..f6cdf40983 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -4.6.8 +4.7.0 diff --git a/indra/newview/animationexplorer.cpp b/indra/newview/animationexplorer.cpp index f62b206580..6d41d59249 100644 --- a/indra/newview/animationexplorer.cpp +++ b/indra/newview/animationexplorer.cpp @@ -70,43 +70,43 @@ void RecentAnimationList::addAnimation(const LLUUID& id, const LLUUID& playedBy) { AnimationEntry entry; - entry.animationID=id; - entry.playedBy=playedBy; - entry.time=LLTimer::getElapsedSeconds(); + entry.animationID = id; + entry.playedBy = playedBy; + entry.time = LLTimer::getElapsedSeconds(); - AnimationExplorer* explorer=LLFloaterReg::findTypedInstance("animation_explorer"); + AnimationExplorer* explorer = LLFloaterReg::findTypedInstance("animation_explorer"); // only remember animation when it wasn't played by ourselves or the explorer window is open, // so the list doesn't get polluted - if(playedBy!=gAgentAvatarp->getID() || explorer!=NULL) + if (playedBy != gAgentAvatarp->getID() || explorer != NULL) { mAnimationList.push_back(entry); // only keep a certain number of entries - if(mAnimationList.size()>MAX_ANIMATIONS) + if (mAnimationList.size() > MAX_ANIMATIONS) { mAnimationList.pop_front(); } } // if the animation explorer floater is open, send this animation over immediately - if(explorer) + if (explorer) { - explorer->addAnimation(id,playedBy,LLTimer::getElapsedSeconds()); + explorer->addAnimation(id, playedBy, LLTimer::getElapsedSeconds()); } } void RecentAnimationList::requestList(AnimationExplorer* explorer) { - if(explorer) + if (explorer) { // send the list of recent animations to the given animation explorer floater - for(std::deque::iterator iter=mAnimationList.begin(); - iter!=mAnimationList.end(); + for (std::deque::iterator iter = mAnimationList.begin(); + iter != mAnimationList.end(); ++iter) { - AnimationEntry entry=*iter; - explorer->addAnimation(entry.animationID,entry.playedBy,entry.time); + AnimationEntry entry = *iter; + explorer->addAnimation(entry.animationID, entry.playedBy, entry.time); } } } @@ -123,45 +123,45 @@ AnimationExplorer::AnimationExplorer(const LLSD& key) AnimationExplorer::~AnimationExplorer() { - mAnimationPreview=NULL; + mAnimationPreview = NULL; } void AnimationExplorer::startMotion(const LLUUID& motionID) { - if(!mAnimationPreview) + if (!mAnimationPreview) { return; } - LLVOAvatar* avatarp=mAnimationPreview->getDummyAvatar(); + LLVOAvatar* avatarp = mAnimationPreview->getDummyAvatar(); avatarp->deactivateAllMotions(); - avatarp->startMotion(ANIM_AGENT_STAND,0.0f); + avatarp->startMotion(ANIM_AGENT_STAND, 0.0f); - if(motionID.notNull()) + if (motionID.notNull()) { - avatarp->startMotion(motionID,0.0f); + avatarp->startMotion(motionID, 0.0f); } } BOOL AnimationExplorer::postBuild() { - mAnimationScrollList=getChild("animation_list"); - mStopButton=getChild("stop_btn"); - mRevokeButton=getChild("revoke_btn"); - mStopAndRevokeButton=getChild("stop_and_revoke_btn"); - mNoOwnedAnimationsCheckBox=getChild("no_owned_animations_check"); + mAnimationScrollList = getChild("animation_list"); + mStopButton = getChild("stop_btn"); + mRevokeButton = getChild("revoke_btn"); + mStopAndRevokeButton = getChild("stop_and_revoke_btn"); + mNoOwnedAnimationsCheckBox = getChild("no_owned_animations_check"); - mAnimationScrollList->setCommitCallback(boost::bind(&AnimationExplorer::onSelectAnimation,this)); - mStopButton->setCommitCallback(boost::bind(&AnimationExplorer::onStopPressed,this)); - mRevokeButton->setCommitCallback(boost::bind(&AnimationExplorer::onRevokePressed,this)); - mStopAndRevokeButton->setCommitCallback(boost::bind(&AnimationExplorer::onStopAndRevokePressed,this)); - mNoOwnedAnimationsCheckBox->setCommitCallback(boost::bind(&AnimationExplorer::onOwnedCheckToggled,this)); + mAnimationScrollList->setCommitCallback(boost::bind(&AnimationExplorer::onSelectAnimation, this)); + mStopButton->setCommitCallback(boost::bind(&AnimationExplorer::onStopPressed, this)); + mRevokeButton->setCommitCallback(boost::bind(&AnimationExplorer::onRevokePressed, this)); + mStopAndRevokeButton->setCommitCallback(boost::bind(&AnimationExplorer::onStopAndRevokePressed, this)); + mNoOwnedAnimationsCheckBox->setCommitCallback(boost::bind(&AnimationExplorer::onOwnedCheckToggled, this)); - mPreviewCtrl=findChild("animation_preview"); - if(mPreviewCtrl) + mPreviewCtrl = findChild("animation_preview"); + if (mPreviewCtrl) { - mAnimationPreview=new LLPreviewAnimation( + mAnimationPreview = new LLPreviewAnimation( mPreviewCtrl->getRect().getWidth(),mPreviewCtrl->getRect().getHeight() ); mAnimationPreview->setZoom(2.0f); @@ -180,37 +180,37 @@ BOOL AnimationExplorer::postBuild() void AnimationExplorer::onSelectAnimation() { - LLScrollListItem* item=mAnimationScrollList->getFirstSelected(); - if(!item) + LLScrollListItem* item = mAnimationScrollList->getFirstSelected(); + if (!item) { return; } - S32 column=mAnimationScrollList->getColumn("animation_id")->mIndex; - mCurrentAnimationID=item->getColumn(column)->getValue().asUUID(); + S32 column = mAnimationScrollList->getColumn("animation_id")->mIndex; + mCurrentAnimationID = item->getColumn(column)->getValue().asUUID(); - column=mAnimationScrollList->getColumn("played_by")->mIndex; - mCurrentObject=item->getColumn(column)->getValue().asUUID(); + column = mAnimationScrollList->getColumn("played_by")->mIndex; + mCurrentObject = item->getColumn(column)->getValue().asUUID(); startMotion(mCurrentAnimationID); } void AnimationExplorer::onStopPressed() { - if(mCurrentAnimationID.notNull()) + if (mCurrentAnimationID.notNull()) { gAgentAvatarp->stopMotion(mCurrentAnimationID); - gAgent.sendAnimationRequest(mCurrentAnimationID,ANIM_REQUEST_STOP); + gAgent.sendAnimationRequest(mCurrentAnimationID, ANIM_REQUEST_STOP); } } void AnimationExplorer::onRevokePressed() { - if(mCurrentObject.notNull()) + if (mCurrentObject.notNull()) { - LLViewerObject* vo=gObjectList.findObject(mCurrentObject); + LLViewerObject* vo = gObjectList.findObject(mCurrentObject); - if(vo) + if (vo) { gAgentAvatarp->revokePermissionsOnObject(vo); } @@ -232,35 +232,35 @@ void AnimationExplorer::onOwnedCheckToggled() void AnimationExplorer::draw() { LLFloater::draw(); - LLRect r=mPreviewCtrl->getRect(); + LLRect r = mPreviewCtrl->getRect(); - if(mAnimationPreview) + if (mAnimationPreview) { mAnimationPreview->requestUpdate(); - gGL.color3f(1.0f,1.0f,1.0f); + gGL.color3f(1.0f, 1.0f, 1.0f); gGL.getTexUnit(0)->bind(mAnimationPreview); gGL.begin(LLRender::QUADS); { - gGL.texCoord2f(0.0f,1.0f); - gGL.vertex2i(r.mLeft,r.mTop); - gGL.texCoord2f(0.0f,0.0f); - gGL.vertex2i(r.mLeft,r.mBottom); - gGL.texCoord2f(1.0f,0.0f); - gGL.vertex2i(r.mRight,r.mBottom); - gGL.texCoord2f(1.0f,1.0f); - gGL.vertex2i(r.mRight,r.mTop); + gGL.texCoord2f(0.0f, 1.0f); + gGL.vertex2i(r.mLeft, r.mTop); + gGL.texCoord2f(0.0f, 0.0f); + gGL.vertex2i(r.mLeft, r.mBottom); + gGL.texCoord2f(1.0f, 0.0f); + gGL.vertex2i(r.mRight, r.mBottom); + gGL.texCoord2f(1.0f, 1.0f); + gGL.vertex2i(r.mRight, r.mTop); } gGL.end(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } // update tiems and "Still playing" status in the list once every few seconds - static F64 last_update=0.0f; - F64 time=LLTimer::getElapsedSeconds(); - if(time-last_update>5.0f) + static F64 last_update = 0.0f; + F64 time = LLTimer::getElapsedSeconds(); + if (time-last_update > 5.0f) { - last_update=time; + last_update = time; updateList(time); } } @@ -276,58 +276,58 @@ void AnimationExplorer::update() void AnimationExplorer::updateList(F64 current_timestamp) { - S32 played_column=mAnimationScrollList->getColumn("played")->mIndex; - S32 timestamp_column=mAnimationScrollList->getColumn("timestamp")->mIndex; - S32 object_id_column=mAnimationScrollList->getColumn("object_id")->mIndex; - S32 anim_id_column=mAnimationScrollList->getColumn("animation_id")->mIndex; + S32 played_column = mAnimationScrollList->getColumn("played")->mIndex; + S32 timestamp_column = mAnimationScrollList->getColumn("timestamp")->mIndex; + S32 object_id_column = mAnimationScrollList->getColumn("object_id")->mIndex; + S32 anim_id_column = mAnimationScrollList->getColumn("animation_id")->mIndex; // go through the full animation scroll list - std::vector items=mAnimationScrollList->getAllData(); - for (std::vector::iterator list_iter=items.begin();list_iter!=items.end();++list_iter) + std::vector items = mAnimationScrollList->getAllData(); + for (std::vector::iterator list_iter = items.begin(); list_iter != items.end(); ++list_iter) { - LLScrollListItem* item=*list_iter; + LLScrollListItem* item = *list_iter; // get a pointer to the "Played" column text - LLScrollListText* played_text=(LLScrollListText*) item->getColumn(played_column); + LLScrollListText* played_text = (LLScrollListText*)item->getColumn(played_column); // get the object ID from the list - LLUUID object_id=item->getColumn(object_id_column)->getValue().asUUID(); + LLUUID object_id = item->getColumn(object_id_column)->getValue().asUUID(); // assume this animation is not running first - bool is_running=false; + bool is_running = false; // go through the list of playing animations to find out if this animation played by // this object is still running - for(LLVOAvatar::AnimSourceIterator anim_iter=gAgentAvatarp->mAnimationSources.begin(); - anim_iter!=gAgentAvatarp->mAnimationSources.end();anim_iter++) + for (LLVOAvatar::AnimSourceIterator anim_iter = gAgentAvatarp->mAnimationSources.begin(); + anim_iter != gAgentAvatarp->mAnimationSources.end(); ++anim_iter) { // object found - if(anim_iter->first==object_id) + if (anim_iter->first == object_id) { - LLUUID anim_id=item->getColumn(anim_id_column)->getValue().asUUID(); + LLUUID anim_id = item->getColumn(anim_id_column)->getValue().asUUID(); // animation found - if(anim_iter->second==anim_id) + if (anim_iter->second == anim_id) { // set text to "Still playing" and break out of this loop played_text->setText(LLTrans::getString("animation_explorer_still_playing")); - is_running=true; + is_running = true; break; } } } // animation was not found to be running - if(!is_running) + if (!is_running) { // get timestamp when this animation was started - F64 timestamp=item->getColumn(timestamp_column)->getValue().asReal(); + F64 timestamp = item->getColumn(timestamp_column)->getValue().asReal(); // update text to show the number of seconds ago when this animation was started LLStringUtil::format_map_t args; - args["SECONDS"]=llformat("%d",(S32) (current_timestamp-timestamp)); + args["SECONDS"] = llformat("%d", (S32) (current_timestamp - timestamp)); - played_text->setText(LLTrans::getString("animation_explorer_seconds_ago",args)); + played_text->setText(LLTrans::getString("animation_explorer_seconds_ago", args)); } } } @@ -335,37 +335,37 @@ void AnimationExplorer::updateList(F64 current_timestamp) void AnimationExplorer::addAnimation(const LLUUID& id, const LLUUID& played_by, F64 time) { // don't add animations that are played by ourselves when the filter box is checked - if(played_by==gAgentAvatarp->getID()) + if (played_by == gAgentAvatarp->getID()) { - if(mNoOwnedAnimationsCheckBox->getValue().asBoolean()) + if (mNoOwnedAnimationsCheckBox->getValue().asBoolean()) { return; } } // set object name to UUID at first - std::string playedByName=played_by.asString(); + std::string playedByName = played_by.asString(); // find out if the object is still in reach - LLViewerObject* vo=gObjectList.findObject(played_by); - if(vo) + LLViewerObject* vo = gObjectList.findObject(played_by); + if (vo) { // if it was an avatar, get the name here - if(vo->isAvatar()) + if (vo->isAvatar()) { - playedByName=std::string(vo->getNVPair("FirstName")->getString())+" "+ + playedByName = std::string(vo->getNVPair("FirstName")->getString()) + " " + std::string(vo->getNVPair("LastName")->getString()); } // not an avatar, do a lookup by UUID else { // find out if we know the name to this UUID already - std::map::iterator iter=mKnownIDs.find(played_by); + std::map::iterator iter = mKnownIDs.find(played_by); // if we don't know it yet, start a lookup - if(iter==mKnownIDs.end()) + if (iter == mKnownIDs.end()) { // if we are not already looking up this object's name, send a request out - if(std::find(mRequestedIDs.begin(),mRequestedIDs.end(),played_by)==mRequestedIDs.end()) + if (std::find(mRequestedIDs.begin(), mRequestedIDs.end(), played_by) == mRequestedIDs.end()) { // remember which object names we already requested mRequestedIDs.push_back(played_by); @@ -374,86 +374,86 @@ void AnimationExplorer::addAnimation(const LLUUID& id, const LLUUID& played_by, msg->newMessageFast(_PREHASH_ObjectSelect); msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID,vo->getLocalID()); + msg->addU32Fast(_PREHASH_ObjectLocalID, vo->getLocalID()); msg->sendReliable(gAgentAvatarp->getRegion()->getHost()); msg->newMessageFast(_PREHASH_ObjectDeselect); msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU32Fast(_PREHASH_ObjectLocalID,vo->getLocalID()); + msg->addU32Fast(_PREHASH_ObjectLocalID, vo->getLocalID()); msg->sendReliable(gAgentAvatarp->getRegion()->getHost()); } } else { // we know the name already - playedByName=mKnownIDs[played_by]; + playedByName = mKnownIDs[played_by]; } } } // insert the item into the scroll list LLSD item; - item["columns"][0]["column"]="played_by"; - item["columns"][0]["value"]=playedByName; - item["columns"][1]["column"]="played"; - item["columns"][1]["value"]=LLTrans::getString("animation_explorer_still_playing"); - item["columns"][2]["column"]="timestamp"; - item["columns"][2]["value"]=time; - item["columns"][3]["column"]="animation_id"; - item["columns"][3]["value"]=id; - item["columns"][4]["column"]="object_id"; - item["columns"][4]["value"]=played_by; + item["columns"][0]["column"] = "played_by"; + item["columns"][0]["value"] = playedByName; + item["columns"][1]["column"] = "played"; + item["columns"][1]["value"] = LLTrans::getString("animation_explorer_still_playing"); + item["columns"][2]["column"] = "timestamp"; + item["columns"][2]["value"] = time; + item["columns"][3]["column"] = "animation_id"; + item["columns"][3]["value"] = id; + item["columns"][4]["column"] = "object_id"; + item["columns"][4]["value"] = played_by; - mAnimationScrollList->addElement(item,ADD_TOP); + mAnimationScrollList->addElement(item, ADD_TOP); } void AnimationExplorer::requestNameCallback(LLMessageSystem* msg) { // if we weren't looking for any IDs, ignore this callback - if(mRequestedIDs.empty()) + if (mRequestedIDs.empty()) { return; } // we might have received more than one answer in one block - S32 num=msg->getNumberOfBlocksFast(_PREHASH_ObjectData); - for (S32 index=0;indexgetNumberOfBlocksFast(_PREHASH_ObjectData); + for (S32 index = 0; index < num; ++index) { LLUUID object_id; - msg->getUUIDFast(_PREHASH_ObjectData,_PREHASH_ObjectID,object_id,index); + msg->getUUIDFast(_PREHASH_ObjectData, _PREHASH_ObjectID, object_id, index); - std::vector::iterator iter; - iter=std::find(mRequestedIDs.begin(),mRequestedIDs.end(),object_id); + uuid_vec_t::iterator iter; + iter = std::find(mRequestedIDs.begin(), mRequestedIDs.end(), object_id); // if this is one of the objects we were looking for, process the data - if(iter!=mRequestedIDs.end()) + if (iter != mRequestedIDs.end()) { // get the name of the object std::string object_name; - msg->getStringFast(_PREHASH_ObjectData,_PREHASH_Name,object_name,index); + msg->getStringFast(_PREHASH_ObjectData, _PREHASH_Name, object_name, index); // remove the object from the lookup list and add it to the known names list mRequestedIDs.erase(iter); - mKnownIDs[object_id]=object_name; + mKnownIDs[object_id] = object_name; - S32 object_id_column=mAnimationScrollList->getColumn("object_id")->mIndex; - S32 played_by_column=mAnimationScrollList->getColumn("played_by")->mIndex; + S32 object_id_column = mAnimationScrollList->getColumn("object_id")->mIndex; + S32 played_by_column = mAnimationScrollList->getColumn("played_by")->mIndex; // find all scroll list entries with this object UUID and update the names there - std::vector items=mAnimationScrollList->getAllData(); - for (std::vector::iterator list_iter=items.begin();list_iter!=items.end();++list_iter) + std::vector items = mAnimationScrollList->getAllData(); + for (std::vector::iterator list_iter = items.begin(); list_iter != items.end(); ++list_iter) { - LLScrollListItem* item=*list_iter; - LLUUID list_object_id=item->getColumn(object_id_column)->getValue().asUUID(); + LLScrollListItem* item = *list_iter; + LLUUID list_object_id = item->getColumn(object_id_column)->getValue().asUUID(); - if(object_id==list_object_id) + if (object_id == list_object_id) { - LLScrollListText* played_by_text=(LLScrollListText*) item->getColumn(played_by_column); + LLScrollListText* played_by_text = (LLScrollListText*)item->getColumn(played_by_column); played_by_text->setText(object_name); } } diff --git a/indra/newview/animationexplorer.h b/indra/newview/animationexplorer.h index 92f5c25ad1..d0891f587b 100644 --- a/indra/newview/animationexplorer.h +++ b/indra/newview/animationexplorer.h @@ -59,7 +59,7 @@ class RecentAnimationList std::deque mAnimationList; - void addAnimation(const LLUUID& id,const LLUUID& playedBy); // called in llviewermessage.cpp + void addAnimation(const LLUUID& id, const LLUUID& playedBy); // called in llviewermessage.cpp void requestList(AnimationExplorer* explorer); // request animation list }; @@ -85,7 +85,7 @@ class AnimationExplorer public: /*virtual*/ BOOL postBuild(); - void addAnimation(const LLUUID& id,const LLUUID& playedBy,F64 time); // called from RecentAnimationList + void addAnimation(const LLUUID& id, const LLUUID& playedBy, F64 time); // called from RecentAnimationList // copied from llfloaterbvhpreview.h BOOL handleMouseDown(S32 x, S32 y, MASK mask); @@ -113,7 +113,7 @@ class AnimationExplorer LLUUID mCurrentObject; // object ID that played the currently selected animation std::vector mRequestedIDs; // list of object IDs we requested named for - std::map mKnownIDs; // known list of names for object IDs + std::map mKnownIDs; // known list of names for object IDs void draw(); void update(); // request list update from RecentAnimationList diff --git a/indra/newview/ao.cpp b/indra/newview/ao.cpp index 5e2ce21785..91cf8b8f30 100644 --- a/indra/newview/ao.cpp +++ b/indra/newview/ao.cpp @@ -342,9 +342,13 @@ void FloaterAO::onRenameSet() std::string name=mSetSelector->getSimple(); LLStringUtil::trim(name); + LLUIString new_set_name=name; + if(!name.empty()) { - if(name.find_first_of(":|")==std::string::npos) + if( + LLTextValidate::validateASCIIPrintableNoPipe(new_set_name.getWString()) && // only allow ASCII + name.find_first_of(":|")==std::string::npos) // don't allow : or | { if(AOEngine::instance().renameSet(mSelectedSet,name)) { @@ -356,7 +360,7 @@ void FloaterAO::onRenameSet() { LLSD args; args["AO_SET_NAME"]=name; - LLNotificationsUtil::add("RenameAOCantContainColon",args); + LLNotificationsUtil::add("RenameAOMustBeASCII",args); } } mSetSelector->setSimple(mSelectedSet->getName()); @@ -445,13 +449,19 @@ BOOL FloaterAO::newSetCallback(const LLSD& notification,const LLSD& response) LLStringUtil::trim(newSetName); + LLUIString new_set_name=newSetName; + if(newSetName.empty()) + { return FALSE; - else if(newSetName.find_first_of(":|")!=std::string::npos) + } + else if( + !LLTextValidate::validateASCIIPrintableNoPipe(new_set_name.getWString()) || // only allow ASCII + newSetName.find_first_of(":|")!=std::string::npos) // don't allow : or | { LLSD args; args["AO_SET_NAME"]=newSetName; - LLNotificationsUtil::add("NewAOCantContainColon",args); + LLNotificationsUtil::add("NewAOCantContainNonASCII",args); return FALSE; } diff --git a/indra/newview/aoengine.cpp b/indra/newview/aoengine.cpp index aac34ca400..5246e36d30 100644 --- a/indra/newview/aoengine.cpp +++ b/indra/newview/aoengine.cpp @@ -1036,6 +1036,13 @@ void AOEngine::update() { LLViewerInventoryCategory* currentCategory=categories->at(index); const std::string& setFolderName=currentCategory->getName(); + + if( setFolderName.empty()) + { + LL_WARNS("AOEngine") << "Folder with emtpy name in AO folder" << LL_ENDL; + continue; + } + std::vector params; LLStringUtil::getTokens(setFolderName,params,":"); diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 9d75719c72..3ba6d2ef7b 100755 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -209,7 +209,7 @@ icon="Command_Search_Icon" label_ref="Command_Search_Label" tooltip_ref="Command_Search_Tooltip" - execute_function="Floater.Toggle" + execute_function="Floater.ToggleOrBringToFront" execute_parameters="search" is_running_function="Floater.IsOpen" is_running_parameters="search" diff --git a/indra/newview/app_settings/grids.fallback.xml b/indra/newview/app_settings/grids.fallback.xml index a6fe8a0183..9de72b2a1e 100644 --- a/indra/newview/app_settings/grids.fallback.xml +++ b/indra/newview/app_settings/grids.fallback.xml @@ -1,5 +1,41 @@ + login.aviworlds.com:8002 + + LastModified + 2014-11-22T20:36:26.43Z + about + http://aviworlds.com + gatekeeper + login.aviworlds.com:8002 + gridname + AviWorlds + gridnick + AviWorlds + helperuri + http://login.aviworlds.com/backend/components/com_opensim/ + login_identifier_types + + agent + account + + loginpage + http://login.aviworlds.com/splash/ + loginuri + + http://login.aviworlds.com:8002/ + + name + login.aviworlds.com:8002 + password + http://login.aviworlds.com:8002/wifi/forgotpassword + platform + OpenSim + register + http://login.aviworlds.com:8002/wifi/user/account + slurl_base + hop://login.aviworlds.com:8002/ + craft-world.org:8002 LastModified diff --git a/indra/newview/app_settings/scriptlibrary_ossl.xml b/indra/newview/app_settings/scriptlibrary_ossl.xml index 35e7dacef5..e78fd0fb0d 100644 --- a/indra/newview/app_settings/scriptlibrary_ossl.xml +++ b/indra/newview/app_settings/scriptlibrary_ossl.xml @@ -12,6 +12,7 @@ + @@ -143,7 +144,7 @@ + desc="float osGetCurrentSunHour();Returns the value of the current region's sun hour" /> + + + + desc="key osOwnerSaveAppearance(string notecard);Creates a notecard with the object owner's current appearance inside the object" /> 0.0 1.0 - Backup - 0 FocusOffsetFrontView @@ -6305,8 +6303,6 @@ 0.0 0.0 - Backup - 0 FocusOffsetGroupView @@ -6322,8 +6318,6 @@ 0.7 1.0 - Backup - 0 FocusPosOnLogout @@ -16928,6 +16922,28 @@ Change of this parameter will affect the layout of buttons in notification toast Backup 0 + VivoxLogDirectory + + Comment + Default log path is Application Support/SecondLife/logs specify alternate absolute path here. + Persist + 1 + Type + String + Value + + + VivoxShutdownTimeout + + Comment + shutdown timeout in miliseconds. The amount of time to wait for the service to shutdown gracefully after the last disconnect + Persist + 1 + Type + String + Value + 5 + VivoxDebugSIPURIHostName Comment @@ -18557,7 +18573,7 @@ Change of this parameter will affect the layout of buttons in notification toast Type String Value - ===OFF=== + Rainbow FSMaxBeamsPerSecond @@ -19915,6 +19931,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + LockToolbars + + Comment + If enabled, toolbars are locked and buttons can not be dragged around, added or removed. + Persist + 1 + Type + Boolean + Value + 0 + FSSkinClobbersToolbarPrefs Comment @@ -20795,10 +20822,10 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 - FSVintageLoginInfo + FSSelectCopyableOnly Comment - Shows the "did you know about Phoenix mode?" message at login screen, once per installation. TRUE means, that notification won't be displayed. + Only include copyable objects during selection Persist 1 Type @@ -22776,6 +22803,74 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1 + FSLogSnapshotsToLocal + + Comment + Log filename of saved snapshots in to chat history + Persist + 1 + Type + Boolean + Value + 0 + + FSLatencyOneTimeFixRun + + Comment + One time fix has run for this install for script dialog colors on Latency + Persist + 1 + HideFromEditor + 1 + Type + Boolean + Value + 0 + + FSUseCtrlShout + + Comment + Set to TRUE to use the keyboard shortcut Ctrl+Enter to Shout in Nearby Chat. + Persist + 1 + Type + Boolean + Value + 1 + + FSUseShiftWhisper + + Comment + Set to TRUE to use the keyboard shortcut Shift+Enter to Whisper in Nearby Chat. + Persist + 1 + Type + Boolean + Value + 1 + + FSUseAltOOC + + Comment + Set to TRUE to use the keyboard shortcut Alt+Enter to send ((OOC)) messages to Nearby Chat. + Persist + 1 + Type + Boolean + Value + 1 + + FSComboboxSubstringSearch + + Comment + Allows fulltext search on comboboxes + Persist + 1 + Type + Boolean + Value + 1 + diff --git a/indra/newview/app_settings/settings_latency.xml b/indra/newview/app_settings/settings_latency.xml index 67689cdc57..90facf0e31 100644 --- a/indra/newview/app_settings/settings_latency.xml +++ b/indra/newview/app_settings/settings_latency.xml @@ -723,15 +723,29 @@ 2 + FSFlashOnMessage + + Persist + 1 + Comment + Flash/Bounce the app icon when a new message is recieved and Firestorm is not in focus + Type + Boolean + Value + 1 + - - - - - - - - + PlayModeUISndScriptFloaterOpen + + Persist + 1 + Comment + Holds state for Prefs > Sound/Media > UI Sounds - UISndScriptFloaterOpen. + Type + Boolean + Value + 0 + diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index cdf3dd8f67..4cfd651064 100755 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -643,6 +643,17 @@ Value 0 + FSKeywordMatchWholeWords + + Comment + Keywords will only match whole words + Persist + 1 + Type + Boolean + Value + 0 + FSKeywords Comment diff --git a/indra/newview/app_settings/settings_phoenix.xml b/indra/newview/app_settings/settings_phoenix.xml index 614a9b50d9..c31179a8e5 100644 --- a/indra/newview/app_settings/settings_phoenix.xml +++ b/indra/newview/app_settings/settings_phoenix.xml @@ -519,6 +519,18 @@ 1 + PlayModeUISndScriptFloaterOpen + + Comment + Holds state for Prefs > Sound/Media > UI Sounds - UISndScriptFloaterOpen. + Persist + 1 + Type + Boolean + Value + 0 + + FSAnimatedScriptDialogs diff --git a/indra/newview/app_settings/windlight/skies/%252ACanimod.xml b/indra/newview/app_settings/windlight/skies/%252ACanimod.xml deleted file mode 100755 index d4e69e6226..0000000000 --- a/indra/newview/app_settings/windlight/skies/%252ACanimod.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - ambient - - 1.4699999094009399 - 1.4699999094009399 - 1.4699999094009399 - 0.48999997973442078 - - blue_density - - 0.099999994039535522 - 0.037499997764825821 - 0.067499987781047821 - 0.049999997019767761 - - blue_horizon - - 0.15130999684333801 - 0.30000001192092896 - 0.35131001472473145 - 1 - - cloud_color - - 0.22999998927116394 - 0.22999998927116394 - 0.22999998927116394 - 0.22999998927116394 - - cloud_pos_density1 - - 0.88419097661972046 - 0.53047597408294678 - 0.52999997138977051 - 1 - - cloud_pos_density2 - - 0.2800000011920929 - 0.19999998807907104 - 0.31999999284744263 - 1 - - cloud_scale - - 0.0099999997764825821 - 0 - 0 - 1 - - cloud_scroll_rate - - 0 - 15.329999446868896 - - cloud_shadow - - 0 - 0 - 0 - 1 - - density_multiplier - - 0.00022000000171829015 - 0 - 0 - 1 - - distance_multiplier - - 16.200000762939453 - 0 - 0 - 1 - - east_angle - 6.2831854820251465 - enable_cloud_scroll - - 1 - 1 - - gamma - - 1.4199999570846558 - 0 - 0 - 1 - - glow - - 18.599998474121094 - 0.0012815999798476696 - 0 - 1 - - haze_density - - 0 - 0 - 0 - 1 - - haze_horizon - - 1 - 0.21744099259376526 - 0.21744099259376526 - 1 - - lightnorm - - -1.7484555314695172e-007 - 0 - 1 - 0 - - max_y - - 403 - 0 - 0 - 1 - - preset_num - 2 - star_brightness - 0 - sun_angle - 0 - sunlight_color - - 0 - 0 - 0 - 0 - - - diff --git a/indra/newview/app_settings/windlight/skies/%252AStarley%252A%20Settings%202.xml b/indra/newview/app_settings/windlight/skies/%252AStarley%252A%20Settings%202.xml deleted file mode 100755 index 6d1c09d30a..0000000000 --- a/indra/newview/app_settings/windlight/skies/%252AStarley%252A%20Settings%202.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - ambient - - 1.4699999094009399 - 1.4699999094009399 - 1.4699999094009399 - 0.48999997973442078 - - blue_density - - 0.14000000059604645 - 0.14000000059604645 - 0.14000000059604645 - 0.070000000298023224 - - blue_horizon - - 0.83809572458267212 - 1.0735483169555664 - 1.2799999713897705 - 0.63999998569488525 - - cloud_color - - 0.12862999737262726 - 0.12862999737262726 - 0.12862999737262726 - 1 - - cloud_pos_density1 - - 0.70999997854232788 - 0.53047597408294678 - 0.4270470142364502 - 1 - - cloud_pos_density2 - - 0.38419300317764282 - 0.5 - 0.125 - 1 - - cloud_scale - - 0.72999995946884155 - 0 - 0 - 1 - - cloud_scroll_rate - - 10 - 10 - - cloud_shadow - - 0.2199999988079071 - 0 - 0 - 1 - - density_multiplier - - 0.00017999998817685992 - 0 - 0 - 1 - - distance_multiplier - - 11.40000057220459 - 0 - 0 - 1 - - east_angle - 0 - enable_cloud_scroll - - 1 - 1 - - gamma - - 1.6899999380111694 - 0 - 0 - 1 - - glow - - 6.4079799652099609 - 0.0012815999798476696 - -0.39999997615814209 - 1 - - haze_density - - 1.4900000095367432 - 0 - 0 - 1 - - haze_horizon - - 0 - 0.21744099259376526 - 0.21744099259376526 - 1 - - lightnorm - - 0 - 0 - 1 - 0 - - max_y - - 805 - 0 - 0 - 1 - - preset_num - 2 - star_brightness - 1.5699999332427979 - sun_angle - 0 - sunlight_color - - 3 - 3 - 3 - 1 - - - diff --git a/indra/newview/app_settings/windlight/skies/%28SS%29%20Atmos%2023.30%202.xml b/indra/newview/app_settings/windlight/skies/%28SS%29%20Atmos%2023%2E30%202.xml similarity index 100% rename from indra/newview/app_settings/windlight/skies/%28SS%29%20Atmos%2023.30%202.xml rename to indra/newview/app_settings/windlight/skies/%28SS%29%20Atmos%2023%2E30%202.xml diff --git a/indra/newview/app_settings/windlight/skies/%5BEUPHORIA%5D%20smoky%20blue%20sky%20%253A%20reverse.xml b/indra/newview/app_settings/windlight/skies/%5BEUPHORIA%5D%20smoky%20blue%20sky%20%253A%20reverse.xml deleted file mode 100755 index 4d50f80912..0000000000 --- a/indra/newview/app_settings/windlight/skies/%5BEUPHORIA%5D%20smoky%20blue%20sky%20%253A%20reverse.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - ambient - - 1.8300000429153442 - 1.8300000429153442 - 1.8300000429153442 - 0.61000001430511475 - - blue_density - - 0.21899415552616119 - 0.40148928761482239 - 0.68000000715255737 - 0.34000000357627869 - - blue_horizon - - 0 - 0.10838708281517029 - 0.14000000059604645 - 0.070000000298023224 - - cloud_color - - 0 - 0 - 0 - 0 - - cloud_pos_density1 - - 0.14000000059604645 - 0.62000000476837158 - 0.99999999999999767 - 1 - - cloud_pos_density2 - - 0.48999997973442078 - 0.19999998807907104 - 0.125 - 1 - - cloud_scale - - 0.43999999761581421 - 0 - 0 - 1 - - cloud_scroll_rate - - 10.199999853917745 - 10.010999722693327 - - cloud_shadow - - 0.29999998211860657 - 0 - 0 - 1 - - density_multiplier - - 0.00015999999595806003 - 0 - 0 - 1 - - distance_multiplier - - 10.800000190734863 - 0 - 0 - 1 - - east_angle - 0 - enable_cloud_scroll - - 1 - 1 - - gamma - - 0.94999998807907104 - 0 - 0 - 1 - - glow - - 4.9999999403953552 - 0.0010000000616982377 - -0.47999998693999579 - 1 - - haze_density - - 0.94999998807907104 - 0 - 0 - 1 - - haze_horizon - - 0.25999999046325684 - 0.19915600121021271 - 0.19915600121021271 - 1 - - lightnorm - - 0 - 0.96692299842834473 - -0.25506836175918579 - 0 - - max_y - - 1128 - 0 - 0 - 1 - - preset_num - 28 - star_brightness - 0 - sun_angle - 1.8287147283554077 - sunlight_color - - 0.65999996662139893 - 0.78157895803451538 - 0.89999997615814209 - 0.29999998211860657 - - - diff --git a/indra/newview/app_settings/windlight/skies/%5BTOR%5D%20MIDDAY%20%2D%20Why%20so%20blue%253F%201.xml b/indra/newview/app_settings/windlight/skies/%5BTOR%5D%20MIDDAY%20%2D%20Why%20so%20blue%253F%201.xml deleted file mode 100755 index e2d59e6bee..0000000000 --- a/indra/newview/app_settings/windlight/skies/%5BTOR%5D%20MIDDAY%20%2D%20Why%20so%20blue%253F%201.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - ambient - - 1.0799999237060547 - 1.0799999237060547 - 1.0799999237060547 - 0.35999998450279236 - - blue_density - - 0.11593805998563766 - 0.21255312860012054 - 0.74000000953674316 - 0.74000000953674316 - - blue_horizon - - 0.52645158767700195 - 0.52645158767700195 - 0.8399999737739563 - 0.8399999737739563 - - cloud_color - - 0.68000000715255737 - 0.32800003886222839 - 0.32800003886222839 - 0.68000000715255737 - - cloud_pos_density1 - - 0.90999996662139893 - 0.45999997854232788 - 0.40999999642372131 - 1 - - cloud_pos_density2 - - 0.63999998569488525 - 0.38999998569488525 - 0 - 1 - - cloud_scale - - 0.36999997496604919 - 0 - 0 - 1 - - cloud_scroll_rate - - 10.050000190734863 - 9.9200000762939453 - - cloud_shadow - - 0.19999998807907104 - 0 - 0 - 1 - - density_multiplier - - 0.00011999999696854502 - 0 - 0 - 1 - - distance_multiplier - - 1 - 0 - 0 - 1 - - east_angle - 0 - enable_cloud_scroll - - 1 - 1 - - gamma - - 0.93999999761581421 - 0 - 0 - 1 - - glow - - 6.1999988555908203 - 0.0010000000474974513 - -0.55000001192092896 - 1 - - haze_density - - 0.34999999403953552 - 0 - 0 - 1 - - haze_horizon - - 0.19999998807907104 - 0.19915600121021271 - 0.19915600121021271 - 1 - - lightnorm - - 0 - 0.77450281381607056 - -0.63257044553756714 - 0 - - max_y - - 913 - 0 - 0 - 1 - - preset_num - 22 - star_brightness - 0.039999999105930328 - sun_angle - 2.2556638717651367 - sunlight_color - - 1.2899999618530273 - 0.88457131385803223 - 0.51599997282028198 - 0.42999997735023499 - - - diff --git a/indra/newview/app_settings/windlight/skies/%5BTOR%5D%20MIDDAY%20%2D%20Why%20so%20blue%253F%202.xml b/indra/newview/app_settings/windlight/skies/%5BTOR%5D%20MIDDAY%20%2D%20Why%20so%20blue%253F%202.xml deleted file mode 100755 index 9606495c41..0000000000 --- a/indra/newview/app_settings/windlight/skies/%5BTOR%5D%20MIDDAY%20%2D%20Why%20so%20blue%253F%202.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - ambient - - 0.29999998211860657 - 0.29999998211860657 - 0.29999998211860657 - 0.099999994039535522 - - blue_density - - 0.07937999814748764 - 0.22679997980594635 - 1.6200000047683716 - 0.81000000238418579 - - blue_horizon - - 0.16684222221374512 - 0.33368346095085144 - 0.57999998331069946 - 0.28999999165534973 - - cloud_color - - 0.56000000238418579 - 0.56000000238418579 - 0.56000000238418579 - 0.56000000238418579 - - cloud_pos_density1 - - 2.8148899078369141 - 0.78999996185302734 - 0.59999996423721313 - 1 - - cloud_pos_density2 - - 5.9584097862243652 - 0.85999995470046997 - 0.059999998658895493 - 1 - - cloud_scale - - 0.32999998331069946 - 0 - 0 - 1 - - cloud_scroll_rate - - 11.679999351501465 - 10.359999656677246 - - cloud_shadow - - 0.11999999731779099 - 0 - 0 - 1 - - density_multiplier - - 0.00031000000308267772 - 0 - 0 - 1 - - distance_multiplier - - 0.60000002384185791 - 0 - 0 - 1 - - east_angle - 0 - enable_cloud_scroll - - 1 - 1 - - gamma - - 1.3500000238418579 - 0 - 0 - 1 - - glow - - 8.8000011444091797 - 0.0010000000474974513 - -0.74999994039535522 - 1 - - haze_density - - 0.029999999329447746 - 0 - 0 - 1 - - haze_horizon - - 0.32999998331069946 - 0.19915600121021271 - 0.19915600121021271 - 1 - - lightnorm - - 0 - 1 - -4.3711388286737929e-008 - 0 - - max_y - - 1181 - 0 - 0 - 1 - - preset_num - 24 - star_brightness - 0.11999999731779099 - sun_angle - 1.5707963705062866 - sunlight_color - - 1.3499999046325684 - 1.0799999237060547 - 1.0799999237060547 - 0.44999998807907104 - - - diff --git a/indra/newview/app_settings/windlight/skies/AnaLu%20%252Astudio%252A%205.xml b/indra/newview/app_settings/windlight/skies/AnaLu%20%252Astudio%252A%205.xml deleted file mode 100755 index b7c6d047f6..0000000000 --- a/indra/newview/app_settings/windlight/skies/AnaLu%20%252Astudio%252A%205.xml +++ /dev/null @@ -1,141 +0,0 @@ - - - ambient - - 2.0099997520446777 - 1.9199999570846558 - 1.8899999856948853 - 2.0099997520446777 - - blue_density - - 0.63999998569488525 - 1.1799999475479126 - 2 - 2 - - blue_horizon - - 0.23999999463558197 - 0.23999999463558197 - 0.31999999284744263 - 0.31999999284744263 - - cloud_color - - 0.39050509865536398 - 0.39050509865536398 - 0.39050509865536398 - 0.39050509865536398 - - cloud_pos_density1 - - 1.6884100437164307 - 0.52609699964523315 - 1 - 1 - - cloud_pos_density2 - - 1.6884100437164307 - 0.52609699964523315 - 0.125 - 1 - - cloud_scale - - 0.41999998254906856 - 0 - 0 - 1 - - cloud_scroll_rate - - 10.199999735331062 - 10.010999579794088 - - cloud_shadow - - 0.12999999523162842 - 0 - 0 - 1 - - density_multiplier - - 0.00017999998391111764 - 0 - 0 - 1 - - distance_multiplier - - 2 - 0 - 0 - 1 - - east_angle - 0 - enable_cloud_scroll - - 1 - 1 - - gamma - - 1.1499999761581421 - 0 - 0 - 1 - - glow - - 4.9999998807907104 - 0.0010000000478643939 - -0.47999998436731417 - 1 - - haze_density - - 0.64999997615814209 - 0 - 0 - 1 - - haze_horizon - - 0.08999999612569809 - 0.19915600121021271 - 0.19915600121021271 - 1 - - lightnorm - - 0 - 0 - 1 - 0 - - max_y - - 188 - 0 - 0 - 1 - - preset_num - 22 - star_brightness - 0 - sun_angle - 0 - sunlight_color - - 2.5799999237060547 - 2.5799999237060547 - 2.5799999237060547 - 2.5799999237060547 - - - diff --git a/indra/newview/app_settings/windlight/water/Phototools-%20Black%20Default%20.xml b/indra/newview/app_settings/windlight/water/Phototools%2D%20Black%20Default%20.xml similarity index 100% rename from indra/newview/app_settings/windlight/water/Phototools-%20Black%20Default%20.xml rename to indra/newview/app_settings/windlight/water/Phototools%2D%20Black%20Default%20.xml diff --git a/indra/newview/app_settings/windlight/water/Phototools-%20Breakwave%20Building%20Water.xml b/indra/newview/app_settings/windlight/water/Phototools%2D%20Breakwave%20Building%20Water.xml similarity index 100% rename from indra/newview/app_settings/windlight/water/Phototools-%20Breakwave%20Building%20Water.xml rename to indra/newview/app_settings/windlight/water/Phototools%2D%20Breakwave%20Building%20Water.xml diff --git a/indra/newview/app_settings/windlight/water/Phototools-%20Chandra%20Sea.xml b/indra/newview/app_settings/windlight/water/Phototools%2D%20Chandra%20Sea.xml similarity index 100% rename from indra/newview/app_settings/windlight/water/Phototools-%20Chandra%20Sea.xml rename to indra/newview/app_settings/windlight/water/Phototools%2D%20Chandra%20Sea.xml diff --git a/indra/newview/app_settings/windlight/water/Phototools-%20Gallery%20Water%2001.xml b/indra/newview/app_settings/windlight/water/Phototools%2D%20Gallery%20Water%2001.xml similarity index 100% rename from indra/newview/app_settings/windlight/water/Phototools-%20Gallery%20Water%2001.xml rename to indra/newview/app_settings/windlight/water/Phototools%2D%20Gallery%20Water%2001.xml diff --git a/indra/newview/app_settings/windlight/water/Phototools-%20Ship%20Light.xml b/indra/newview/app_settings/windlight/water/Phototools%2D%20Ship%20Light.xml similarity index 100% rename from indra/newview/app_settings/windlight/water/Phototools-%20Ship%20Light.xml rename to indra/newview/app_settings/windlight/water/Phototools%2D%20Ship%20Light.xml diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 7b9418adaa..d96129da0a 100755 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -66,7 +66,7 @@ RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 -WatchdogDisabled 1 1 +//WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 528cea9c6f..ae9938f38e 100755 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -66,7 +66,7 @@ RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 -WatchdogDisabled 1 1 +//WatchdogDisabled 1 1 RenderUseStreamVBO 0 0 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 diff --git a/indra/newview/featuretable_solaris.txt b/indra/newview/featuretable_solaris.txt index e7cae1abdc..9eaf2ce765 100755 --- a/indra/newview/featuretable_solaris.txt +++ b/indra/newview/featuretable_solaris.txt @@ -41,7 +41,7 @@ VertexShaderEnable 1 1 RenderTextureMemoryMultiple 1 1.0 UseOcclusion 1 1 RenderCubeMap 1 1 -WatchdogDisabled 1 1 +//WatchdogDisabled 1 1 RenderUseFBO 1 1 diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 14cc8b6ae3..cdf72ee460 100755 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -66,7 +66,7 @@ RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 -WatchdogDisabled 1 1 +//WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 RenderFSAASamples 1 16 RenderMaxTextureIndex 1 16 diff --git a/indra/newview/fschathistory.cpp b/indra/newview/fschathistory.cpp index 166c2c414e..93ba68af06 100644 --- a/indra/newview/fschathistory.cpp +++ b/indra/newview/fschathistory.cpp @@ -509,7 +509,14 @@ public: switch (mSourceType) { case CHAT_SOURCE_AGENT: - icon->setValue(chat.mFromID); + if (!chat.mRlvNamesFiltered) + { + icon->setValue(chat.mFromID); + } + else + { + icon->setValue(LLSD("Unknown_Icon")); + } break; case CHAT_SOURCE_OBJECT: icon->setValue(LLSD("OBJECT_Icon")); @@ -519,7 +526,14 @@ public: // FS:LO FIRE-1439 - Clickable avatar names on local chat radar crossing reports if(chat.mChatType == CHAT_TYPE_RADAR) { - icon->setValue(chat.mFromID); + if (!chat.mRlvNamesFiltered) + { + icon->setValue(chat.mFromID); + } + else + { + icon->setValue(LLSD("Unknown_Icon")); + } } else { diff --git a/indra/newview/fsfloateraddtocontactset.cpp b/indra/newview/fsfloateraddtocontactset.cpp index 3d972968e2..b5b07370f1 100644 --- a/indra/newview/fsfloateraddtocontactset.cpp +++ b/indra/newview/fsfloateraddtocontactset.cpp @@ -43,9 +43,9 @@ FSFloaterAddToContactSet::FSFloaterAddToContactSet(const LLSD& target) if (target.isArray()) { mHasMultipleAgents = true; - for (S32 i = 0; i < target.size(); ++i) + for (LLSD::array_const_iterator it = target.beginArray(); it != target.endArray(); ++it) { - mAgentIDs.push_back(target[i].asUUID()); + mAgentIDs.push_back((*it).asUUID()); } } else diff --git a/indra/newview/fsfloatercontacts.cpp b/indra/newview/fsfloatercontacts.cpp index 52b14760de..3992ad980d 100644 --- a/indra/newview/fsfloatercontacts.cpp +++ b/indra/newview/fsfloatercontacts.cpp @@ -43,6 +43,7 @@ #include "llgrouplist.h" #include "llnotificationsutil.h" #include "llscrolllistctrl.h" +#include "llslurl.h" #include "llstartup.h" #include "lltabcontainer.h" #include "llviewermenu.h" @@ -85,7 +86,8 @@ FSFloaterContacts::FSFloaterContacts(const LLSD& seed) mObserver(NULL), mFriendsList(NULL), mGroupList(NULL), - mAllowRightsChange(TRUE), + mAllowRightsChange(true), + mRightsChangeNotificationTriggered(false), mNumRightsChanged(0), mRlvBehaviorCallbackConnection(), mResetLastColumnDisplayModeChanged(false), @@ -141,6 +143,8 @@ BOOL FSFloaterContacts::postBuild() mFriendsTab->childSetAction("add_btn", boost::bind(&FSFloaterContacts::onAddFriendWizButtonClicked, this)); mFriendsTab->setDefaultBtn("im_btn"); + mFriendsTab->getChild("friend_count")->setTextArg("COUNT", llformat("%d", mFriendsList->getItemCount())); + mGroupsTab = getChild(GROUP_TAB_NAME); mGroupList = mGroupsTab->getChild("group_list"); mGroupList->setNoItemsMsg(getString("no_groups_msg")); @@ -552,11 +556,11 @@ void FSFloaterContacts::onFriendListUpdate(U32 changed_mask) --mNumRightsChanged; if (mNumRightsChanged > 0) { - mAllowRightsChange = FALSE; + mAllowRightsChange = false; } else { - mAllowRightsChange = TRUE; + mAllowRightsChange = true; } const std::set& changed_items = at.getChangedIDs(); @@ -870,12 +874,7 @@ void FSFloaterContacts::confirmModifyRights(rights_map_t& ids, EGrantRevoke comm // for single friend, show their name if (ids.size() == 1) { - LLUUID agent_id = ids.begin()->first; - std::string name; - if (gCacheName->getFullName(agent_id, name)) - { - args["NAME"] = name; - } + args["NAME"] = LLSLURL("agent", ids.begin()->first, "completename").getSLURLString(); if (command == GRANT) { LLNotificationsUtil::add("GrantModifyRights", @@ -909,10 +908,13 @@ void FSFloaterContacts::confirmModifyRights(rights_map_t& ids, EGrantRevoke comm } } } + } bool FSFloaterContacts::modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights) { + mRightsChangeNotificationTriggered = false; + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { @@ -936,6 +938,11 @@ bool FSFloaterContacts::modifyRightsConfirmation(const LLSD& notification, const void FSFloaterContacts::applyRightsToFriends() { + if (mRightsChangeNotificationTriggered) + { + return; + } + bool rights_changed = false; // store modify rights separately for confirmation @@ -1023,6 +1030,7 @@ void FSFloaterContacts::applyRightsToFriends() if (need_confirmation) { confirmModifyRights(rights_updates, confirmation_type); + mRightsChangeNotificationTriggered = true; } else { diff --git a/indra/newview/fsfloatercontacts.h b/indra/newview/fsfloatercontacts.h index a923367a79..6364329470 100644 --- a/indra/newview/fsfloatercontacts.h +++ b/indra/newview/fsfloatercontacts.h @@ -145,8 +145,9 @@ private: LLTabContainer* mTabContainer; LLFriendObserver* mObserver; - BOOL mAllowRightsChange; + bool mAllowRightsChange; S32 mNumRightsChanged; + bool mRightsChangeNotificationTriggered; std::string mFriendListFontName; diff --git a/indra/newview/fsfloaterim.cpp b/indra/newview/fsfloaterim.cpp index 7303a02c25..b6a50d9a54 100644 --- a/indra/newview/fsfloaterim.cpp +++ b/indra/newview/fsfloaterim.cpp @@ -763,6 +763,8 @@ BOOL FSFloaterIM::postBuild() if ( im_session && im_session->isP2PSessionType()) { + mTypingStart.setArg("[NAME]", im_session->mName); + updateSessionName(im_session->mName, im_session->mName); fetchAvatarName(im_session->mOtherParticipantID); } else @@ -856,6 +858,10 @@ void FSFloaterIM::onAvatarNameCache(const LLUUID& agent_id, updateSessionName(name, name); mTypingStart.setArg("[NAME]", name); + if (mOtherTyping) + { + setTitle((gSavedSettings.getBOOL("FSTypingChevronPrefix") ? "> " : "") + mTypingStart.getString()); + } LL_DEBUGS("FSFloaterIM") << "Setting IM tab name to '" << name << "'" << LL_ENDL; // } @@ -1462,6 +1468,11 @@ void FSFloaterIM::processChatHistoryStyleUpdate(const LLSD& newvalue) { floater->updateChatHistoryStyle(); floater->mInputEditor->setFont(font); + + // Re-set the current text to make style update instant + std::string text = floater->mInputEditor->getText(); + floater->mInputEditor->clear(); + floater->mInputEditor->setText(text); } } } diff --git a/indra/newview/fsfloaternearbychat.cpp b/indra/newview/fsfloaternearbychat.cpp index 9029910243..3e3df56dad 100644 --- a/indra/newview/fsfloaternearbychat.cpp +++ b/indra/newview/fsfloaternearbychat.cpp @@ -495,6 +495,12 @@ void FSFloaterNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue) if (nearby_chat) { nearby_chat->updateChatHistoryStyle(); + nearby_chat->mInputEditor->setFont(LLViewerChat::getChatFont()); + + // Re-set the current text to make style update instant + std::string text = nearby_chat->mInputEditor->getText(); + nearby_chat->mInputEditor->clear(); + nearby_chat->mInputEditor->setText(text); } } @@ -683,21 +689,21 @@ BOOL FSFloaterNearbyChat::handleKeyHere( KEY key, MASK mask ) if (KEY_RETURN == key) { - if (mask == MASK_CONTROL) + if (mask == MASK_CONTROL && gSavedSettings.getBOOL("FSUseCtrlShout")) { // shout mInputEditor->updateHistory(); sendChat(CHAT_TYPE_SHOUT); handled = TRUE; } - else if (mask == MASK_SHIFT) + else if (mask == MASK_SHIFT && gSavedSettings.getBOOL("FSUseShiftWhisper")) { // whisper mInputEditor->updateHistory(); sendChat(CHAT_TYPE_WHISPER); handled = TRUE; } - else if (mask == MASK_ALT) + else if (mask == MASK_ALT && gSavedSettings.getBOOL("FSUseAltOOC")) { // OOC mInputEditor->updateHistory(); @@ -1015,7 +1021,10 @@ void FSFloaterNearbyChat::sendChat( EChatType type ) utf8text = applyMuPose(utf8text); // discard returned "found" boolean - LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); + if(!LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text)) + { + utf8_revised_text = utf8text; + } } else { diff --git a/indra/newview/fsfloatervramusage.cpp b/indra/newview/fsfloatervramusage.cpp new file mode 100644 index 0000000000..3e6d0df0c8 --- /dev/null +++ b/indra/newview/fsfloatervramusage.cpp @@ -0,0 +1,343 @@ +/** + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2015 Nicky Dasmijn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "fsfloatervramusage.h" +#include "llscrolllistctrl.h" +#include "llviewerobjectlist.h" +#include "lldrawable.h" +#include "llviewertexture.h" +#include "lltoolpie.h" +#include "llfloaterreg.h" +#include "llface.h" +#include "llvertexbuffer.h" +#include "llcallbacklist.h" +#include "llvoavatarself.h" +#include "llagentcamera.h" + +const F32 PROPERTIES_REQUEST_TIMEOUT = 10.0f; +const F32 PROPERY_REQUEST_INTERVAL = 2.0f; +const U32 PROPERTIES_MAX_REQUEST_COUNT = 250; + +static void onIdle( void *aData ) +{ + FSFloaterVRAMUsage *pFloater = reinterpret_cast(aData); + pFloater->onIdle(); +} + +struct ObjectStat +{ + LLUUID mId; + U32 mTextureSize; +}; + +struct FSFloaterVRAMUsage::ImplData +{ + LLScrollListCtrl *mList; + LLObjectSelectionHandle mSelection; + U32 mPending; + LLFrameTimer mPropTimer; + + std::deque< ObjectStat > mObjects; +}; + +bool sortByTexture( ObjectStat const &lhs, ObjectStat const &rhs ) +{ + return lhs.mTextureSize > rhs.mTextureSize; +} + +FSFloaterVRAMUsage::FSFloaterVRAMUsage(const LLSD& seed) + : LLFloater( seed ) +{ + mData = new ImplData(); + mData->mList = 0; + mData->mPending = 0; + + gIdleCallbacks.addFunction( &::onIdle, this) ; +} + +FSFloaterVRAMUsage::~FSFloaterVRAMUsage() +{ + gIdleCallbacks.deleteFunction( &::onIdle, this ); + delete mData; + LLSelectMgr::instance().removePropertyListener( this ); + LLSelectMgr::instance().enableSilhouette( TRUE ); +} + +void FSFloaterVRAMUsage::onOpen(const LLSD& key) +{ +} + +BOOL FSFloaterVRAMUsage::postBuild() +{ + LLButton *pRefresh = getChild< LLButton >( "refresh_button" ); + pRefresh->setClickedCallback( boost::bind( &FSFloaterVRAMUsage::doRefresh, this ) ); + + mData->mList = getChild< LLScrollListCtrl >( "result_list" ); + + LLSelectMgr::instance().registerPropertyListener( this ); + LLSelectMgr::instance().enableSilhouette( FALSE ); + + return TRUE; +} + +void FSFloaterVRAMUsage::onIdle() +{ + if( !mData->mPending && mData->mObjects.empty() ) + { + LLSelectMgr::instance().deselectAll(); + return; + } + + if( mData->mPending && mData->mPropTimer.getElapsedTimeF32() < PROPERTIES_REQUEST_TIMEOUT ) + return; + + if( !mData->mPending && mData->mPropTimer.getStarted() && mData->mPropTimer.getElapsedTimeF32() < PROPERY_REQUEST_INTERVAL ) + return; + + LLSelectMgr::instance().deselectAll(); + mData->mPending = 0; + + std::vector< LLViewerObject* > vctSelection; + std::deque< ObjectStat > withoutRegion; + + while( mData->mPending < PROPERTIES_MAX_REQUEST_COUNT && !mData->mObjects.empty() ) + { + LLViewerObject *pObj = gObjectList.findObject( mData->mObjects[ 0 ].mId ); + if( pObj && pObj->getRegion() ) + { + ++mData->mPending; + vctSelection.push_back( pObj ); + } + else if( pObj ) + withoutRegion.push_back( mData->mObjects[0] ); + + mData->mObjects.erase( mData->mObjects.begin() ); + } + + mData->mObjects.insert( mData->mObjects.end(), withoutRegion.begin(), withoutRegion.end() ); + + mData->mPropTimer.start(); + if( vctSelection.size() ) + { + LLSelectMgr::instance().enableBatchMode(); + mData->mSelection = LLSelectMgr::instance().selectObjectAndFamily( vctSelection ); + LLSelectMgr::instance().disableBatchMode(); + } +} + +U32 FSFloaterVRAMUsage::calcTexturSize( LLViewerObject *aObject, std::ostream *aTooltip ) +{ + if( !aObject || !aObject->mDrawable || aObject->mDrawable->isDead() ) + return 0; + + std::map< LLUUID, U32 > stTextures; + + F64 totalTexSize = 0; + U8 numTEs = aObject->getNumTEs(); + + if (aTooltip ) + *aTooltip << (U32)numTEs << " TEs" << std::endl; + + for( U8 j = 0; j < numTEs; ++j ) + { + LLViewerTexture *pTex = aObject->getTEImage( j ); + if( !pTex || pTex->isMissingAsset() ) + continue; + + U32 textureId = stTextures.size(); + bool bOldTexId( false ); + + if( stTextures.end() != stTextures.find( pTex->getID() ) ) + { + textureId = stTextures[ pTex->getID() ]; + bOldTexId = true; + } + + if (aTooltip ) + *aTooltip << "TE: " << (U32)j << " tx: " << textureId << " w/h/c " << pTex->getFullWidth() << "/" << pTex->getFullHeight() << "/" << (U32)pTex->getComponents() << std::endl; + + if( bOldTexId ) + continue; + + stTextures[ pTex->getID() ] = textureId; + + S32 texSize = pTex->getFullWidth() * pTex->getFullHeight() * pTex->getComponents(); + if( pTex->getUseMipMaps() ) + texSize += (texSize*33)/100; + + totalTexSize += texSize; + } + + totalTexSize /= 1024.0; + return static_cast< U32 >( totalTexSize ); +} + +void FSFloaterVRAMUsage::doRefresh() +{ + mData->mList->deleteAllItems(); + S32 numObjects = gObjectList.getNumObjects(); + + mData->mPending = 0; + mData->mObjects.clear(); + LLSelectMgr::instance().deselectAll(); + + for( S32 i = 0; i < numObjects; ++i ) + { + LLViewerObject *pObj = gObjectList.getObject( i ); + if( !pObj ) // Might be dead + continue; + + if( !pObj->mbCanSelect || + pObj->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH || + pObj->getPCode() == LLViewerObject::LL_VO_SKY || + pObj->getPCode() == LLViewerObject::LL_VO_WL_SKY || + pObj->getPCode() == LLViewerObject::LL_VO_VOID_WATER || + pObj->getPCode() == LLViewerObject::LL_VO_WATER || + pObj->isAvatar() ) + continue; + + // Exclude everything that's not in a sphere with r=draw distance around the avatar. + F64 distance = (pObj->getPositionGlobal() - gAgentAvatarp->getPositionGlobal()).length(); + if( distance > gAgentCamera.mDrawDistance ) + continue; + + ObjectStat oObject; + oObject.mId = pObj->getID(); + oObject.mTextureSize = calcTexturSize( pObj ); + + mData->mObjects.push_back( oObject ); + } + std::sort( mData->mObjects.begin(), mData->mObjects.end(), sortByTexture ); +} + +void FSFloaterVRAMUsage::addObjectToList( LLViewerObject *aObject, std::string const &aName ) +{ + LLScrollListItem::Params item; + + F64 distance = (aObject->getPositionGlobal() - gAgentAvatarp->getPositionGlobal()).length(); + + item.columns.add().column("uuid").value( aObject->getID() ); + item.columns.add().column("name").value( aName ); + item.columns.add().column("distance").value( distance ); + item.columns.add().column("faces").value( aObject->getNumFaces() ); + item.columns.add().column("vertices").value( static_cast( aObject->getNumVertices() ) ); + item.columns.add().column("indices").value( static_cast( aObject->getNumIndices() ) ); + + std::stringstream strTooltip; + U32 totalTexSize = calcTexturSize( aObject, &strTooltip ); + + F64 totalVboSize(0.0); + + LLPointer< LLDrawable > pDrawable = aObject->mDrawable; + S32 numFaces = 0; + if( pDrawable && !pDrawable->isDead() ) + numFaces = pDrawable->getNumFaces(); + + strTooltip << numFaces << " faces" << std::endl; + for (S32 j = 0; j < numFaces; j++) + { + LLFace* pFace = pDrawable->getFace( j ); + if( !pFace ) + continue; + + S32 cmW = 0, cmH = 0; + + calcFaceSize( pFace, cmW, cmH ); + + strTooltip << "Face: " << j << " extends (cm) w/h " << cmW << "/" << cmH << std::endl; + + S32 vertexSize = calcVBOEntrySize( pFace->getVertexBuffer() ) * aObject->getNumVertices();; + S32 indexSize = sizeof( S16 ) * aObject->getNumIndices(); + + totalVboSize += vertexSize; + totalVboSize += indexSize; + } + + totalVboSize /= 1024.0; + + item.columns.add().column("vram_usage").value( (S32)totalTexSize ); + item.columns.add().column("vram_usage_vbo").value( (S32)totalVboSize ); + + LLScrollListItem *pRow = mData->mList->addRow( item ); + if( pRow ) + { + for( S32 j = 0; j < pRow->getNumColumns(); ++j ) + pRow->getColumn( j )->setToolTip( strTooltip.str() ); + } +} + +void FSFloaterVRAMUsage::calcFaceSize( LLFace *aFace, S32 &aW, S32 &aH ) +{ + aW = aH = 0; + if( !aFace ) + return; + + LLVector4a size; + size.setSub( aFace->mExtents[1], aFace->mExtents[0] ); + + S32 cmX = static_cast( size[0]*100 ); + S32 cmY = static_cast( size[1]*100 ); + S32 cmZ = static_cast( size[2]*100 ); + + aW = cmX; + aH = cmY; + + if( 0 != cmZ ) + { + if( 0 == aW ) + aW = cmZ; + else + aH = cmZ; + } +} + +S32 FSFloaterVRAMUsage::calcVBOEntrySize( LLVertexBuffer *aVBO ) +{ + if( !aVBO ) + return 0; + + S32 vboEntrySize(0); + + U32 vboMask = aVBO->getTypeMask(); + for( S32 k = 0, l = 1; k < LLVertexBuffer::TYPE_MAX; ++k ) + { + if( vboMask & l && k != LLVertexBuffer::TYPE_TEXTURE_INDEX ) + vboEntrySize += LLVertexBuffer::sTypeSize[ k ]; + l = l << 1; + } + + return vboEntrySize; +} + +void FSFloaterVRAMUsage::onProperties( LLSelectNode const *aProps ) +{ + if( !aProps && !aProps->getObject() ) + return; + + LLUUID id = aProps->getObject()->getID(); + LLViewerObject *pObj = gObjectList.findObject( id ); + addObjectToList( pObj, aProps->mName ); +} diff --git a/indra/newview/fsfloatervramusage.h b/indra/newview/fsfloatervramusage.h new file mode 100644 index 0000000000..19984dc0cd --- /dev/null +++ b/indra/newview/fsfloatervramusage.h @@ -0,0 +1,61 @@ +/** + * $LicenseInfo:firstyear=2015&license=viewerlgpl$ + * Phoenix Firestorm Viewer Source Code + * Copyright (c) 2015 Nicky Dasmijn + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * The Phoenix Firestorm Project, Inc., 1831 Oakwood Drive, Fairmont, Minnesota 56031-3225 USA + * http://www.firestormviewer.org + * $/LicenseInfo$ + */ + +#ifndef FS_FLOATERVRAMUSAGE_H +#define FS_FLOATERVRAMUSAGE_H + +#include "llfloater.h" +#include "llselectmgr.h" + +class LLScrollListCtrl; +class LLViewerObject; +class LLFace; +class LLVertexBuffer; + +class FSFloaterVRAMUsage : public LLFloater, public nd::selection::PropertiesListener +{ +public: + FSFloaterVRAMUsage(const LLSD& seed); + /*virtual*/ ~FSFloaterVRAMUsage(); + /*virtual*/ void onOpen(const LLSD& key); + + BOOL postBuild(); + + virtual void onProperties( LLSelectNode const * ); + + void onIdle(); + +private: + void doRefresh(); + + void addObjectToList( LLViewerObject*, std::string const& ); + void calcFaceSize( LLFace *aFace, S32 &aW, S32 &aH ); + S32 calcVBOEntrySize( LLVertexBuffer *aVBO ); + U32 calcTexturSize( LLViewerObject*, std::ostream * = 0 ); + + struct ImplData; + ImplData *mData; +}; + +#endif // FS_FLOATERBLOCKLIST_H diff --git a/indra/newview/fsfloaterwsassetblacklist.cpp b/indra/newview/fsfloaterwsassetblacklist.cpp index d1e7dec5c5..a50104490a 100644 --- a/indra/newview/fsfloaterwsassetblacklist.cpp +++ b/indra/newview/fsfloaterwsassetblacklist.cpp @@ -61,6 +61,9 @@ std::string FSFloaterWSAssetBlacklist::getTypeString(S32 type) case 6: return getString("asset_object"); break; + case 45: + return getString("asset_resident"); + break; default: return getString("asset_unknown"); break; diff --git a/indra/newview/fskeywords.cpp b/indra/newview/fskeywords.cpp index 59c37f272f..836eda8f68 100644 --- a/indra/newview/fskeywords.cpp +++ b/indra/newview/fskeywords.cpp @@ -35,13 +35,12 @@ #include "llviewercontrol.h" #include -//#include //for boost::ifind_first - FSKeywords::FSKeywords() { gSavedPerAccountSettings.getControl("FSKeywords")->getSignal()->connect(boost::bind(&FSKeywords::updateKeywords, this)); gSavedPerAccountSettings.getControl("FSKeywordCaseSensitive")->getSignal()->connect(boost::bind(&FSKeywords::updateKeywords, this)); + gSavedPerAccountSettings.getControl("FSKeywordMatchWholeWords")->getSignal()->connect(boost::bind(&FSKeywords::updateKeywords, this)); updateKeywords(); } @@ -51,6 +50,7 @@ FSKeywords::~FSKeywords() void FSKeywords::updateKeywords() { + BOOL match_whole_words = gSavedPerAccountSettings.getBOOL("FSKeywordMatchWholeWords"); std::string s = gSavedPerAccountSettings.getString("FSKeywords"); if (!gSavedPerAccountSettings.getBOOL("FSKeywordCaseSensitive")) { @@ -61,7 +61,14 @@ void FSKeywords::updateKeywords() mWordList.clear(); while (begin != end) { - mWordList.push_back(*begin++); + if (match_whole_words) + { + mWordList.push_back(boost::regex_replace(std::string(*begin++), boost::regex("[.^$|()\\[\\]{}*+?\\\\]"), "\\\\&", boost::match_default|boost::format_sed)); + } + else + { + mWordList.push_back(*begin++); + } } } @@ -71,6 +78,7 @@ bool FSKeywords::chatContainsKeyword(const LLChat& chat, bool is_local) static LLCachedControl sFSKeywordInChat(gSavedPerAccountSettings, "FSKeywordInChat", false); static LLCachedControl sFSKeywordInIM(gSavedPerAccountSettings, "FSKeywordInIM", false); static LLCachedControl sFSKeywordCaseSensitive(gSavedPerAccountSettings, "FSKeywordCaseSensitive", false); + static LLCachedControl sFSKeywordMatchWholeWords(gSavedPerAccountSettings, "FSKeywordMatchWholeWords", false); if (!sFSKeywordOn || (is_local && !sFSKeywordInChat) || @@ -86,13 +94,27 @@ bool FSKeywords::chatContainsKeyword(const LLChat& chat, bool is_local) LLStringUtil::toLower(source); } - for (std::vector::iterator it = mWordList.begin(); it != mWordList.end(); ++it) + if (sFSKeywordMatchWholeWords) { - if (source.find((*it)) != std::string::npos) + for (std::vector::iterator it = mWordList.begin(); it != mWordList.end(); ++it) { - return true; + if (boost::regex_search(source, boost::regex("\\b" + (*it) + "\\b"))) + { + return true; + } } } + else + { + for (std::vector::iterator it = mWordList.begin(); it != mWordList.end(); ++it) + { + if (source.find((*it)) != std::string::npos) + { + return true; + } + } + } + return false; } @@ -101,7 +123,7 @@ void FSKeywords::notify(const LLChat& chat) { if (chat.mFromID != gAgentID || chat.mFromName == SYSTEM_FROM) { - if (!LLMuteList::getInstance()->isMuted(chat.mFromID) && !chat.mMuted) + if (!chat.mMuted && !LLMuteList::getInstance()->isMuted(chat.mFromID)) { static LLCachedControl PlayModeUISndFSKeywordSound(gSavedSettings, "PlayModeUISndFSKeywordSound"); if (PlayModeUISndFSKeywordSound) diff --git a/indra/newview/fslslbridge.h b/indra/newview/fslslbridge.h index f555722d75..8b21f40c8f 100644 --- a/indra/newview/fslslbridge.h +++ b/indra/newview/fslslbridge.h @@ -77,6 +77,7 @@ public: void setBridge(LLViewerInventoryItem* item) { mpBridge = item; }; LLViewerInventoryItem* getBridge() { return mpBridge; }; bool canUseBridge(); + bool isBridgeValid() const { return NULL != mpBridge; } void checkBridgeScriptName(const std::string& fileName); std::string currentFullName() { return mCurrentFullName; } @@ -106,7 +107,6 @@ private: LLUUID mBridgeUUID; bool mIsFirstCallDone; //initialization conversation - bool isBridgeValid() const { return NULL != mpBridge; } uuid_vec_t mAllowedDetachables; diff --git a/indra/newview/fslslbridgerequest.cpp b/indra/newview/fslslbridgerequest.cpp index 8baa612a58..58a81c9281 100644 --- a/indra/newview/fslslbridgerequest.cpp +++ b/indra/newview/fslslbridgerequest.cpp @@ -89,7 +89,7 @@ void FSLSLBridgeRequestRadarPosResponder::result(const LLSD& content) FSRadarEntry* entry = radar->getEntry(targetAv); if (entry) { - entry->setZOffset((F32)(targetZ)); + entry->setZOffset(targetZ); //LL_INFOS() << targetAv << " ::: " << targetZ << LL_ENDL; } } diff --git a/indra/newview/fslslpreproc.cpp b/indra/newview/fslslpreproc.cpp index 5c8f22739c..78f52a0c45 100644 --- a/indra/newview/fslslpreproc.cpp +++ b/indra/newview/fslslpreproc.cpp @@ -137,7 +137,6 @@ using namespace boost::regex_constants; std::string FSLSLPreprocessor::encode(std::string script) { - std::string otext = FSLSLPreprocessor::decode(script); BOOL mono = mono_directive(script); @@ -157,19 +156,17 @@ std::string FSLSLPreprocessor::encode(std::string script) if(mono)otext += "//mono\n"; else otext += "//lsl2\n"; - return otext; } std::string FSLSLPreprocessor::decode(std::string script) { - static S32 startpoint = encode_start.length(); std::string tip = script.substr(0,startpoint); - if(tip != encode_start) + if (tip != encode_start) { LL_DEBUGS() << "No start" << LL_ENDL; //if(sp != -1)trigger warningg/error? @@ -178,24 +175,19 @@ std::string FSLSLPreprocessor::decode(std::string script) S32 end = script.find(encode_end); - if(end == -1) + if (end == -1) { LL_DEBUGS() << "No end" << LL_ENDL; return script; } - std::string data = script.substr(startpoint,end-startpoint); LL_DEBUGS() << "data = " << data << LL_ENDL; - std::string otext = data; - - otext = boost::regex_replace(otext, boost::regex("([/*])\\|",boost::regex::perl), "$1"); - //otext = curl_unescape(otext.c_str(),otext.length()); return otext; @@ -204,30 +196,36 @@ std::string FSLSLPreprocessor::decode(std::string script) std::string scopeript2(std::string& top, S32 fstart, char left = '{', char right = '}') { - - if(fstart >= int(top.length())) + if (fstart >= S32(top.length())) { return "begin out of bounds"; } - int cursor = fstart; + S32 cursor = fstart; bool noscoped = true; bool in_literal = false; - int count = 0; + S32 count = 0; char ltoken = ' '; do { char token = top.at(cursor); - if(token == '"' && ltoken != '\\')in_literal = !in_literal; - else if(token == '\\' && ltoken == '\\')token = ' '; - else if(!in_literal) + if (token == '"' && ltoken != '\\') { - if(token == left) + in_literal = !in_literal; + } + else if (token == '\\' && ltoken == '\\') + { + token = ' '; + } + else if (!in_literal) + { + if (token == left) { count += 1; noscoped = false; - }else if(token == right) + } + else if (token == right) { count -= 1; noscoped = false; @@ -235,9 +233,11 @@ std::string scopeript2(std::string& top, S32 fstart, char left = '{', char right } ltoken = token; cursor += 1; - }while((count > 0 || noscoped) && cursor < int(top.length())); - int end = (cursor-fstart); - if(end > int(top.length())) + } + while ((count > 0 || noscoped) && cursor < S32(top.length())); + + S32 end = (cursor-fstart); + if (end > S32(top.length())) { return "end out of bounds"; } @@ -245,19 +245,20 @@ std::string scopeript2(std::string& top, S32 fstart, char left = '{', char right return top.substr(fstart,(cursor-fstart)); } -inline int const_iterator_to_pos(std::string::const_iterator begin, std::string::const_iterator cursor) +inline S32 const_iterator_to_pos(std::string::const_iterator begin, std::string::const_iterator cursor) { return std::distance(begin, cursor); } void shredder(std::string& text) { - int cursor = 0; - if(int(text.length()) == 0) + S32 cursor = 0; + if (text.length() == 0) { - text = "y u do dis?"; + text = "No text to shredder."; return; } + char ltoken = ' '; do { @@ -266,7 +267,7 @@ void shredder(std::string& text) { ltoken = token; token = text[++cursor]; - while(cursor < int(text.length())) + while(cursor < S32(text.length())) { if(token == '\\' && ltoken == '\\') token = ' '; if(token == '"' && ltoken != '\\') @@ -294,13 +295,14 @@ void shredder(std::string& text) } ltoken = token; ++cursor; - }while(cursor < int(text.length())); + } + while (cursor < S32(text.length())); } std::string FSLSLPreprocessor::lslopt(std::string script) { - script = " \n"+script;//HACK//this should prevent regex fail for functions starting on line 0, column 0 + script = " \n" + script;//HACK//this should prevent regex fail for functions starting on line 0, column 0 //added more to prevent split fail on scripts with no global data //this should be fun @@ -327,13 +329,13 @@ std::string FSLSLPreprocessor::lslopt(std::string script) std::set kept_functions; std::map functions; - while(boost::regex_search(std::string::const_iterator(top.begin()), std::string::const_iterator(top.end()), TOPfmatch, findfuncts, boost::match_default)) + while (boost::regex_search(std::string::const_iterator(top.begin()), std::string::const_iterator(top.end()), TOPfmatch, findfuncts, boost::match_default)) { //std::string type = TOPfmatch[1]; std::string funcname = TOPfmatch[2]; - int pos = TOPfmatch.position(boost::match_results::size_type(0)); + S32 pos = TOPfmatch.position(boost::match_results::size_type(0)); std::string funcb = scopeript2(top, pos); functions[funcname] = funcb; LL_DEBUGS() << "func " << funcname << " added to list[" << funcb << "]" << LL_ENDL; @@ -346,12 +348,12 @@ std::string FSLSLPreprocessor::lslopt(std::string script) repass = false; std::map::iterator func_it; - for(func_it = functions.begin(); func_it != functions.end(); func_it++) + for (func_it = functions.begin(); func_it != functions.end(); func_it++) { std::string funcname = func_it->first; - if(kept_functions.find(funcname) == kept_functions.end()) + if (kept_functions.find(funcname) == kept_functions.end()) { boost::smatch calls; @@ -361,7 +363,7 @@ std::string FSLSLPreprocessor::lslopt(std::string script) std::string::const_iterator bstart = bottom.begin(); std::string::const_iterator bend = bottom.end(); - if(boost::regex_search(bstart, bend, calls, findcalls, boost::match_default)) + if (boost::regex_search(bstart, bend, calls, findcalls, boost::match_default)) { std::string function = func_it->second; @@ -371,7 +373,8 @@ std::string FSLSLPreprocessor::lslopt(std::string script) } } } - }while(repass); + } + while (repass); std::map gvars; boost::regex findvars("(integer|float|string|key|vector|rotation|list)\\s+([a-zA-Z0-9_]+)([^\\(\\);]*;)"); @@ -384,12 +387,12 @@ std::string FSLSLPreprocessor::lslopt(std::string script) std::string fullref = TOPvmatch[1] + " " + varname+TOPvmatch[3]; gvars[varname] = fullref; - int start = const_iterator_to_pos(std::string::const_iterator(top.begin()), TOPvmatch[1].first); + S32 start = const_iterator_to_pos(std::string::const_iterator(top.begin()), TOPvmatch[1].first); top.erase(start,fullref.length()); } std::map::iterator var_it; - for(var_it = gvars.begin(); var_it != gvars.end(); var_it++) + for (var_it = gvars.begin(); var_it != gvars.end(); var_it++) { std::string varname = var_it->first; @@ -398,7 +401,7 @@ std::string FSLSLPreprocessor::lslopt(std::string script) std::string::const_iterator bstart = bottom.begin(); std::string::const_iterator bend = bottom.end(); - if(boost::regex_search(bstart, bend, vcalls, findvcalls, boost::match_default)) + if (boost::regex_search(bstart, bend, vcalls, findvcalls, boost::match_default)) { bottom = var_it->second + "\n" + bottom; } @@ -457,17 +460,16 @@ inline std::string shortfile(std::string in) class trace_include_files : public boost::wave::context_policies::default_preprocessing_hooks { public: - trace_include_files(FSLSLPreprocessor* proc) - : mProc(proc) - { + trace_include_files(FSLSLPreprocessor* proc) + : mProc(proc) + { mAssetStack.push(LLUUID::null.asString()); mFileStack.push(proc->mMainScriptName); } template - bool found_include_directive(ContextT const& ctx, - std::string const &filename, bool include_next) + bool found_include_directive(ContextT const& ctx, std::string const &filename, bool include_next) { std::string cfilename = filename.substr(1,filename.length()-2); LL_DEBUGS() << cfilename << ":found_include_directive" << LL_ENDL; @@ -512,13 +514,14 @@ public: } } } - }else + } + else { //todo check on HDD in user defined dir for file in question } - //++include_depth; + //++include_depth; return false; - } + } template void opened_include_file(ContextT const& ctx, @@ -530,10 +533,14 @@ public: std::string id; std::string filename = shortfile(relname);//boost::filesystem::path(std::string(relname)).filename(); std::map::iterator it = mProc->cached_assetids.find(filename); - if(it != mProc->cached_assetids.end()) + if (it != mProc->cached_assetids.end()) { id = mProc->cached_assetids[filename].asString(); - }else id = "NOT_IN_WORLD";//I guess, still need to add external includes atm + } + else + { + id = "NOT_IN_WORLD";//I guess, still need to add external includes atm + } mAssetStack.push(id); std::string macro = "__ASSETID__"; usefulctx.remove_macro_definition(macro, true); @@ -575,12 +582,14 @@ public: { std::string err; err = "warning: last line of file ends without a newline"; - if( !err.compare( e.description())){ + if( !err.compare( e.description())) + { err = "Ignoring warning: "; err += e.description(); LL_WARNS() << err << LL_ENDL; } - else{ + else + { boost::throw_exception(e); } } @@ -594,7 +603,7 @@ private: std::string cachepath(std::string name) { - return gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"lslpreproc",name); + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "lslpreproc", name); } void cache_script(std::string name, std::string content) @@ -612,16 +621,15 @@ void cache_script(std::string name, std::string content) void FSLSLPreprocessor::FSProcCacheCallback(LLVFS *vfs, const LLUUID& iuuid, LLAssetType::EType type, void *userdata, S32 result, LLExtStat extstat) { - LLUUID uuid = iuuid; LL_DEBUGS() << "cachecallback called" << LL_ENDL; - ProcCacheInfo* info =(ProcCacheInfo*)userdata; + ProcCacheInfo* info = (ProcCacheInfo*)userdata; LLViewerInventoryItem* item = info->item; FSLSLPreprocessor* self = info->self; - if(item && self) + if (item && self) { std::string name = item->getName(); - if(result == LL_ERR_NOERR) + if (result == LL_ERR_NOERR) { LLVFile file(vfs, uuid, type); S32 file_length = file.getSize(); @@ -637,13 +645,13 @@ void FSLSLPreprocessor::FSProcCacheCallback(LLVFS *vfs, const LLUUID& iuuid, LLA content += "\n#define __ITEMID__ __UP_ITEMID__\n";*/ //prolly wont work and ill have to be not lazy, but worth a try delete buffer; - if(boost::filesystem::native(name)) + if (boost::filesystem::native(name)) { LL_DEBUGS() << "native name of " << name << LL_ENDL; - self->mCore->mErrorList->setCommentText(std::string("Cached ")+name); + self->mCore->mErrorList->setCommentText("Cached " + name); cache_script(name, content); std::set::iterator loc = self->caching_files.find(name); - if(loc != self->caching_files.end()) + if (loc != self->caching_files.end()) { LL_DEBUGS() << "finalizing cache" << LL_ENDL; self->caching_files.erase(loc); @@ -666,33 +674,36 @@ void FSLSLPreprocessor::FSProcCacheCallback(LLVFS *vfs, const LLUUID& iuuid, LLA } } - if(info) + if (info) { delete info; } } -void FSLSLPreprocessor::preprocess_script(BOOL close, BOOL defcache) +void FSLSLPreprocessor::preprocess_script(BOOL close, bool sync, BOOL defcache) { mClose = close; + mSync = sync; mDefinitionCaching = defcache; caching_files.clear(); - mCore->mErrorList->setCommentText(std::string("PreProc Starting...")); + mCore->mErrorList->setCommentText("PreProc Starting..."); - LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"")+gDirUtilp->getDirDelimiter()+"lslpreproc"); + LLFile::mkdir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() + "lslpreproc"); std::string script = mCore->mEditor->getText(); - if(mMainScriptName == "")//more sanity + if (mMainScriptName.empty())//more sanity { const LLInventoryItem* item = NULL; LLPreview* preview = (LLPreview*)mCore->mUserdata; - if(preview) + if (preview) { item = preview->getItem(); } - if(item) + + if (item) { mMainScriptName = item->getName(); - }else + } + else { mMainScriptName = "(Unknown)"; } @@ -702,7 +713,6 @@ void FSLSLPreprocessor::preprocess_script(BOOL close, BOOL defcache) cache_script(name, script); //start the party start_process(); - } const std::string lazy_list_set_func("\ @@ -730,15 +740,15 @@ list lazy_list_set(list target, integer pos, list newval)\n\ std::string reformat_lazy_lists(std::string script) { - BOOL add_set = FALSE; + bool add_set = false; std::string nscript = script; nscript = boost::regex_replace(nscript, boost::regex("([a-zA-Z0-9_]+)\\[([a-zA-Z0-9_()\"]+)]\\s*=\\s*([a-zA-Z0-9_()\"\\+\\-\\*/]+)([;)])",boost::regex::perl), "$1=lazy_list_set($1,$2,[$3])$4"); - if(nscript != script) + if (nscript != script) { - add_set = TRUE; + add_set = true; } - if(add_set == TRUE) + if (add_set) { //add lazy_list_set function to top of script, as it is used nscript = utf8str_removeCRLF(lazy_list_set_func) + "\n" + nscript; @@ -747,14 +757,14 @@ std::string reformat_lazy_lists(std::string script) } -inline std::string randstr(int len, std::string chars) +inline std::string randstr(S32 len, std::string chars) { - int clen = int(chars.length()); - int built = 0; + S32 clen = S32(chars.length()); + S32 built = 0; std::string ret; - while(built < len) + while (built < len) { - int r = std::rand() / ( RAND_MAX / clen ); + S32 r = std::rand() / ( RAND_MAX / clen ); r = r % clen;//sanity ret += chars.at(r); built += 1; @@ -764,12 +774,12 @@ inline std::string randstr(int len, std::string chars) inline std::string quicklabel() { - return std::string("c")+randstr(5,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); + return std::string("c") + randstr(5, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); } std::string minimalize_whitespace(std::string in) { - return boost::regex_replace(in, boost::regex("\\s*",boost::regex::perl), "\n"); + return boost::regex_replace(in, boost::regex("\\s*",boost::regex::perl), "\n"); } std::string reformat_switch_statements(std::string script) @@ -784,13 +794,13 @@ std::string reformat_switch_statements(std::string script) static std::string switchstr = "switch("; - int escape = 100; + S32 escape = 100; while(boost::regex_search(std::string::const_iterator(buffer.begin()), std::string::const_iterator(buffer.end()), matches, findswitches, boost::match_default) && escape > 1) { - int res = matches.position(boost::match_results::size_type(0))+1; + S32 res = matches.position(boost::match_results::size_type(0))+1; - static int slen = switchstr.length(); + static S32 slen = switchstr.length(); std::string arg = scopeript2(buffer, res+slen-1,'(',')'); @@ -803,7 +813,7 @@ std::string reformat_switch_statements(std::string script) LL_DEBUGS() << "arg=[" << arg << "]" << LL_ENDL;; std::string rstate = scopeript2(buffer, res+slen+arg.length()-1); - int cutlen = slen; + S32 cutlen = slen; cutlen -= 1; cutlen += arg.length(); cutlen += rstate.length(); @@ -811,7 +821,7 @@ std::string reformat_switch_statements(std::string script) //then add arg len and state len to get section to excise //rip off the scope edges - int slicestart = rstate.find("{")+1; + S32 slicestart = rstate.find("{")+1; rstate = rstate.substr(slicestart,(rstate.rfind("}")-slicestart)-1); LL_DEBUGS() << "rstate=[" << rstate << "]" << LL_ENDL; @@ -825,11 +835,11 @@ std::string reformat_switch_statements(std::string script) { //if(statematches[0].matched) { - int case_start = statematches.position(boost::match_results::size_type(0))+1;//const_iterator2pos(statematches[0].first+1, std::string::const_iterator(rstate.begin()))-1; - int next_curl = rstate.find("{",case_start+1); - int next_semi = rstate.find(":",case_start+1); - int case_end = (next_curl < next_semi && next_curl != -1) ? next_curl : next_semi; - static int caselen = std::string("case").length(); + S32 case_start = statematches.position(boost::match_results::size_type(0))+1;//const_iterator2pos(statematches[0].first+1, std::string::const_iterator(rstate.begin()))-1; + S32 next_curl = rstate.find("{",case_start+1); + S32 next_semi = rstate.find(":",case_start+1); + S32 case_end = (next_curl < next_semi && next_curl != -1) ? next_curl : next_semi; + static S32 caselen = std::string("case").length(); if(case_end != -1) { std::string casearg = rstate.substr(case_start+caselen,case_end-(case_start+caselen)); @@ -928,11 +938,12 @@ std::string reformat_switch_statements(std::string script) void FSLSLPreprocessor::start_process() { - if(mWaving) + if (mWaving) { LL_WARNS() << "already waving?" << LL_ENDL; return; } + mWaving = TRUE; boost::wave::util::file_position_type current_position; std::string input = mCore->mEditor->getText(); @@ -944,31 +955,34 @@ void FSLSLPreprocessor::start_process() std::string name = mMainScriptName; bool lazy_lists = gSavedSettings.getBOOL("_NACL_PreProcLSLLazyLists"); bool use_switch = gSavedSettings.getBOOL("_NACL_PreProcLSLSwitch"); + bool use_optimizer = gSavedSettings.getBOOL("_NACL_PreProcLSLOptimizer"); + bool enable_hdd_include = gSavedSettings.getBOOL("_NACL_PreProcEnableHDDInclude"); + bool use_compression = gSavedSettings.getBOOL("_NACL_PreProcLSLTextCompress"); std::string settings; settings = "Settings: preproc "; if (lazy_lists) { - settings = settings + " Lazy Lists"; - } + settings = settings + " Lazy Lists"; + } if (use_switch) { - settings = settings + " Switches"; + settings = settings + " Switches"; } - if(gSavedSettings.getBOOL("_NACL_PreProcLSLOptimizer")) + if (use_optimizer) { - settings = settings + " Optimize"; + settings = settings + " Optimize"; } - if(gSavedSettings.getBOOL("_NACL_PreProcEnableHDDInclude")) + if (enable_hdd_include) { - settings = settings + " HDDInclude"; + settings = settings + " HDDInclude"; } - if(gSavedSettings.getBOOL("_NACL_PreProcLSLTextCompress")) + if (use_compression) { - settings = settings + " Compress"; + settings = settings + " Compress"; } //display the settings - mCore->mErrorList->setCommentText(std::string(settings)); - + mCore->mErrorList->setCommentText(settings); + LL_DEBUGS() << settings << LL_ENDL; bool errored = false; std::string err; @@ -985,29 +999,29 @@ void FSLSLPreprocessor::start_process() ctx.set_language(boost::wave::enable_prefer_pp_numbers(ctx.get_language())); ctx.set_language(boost::wave::enable_variadics(ctx.get_language())); - std::string path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"")+gDirUtilp->getDirDelimiter()+"lslpreproc"+gDirUtilp->getDirDelimiter(); + std::string path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"") + gDirUtilp->getDirDelimiter() + "lslpreproc" + gDirUtilp->getDirDelimiter(); ctx.add_include_path(path.c_str()); - if(gSavedSettings.getBOOL("_NACL_PreProcEnableHDDInclude")) + if (enable_hdd_include) { std::string hddpath = gSavedSettings.getString("_NACL_PreProcHDDIncludeLocation"); - if(hddpath != "") + if (!hddpath.empty()) { ctx.add_include_path(hddpath.c_str()); ctx.add_sysinclude_path(hddpath.c_str()); } } - std::string def = llformat("__AGENTKEY__=\"%s\"",gAgent.getID().asString().c_str());//legacy because I used it earlier + std::string def = llformat("__AGENTKEY__=\"%s\"", gAgentID.asString().c_str());//legacy because I used it earlier ctx.add_macro_definition(def,false); - def = llformat("__AGENTID__=\"%s\"",gAgent.getID().asString().c_str()); + def = llformat("__AGENTID__=\"%s\"", gAgentID.asString().c_str()); ctx.add_macro_definition(def,false); - def = llformat("__AGENTIDRAW__=%s",gAgent.getID().asString().c_str()); + def = llformat("__AGENTIDRAW__=%s", gAgentID.asString().c_str()); ctx.add_macro_definition(def,false); std::string aname = gAgentAvatarp->getFullname(); - def = llformat("__AGENTNAME__=\"%s\"",aname.c_str()); + def = llformat("__AGENTNAME__=\"%s\"", aname.c_str()); ctx.add_macro_definition(def,false); - def = llformat("__ASSETID__=%s",LLUUID::null.asString().c_str()); + def = llformat("__ASSETID__=%s", LLUUID::null.asString().c_str()); ctx.add_macro_definition(def,false); - def = llformat("__SHORTFILE__=\"%s\"",name.c_str()); + def = llformat("__SHORTFILE__=\"%s\"", name.c_str()); ctx.add_macro_definition(def,false); ctx.add_macro_definition("list(input)=((list)(input))",false); @@ -1022,15 +1036,15 @@ void FSLSLPreprocessor::start_process() context_type::iterator_type first = ctx.begin(); context_type::iterator_type last = ctx.end(); - - while (first != last) + + while (first != last) { - if(caching_files.size() != 0) + if (caching_files.size() != 0) { mWaving = FALSE; return; } - current_position = (*first).get_position(); + current_position = (*first).get_position(); std::string token = std::string((*first).get_value().c_str());//stupid boost bitching even though we know its a std::string @@ -1041,17 +1055,17 @@ void FSLSLPreprocessor::start_process() output += token; - if(lazy_lists == FALSE) + if (!lazy_lists) { lazy_lists = ctx.is_defined_macro(std::string("USE_LAZY_LISTS")); } - if(use_switch == FALSE) + if (!use_switch) { use_switch = ctx.is_defined_macro(std::string("USE_SWITCHES")); } - ++first; - } + ++first; + } } catch(boost::wave::cpp_exception const& e) { @@ -1080,31 +1094,33 @@ void FSLSLPreprocessor::start_process() mCore->mErrorList->setCommentText(err); } - if(!errored) + if (!errored) { FAILDEBUG - if(lazy_lists == TRUE) + if (lazy_lists) { try { mCore->mErrorList->setCommentText("Applying lazy list set transform"); output = reformat_lazy_lists(output); - }catch(...) - { + } + catch(...) + { errored = TRUE; err = "unexpected exception in lazy list converter."; mCore->mErrorList->setCommentText(err); } } - if(use_switch == TRUE) + if (use_switch) { try { mCore->mErrorList->setCommentText("Applying switch statement transform"); output = reformat_switch_statements(output); - }catch(...) - { + } + catch(...) + { errored = TRUE; err = "unexpected exception in switch statement converter."; mCore->mErrorList->setCommentText(err); @@ -1112,11 +1128,11 @@ void FSLSLPreprocessor::start_process() } } - if(!mDefinitionCaching) + if (!mDefinitionCaching) { - if(!errored) + if (!errored) { - if(gSavedSettings.getBOOL("_NACL_PreProcLSLOptimizer")) + if (use_optimizer) { mCore->mErrorList->setCommentText("Optimizing out unreferenced user-defined functions and global variables"); try @@ -1131,32 +1147,33 @@ void FSLSLPreprocessor::start_process() } } } - if(!errored) + if (!errored) { - if(gSavedSettings.getBOOL("_NACL_PreProcLSLTextCompress")) + if (use_compression) { mCore->mErrorList->setCommentText("Compressing lsltext by removing unnecessary space"); try { output = lslcomp(output); - }catch(...) - { + } + catch(...) + { errored = TRUE; err = "unexpected exception in lsl compressor"; mCore->mErrorList->setCommentText(err); } } } - output = encode(rinput)+"\n\n"+output; + output = encode(rinput) + "\n\n" + output; LLTextEditor* outfield = mCore->mPostEditor;//getChild("post_process"); - if(outfield) + if (outfield) { outfield->setText(LLStringExplicit(output)); } mCore->mPostScript = output; - mCore->doSaveComplete((void*)mCore,mClose); + mCore->doSaveComplete((void*)mCore, mClose, mSync); } mWaving = FALSE; } @@ -1207,13 +1224,13 @@ bool FSLSLPreprocessor::mono_directive(std::string const& text, bool agent_inv) { bool domono = agent_inv; - if(text.find("//mono\n") != -1) + if (text.find("//mono\n") != -1) { - domono = TRUE; + domono = true; } - else if(text.find("//lsl2\n") != -1) + else if (text.find("//lsl2\n") != -1) { - domono = FALSE; + domono = false; } return domono; } diff --git a/indra/newview/fslslpreproc.h b/indra/newview/fslslpreproc.h index 17bf9ffc93..7b1222518d 100644 --- a/indra/newview/fslslpreproc.h +++ b/indra/newview/fslslpreproc.h @@ -46,7 +46,7 @@ class FSLSLPreprocessor public: FSLSLPreprocessor(LLScriptEdCore* corep) - : mCore(corep), mWaving(FALSE), mClose(FALSE) + : mCore(corep), mWaving(FALSE), mClose(FALSE), mSync(false) {} static bool mono_directive(std::string const& text, bool agent_inv = true); @@ -59,7 +59,7 @@ public: static LLUUID findInventoryByName(std::string name); static void FSProcCacheCallback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, void *userdata, S32 result, LLExtStat extstat); - void preprocess_script(BOOL close = FALSE, BOOL defcache = FALSE); + void preprocess_script(BOOL close = FALSE, bool sync = false, BOOL defcache = FALSE); void start_process(); void display_error(std::string err); @@ -86,6 +86,7 @@ public: LLScriptEdCore* mCore; BOOL mWaving; BOOL mClose; + bool mSync; BOOL mHDDInclude; std::string mMainScriptName; }; diff --git a/indra/newview/fsnearbychatcontrol.cpp b/indra/newview/fsnearbychatcontrol.cpp index d9bbff2c1a..56c4602d09 100644 --- a/indra/newview/fsnearbychatcontrol.cpp +++ b/indra/newview/fsnearbychatcontrol.cpp @@ -357,19 +357,19 @@ BOOL FSNearbyChatControl::handleKeyHere(KEY key, MASK mask ) } else if( KEY_RETURN == key ) { - if (mask == MASK_CONTROL) + if (mask == MASK_CONTROL && gSavedSettings.getBOOL("FSUseCtrlShout")) { // shout type = CHAT_TYPE_SHOUT; handled = TRUE; } - else if (mask == MASK_SHIFT) + else if (mask == MASK_SHIFT && gSavedSettings.getBOOL("FSUseShiftWhisper")) { // whisper type = CHAT_TYPE_WHISPER; handled = TRUE; } - else if (mask == MASK_ALT) + else if (mask == MASK_ALT && gSavedSettings.getBOOL("FSUseAltOOC")) { // OOC type = CHAT_TYPE_OOC; @@ -381,6 +381,12 @@ BOOL FSNearbyChatControl::handleKeyHere(KEY key, MASK mask ) type = CHAT_TYPE_NORMAL; handled = TRUE; } + else + { + // say + type = CHAT_TYPE_NORMAL; + handled = TRUE; + } } if (handled == TRUE) diff --git a/indra/newview/fsnearbychathub.cpp b/indra/newview/fsnearbychathub.cpp index d8535f0834..19f80b0c5f 100644 --- a/indra/newview/fsnearbychathub.cpp +++ b/indra/newview/fsnearbychathub.cpp @@ -480,7 +480,10 @@ void FSNearbyChat::sendChat(LLWString text, EChatType type) utf8text = applyMuPose(utf8text); // discard returned "found" boolean - LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text); + if(!LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text)) + { + utf8_revised_text = utf8text; + } } else { diff --git a/indra/newview/fspanelblocklist.cpp b/indra/newview/fspanelblocklist.cpp index b7fa6ead61..ce1a0d0469 100644 --- a/indra/newview/fspanelblocklist.cpp +++ b/indra/newview/fspanelblocklist.cpp @@ -125,6 +125,11 @@ void FSPanelBlockList::selectBlocked(const LLUUID& mute_id) void FSPanelBlockList::showPanelAndSelect(const LLUUID& idToSelect) { + if (gSavedSettings.getBOOL("FSDisableBlockListAutoOpen")) + { + return; + } + if (gSavedSettings.getBOOL("FSUseStandaloneBlocklistFloater")) { LLFloaterReg::showInstance("fs_blocklist", LLSD().with(BLOCKED_PARAM_NAME, idToSelect)); @@ -162,7 +167,9 @@ void FSPanelBlockList::refreshBlockedList() void FSPanelBlockList::updateButtons() { - getChildView("unblock_btn")->setEnabled(mBlockedList->getNumSelected() > 0); + bool has_selection = mBlockedList->getNumSelected() > 0; + getChildView("blocked_gear_btn")->setEnabled(has_selection); + getChildView("unblock_btn")->setEnabled(has_selection); } void FSPanelBlockList::removeMutes() @@ -300,7 +307,7 @@ void FSPanelBlockList::blockResidentByName() void FSPanelBlockList::blockObjectByName() { - LLFloaterGetBlockedObjectName* picker = LLFloaterGetBlockedObjectName::show(&FSPanelBlockList::callbackBlockByName); + LLFloaterGetBlockedObjectName* picker = LLFloaterGetBlockedObjectName::show(boost::bind(&FSPanelBlockList::callbackBlockByName, this, _1)); LLFloater* parent = dynamic_cast(getParent()); if (parent) { @@ -331,7 +338,6 @@ void FSPanelBlockList::callbackBlockPicked(const uuid_vec_t& ids, const std::vec showPanelAndSelect(mute.mID); } -//static void FSPanelBlockList::callbackBlockByName(const std::string& text) { if (text.empty()) return; @@ -342,6 +348,11 @@ void FSPanelBlockList::callbackBlockByName(const std::string& text) { LLNotificationsUtil::add("MuteByNameFailed"); } + else + { + mBlockedList->selectItemByLabel(text); + mBlockedList->scrollToShowSelected(); + } } void FSPanelBlockList::onFilterEdit(std::string search_string) diff --git a/indra/newview/fspanelblocklist.h b/indra/newview/fspanelblocklist.h index ce7da3dcca..4113f5f096 100644 --- a/indra/newview/fspanelblocklist.h +++ b/indra/newview/fspanelblocklist.h @@ -57,7 +57,7 @@ public: * @param idToSelect - LLUUID of blocked Resident or Object to be selected. * If it is LLUUID::null, nothing will be selected. */ - static void showPanelAndSelect(const LLUUID& idToSelect); + static void showPanelAndSelect(const LLUUID& idToSelect = LLUUID::null); // LLMuteListObserver callback interface implementation. /* virtual */ void onChange() { refreshBlockedList();} @@ -90,7 +90,7 @@ private: bool isActionEnabled(const LLSD& userdata); void callbackBlockPicked(const uuid_vec_t& ids, const std::vector names); - static void callbackBlockByName(const std::string& text); + void callbackBlockByName(const std::string& text); private: FSBlockListCtrl* mBlockedList; diff --git a/indra/newview/fspanelprofile.cpp b/indra/newview/fspanelprofile.cpp index 3b5e2c0ad7..93097800e2 100644 --- a/indra/newview/fspanelprofile.cpp +++ b/indra/newview/fspanelprofile.cpp @@ -1929,10 +1929,9 @@ void FSPanelAvatarNotes::rightsConfirmationCallback(const LLSD& notification, } void FSPanelAvatarNotes::confirmModifyRights(bool grant, S32 rights) -// AO: If this is modified, also modify LLPanelAvatar::ConfirmModifyRights { LLSD args; - args["NAME"] = LLSLURL("agent", getAvatarId(), "displayname").getSLURLString(); + args["NAME"] = LLSLURL("agent", getAvatarId(), "completename").getSLURLString(); if (grant) { diff --git a/indra/newview/fspanelradar.cpp b/indra/newview/fspanelradar.cpp index 849b7d1c1d..d0ca7d9cf9 100644 --- a/indra/newview/fspanelradar.cpp +++ b/indra/newview/fspanelradar.cpp @@ -43,6 +43,7 @@ #include "llavataractions.h" #include "llfloatersidepanelcontainer.h" #include "llnetmap.h" +#include "llpanelblockedlist.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewermenu.h" // for gMenuHolder #include "rlvhandler.h" @@ -190,7 +191,7 @@ void FSPanelRadar::updateButtons() is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL; } mAddFriendButton->setEnabled(!is_friend && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); - mRadarGearButton->setEnabled(selected_uuids.size() > 0); + mRadarGearButton->setEnabled(selected_uuids.size() > 0 && !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)); } LLUUID FSPanelRadar::getCurrentItemID() const @@ -279,15 +280,7 @@ void FSPanelRadar::onOptionsMenuItemClicked(const LLSD& userdata) if (chosen_item == "panel_block_list_sidetray") { - if (gSavedSettings.getBOOL("FSUseStandaloneBlocklistFloater")) - { - LLFloaterReg::showInstance("fs_blocklist", LLSD()); - } - else - { - LLFloaterSidePanelContainer::showPanel("people", "panel_people", - LLSD().with("people_panel_tab_name", "blocked_panel")); - } + LLPanelBlockedList::showPanelAndSelect(); } } diff --git a/indra/newview/fsradar.cpp b/indra/newview/fsradar.cpp index e5c63679ec..3a0f7c2075 100644 --- a/indra/newview/fsradar.cpp +++ b/indra/newview/fsradar.cpp @@ -509,10 +509,10 @@ void FSRadar::updateRadarList() entry["range"] = (avRange > AVATAR_UNKNOWN_RANGE ? llformat("%3.2f", avRange) : llformat(">%3.2f", drawRadius)); entry["typing"] = (avVo && avVo->isTyping()); entry["sitting"] = (avVo && (avVo->getParent() || avVo->isMotionActive(ANIM_AGENT_SIT_GROUND) || avVo->isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED))); - entry["has_notes"] = ent->hasNotes(); if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) { + entry["has_notes"] = ent->hasNotes(); entry["age"] = (avAge > -1 ? llformat("%d", avAge) : ""); if (ent->hasAlertAge()) { @@ -531,6 +531,7 @@ void FSRadar::updateRadarList() } else { + entry["has_notes"] = false; entry["age"] = "---"; } diff --git a/indra/newview/fswsassetblacklist.cpp b/indra/newview/fswsassetblacklist.cpp index aa12ae59c8..d0d3bed04d 100644 --- a/indra/newview/fswsassetblacklist.cpp +++ b/indra/newview/fswsassetblacklist.cpp @@ -53,6 +53,9 @@ LLAssetType::EType S32toAssetType(S32 assetindex) case 6: type = LLAssetType::AT_OBJECT; break; + case 45: + type = LLAssetType::AT_PERSON; + break; default: type = LLAssetType::AT_NONE; } diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 62435e677e..d8308da328 100755 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -140,9 +140,14 @@ ATI Radeon HD 8600D/G/M .*ATI.*AMD Radeon.* (HD|HD )86..[DGM].* 4 1 0 4.2 ATI Radeon HD 8700D/G/M .*ATI.*AMD Radeon.* (HD|HD )87..[DGM].* 4 1 0 4.2 ATI Radeon HD 8800D/G/M .*ATI.*AMD Radeon.* (HD|HD )88..[DGM].* 4 1 0 4.2 ATI Radeon HD 8900D/G/M .*ATI.*AMD Radeon.* (HD|HD )89..[DGM].* 4 1 0 4.2 +ATI Radeon R2 Mobile Series .*ATI.*AMD Radeon.* R2 M2\d\d.* 2 1 0 4.2 +ATI Radeon R3 Mobile Series .*ATI.*AMD Radeon.* R3 M2\d\d.* 3 1 0 4.2 +ATI Radeon R4 Mobile Series .*ATI.*AMD Radeon.* R4 M2\d\d.* 3 1 0 4.2 ATI Radeon R5 Mobile Series .*ATI.*AMD Radeon.* R5 M2\d\d.* 3 1 0 4.2 +ATI Radeon R6 Mobile Series .*ATI.*AMD Radeon.* R6 M2\d\d.* 3 1 0 4.2 ATI Radeon R7 Mobile Series .*ATI.*AMD Radeon.* R7 M2\d\d.* 4 1 0 4.2 -ATI Radeon R9 Mobile Series .*ATI.*AMD Radeon.* R9 M2\d\d.* 4 1 0 4.2 +ATI Radeon R8 Mobile Series .*ATI.*AMD Radeon.* R8 M2\d\d.* 4 1 0 4.2 +ATI Radeon R9 Mobile Series .*ATI.*AMD Radeon.* R9 M2\d\d.* 5 1 0 4.2 AMD Radeon R5(TM) OEM Mobile Series .*ATI.*AMD Radeon\(TM\).* R5 .* 3 1 0 4.2 AMD Radeon R7(TM) OEM Mobile Series .*ATI.*AMD Radeon\(TM\).* R7 .* 4 1 0 4.2 AMD Radeon R9(TM) OEM Mobile Series .*ATI.*AMD Radeon\(TM\).* R9 .* 4 1 0 4.2 @@ -204,10 +209,17 @@ ATI Radeon HD 8600 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)86.* 3 1 0 4.2 ATI Radeon HD 8700 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)87.* 4 1 1 4.2 ATI Radeon HD 8800 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)88.* 5 1 1 4.2 ATI Radeon HD 8900 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)89.* 5 1 1 4.2 -AMD Radeon R3 Series .*ATI.*(Radeon|ASUS).* R3.* 3 1 0 4.2 AMD Radeon R5 200 Series .*ATI.*(Radeon|ASUS).* R5 2[0-9].* 3 1 0 4.2 AMD Radeon R7 200 Series .*ATI.*(Radeon|ASUS).* R7 2[0-9].* 4 1 0 4.2 AMD Radeon R9 200 Series .*ATI.*(Radeon|ASUS).* R9 2[0-9].* 5 1 0 4.2 +AMD Radeon R2 Series .*ATI.*(Radeon|ASUS).* R2.* 2 1 0 4.2 +AMD Radeon R3 Series .*ATI.*(Radeon|ASUS).* R3.* 3 1 0 4.2 +AMD Radeon R4 Series .*ATI.*(Radeon|ASUS).* R4.* 3 1 0 4.2 +AMD Radeon R5 Series .*ATI.*(Radeon|ASUS).* R5.* 3 1 0 4.2 +AMD Radeon R6 Series .*ATI.*(Radeon|ASUS).* R6.* 3 1 0 4.2 +AMD Radeon R7 Series .*ATI.*(Radeon|ASUS).* R7.* 4 1 0 4.2 +AMD Radeon R8 Series .*ATI.*(Radeon|ASUS).* R8.* 4 1 0 4.2 +AMD Radeon R9 Series .*ATI.*(Radeon|ASUS).* R9.* 4 1 0 4.2 ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0 ATI Radeon 2100 .*ATI.*Radeon 21.. 0 0 1 2.1 ATI Radeon 3000 .*ATI.*Radeon 30.. 0 0 1 4 @@ -469,6 +481,9 @@ NVIDIA GTX 850M .*NVIDIA .*GTX *85[0-9]M.* 5 1 0 4.4 NVIDIA GTX 860M .*NVIDIA .*GTX *86[0-9]M.* 5 1 0 4.4 NVIDIA GTX 870M .*NVIDIA .*GTX *87[0-9]M.* 5 1 0 4.4 NVIDIA GTX 880M .*NVIDIA .*GTX *88[0-9]M.* 5 1 0 4.4 +NVIDIA GTX 960M .*NVIDIA .*GTX *96[0-9]M.* 5 1 0 4.4 +NVIDIA GTX 970M .*NVIDIA .*GTX *97[0-9]M.* 5 1 0 4.4 +NVIDIA GTX 980M .*NVIDIA .*GTX *98[0-9]M.* 5 1 0 4.4 NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 3.3 NVIDIA GT 120 .*NVIDIA .*GT 12.* 2 1 0 3.3 NVIDIA GT 130 .*NVIDIA .*GT 13.* 2 1 0 3.3 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 854fa1e482..1436733aaa 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4389,6 +4389,10 @@ void LLAgent::restartFailedTeleportRequest() void LLAgent::clearTeleportRequest() { + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->setHidden(FALSE); + } mTeleportRequest.reset(); } @@ -4407,6 +4411,10 @@ bool LLAgent::hasPendingTeleportRequest() void LLAgent::startTeleportRequest() { + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->setHidden(TRUE); + } if (hasPendingTeleportRequest()) { if (!isMaturityPreferenceSyncedWithServer()) @@ -4452,6 +4460,11 @@ void LLAgent::handleTeleportFinished() void LLAgent::handleTeleportFailed() { + if(LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->setHidden(FALSE); + } + if (mTeleportRequest != NULL) { mTeleportRequest->setStatus(LLTeleportRequest::kFailed); diff --git a/indra/newview/llagentlanguage.cpp b/indra/newview/llagentlanguage.cpp index 16af26eb5b..d96e63e559 100755 --- a/indra/newview/llagentlanguage.cpp +++ b/indra/newview/llagentlanguage.cpp @@ -40,6 +40,7 @@ void LLAgentLanguage::init() gSavedSettings.getControl("InstallLanguage")->getSignal()->connect(boost::bind(&onChange)); gSavedSettings.getControl("SystemLanguage")->getSignal()->connect(boost::bind(&onChange)); gSavedSettings.getControl("LanguageIsPublic")->getSignal()->connect(boost::bind(&onChange)); + gSavedSettings.getControl("LanguageIsPublic")->getSignal()->connect(boost::bind(&update)); // Make change instant } // static diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp index 91420f6b7e..e1955e6fe8 100755 --- a/indra/newview/llagentui.cpp +++ b/indra/newview/llagentui.cpp @@ -137,7 +137,7 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const region_name = RlvStrings::getString(RLV_STRING_HIDDEN_REGION); if (LOCATION_FORMAT_NO_MATURITY == fmt) fmt = LOCATION_FORMAT_LANDMARK; - else if (LOCATION_FORMAT_FULL == fmt) + else if (LOCATION_FORMAT_FULL == fmt || LOCATION_FORMAT_V1_STATUSBAR == fmt) fmt = LOCATION_FORMAT_NO_COORDS; } // [/RLVa:KB] diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f4aab9b972..c4324db135 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3384,6 +3384,17 @@ bool LLAppViewer::initConfiguration() gLastRunVersion = gSavedSettings.getString("LastRunVersion"); loadColorSettings(); + + // One time fix for Latency + if ((gLastRunVersion != LLVersionInfo::getChannelAndVersion()) && (gSavedSettings.getString("SkinCurrent") == "latency") && !gSavedSettings.getBOOL("FSLatencyOneTimeFixRun")) + { + LL_INFOS() << "FSLatencyOneTimeFix: Fixing script dialog colors." << LL_ENDL; + // Replace previously saved script dialog colors with new defaults, which happen to be the same as the group notice colors + LLUIColorTable::instance().setColor("ScriptDialog", LLUIColorTable::instance().getColor("GroupNotifyDialogBG", LLColor4::grey4)); + LLUIColorTable::instance().setColor("ScriptDialogFg", LLUIColorTable::instance().getColor("GroupNotifyTextColor", LLColor4::white)); + } + gSavedSettings.setBOOL("FSLatencyOneTimeFixRun", TRUE); + // // Let anyone else who cares know that we've populated our settings // variables. @@ -3711,19 +3722,22 @@ bool LLAppViewer::initWindow() LL_INFOS("AppInit") << "gViewerwindow created." << LL_ENDL; // Need to load feature table before cheking to start watchdog. - bool use_watchdog = false; - int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled"); - if (watchdog_enabled_setting == -1) - { - use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled"); - } - else - { - // The user has explicitly set this setting; always use that value. - use_watchdog = bool(watchdog_enabled_setting); - } + // Fix Watchdog settings/feature table mess + //bool use_watchdog = false; + //int watchdog_enabled_setting = gSavedSettings.getS32("WatchdogEnabled"); + //if (watchdog_enabled_setting == -1) + //{ + // use_watchdog = !LLFeatureManager::getInstance()->isFeatureAvailable("WatchdogDisabled"); + //} + //else + //{ + // // The user has explicitly set this setting; always use that value. + // use_watchdog = bool(watchdog_enabled_setting); + //} - if (use_watchdog) + //if (use_watchdog) + if (gSavedSettings.getBOOL("WatchdogEnabled")) + // { LLWatchdog::getInstance()->init(watchdog_killer_callback); } @@ -5691,7 +5705,10 @@ void LLAppViewer::idle() // Handle the regular UI idle callbacks as well as // hover callbacks // - + +#ifdef LL_DARWIN + if (!mQuitRequested) //MAINT-4243 +#endif { // LL_RECORD_BLOCK_TIME(FTM_IDLE_CB); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 12bf22f970..bb7a7041bd 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -425,14 +425,25 @@ void LLAppViewerWin32::disableWinErrorReporting() HINSTANCE fault_rep_dll_handle = LoadLibrary(L"faultrep.dll"); /* Flawfinder: ignore */ if( fault_rep_dll_handle ) { - pfn_ADDEREXCLUDEDAPPLICATIONA pAddERExcludedApplicationA = (pfn_ADDEREXCLUDEDAPPLICATIONA) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationA"); - if( pAddERExcludedApplicationA ) + // Use unicode version + //pfn_ADDEREXCLUDEDAPPLICATIONA pAddERExcludedApplicationA = (pfn_ADDEREXCLUDEDAPPLICATIONA) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationA"); + //if( pAddERExcludedApplicationA ) + //{ + + // // Strip the path off the name + // const char* executable_name = gDirUtilp->getExecutableFilename().c_str(); + + // if( 0 == pAddERExcludedApplicationA( executable_name ) ) + pfn_ADDEREXCLUDEDAPPLICATIONW pAddERExcludedApplicationW = (pfn_ADDEREXCLUDEDAPPLICATIONW) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationW"); + if( pAddERExcludedApplicationW ) { // Strip the path off the name - const char* executable_name = gDirUtilp->getExecutableFilename().c_str(); + std::string executable_name = gDirUtilp->getExecutableFilename(); + llutf16string wstr = utf8str_to_utf16str(executable_name); - if( 0 == pAddERExcludedApplicationA( executable_name ) ) + if( 0 == pAddERExcludedApplicationW( wstr.c_str() ) ) + // { U32 error_code = GetLastError(); LL_INFOS() << "AddERExcludedApplication() failed with error code " << error_code << LL_ENDL; @@ -465,8 +476,8 @@ void LLAppViewerWin32::disableWinErrorReporting() if( pAddERExcludedApplicationW ) { // Strip the path off the name - const char* executable_name = gDirUtilp->getExecutableFilename().c_str(); - std::wstring wstr(executable_name, executable_name+strlen(executable_name)); + std::string executable_name = gDirUtilp->getExecutableFilename(); + llutf16string wstr = utf8str_to_utf16str(executable_name); if( S_OK == pAddERExcludedApplicationW( wstr.c_str(), FALSE ) ) { diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 9937716030..8da86d6f9b 100755 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -570,9 +570,10 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content) } } // Client LSL Bridge - if (FSLSLBridge::instance().canUseBridge()) + FSLSLBridge& fs_bridge = FSLSLBridge::instance(); + if (fs_bridge.canUseBridge() && fs_bridge.getBridgeCreating()) { - FSLSLBridge::instance().checkBridgeScriptName(mFileName); + fs_bridge.checkBridgeScriptName(mFileName); } // break; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index d07eabb846..e3c1eaf2a9 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -2148,7 +2148,7 @@ void LLAvatarActions::onDerenderAvatarNameLookup(const LLUUID& agent_id, const L { if (permanent) { - FSWSAssetBlacklist::getInstance()->addNewItemToBlacklist(agent_id, av_name.getUserName(), "", LLAssetType::AT_OBJECT); + FSWSAssetBlacklist::getInstance()->addNewItemToBlacklist(agent_id, av_name.getUserName(), "", LLAssetType::AT_PERSON); } LLViewerObject* av_obj = gObjectList.findObject(agent_id); diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index 05a413f1a9..6fa92ed7b6 100755 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -1122,7 +1122,9 @@ void LLAvatarListItem::confirmModifyRights(bool grant, S32 rights) // Same as llpanelavatar::confirmModifyRights { LLSD args; - args["NAME"] = LLSLURL("agent", getAvatarId(), "displayname").getSLURLString(); + // Always show complete name in rights confirmation dialogs + //args["NAME"] = LLSLURL("agent", getAvatarId(), "displayname").getSLURLString(); + args["NAME"] = LLSLURL("agent", getAvatarId(), "completename").getSLURLString(); if (grant) { diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 9e30a26042..be2776fd30 100755 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -706,7 +706,9 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) { LLSD args; - args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString(); + // Always show complete name in rights dialogs + //args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString(); + args["NAME"] = LLSLURL("agent", agent_id, "completename").getSLURLString(); LLSD payload; payload["from_id"] = agent_id; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 77e1ed7f31..20c1c4952c 100755 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1681,11 +1681,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* { LLPointer cur_buffer = facep->getVertexBuffer(); const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i); - if( cur_vol_face.mNumVertices > 0x10000 || cur_vol_face.mNumVertices < 0 || cur_vol_face.mNumIndices < 0 ) - { - LL_WARNS() << "Skipping face " << i - << " vertices " << cur_vol_face.mNumVertices << " indices " << cur_vol_face.mNumIndices - << " face is possibly corrupted" + if( cur_vol_face.mNumVertices > 0x10000 || cur_vol_face.mNumVertices < 0 || cur_vol_face.mNumIndices < 0 ) + { + LL_WARNS() << "Skipping face " << i + << " vertices " << cur_vol_face.mNumVertices << " indices " << cur_vol_face.mNumIndices + << " face is possibly corrupted" << LL_ENDL; continue; } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 10fd4a9c47..0250a871c3 100755 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -954,6 +954,23 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po void LLFace::getPlanarProjectedParams(LLQuaternion* face_rot, LLVector3* face_pos, F32* scale) const { const LLMatrix4& vol_mat = getWorldMatrix(); + if( ! getViewerObject() ) + { + LL_WARNS() << "No viewer object" << LL_ENDL; + return; + } + if( ! getViewerObject()->getVolume() ) + { + LL_WARNS() << "No volume" << LL_ENDL; + return; + } + + if( getViewerObject()->getVolume()->getNumVolumeFaces() <= mTEOffset ) + { + LL_WARNS() << "No volume face" << (S32)mTEOffset << LL_ENDL; + return; + } + const LLVolumeFace& vf = getViewerObject()->getVolume()->getVolumeFace(mTEOffset); const LLVector4a& normal4a = vf.mNormals[0]; const LLVector4a& tangent = vf.mTangents[0]; diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 1b1f1189d7..5d5050103c 100755 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -256,6 +256,14 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) bar_index < end_index; ++bar_index) { + // FIRE-14600: mBars might be null here + if (!row.mBars) + { + LL_WARNS() << "Skipping null row bars" << LL_ENDL; + continue; + } + // + TimerBar& bar = row.mBars[bar_index]; if (bar.mSelfStart > mouse_time_offset) { diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index bc7f14a39d..8c29e6b77e 100755 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -422,13 +422,71 @@ bool LLFeatureManager::parseFeatureTable(std::string filename) return parse_ok; } +F32 gpu_benchmark(); + bool LLFeatureManager::loadGPUClass() { - // defaults - mGPUClass = GPU_CLASS_UNKNOWN; - mGPUString = gGLManager.getRawGLString(); - mGPUSupported = FALSE; + //get memory bandwidth from benchmark + F32 gbps = gpu_benchmark(); + if (gbps < 0.f) + { //couldn't bench, use GLVersion +#if LL_DARWIN + //GLVersion is misleading on OSX, just default to class 3 if we can't bench + mGPUClass = GPU_CLASS_3; +#else + if (gGLManager.mGLVersion < 2.f) + { + mGPUClass = GPU_CLASS_0; + } + else if (gGLManager.mGLVersion < 3.f) + { + mGPUClass = GPU_CLASS_1; + } + else if (gGLManager.mGLVersion < 3.3f) + { + mGPUClass = GPU_CLASS_2; + } + else if (gGLManager.mGLVersion < 4.f) + { + mGPUClass = GPU_CLASS_3; + } + else + { + mGPUClass = GPU_CLASS_4; + } +#endif + } + else if (gbps < 5.f) + { + mGPUClass = GPU_CLASS_0; + } + else if (gbps < 10.f) + { + mGPUClass = GPU_CLASS_1; + } + else if (gbps < 20.f) + { + mGPUClass = GPU_CLASS_2; + } + else if (gbps < 40.f) + { + mGPUClass = GPU_CLASS_3; + } + else if (gbps < 80.f) + { + mGPUClass = GPU_CLASS_4; + } + else + { + mGPUClass = GPU_CLASS_5; + } + + // defaults + mGPUString = gGLManager.getRawGLString(); + mGPUSupported = TRUE; + +#if 0 // first table is in the app dir std::string app_path = gDirUtilp->getAppRODataDir(); app_path += gDirUtilp->getDirDelimiter(); @@ -456,8 +514,8 @@ bool LLFeatureManager::loadGPUClass() { parse_ok = parseGPUTable(app_path); } - - return parse_ok; // indicates that the file parsed correctly, not that the gpu was recognized +#endif + return true; // indicates that the file parsed correctly, not that the gpu was recognized } @@ -778,6 +836,7 @@ void LLFeatureManager::init() void LLFeatureManager::applyRecommendedSettings() { + loadGPUClass(); // apply saved settings // cap the level at 2 (high) U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5)); diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 14cecb48d7..5dd38e83dc 100755 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -65,6 +65,9 @@ //put it back as a member once the legacy path is out? static std::map sAvatarNameMap; +// FIRE-15194: Avatar picker doesn't work anymore when using legacy simulator messages +LLFloaterAvatarPicker::query_id_name_map_t LLFloaterAvatarPicker::sQueryNameMap; + LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback, BOOL allow_multiple, BOOL closeOnSelect, @@ -219,6 +222,14 @@ LLFloaterAvatarPicker::~LLFloaterAvatarPicker() } // + // FIRE-15194: Avatar picker doesn't work anymore when using legacy simulator messages + query_id_name_map_t::iterator found = sQueryNameMap.find(mQueryID); + if (found != sQueryNameMap.end()) + { + sQueryNameMap.erase(found); + } + // + gFocusMgr.releaseFocusIfNeeded( this ); } @@ -649,6 +660,9 @@ void LLFloaterAvatarPicker::find() } else { + // FIRE-15194: Avatar picker doesn't work anymore when using legacy simulator messages + sQueryNameMap[mQueryID] = getKey().asString(); + LLMessageSystem* msg = gMessageSystem; msg->newMessage("AvatarPickerRequest"); msg->nextBlock("AgentData"); @@ -775,7 +789,17 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void* // Not for us if (agent_id != gAgent.getID()) return; - LLFloaterAvatarPicker* floater = LLFloaterReg::findTypedInstance("avatar_picker"); + // FIRE-15194: Avatar picker doesn't work anymore when using legacy simulator messages + //LLFloaterAvatarPicker* floater = LLFloaterReg::findTypedInstance("avatar_picker"); + query_id_name_map_t::iterator found = sQueryNameMap.find(query_id); + if (found == sQueryNameMap.end()) + { + return; + } + const LLSD floater_key(found->second); + sQueryNameMap.erase(found); + LLFloaterAvatarPicker* floater = LLFloaterReg::findTypedInstance("avatar_picker", floater_key); + // // floater is closed or these are not results from our last request if (NULL == floater || query_id != floater->mQueryID) diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index 565fb15e3d..38ef55ecee 100755 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -68,6 +68,11 @@ public: void openFriendsTab(); BOOL isExcludeAgentFromSearchResults() {return mExcludeAgentFromSearchResults;} + // FIRE-15194: Avatar picker doesn't work anymore when using legacy simulator messages + typedef std::map query_id_name_map_t; + static query_id_name_map_t sQueryNameMap; + // + private: void editKeystroke(class LLLineEditor* caller, void* user_data); // Search by UUID diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 13e54d2c02..f3e6ce6f9f 100755 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -661,15 +661,18 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param) // if (camera_floater) // camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); // } - else if ("object_view" == name && camera_floater) + else if ("object_view" == name) { - if (camera_floater->mUseFlatUI) + if (camera_floater) { - camera_floater->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA ? camera_floater->switchMode(CAMERA_CTRL_MODE_PAN) : camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); - } - else - { - camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); + if (camera_floater->mUseFlatUI) + { + camera_floater->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA ? camera_floater->switchMode(CAMERA_CTRL_MODE_PAN) : camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); + } + else + { + camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); + } } } // @@ -699,15 +702,18 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param) { gAgentCamera.changeCameraToMouselook(); } - else if ("object_view" == name && camera_floater) + else if ("object_view" == name) { - if (camera_floater->mUseFlatUI) + if (camera_floater) { - camera_floater->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA ? camera_floater->switchMode(CAMERA_CTRL_MODE_PAN) : camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); - } - else - { - camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); + if (camera_floater->mUseFlatUI) + { + camera_floater->mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA ? camera_floater->switchMode(CAMERA_CTRL_MODE_PAN) : camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); + } + else + { + camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA); + } } } else diff --git a/indra/newview/llfloatergroupbulkban.cpp b/indra/newview/llfloatergroupbulkban.cpp new file mode 100644 index 0000000000..44074047a7 --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.cpp @@ -0,0 +1,134 @@ +/** +* @file llfloatergroupbulkban.cpp +* @brief Floater to ban Residents from a group. +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatergroupbulkban.h" +#include "llpanelgroupbulkban.h" +#include "lltrans.h" +#include "lldraghandle.h" + + +class LLFloaterGroupBulkBan::impl +{ +public: + impl(const LLUUID& group_id) : mGroupID(group_id), mBulkBanPanelp(NULL) {} + ~impl() {} + + static void closeFloater(void* data); + +public: + LLUUID mGroupID; + LLPanelGroupBulkBan* mBulkBanPanelp; + + static std::map sInstances; +}; + +// +// Globals +// +std::map LLFloaterGroupBulkBan::impl::sInstances; + +void LLFloaterGroupBulkBan::impl::closeFloater(void* data) +{ + LLFloaterGroupBulkBan* floaterp = (LLFloaterGroupBulkBan*)data; + if(floaterp) + floaterp->closeFloater(); +} + +//----------------------------------------------------------------------------- +// Implementation +//----------------------------------------------------------------------------- +LLFloaterGroupBulkBan::LLFloaterGroupBulkBan(const LLUUID& group_id/*=LLUUID::null*/) + : LLFloater(group_id) +{ + S32 floater_header_size = getHeaderHeight(); + LLRect contents; + + mImpl = new impl(group_id); + mImpl->mBulkBanPanelp = new LLPanelGroupBulkBan(group_id); + + contents = mImpl->mBulkBanPanelp->getRect(); + contents.mTop -= floater_header_size; + + setTitle(mImpl->mBulkBanPanelp->getString("GroupBulkBan")); + mImpl->mBulkBanPanelp->setCloseCallback(impl::closeFloater, this); + mImpl->mBulkBanPanelp->setRect(contents); + + addChild(mImpl->mBulkBanPanelp); +} + +LLFloaterGroupBulkBan::~LLFloaterGroupBulkBan() +{ + if(mImpl->mGroupID.notNull()) + { + impl::sInstances.erase(mImpl->mGroupID); + } + + delete mImpl->mBulkBanPanelp; + delete mImpl; +} + +void LLFloaterGroupBulkBan::showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids) +{ + const LLFloater::Params& floater_params = LLFloater::getDefaultParams(); + S32 floater_header_size = floater_params.header_height; + LLRect contents; + + // Make sure group_id isn't null + if (group_id.isNull()) + { + LL_WARNS() << "LLFloaterGroupInvite::showForGroup with null group_id!" << LL_ENDL; + return; + } + + // If we don't have a floater for this group, create one. + LLFloaterGroupBulkBan* fgb = get_if_there(impl::sInstances, + group_id, + (LLFloaterGroupBulkBan*)NULL); + if (!fgb) + { + fgb = new LLFloaterGroupBulkBan(group_id); + contents = fgb->mImpl->mBulkBanPanelp->getRect(); + contents.mTop += floater_header_size; + fgb->setRect(contents); + fgb->getDragHandle()->setRect(contents); + fgb->getDragHandle()->setTitle(fgb->mImpl->mBulkBanPanelp->getString("GroupBulkBan")); + + impl::sInstances[group_id] = fgb; + + fgb->mImpl->mBulkBanPanelp->clear(); + } + + if (agent_ids != NULL) + { + fgb->mImpl->mBulkBanPanelp->addUsers(*agent_ids); + } + + fgb->center(); + fgb->openFloater(); + fgb->mImpl->mBulkBanPanelp->update(); +} diff --git a/indra/newview/llfloatergroupbulkban.h b/indra/newview/llfloatergroupbulkban.h new file mode 100644 index 0000000000..5b680a1ba4 --- /dev/null +++ b/indra/newview/llfloatergroupbulkban.h @@ -0,0 +1,48 @@ +/** +* @file llfloatergroupbulkban.h +* @brief This floater is a wrapper for LLPanelGroupBulkBan, which +* is used to ban Residents from a specific group. +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLFLOATERGROUPBULKBAN_H +#define LL_LLFLOATERGROUPBULKBAN_H + +#include "llfloater.h" +#include "lluuid.h" + +class LLFloaterGroupBulkBan : public LLFloater +{ +public: + virtual ~LLFloaterGroupBulkBan(); + + static void showForGroup(const LLUUID& group_id, uuid_vec_t* agent_ids = NULL); + +protected: + LLFloaterGroupBulkBan(const LLUUID& group_id = LLUUID::null); + + class impl; + impl* mImpl; +}; + +#endif // LL_LLFLOATERGROUPBULKBAN_H diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index eaf557d278..339d15f26e 100755 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -1272,6 +1272,22 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata) uuid_vec_t uuids; getParticipantUUIDs(uuids); + + //If there is group or ad-hoc chat in multiselection, everything needs to be disabled + if(uuids.size() > 1) + { + const std::set selectedItems = mConversationsRoot->getSelectionList(); + LLConversationItem * conversationItem; + for(std::set::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it) + { + conversationItem = static_cast((*it)->getViewModelItem()); + if((conversationItem->getType() == LLConversationItem::CONV_SESSION_GROUP) || (conversationItem->getType() == LLConversationItem::CONV_SESSION_AD_HOC)) + { + return false; + } + } + } + if ("conversation_log" == item) { return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0; @@ -1376,6 +1392,10 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v else if ("can_call" == item) { return LLAvatarActions::canCall(); + } + else if ("can_open_voice_conversation" == item) + { + return is_single_select && LLAvatarActions::canCall(); } else if ("can_zoom_in" == item) { diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index c71e1c7519..b50971b0ce 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -659,6 +659,13 @@ void LLFloaterModelPreview::disableViewOption(const std::string& option) void LLFloaterModelPreview::loadModel(S32 lod) { + // FIRE-15204: Viewer crashes when clicking "upload model" quickly twice then closing both filepickers + if (mModelPreview->mLoading) + { + return; + } + // + mModelPreview->mLoading = true; (new LLMeshFilePicker(mModelPreview, lod))->getFile(); @@ -666,6 +673,13 @@ void LLFloaterModelPreview::loadModel(S32 lod) void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm) { + // FIRE-15204: Viewer crashes when clicking "upload model" quickly twice then closing both filepickers + if (mModelPreview->mLoading) + { + return; + } + // + mModelPreview->mLoading = true; mModelPreview->loadModel(file_name, lod, force_disable_slm); @@ -1434,32 +1448,6 @@ LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* pre mJointMap["lShin"] = "mKneeLeft"; mJointMap["lFoot"] = "mFootLeft"; -// FIRE-7937 : Patch from Magus Freston - allows ALL bones including all attachment points to be weighted to mesh and animated - mJointMap["Right_Ear"] = "Right Ear"; - mJointMap["Left_Ear"] = "Left Ear"; - mJointMap["Right_Eyeball"] = "Right Eyeball"; - mJointMap["Left_Eyeball"] = "Left Eyeball"; - mJointMap["Right_Shoulder"] = "Right Shoulder"; - mJointMap["Left_Shoulder"] = "Left Shoulder"; - mJointMap["R_Upper_Arm"] = "R Upper Arm"; - mJointMap["L_Upper_Arm"] = "L Upper Arm"; - mJointMap["R_Forearm"] = "R Forearm"; - mJointMap["L_Forearm"] = "L Forearm"; - mJointMap["Right_Hand"] = "Right Hand"; - mJointMap["Left_Hand"] = "Left Hand"; - mJointMap["Right_Pec"] = "Right Pec"; - mJointMap["Left_Pec"] = "Left Pec"; - mJointMap["Avatar_Center"] = "Avatar Center"; - mJointMap["Right_Hip"] = "Right Hip"; - mJointMap["Left_Hip"] = "Left Hip"; - mJointMap["R_Upper_Leg"] = "R Upper Leg"; - mJointMap["L_Upper_Leg"] = "L Upper Leg"; - mJointMap["R_Lower_Leg"] = "R Lower Leg"; - mJointMap["R_Lower_Leg"] = "R Lower Leg"; - mJointMap["Right_Foot"] = "Right Foot"; - mJointMap["Left_Foot"] = "Left Foot"; -// FIRE-7937 end - if (mPreview) { //only try to load from slm if viewer is configured to do so and this is the diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 90a08c7927..7bd91743f8 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -123,6 +123,7 @@ #include "lleventtimer.h" #include "lldiriterator.h" // for populating the fonts combo #include "llline.h" +#include "llpanelblockedlist.h" #include "llpanelmaininventory.h" #include "llscrolllistctrl.h" #include "llspellcheck.h" @@ -2458,15 +2459,7 @@ void LLFloaterPreference::onClickBlockList() // Optional standalone blocklist floater //LLFloaterSidePanelContainer::showPanel("people", "panel_people", // LLSD().with("people_panel_tab_name", "blocked_panel")); - if (gSavedSettings.getBOOL("FSUseStandaloneBlocklistFloater")) - { - LLFloaterReg::showInstance("fs_blocklist", LLSD()); - } - else - { - LLFloaterSidePanelContainer::showPanel("people", "panel_people", - LLSD().with("people_panel_tab_name", "blocked_panel")); - } + LLPanelBlockedList::showPanelAndSelect(); // } diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 6494c3a4f7..c6cdb3fe3a 100755 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2923,7 +2923,7 @@ bool LLDispatchSetEstateAccess::operator()( if (num_banned_agents > 0 && !(access_flags & ESTATE_ACCESS_BANNED_AGENTS)) { - LL_WARNS() << "non-zero count for banned agents, but no corresponding flag" << LL_ENDL; + LL_WARNS() << "non-zero count for banned residents, but no corresponding flag" << LL_ENDL; } if (num_estate_managers > 0 && !(access_flags & ESTATE_ACCESS_MANAGERS)) diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index 80a2020677..0faabce9e9 100755 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -178,6 +178,9 @@ BOOL LLFloaterReporter::postBuild() std::string reporter = LLSLURL("agent", gAgent.getID(), "inspect").getSLURLString(); getChild("reporter_field")->setValue(reporter); + // FIRE-15218: Refresh screenshot button + getChild("refresh_screenshot")->setCommitCallback(boost::bind(&LLFloaterReporter::takeScreenshot, this)); + center(); return TRUE; diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 85bbb0bb13..cd7ff22bb7 100755 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -674,9 +674,16 @@ void LLFloaterTools::refresh() getChild("selection_count")->setText(selection_info.str()); bool have_selection = !LLSelectMgr::getInstance()->getSelection()->isEmpty(); - childSetVisible("selection_count", have_selection); - childSetVisible("remaining_capacity", have_selection); - childSetVisible("selection_empty", !have_selection); + // FIRE-13838 / VWR-29517: Text and link from other tools is presented in Land tool from Build floater + //childSetVisible("selection_count", have_selection); + //childSetVisible("remaining_capacity", have_selection); + //childSetVisible("selection_empty", !have_selection); + LLTool *tool = LLToolMgr::getInstance()->getCurrentTool(); + bool land_visible = (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance() ); + childSetVisible("selection_count", !land_visible && have_selection); + childSetVisible("remaining_capacity", !land_visible && have_selection); + childSetVisible("selection_empty", !land_visible && !have_selection); + // } // disable the object and prim counts if nothing selected diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index 7339398fa5..7615c12043 100755 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -133,9 +133,9 @@ void LLFolderViewModelItemInventory::setPassedFilter(bool passed, S32 filter_gen bool before = mPrevPassedAllFilters; mPrevPassedAllFilters = passedFilter(filter_generation); - if (before != mPrevPassedAllFilters) + if (before != mPrevPassedAllFilters) { - // Need to rearrange the folder if the filtered state of the item changed + // Need to rearrange the folder if the filtered state of the item changed LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder(); if (parent_folder) { diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 71b837c896..d0ad51eee1 100755 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -943,13 +943,32 @@ void LLViewerObjectList::renderObjectBeacons() } -void gpu_benchmark() +F32 gpu_benchmark() { - if (!LLGLSLShader::sNoFixedFunction) + if (!gGLManager.mHasShaderObjects) { //don't bother benchmarking the fixed function - return; + return -1.f; } + + if (gBenchmarkProgram.mProgramObject == 0) + { + LLViewerShaderMgr::instance()->initAttribsAndUniforms(); + + gBenchmarkProgram.mName = "Benchmark Shader"; + gBenchmarkProgram.mFeatures.attachNothing = true; + gBenchmarkProgram.mShaderFiles.clear(); + gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB)); + gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB)); + gBenchmarkProgram.mShaderLevel = 1; + if (!gBenchmarkProgram.createShader(NULL, NULL)) + { + return -1.f; + } + } + + LLGLDisable blend(GL_BLEND); + //measure memory bandwidth by: // - allocating a batch of textures and render targets // - rendering those textures to those render targets @@ -994,7 +1013,8 @@ void gpu_benchmark() gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, source[i]); LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels); } - delete [] pixels; + + delete [] pixels; //make a dummy triangle to draw with LLPointer buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STATIC_DRAW_ARB); @@ -1016,6 +1036,8 @@ void gpu_benchmark() //wait for any previoius GL commands to finish glFinish(); + bool busted_finish = false; + for (S32 c = -1; c < samples; ++c) { LLTimer timer; @@ -1030,7 +1052,18 @@ void gpu_benchmark() } //wait for current batch of copies to finish - glFinish(); + if (busted_finish) + { + //read a pixel off the last target since some drivers seem to ignore glFinish + dest[count-1].bindTarget(); + U32 pixel = 0; + glReadPixels(0,0,1,1,GL_RGBA, GL_UNSIGNED_BYTE, &pixel); + dest[count-1].flush(); + } + else + { + glFinish(); + } F32 time = timer.getElapsedTimeF32(); @@ -1041,13 +1074,20 @@ void gpu_benchmark() F32 gbps = gb/time; - results.push_back(gbps); + if (!gGLManager.mHasTimerQuery && !busted_finish && gbps > 128.f) + { //unrealistically high bandwidth for a card without timer queries, glFinish is probably ignored + busted_finish = true; + } + else + { + results.push_back(gbps); + } } } gBenchmarkProgram.unbind(); - LLGLSLShader::finishProfile(); + LLGLSLShader::finishProfile(false); LLImageGL::deleteTextures(count, source); @@ -1057,21 +1097,32 @@ void gpu_benchmark() F32 gbps = results[results.size()/2]; LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << LL_ENDL; - - F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f; - F32 seconds = ms/1000.f; - - F64 samples_drawn = res*res*count*samples; - F32 samples_sec = (samples_drawn/1000000000.0)/seconds; - gbps = samples_sec*8; + +#if LL_DARWIN + if (gbps > 512.f) + { + LL_INFOS() << "Memory bandwidth is improbably high and likely incorrect." << LL_ENDL; + //OSX is probably lying, discard result + gbps = -1.f; + } +#endif if (gGLManager.mHasTimerQuery) { + F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f; + F32 seconds = ms/1000.f; + + F64 samples_drawn = res*res*count*samples; + F32 samples_sec = (samples_drawn/1000000000.0)/seconds; + gbps = samples_sec*8; + LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL; } else { LL_INFOS() << "ARB_timer_query unavailable." << LL_ENDL; } + + return gbps; } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index af7c630ee7..10a55dbc41 100755 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -173,7 +173,7 @@ public: void changed(LLGroupChange gc) { - if (gc == GC_MEMBER_DATA && !mRequestProcessed) + if (gc == GC_PROPERTIES && !mRequestProcessed) { LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId); if (!gdatap) @@ -183,9 +183,6 @@ public: else if (!gdatap->isMemberDataComplete()) { LL_WARNS() << "LLGroupMgr::getInstance()->getGroupData()->isMemberDataComplete() was FALSE" << LL_ENDL; - } - else - { processGroupData(); mRequestProcessed = true; } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index 1c7e910f29..9f63706ee9 100755 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -238,11 +238,11 @@ LLGroupMgrGroupData::LLGroupMgrGroupData(const LLUUID& id) : mMemberCount(0), mRoleCount(0), mReceivedRoleMemberPairs(0), - mMemberDataComplete(FALSE), - mRoleDataComplete(FALSE), - mRoleMemberDataComplete(FALSE), - mGroupPropertiesDataComplete(FALSE), - mPendingRoleMemberRequest(FALSE), + mMemberDataComplete(false), + mRoleDataComplete(false), + mRoleMemberDataComplete(false), + mGroupPropertiesDataComplete(false), + mPendingRoleMemberRequest(false), mAccessTime(0.0f) { mMemberVersion.generate(); @@ -431,7 +431,7 @@ void LLGroupMgrGroupData::removeMemberData() delete mi->second; } mMembers.clear(); - mMemberDataComplete = FALSE; + mMemberDataComplete = false; mMemberVersion.generate(); } @@ -453,8 +453,8 @@ void LLGroupMgrGroupData::removeRoleData() } mRoles.clear(); mReceivedRoleMemberPairs = 0; - mRoleDataComplete = FALSE; - mRoleMemberDataComplete = FALSE; + mRoleDataComplete = false; + mRoleMemberDataComplete= false; } void LLGroupMgrGroupData::removeRoleMemberData() @@ -478,7 +478,7 @@ void LLGroupMgrGroupData::removeRoleMemberData() } mReceivedRoleMemberPairs = 0; - mRoleMemberDataComplete = FALSE; + mRoleMemberDataComplete= false; } LLGroupMgrGroupData::~LLGroupMgrGroupData() @@ -754,6 +754,20 @@ void LLGroupMgrGroupData::cancelRoleChanges() // Clear out all changes! mRoleChanges.clear(); } + +void LLGroupMgrGroupData::createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data) +{ + mBanList[ban_id] = ban_data; +} + +void LLGroupMgrGroupData::removeBanEntry(const LLUUID& ban_id) +{ + mBanList.erase(ban_id); +} + + + + // // LLGroupMgr // @@ -963,12 +977,12 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) if (group_datap->mMembers.size() == (U32)group_datap->mMemberCount) { - group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberDataComplete = true; group_datap->mMemberRequestID.setNull(); // We don't want to make role-member data requests until we have all the members if (group_datap->mPendingRoleMemberRequest) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID); } } @@ -1038,7 +1052,7 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) group_datap->mMemberCount = num_group_members; group_datap->mRoleCount = num_group_roles + 1; // Add the everyone role. - group_datap->mGroupPropertiesDataComplete = TRUE; + group_datap->mGroupPropertiesDataComplete = true; group_datap->mChanged = TRUE; LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES); @@ -1115,12 +1129,12 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) if (group_datap->mRoles.size() == (U32)group_datap->mRoleCount) { - group_datap->mRoleDataComplete = TRUE; + group_datap->mRoleDataComplete = true; group_datap->mRoleDataRequestID.setNull(); // We don't want to make role-member data requests until we have all the role data if (group_datap->mPendingRoleMemberRequest) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_datap->mID); } } @@ -1229,7 +1243,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) } } - group_datap->mRoleMemberDataComplete = TRUE; + group_datap->mRoleMemberDataComplete= true; group_datap->mRoleMembersRequestID.setNull(); } @@ -1555,7 +1569,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id) LL_INFOS() << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N") << " MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N") << " RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << LL_ENDL; - group_datap->mPendingRoleMemberRequest = TRUE; + group_datap->mPendingRoleMemberRequest = true; return; } @@ -1808,7 +1822,7 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, { // Or check if they're listed in an active group session LLIMSpeakerMgr* mgr = LLIMModel::instance().getSpeakerManager(LLIMMgr::computeSessionID(IM_SESSION_GROUP_START, group_id)); - if ( (!mgr) && (mgr->findSpeaker(ejected_member_id).isNull()) ) + if ( (!mgr) || (mgr->findSpeaker(ejected_member_id).isNull()) ) { continue; } @@ -1873,6 +1887,138 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, } +// Responder class for capability group management +class GroupBanDataResponder : public LLHTTPClient::Responder +{ +public: + GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh=false); + virtual ~GroupBanDataResponder() {} + virtual void result(const LLSD& pContent); + virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent); +private: + LLUUID mGroupID; + BOOL mForceRefresh; +}; + +GroupBanDataResponder::GroupBanDataResponder(const LLUUID& gropup_id, BOOL force_refresh) : + mGroupID(gropup_id), + mForceRefresh(force_refresh) +{} + +void GroupBanDataResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent) +{ + LL_WARNS("GrpMgr") << "Error receiving group member data [status:" + << pStatus << "]: " << pContent << LL_ENDL; +} + +void GroupBanDataResponder::result(const LLSD& content) +{ + if (content.has("ban_list")) + { + // group ban data received + LLGroupMgr::processGroupBanRequest(content); + } + else if (mForceRefresh) + { + // no ban data received, refreshing data after successful operation + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); + } +} + +void LLGroupMgr::sendGroupBanRequest( EBanRequestType request_type, + const LLUUID& group_id, + U32 ban_action, /* = BAN_NO_ACTION */ + const std::vector ban_list) /* = std::vector() */ +{ + LLViewerRegion* currentRegion = gAgent.getRegion(); + if(!currentRegion) + { + LL_WARNS("GrpMgr") << "Agent does not have a current region." << LL_ENDL; + return; + } + + // Check to make sure we have our capabilities + if(!currentRegion->capabilitiesReceived()) + { + LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL; + return; + } + + // Get our capability + std::string cap_url = currentRegion->getCapability("GroupAPIv1"); + if(cap_url.empty()) + { + return; + } + cap_url += "?group_id=" + group_id.asString(); + + LLSD body = LLSD::emptyMap(); + body["ban_action"] = (LLSD::Integer)(ban_action & ~BAN_UPDATE); + // Add our list of potential banned residents to the list + body["ban_ids"] = LLSD::emptyArray(); + LLSD ban_entry; + + uuid_vec_t::const_iterator iter = ban_list.begin(); + for(;iter != ban_list.end(); ++iter) + { + ban_entry = (*iter); + body["ban_ids"].append(ban_entry); + } + + LLHTTPClient::ResponderPtr grp_ban_responder = new GroupBanDataResponder(group_id, ban_action & BAN_UPDATE); + switch(request_type) + { + case REQUEST_GET: + LLHTTPClient::get(cap_url, grp_ban_responder); + break; + case REQUEST_POST: + LLHTTPClient::post(cap_url, body, grp_ban_responder); + break; + case REQUEST_PUT: + case REQUEST_DEL: + break; + } +} + + +void LLGroupMgr::processGroupBanRequest(const LLSD& content) +{ + // Did we get anything in content? + if(!content.size()) + { + LL_WARNS("GrpMgr") << "No group member data received." << LL_ENDL; + return; + } + + LLUUID group_id = content["group_id"].asUUID(); + + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(group_id); + if (!gdatap) + return; + + LLSD::map_const_iterator i = content["ban_list"].beginMap(); + LLSD::map_const_iterator iEnd = content["ban_list"].endMap(); + for(;i != iEnd; ++i) + { + const LLUUID ban_id(i->first); + LLSD ban_entry(i->second); + + LLGroupBanData ban_data; + if(ban_entry.has("ban_date")) + { + ban_data.mBanDate = ban_entry["ban_date"].asDate(); + // TODO: Ban Reason + } + + gdatap->createBanEntry(ban_id, ban_data); + } + + gdatap->mChanged = TRUE; + LLGroupMgr::getInstance()->notifyObservers(GC_BANLIST); +} + + + // Responder class for capability group management class GroupMemberDataResponder : public LLHTTPClient::Responder { @@ -1966,7 +2112,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) if(num_members < 1) return; - LLUUID group_id = content["group_id"].asUUID(); + LLUUID group_id = content["group_id"].asUUID(); LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); if(!group_datap) @@ -2049,12 +2195,12 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); - group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberDataComplete = true; group_datap->mMemberRequestID.setNull(); // Make the role-member data request if (group_datap->mPendingRoleMemberRequest) { - group_datap->mPendingRoleMemberRequest = FALSE; + group_datap->mPendingRoleMemberRequest = false; LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id); } diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index ece6a8cdbb..44a666ef0a 100755 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -33,8 +33,10 @@ #include #include +// Forward Declarations class LLMessageSystem; - +class LLGroupRoleData; +class LLGroupMgr; enum LLGroupChange { @@ -43,9 +45,12 @@ enum LLGroupChange GC_ROLE_DATA, GC_ROLE_MEMBER_DATA, GC_TITLES, + GC_BANLIST, GC_ALL }; +const U32 GB_MAX_BANNED_AGENTS = 500; + class LLGroupMgrObserver { public: @@ -65,8 +70,6 @@ public: virtual void changed(const LLUUID& group_id, LLGroupChange gc) = 0; }; -class LLGroupRoleData; - class LLGroupMemberData { friend class LLGroupMgrGroupData; @@ -205,6 +208,17 @@ struct lluuid_pair_less } }; + +struct LLGroupBanData +{ + LLGroupBanData(): mBanDate() {} + ~LLGroupBanData() {} + + LLDate mBanDate; + // TODO: std:string ban_reason; +}; + + struct LLGroupTitle { std::string mTitle; @@ -212,8 +226,6 @@ struct LLGroupTitle BOOL mSelected; }; -class LLGroupMgr; - class LLGroupMgrGroupData { friend class LLGroupMgr; @@ -244,16 +256,16 @@ public: void recalcAgentPowers(const LLUUID& agent_id); // [SL:KB] - Patch: Chat-GroupSessionEject | Checked: 2012-02-04 (Catznip-3.2.1) | Added: Catznip-3.2.1 - BOOL isMemberDataComplete() const { return mMemberDataComplete; } - BOOL isRoleDataComplete() const { return mRoleDataComplete; } - BOOL isRoleMemberDataComplete() const { return mRoleMemberDataComplete; } - BOOL isGroupPropertiesDataComplete() const { return mGroupPropertiesDataComplete; } + bool isMemberDataComplete() const { return mMemberDataComplete; } + bool isRoleDataComplete() const { return mRoleDataComplete; } + bool isRoleMemberDataComplete() const { return mRoleMemberDataComplete; } + bool isGroupPropertiesDataComplete() const { return mGroupPropertiesDataComplete; } // [/SL:KB] -// BOOL isMemberDataComplete() { return mMemberDataComplete; } -// BOOL isRoleDataComplete() { return mRoleDataComplete; } -// BOOL isRoleMemberDataComplete() { return mRoleMemberDataComplete; } -// BOOL isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } - +// bool isMemberDataComplete() { return mMemberDataComplete; } +// bool isRoleDataComplete() { return mRoleDataComplete; } +// bool isRoleMemberDataComplete() { return mRoleMemberDataComplete; } +// bool isGroupPropertiesDataComplete() { return mGroupPropertiesDataComplete; } + bool isSingleMemberNotOwner(); F32 getAccessTime() const { return mAccessTime; } @@ -261,17 +273,26 @@ public: const LLUUID& getMemberVersion() const { return mMemberVersion; } + void clearBanList() { mBanList.clear(); } + void getBanList(const LLUUID& group_id, LLGroupBanData& ban_data); + const LLGroupBanData& getBanEntry(const LLUUID& ban_id) { return mBanList[ban_id]; } + + void createBanEntry(const LLUUID& ban_id, const LLGroupBanData& ban_data = LLGroupBanData()); + void removeBanEntry(const LLUUID& ban_id); + + public: typedef std::map member_list_t; typedef std::map role_list_t; typedef std::map change_map_t; typedef std::map role_data_map_t; + typedef std::map ban_list_t; + member_list_t mMembers; role_list_t mRoles; - - change_map_t mRoleMemberChanges; role_data_map_t mRoleChanges; + ban_list_t mBanList; std::vector mTitles; @@ -302,12 +323,12 @@ private: LLUUID mTitlesRequestID; U32 mReceivedRoleMemberPairs; - BOOL mMemberDataComplete; - BOOL mRoleDataComplete; - BOOL mRoleMemberDataComplete; - BOOL mGroupPropertiesDataComplete; + bool mMemberDataComplete; + bool mRoleDataComplete; + bool mRoleMemberDataComplete; + bool mGroupPropertiesDataComplete; - BOOL mPendingRoleMemberRequest; + bool mPendingRoleMemberRequest; F32 mAccessTime; // Generate a new ID every time mMembers @@ -334,6 +355,23 @@ class LLGroupMgr : public LLSingleton { LOG_CLASS(LLGroupMgr); +public: + enum EBanRequestType + { + REQUEST_GET = 0, + REQUEST_POST, + REQUEST_PUT, + REQUEST_DEL + }; + + enum EBanRequestAction + { + BAN_NO_ACTION = 0, + BAN_CREATE = 1, + BAN_DELETE = 2, + BAN_UPDATE = 4 + }; + public: LLGroupMgr(); ~LLGroupMgr(); @@ -367,8 +405,14 @@ public: static void sendGroupMemberInvites(const LLUUID& group_id, std::map& role_member_pairs); static void sendGroupMemberEjects(const LLUUID& group_id, uuid_vec_t& member_ids); + + static void sendGroupBanRequest(EBanRequestType request_type, + const LLUUID& group_id, + U32 ban_action = BAN_NO_ACTION, + const uuid_vec_t ban_list = uuid_vec_t()); + + static void processGroupBanRequest(const LLSD& content); - // BAKER void sendCapGroupMembersRequest(const LLUUID& group_id); static void processCapGroupMembersRequest(const LLSD& content); @@ -413,4 +457,3 @@ private: #endif - diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index f1a1f70270..4f9befff8d 100755 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -64,11 +64,9 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p) mNameColumnIndex(p.name_column.column_index), mNameColumn(p.name_column.column_name), mAllowCallingCardDrop(p.allow_calling_card_drop), - // FIRE-12347 / MAINT-3187: Name list not loading - //mShortNames(p.short_names), mShortNames(p.short_names) - //mAvatarNameCacheConnection() - // + // Fix Baker's NameListCtrl un-fix + //mPendingLookupsRemaining(0) {} // public @@ -357,6 +355,19 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( } mAvatarNameCacheConnections[id] = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, suffix, item->getHandle())); // + + // Fix Baker's NameListCtrl un-fix + //if(mPendingLookupsRemaining <= 0) + //{ + // // BAKER TODO: + // // We might get into a state where mPendingLookupsRemaining might + // // go negative. So just reset it right now and figure out if it's + // // possible later :) + // mPendingLookupsRemaining = 0; + // mNameListCompleteSignal(false); + //} + //mPendingLookupsRemaining++; + // } break; } @@ -408,6 +419,9 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) { selectNthItem(idx); // not sure whether this is needed, taken from previous implementation deleteSingleItem(idx); + + // Fix Baker's NameListCtrl un-fix + //mPendingLookupsRemaining--; } } @@ -456,6 +470,25 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, } } + //////////////////////////////////////////////////////////////////////////// + //// BAKER - FIX NameListCtrl +// Fix Baker's NameListCtrl un-fix + // //if (mPendingLookupsRemaining <= 0) + // { + // // We might get into a state where mPendingLookupsRemaining might + // // go negative. So just reset it right now and figure out if it's + // // possible later :) + // //mPendingLookupsRemaining = 0; + // + // mNameListCompleteSignal(true); + // } + // //else + // { + // // mPendingLookupsRemaining--; + // } +// + //////////////////////////////////////////////////////////////////////////// + dirtyColumns(); } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index aeeb5e9b86..ec059bcf55 100755 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -70,6 +70,7 @@ class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker { public: + typedef boost::signals2::signal namelist_complete_signal_t; typedef enum e_name_type { @@ -165,7 +166,7 @@ public: /*virtual*/ void updateColumns(bool force_update); - /*virtual*/ void mouseOverHighlightNthItem( S32 index ); + /*virtual*/ void mouseOverHighlightNthItem( S32 index ); private: void showInspector(const LLUUID& avatar_id, bool is_group); // FIRE-12347 / MAINT-3187: Name list not loading @@ -183,6 +184,18 @@ private: typedef boost::unordered_map avatar_name_cache_connection_map_t; avatar_name_cache_connection_map_t mAvatarNameCacheConnections; // + +// Fix Baker's NameListCtrl un-fix +// S32 mPendingLookupsRemaining; +// namelist_complete_signal_t mNameListCompleteSignal; +// +//public: +// boost::signals2::connection setOnNameListCompleteCallback(boost::function onNameListCompleteCallback) +// { +// return mNameListCompleteSignal.connect(onNameListCompleteCallback); +// } +// + }; diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp index 248dc0e717..f11559739a 100755 --- a/indra/newview/llpanelblockedlist.cpp +++ b/indra/newview/llpanelblockedlist.cpp @@ -48,6 +48,8 @@ #include "llsidetraypanelcontainer.h" #include "llviewercontrol.h" +#include "fspanelblocklist.h" + static LLPanelInjector t_panel_blocked_list("panel_block_list_sidetray"); // @@ -78,10 +80,6 @@ BOOL LLPanelBlockedList::postBuild() { mBlockedList = getChild("blocked"); mBlockedList->setCommitOnSelectionChange(TRUE); - // Performance tweak - mBlockedList->setCommitCallback(boost::bind(&LLPanelBlockedList::onSelectionChanged, this)); - // Blocklist multi selection - mBlockedList->setAllowMultipleSelection(true); this->setVisibleCallback(boost::bind(&LLPanelBlockedList::removePicker, this)); switch (gSavedSettings.getU32("BlockPeopleSortOrder")) @@ -108,16 +106,12 @@ BOOL LLPanelBlockedList::postBuild() getChild("unblock_btn")->setCommitCallback(boost::bind(&LLPanelBlockedList::unblockItem, this)); getChild("blocked_filter_input")->setCommitCallback(boost::bind(&LLPanelBlockedList::onFilterEdit, this, _2)); - // Performance tweak - onSelectionChanged(); - return LLPanel::postBuild(); } void LLPanelBlockedList::draw() { - // Performance tweak - //updateButtons(); + updateButtons(); LLPanel::draw(); } @@ -131,31 +125,15 @@ void LLPanelBlockedList::onOpen(const LLSD& key) void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id) { - // Clear selection first before selecting new - mBlockedList->resetSelection(); mBlockedList->selectItemByUUID(mute_id); } void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect) { - // FIRE-572: Disable auto-open of blocklist - if (gSavedSettings.getBOOL("FSDisableBlockListAutoOpen")) - { - return; - } - - // Optional standalone blocklist floater + // Defer handling to our blocklist panel for convenience since it is replacing LL's version //LLFloaterSidePanelContainer::showPanel("people", "panel_people", // LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect)); - if (gSavedSettings.getBOOL("FSUseStandaloneBlocklistFloater")) - { - LLFloaterReg::showInstance("fs_blocklist", LLSD().with(BLOCKED_PARAM_NAME, idToSelect)); - } - else - { - LLFloaterSidePanelContainer::showPanel("people", "panel_people", - LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect)); - } + FSPanelBlockList::showPanelAndSelect(idToSelect); // } @@ -172,27 +150,12 @@ void LLPanelBlockedList::updateButtons() void LLPanelBlockedList::unblockItem() { - // Blocklist multi selection - //LLBlockedListItem* item = mBlockedList->getBlockedItem(); - //if (item) - //{ - // LLMute mute(item->getUUID(), item->getName()); - // LLMuteList::instance().remove(mute); - //} - - std::vector panels; - mBlockedList->getSelectedItems(panels); - for (std::vector::iterator it = panels.begin(); it != panels.end(); ++it) + LLBlockedListItem* item = mBlockedList->getBlockedItem(); + if (item) { - LLBlockedListItem* item = dynamic_cast(*it); - if (item) - { - LLMute mute(item->getUUID(), item->getName()); - LLMuteList::getInstance()->remove(mute); - } + LLMute mute(item->getUUID(), item->getName()); + LLMuteList::instance().remove(mute); } - onSelectionChanged(); - // } void LLPanelBlockedList::onCustomAction(const LLSD& userdata) @@ -267,13 +230,6 @@ void LLPanelBlockedList::onFilterEdit(const std::string& search_string) mBlockedList->setNameFilter(filter); } -// Performance tweak -void LLPanelBlockedList::onSelectionChanged() -{ - updateButtons(); -} -// - void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector names) { if (names.empty() || ids.empty()) return; diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h index e55fdf668a..d39725e4a0 100755 --- a/indra/newview/llpanelblockedlist.h +++ b/indra/newview/llpanelblockedlist.h @@ -52,7 +52,9 @@ public: * @param idToSelect - LLUUID of blocked Resident or Object to be selected. * If it is LLUUID::null, nothing will be selected. */ - static void showPanelAndSelect(const LLUUID& idToSelect); + // Optional standalone blocklist floater + //static void showPanelAndSelect(const LLUUID& idToSelect); + static void showPanelAndSelect(const LLUUID& idToSelect = LLUUID::null); private: @@ -70,9 +72,6 @@ private: void blockObjectByName(); void onFilterEdit(const std::string& search_string); - // Performance tweak - void onSelectionChanged(); - // List commnads void onCustomAction(const LLSD& userdata); BOOL isActionChecked(const LLSD& userdata); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index 6cfa7cde54..d03bc7dd07 100755 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -956,7 +956,7 @@ void LLPanelEditWearable::onCommitSexChange() gAgentAvatarp->updateSexDependentLayerSets(); gAgentAvatarp->updateVisualParams(); - + showWearable(mWearablePtr, TRUE, TRUE); updateScrollingPanelUI(); } diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp new file mode 100644 index 0000000000..76792cc6fd --- /dev/null +++ b/indra/newview/llpanelgroupbulk.cpp @@ -0,0 +1,421 @@ +/** +* @file llpanelgroupbulk.cpp +* @brief Implementation of llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h" + +#include "llagent.h" +#include "llavatarnamecache.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcallingcard.h" +#include "llcombobox.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + + +////////////////////////////////////////////////////////////////////////// +// Implementation of llpanelgroupbulkimpl.h functions +////////////////////////////////////////////////////////////////////////// +LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : + mGroupID(group_id), + mBulkAgentList(NULL), + mOKButton(NULL), + mRemoveButton(NULL), + mGroupName(NULL), + mLoadingText(), + mTooManySelected(), + mCloseCallback(NULL), + mCloseCallbackUserData(NULL), + mAvatarNameCacheConnection(), + mRoleNames(NULL), + mOwnerWarning(), + mAlreadyInGroup(), + mConfirmedOwnerInvite(false), + mListFullNotificationSent(false) +{} + +LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() +{ + if(mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } +} + +void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata) +{ + LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata; + + if(panelp) + { + //Right now this is hard coded with some knowledge that it is part + //of a floater since the avatar picker needs to be added as a dependent + //floater to the parent floater. + //Soon the avatar picker will be embedded into this panel + //instead of being it's own separate floater. But that is next week. + //This will do for now. -jwolk May 10, 2006 + LLView* button = panelp->findChild("add_button"); + LLFloater* root_floater = gFloaterView->getParentFloater(panelp); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + boost::bind(callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button); + if(picker) + { + root_floater->addDependentFloater(picker); + } + } +} + +void LLPanelGroupBulkImpl::callbackClickRemove(void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if (selfp) + selfp->handleRemove(); +} + +void LLPanelGroupBulkImpl::callbackClickCancel(void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if(selfp) + (*(selfp->mCloseCallback))(selfp->mCloseCallbackUserData); +} + +void LLPanelGroupBulkImpl::callbackSelect(LLUICtrl* ctrl, void* userdata) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*)userdata; + if (selfp) + selfp->handleSelection(); +} + +void LLPanelGroupBulkImpl::callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data) +{ + std::vector names; + for (S32 i = 0; i < (S32)agent_ids.size(); i++) + { + LLAvatarName av_name; + if (LLAvatarNameCache::get(agent_ids[i], &av_name)) + { + onAvatarNameCache(agent_ids[i], av_name, user_data); + } + else + { + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data; + if (selfp) + { + if (selfp->mAvatarNameCacheConnection.connected()) + { + selfp->mAvatarNameCacheConnection.disconnect(); + } + // *TODO : Add a callback per avatar name being fetched. + selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(onAvatarNameCache, _1, _2, user_data)); + } + } + } +} + +void LLPanelGroupBulkImpl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data) +{ + LLPanelGroupBulkImpl* selfp = (LLPanelGroupBulkImpl*) user_data; + + if (selfp) + { + if (selfp->mAvatarNameCacheConnection.connected()) + { + selfp->mAvatarNameCacheConnection.disconnect(); + } + std::vector names; + uuid_vec_t agent_ids; + agent_ids.push_back(agent_id); + names.push_back(av_name.getCompleteName()); + + selfp->addUsers(names, agent_ids); + } +} + +void LLPanelGroupBulkImpl::handleRemove() +{ + std::vector selection = mBulkAgentList->getAllSelected(); + if (selection.empty()) + return; + + std::vector::iterator iter; + for(iter = selection.begin(); iter != selection.end(); ++iter) + { + mInviteeIDs.erase((*iter)->getUUID()); + } + + mBulkAgentList->deleteSelectedItems(); + mRemoveButton->setEnabled(FALSE); + + if( mOKButton && mOKButton->getEnabled() && + mBulkAgentList->isEmpty()) + { + mOKButton->setEnabled(FALSE); + } +} + +void LLPanelGroupBulkImpl::handleSelection() +{ + std::vector selection = mBulkAgentList->getAllSelected(); + if (selection.empty()) + mRemoveButton->setEnabled(FALSE); + else + mRemoveButton->setEnabled(TRUE); +} + +void LLPanelGroupBulkImpl::addUsers(const std::vector& names, const uuid_vec_t& agent_ids) +{ + std::string name; + LLUUID id; + + if(mListFullNotificationSent) + { + return; + } + + if( !mListFullNotificationSent && + (names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES)) + { + mListFullNotificationSent = true; + + // Fail! Show a warning and don't add any names. + LLSD msg; + msg["MESSAGE"] = mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + return; + } + + for (S32 i = 0; i < (S32)names.size(); ++i) + { + name = names[i]; + id = agent_ids[i]; + + if(mInviteeIDs.find(id) != mInviteeIDs.end()) + { + continue; + } + + //add the name to the names list + LLSD row; + row["id"] = id; + row["columns"][0]["value"] = name; + + mBulkAgentList->addElement(row); + mInviteeIDs.insert(id); + + // We've successfully added someone to the list. + if(mOKButton && !mOKButton->getEnabled()) + mOKButton->setEnabled(TRUE); + } +} + +void LLPanelGroupBulkImpl::setGroupName(std::string name) +{ + if(mGroupName) + mGroupName->setText(name); +} + + +LLPanelGroupBulk::LLPanelGroupBulk(const LLUUID& group_id) : + LLPanel(), + mImplementation(new LLPanelGroupBulkImpl(group_id)), + mPendingGroupPropertiesUpdate(false), + mPendingRoleDataUpdate(false), + mPendingMemberDataUpdate(false) +{} + +LLPanelGroupBulk::~LLPanelGroupBulk() +{ + delete mImplementation; +} + +void LLPanelGroupBulk::clear() +{ + mImplementation->mInviteeIDs.clear(); + + if(mImplementation->mBulkAgentList) + mImplementation->mBulkAgentList->deleteAllItems(); + + if(mImplementation->mOKButton) + mImplementation->mOKButton->setEnabled(FALSE); +} + +void LLPanelGroupBulk::update() +{ + updateGroupName(); + updateGroupData(); +} + +void LLPanelGroupBulk::draw() +{ + LLPanel::draw(); + update(); +} + +void LLPanelGroupBulk::updateGroupName() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + + if( gdatap && + gdatap->isGroupPropertiesDataComplete()) + { + // Only do work if the current group name differs + if(mImplementation->mGroupName->getText().compare(gdatap->mName) != 0) + mImplementation->setGroupName(gdatap->mName); + } + else + { + mImplementation->setGroupName(mImplementation->mLoadingText); + } +} + +void LLPanelGroupBulk::updateGroupData() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + if(gdatap && gdatap->isGroupPropertiesDataComplete()) + { + mPendingGroupPropertiesUpdate = false; + } + else + { + if(!mPendingGroupPropertiesUpdate) + { + mPendingGroupPropertiesUpdate = true; + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); + } + } + + if(gdatap && gdatap->isRoleDataComplete()) + { + mPendingRoleDataUpdate = false; + } + else + { + if(!mPendingRoleDataUpdate) + { + mPendingRoleDataUpdate = true; + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + } + } + + if(gdatap && gdatap->isMemberDataComplete()) + { + mPendingMemberDataUpdate = false; + } + else + { + if(!mPendingMemberDataUpdate) + { + mPendingMemberDataUpdate = true; + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); + } + } +} + +void LLPanelGroupBulk::addUserCallback(const LLUUID& id, const LLAvatarName& av_name) +{ + std::vector names; + uuid_vec_t agent_ids; + agent_ids.push_back(id); + names.push_back(av_name.getAccountName()); + + mImplementation->addUsers(names, agent_ids); +} + +void LLPanelGroupBulk::setCloseCallback(void (*close_callback)(void*), void* data) +{ + mImplementation->mCloseCallback = close_callback; + mImplementation->mCloseCallbackUserData = data; +} + +void LLPanelGroupBulk::addUsers(uuid_vec_t& agent_ids) +{ + std::vector names; + for (S32 i = 0; i < (S32)agent_ids.size(); i++) + { + std::string fullname; + LLUUID agent_id = agent_ids[i]; + LLViewerObject* dest = gObjectList.findObject(agent_id); + if(dest && dest->isAvatar()) + { + LLNameValue* nvfirst = dest->getNVPair("FirstName"); + LLNameValue* nvlast = dest->getNVPair("LastName"); + if(nvfirst && nvlast) + { + fullname = LLCacheName::buildFullName( + nvfirst->getString(), nvlast->getString()); + + } + if (!fullname.empty()) + { + names.push_back(fullname); + } + else + { + LL_WARNS() << "llPanelGroupBulk: Selected avatar has no name: " << dest->getID() << LL_ENDL; + names.push_back("(Unknown)"); + } + } + else + { + //looks like user try to invite offline friend + //for offline avatar_id gObjectList.findObject() will return null + //so we need to do this additional search in avatar tracker, see EXT-4732 + if (LLAvatarTracker::instance().isBuddy(agent_id)) + { + LLAvatarName av_name; + if (!LLAvatarNameCache::get(agent_id, &av_name)) + { + // actually it should happen, just in case + LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupBulk::addUserCallback, this, _1, _2)); + // for this special case! + //when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence + // removed id will be added in callback + agent_ids.erase(agent_ids.begin() + i); + } + else + { + names.push_back(av_name.getAccountName()); + } + } + } + } + mImplementation->mListFullNotificationSent = false; + mImplementation->addUsers(names, agent_ids); +} + diff --git a/indra/newview/llpanelgroupbulk.h b/indra/newview/llpanelgroupbulk.h new file mode 100644 index 0000000000..222931eabc --- /dev/null +++ b/indra/newview/llpanelgroupbulk.h @@ -0,0 +1,74 @@ +/** +* @file llpanelgroupbulk.h +* @brief Header file for llpanelgroupbulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LL_LLPANELGROUPBULK_H +#define LL_LLPANELGROUPBULK_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLAvatarName; +class LLGroupMgrGroupData; +class LLPanelGroupBulkImpl; + +// Base panel class for bulk group invite / ban floaters +class LLPanelGroupBulk : public LLPanel +{ +public: + LLPanelGroupBulk(const LLUUID& group_id); + ~LLPanelGroupBulk(); + +public: + static void callbackClickSubmit(void* userdata) {} + virtual void submit() = 0; + +public: + virtual void clear(); + virtual void update(); + virtual void draw(); + +protected: + virtual void updateGroupName(); + virtual void updateGroupData(); + +public: + // this callback is being used to add a user whose fullname isn't been loaded before invoking of addUsers(). + virtual void addUserCallback(const LLUUID& id, const LLAvatarName& av_name); + virtual void setCloseCallback(void (*close_callback)(void*), void* data); + + virtual void addUsers(uuid_vec_t& agent_ids); + +public: + LLPanelGroupBulkImpl* mImplementation; + +protected: + bool mPendingGroupPropertiesUpdate; + bool mPendingRoleDataUpdate; + bool mPendingMemberDataUpdate; +}; + +#endif // LL_LLPANELGROUPBULK_H + diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp new file mode 100644 index 0000000000..cf1f0bc32f --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.cpp @@ -0,0 +1,259 @@ +/** +* @file llpanelgroupbulkban.cpp +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llpanelgroupbulkban.h" +#include "llpanelgroupbulk.h" +#include "llpanelgroupbulkimpl.h" + +#include "llagent.h" +#include "llavatarnamecache.h" +#include "llavataractions.h" +#include "llfloateravatarpicker.h" +#include "llbutton.h" +#include "llcallingcard.h" +#include "llcombobox.h" +#include "llgroupactions.h" +#include "llgroupmgr.h" +#include "llnamelistctrl.h" +#include "llnotificationsutil.h" +#include "llscrolllistitem.h" +#include "llslurl.h" +#include "llspinctrl.h" +#include "lltextbox.h" +#include "llviewerobject.h" +#include "llviewerobjectlist.h" +#include "lluictrlfactory.h" +#include "llviewerwindow.h" + +#include + +LLPanelGroupBulkBan::LLPanelGroupBulkBan(const LLUUID& group_id) : LLPanelGroupBulk(group_id) +{ + // Pass on construction of this panel to the control factory. + buildFromFile( "panel_group_bulk_ban.xml"); +} + +BOOL LLPanelGroupBulkBan::postBuild() +{ + BOOL recurse = TRUE; + + mImplementation->mLoadingText = getString("loading"); + mImplementation->mGroupName = getChild("group_name_text", recurse); + mImplementation->mBulkAgentList = getChild("banned_agent_list", recurse); + if ( mImplementation->mBulkAgentList ) + { + mImplementation->mBulkAgentList->setCommitOnSelectionChange(TRUE); + mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation); + } + + LLButton* button = getChild("add_button", recurse); + if ( button ) + { + // default to opening avatarpicker automatically + // (*impl::callbackClickAdd)((void*)this); + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this); + } + + mImplementation->mRemoveButton = + getChild("remove_button", recurse); + if ( mImplementation->mRemoveButton ) + { + mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); + mImplementation->mRemoveButton->setEnabled(FALSE); + } + + mImplementation->mOKButton = + getChild("ban_button", recurse); + if ( mImplementation->mOKButton ) + { + mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); + mImplementation->mOKButton->setEnabled(FALSE); + } + + button = getChild("cancel_button", recurse); + if ( button ) + { + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); + } + + mImplementation->mTooManySelected = getString("ban_selection_too_large"); + mImplementation->mBanNotPermitted = getString("ban_not_permitted"); + mImplementation->mBanLimitFail = getString("ban_limit_fail"); + mImplementation->mCannotBanYourself = getString("cant_ban_yourself"); + + update(); + return TRUE; +} + +// TODO: Refactor the shitty callback functions with void* -- just use boost::bind to call submit() instead. +void LLPanelGroupBulkBan::callbackClickSubmit(void* userdata) +{ + LLPanelGroupBulkBan* selfp = (LLPanelGroupBulkBan*)userdata; + + if(selfp) + selfp->submit(); +} + + +void LLPanelGroupBulkBan::submit() +{ + if (!gAgent.hasPowerInGroup(mImplementation->mGroupID, GP_GROUP_BAN_ACCESS)) + { + // Fail! Agent no longer have ban rights. Permissions could have changed after button was pressed. + LLSD msg; + msg["MESSAGE"] = mImplementation->mBanNotPermitted; + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + LLGroupMgrGroupData * group_datap = LLGroupMgr::getInstance()->getGroupData(mImplementation->mGroupID); + if (group_datap && group_datap->mBanList.size() >= GB_MAX_BANNED_AGENTS) + { + // Fail! Size limit exceeded. List could have updated after button was pressed. + LLSD msg; + msg["MESSAGE"] = mImplementation->mBanLimitFail; + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + std::vector banned_agent_list; + std::vector agents = mImplementation->mBulkAgentList->getAllData(); + std::vector::iterator iter = agents.begin(); + for(;iter != agents.end(); ++iter) + { + LLScrollListItem* agent = *iter; + banned_agent_list.push_back(agent->getUUID()); + } + + const S32 MAX_BANS_PER_REQUEST = 100; // Max bans per request. 100 to match server cap. + if (banned_agent_list.size() > MAX_BANS_PER_REQUEST) + { + // Fail! + LLSD msg; + msg["MESSAGE"] = mImplementation->mTooManySelected; + LLNotificationsUtil::add("GenericAlert", msg); + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); + return; + } + + // remove already banned users and yourself from request. + std::vector banned_avatar_names; + std::vector out_of_limit_names; + bool banning_self = FALSE; + std::vector::iterator conflict = std::find(banned_agent_list.begin(), banned_agent_list.end(), gAgent.getID()); + if (conflict != banned_agent_list.end()) + { + banned_agent_list.erase(conflict); + banning_self = TRUE; + } + if (group_datap) + { + BOOST_FOREACH(const LLGroupMgrGroupData::ban_list_t::value_type& group_ban_pair, group_datap->mBanList) + { + const LLUUID& group_ban_agent_id = group_ban_pair.first; + std::vector::iterator conflict = std::find(banned_agent_list.begin(), banned_agent_list.end(), group_ban_agent_id); + if (conflict != banned_agent_list.end()) + { + LLAvatarName av_name; + LLAvatarNameCache::get(group_ban_agent_id, &av_name); + banned_avatar_names.push_back(av_name); + + banned_agent_list.erase(conflict); + if (banned_agent_list.size() == 0) + { + break; + } + } + } + // this check should always be the last one before we send the request. + // Otherwise we have a possibility of cutting more then we need to. + if (banned_agent_list.size() > GB_MAX_BANNED_AGENTS - group_datap->mBanList.size()) + { + std::vector::iterator exeedes_limit = banned_agent_list.begin() + GB_MAX_BANNED_AGENTS - group_datap->mBanList.size(); + for (std::vector::iterator itor = exeedes_limit ; + itor != banned_agent_list.end(); ++itor) + { + LLAvatarName av_name; + LLAvatarNameCache::get(*itor, &av_name); + out_of_limit_names.push_back(av_name); + } + banned_agent_list.erase(exeedes_limit,banned_agent_list.end()); + } + } + + // sending request and ejecting members + if (banned_agent_list.size() != 0) + { + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mImplementation->mGroupID, LLGroupMgr::BAN_CREATE | LLGroupMgr::BAN_UPDATE, banned_agent_list); + LLGroupMgr::getInstance()->sendGroupMemberEjects(mImplementation->mGroupID, banned_agent_list); + } + + // building notification + if (banned_avatar_names.size() > 0 || banning_self || out_of_limit_names.size() > 0) + { + std::string reasons; + if(banned_avatar_names.size() > 0) + { + reasons = "\n " + buildResidentsArgument(banned_avatar_names, "residents_already_banned"); + } + + if(banning_self) + { + reasons += "\n " + mImplementation->mCannotBanYourself; + } + + if(out_of_limit_names.size() > 0) + { + reasons += "\n " + buildResidentsArgument(out_of_limit_names, "ban_limit_reached"); + } + + LLStringUtil::format_map_t msg_args; + msg_args["[REASONS]"] = reasons; + LLSD msg; + if (banned_agent_list.size() == 0) + { + msg["MESSAGE"] = getString("ban_failed", msg_args); + } + else + { + msg["MESSAGE"] = getString("partial_ban", msg_args); + } + LLNotificationsUtil::add("GenericAlert", msg); + } + + //then close + (*(mImplementation->mCloseCallback))(mImplementation->mCloseCallbackUserData); +} + +std::string LLPanelGroupBulkBan::buildResidentsArgument(std::vector avatar_names, const std::string &format) +{ + std::string names_string; + LLAvatarActions::buildResidentsString(avatar_names, names_string); + LLStringUtil::format_map_t args; + args["[RESIDENTS]"] = names_string; + return getString(format, args); +} diff --git a/indra/newview/llpanelgroupbulkban.h b/indra/newview/llpanelgroupbulkban.h new file mode 100644 index 0000000000..9060d275f9 --- /dev/null +++ b/indra/newview/llpanelgroupbulkban.h @@ -0,0 +1,49 @@ +/** +* @file llpanelgroupbulkban.h +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLPANELGROUPBULKBAN_H +#define LL_LLPANELGROUPBULKBAN_H + +#include "llpanel.h" +#include "lluuid.h" +#include "llpanelgroupbulk.h" + +class LLAvatarName; + +class LLPanelGroupBulkBan : public LLPanelGroupBulk +{ +public: + LLPanelGroupBulkBan(const LLUUID& group_id); + ~LLPanelGroupBulkBan() {} + + virtual BOOL postBuild(); + + static void callbackClickSubmit(void* userdata); + virtual void submit(); +private: + std::string buildResidentsArgument(std::vector avatar_names, const std::string &format); +}; + +#endif // LL_LLPANELGROUPBULKBAN_H diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h new file mode 100644 index 0000000000..d3a48e5a9a --- /dev/null +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -0,0 +1,99 @@ +/** +* @file llpanelgroupbulkimpl.h +* @brief Class definition for implementation class of LLPanelGroupBulk +* @author Baker@lindenlab.com +* +* $LicenseInfo:firstyear=2013&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2013, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ +#ifndef LL_LLPANELGROUPBULKIMPL_H +#define LL_LLPANELGROUPBULKIMPL_H + +#include "llpanel.h" +#include "lluuid.h" + +class LLAvatarName; +class LLNameListCtrl; +class LLTextBox; +class LLComboBox; + +////////////////////////////////////////////////////////////////////////// +// Implementation found in llpanelgroupbulk.cpp +////////////////////////////////////////////////////////////////////////// +class LLPanelGroupBulkImpl +{ +public: + LLPanelGroupBulkImpl(const LLUUID& group_id); + ~LLPanelGroupBulkImpl(); + + static void callbackClickAdd(void* userdata); + static void callbackClickRemove(void* userdata); + + static void callbackClickCancel(void* userdata); + + static void callbackSelect(LLUICtrl* ctrl, void* userdata); + static void callbackAddUsers(const uuid_vec_t& agent_ids, void* user_data); + + static void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, void* user_data); + + void handleRemove(); + void handleSelection(); + + void addUsers(const std::vector& names, const uuid_vec_t& agent_ids); + void setGroupName(std::string name); + + +public: + static const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap. + + + LLUUID mGroupID; + + LLNameListCtrl* mBulkAgentList; + LLButton* mOKButton; + LLButton* mRemoveButton; + LLTextBox* mGroupName; + + std::string mLoadingText; + std::string mTooManySelected; + std::string mBanNotPermitted; + std::string mBanLimitFail; + std::string mCannotBanYourself; + + std::set mInviteeIDs; + + void (*mCloseCallback)(void* data); + void* mCloseCallbackUserData; + boost::signals2::connection mAvatarNameCacheConnection; + + // The following are for the LLPanelGroupInvite subclass only. + // These aren't needed for LLPanelGroupBulkBan, but if we have to add another + // group bulk floater for some reason, we'll have these objects too. +public: + LLComboBox* mRoleNames; + std::string mOwnerWarning; + std::string mAlreadyInGroup; + bool mConfirmedOwnerInvite; + bool mListFullNotificationSent; +}; + +#endif // LL_LLPANELGROUPBULKIMPL_H + diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index 5dfa7f32b4..3227333e96 100755 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -260,7 +260,7 @@ void LLPanelGroupInvite::impl::addRoleNames(LLGroupMgrGroupData* gdatap) //else if they have the limited add to roles power //we add every role the user is in //else we just add to everyone - bool is_owner = member_data->isInRole(gdatap->mOwnerRole); + bool is_owner = member_data->isOwner(); bool can_assign_any = gAgent.hasPowerInGroup(mGroupID, GP_ROLE_ASSIGN_MEMBER); bool can_assign_limited = gAgent.hasPowerInGroup(mGroupID, @@ -581,7 +581,7 @@ void LLPanelGroupInvite::updateLists() { waiting = true; } - if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete()) + if (gdatap->isRoleDataComplete() && gdatap->isMemberDataComplete() && gdatap->isRoleMemberDataComplete()) { if ( mImplementation->mRoleNames ) { @@ -609,6 +609,7 @@ void LLPanelGroupInvite::updateLists() { LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } mPendingUpdate = TRUE; @@ -656,7 +657,7 @@ BOOL LLPanelGroupInvite::postBuild() } mImplementation->mOKButton = - getChild("ok_button", recurse); + getChild("invite_button", recurse); if ( mImplementation->mOKButton ) { mImplementation->mOKButton->setClickedCallback(impl::callbackClickOK, mImplementation); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index e6e06c59d2..2bfd1b90ce 100755 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -1,4 +1,4 @@ -/** +/** * @file llpanelgrouproles.cpp * @brief Panel for roles information about a particular group. * @@ -32,6 +32,7 @@ #include "llavatarnamecache.h" #include "llbutton.h" #include "llfiltereditor.h" +#include "llfloatergroupbulkban.h" #include "llfloatergroupinvite.h" #include "llavataractions.h" #include "lliconctrl.h" @@ -112,8 +113,10 @@ bool agentCanAddToRole(const LLUUID& group_id, return false; } -// static +// LLPanelGroupRoles ///////////////////////////////////////////////////// + +// static LLPanelGroupRoles::LLPanelGroupRoles() : LLPanelGroupTab(), mCurrentTab(NULL), @@ -300,7 +303,6 @@ bool LLPanelGroupRoles::onModalClose(const LLSD& notification, const LLSD& respo return false; } - bool LLPanelGroupRoles::apply(std::string& mesg) { // Pass this along to the currently visible sub tab. @@ -337,7 +339,6 @@ void LLPanelGroupRoles::update(LLGroupChange gc) { if (mGroupID.isNull()) return; - LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel(); if (panelp) { @@ -354,39 +355,33 @@ void LLPanelGroupRoles::activate() { // Start requesting member and role data if needed. LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); - //if (!gdatap || mFirstUse) + if (!gdatap || !gdatap->isMemberDataComplete() ) { - // Check member data. - - if (!gdatap || !gdatap->isMemberDataComplete() ) - { - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); - } - - // Check role data. - if (!gdatap || !gdatap->isRoleDataComplete() ) - { - // Mildly hackish - clear all pending changes - cancel(); - - LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); - } - - // Check role-member mapping data. - if (!gdatap || !gdatap->isRoleMemberDataComplete() ) - { - LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); - } - - // Need this to get base group member powers - if (!gdatap || !gdatap->isGroupPropertiesDataComplete() ) - { - LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); - } - - mFirstUse = FALSE; + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } + if (!gdatap || !gdatap->isRoleDataComplete() ) + { + // Mildly hackish - clear all pending changes + cancel(); + + LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mGroupID); + } + + // Check role-member mapping data. + if (!gdatap || !gdatap->isRoleMemberDataComplete() ) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + } + + // Need this to get base group member powers + if (!gdatap || !gdatap->isGroupPropertiesDataComplete() ) + { + LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); + } + + mFirstUse = FALSE; + LLPanelGroupTab* panelp = (LLPanelGroupTab*) mSubTabContainer->getCurrentPanel(); if (panelp) panelp->activate(); } @@ -415,15 +410,45 @@ BOOL LLPanelGroupRoles::hasModal() return panelp->hasModal(); } +void LLPanelGroupRoles::setGroupID(const LLUUID& id) +{ + LLPanelGroupTab::setGroupID(id); -//////////////////////////// -// LLPanelGroupSubTab -//////////////////////////// + LLPanelGroupMembersSubTab* group_members_tab = findChild("members_sub_tab"); + LLPanelGroupRolesSubTab* group_roles_tab = findChild("roles_sub_tab"); + LLPanelGroupActionsSubTab* group_actions_tab = findChild("actions_sub_tab"); + LLPanelGroupBanListSubTab* group_ban_tab = findChild("banlist_sub_tab"); + + if(group_members_tab) group_members_tab->setGroupID(id); + if(group_roles_tab) group_roles_tab->setGroupID(id); + if(group_actions_tab) group_actions_tab->setGroupID(id); + if(group_ban_tab) group_ban_tab->setGroupID(id); + + LLButton* button = getChild("member_invite"); + if ( button ) + button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); + // [FS:CR] FIRE-12276 + button = getChild("export_list"); + if (button) + button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_VISIBLE_IN_DIR)); + // [/FS:CR] + if(mSubTabContainer) + // FIRE-13501: Activate "Members" tab by default + //mSubTabContainer->selectTab(1); + mSubTabContainer->selectTab(0); + // + group_roles_tab->mFirstOpen = TRUE; + activate(); +} + + +// LLPanelGroupSubTab //////////////////////////////////////////////////// LLPanelGroupSubTab::LLPanelGroupSubTab() : LLPanelGroupTab(), mHeader(NULL), mFooter(NULL), mActivated(false), + mHasGroupBanPower(false), mSearchEditor(NULL) { } @@ -545,9 +570,10 @@ void LLPanelGroupSubTab::buildActionsList(LLScrollListCtrl* ctrl, return; } + mHasGroupBanPower = false; + std::vector::iterator ras_it = LLGroupMgr::getInstance()->mRoleActionSets.begin(); std::vector::iterator ras_end = LLGroupMgr::getInstance()->mRoleActionSets.end(); - for ( ; ras_it != ras_end; ++ras_it) { buildActionCategory(ctrl, @@ -677,6 +703,31 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, row["columns"][column_index]["value"] = (*ra_it)->mDescription; row["columns"][column_index]["font"] = "SANSSERIF_SMALL"; + if(mHasGroupBanPower) + { + // The ban ability is being set. Prevent these abilities from being manipulated + if((*ra_it)->mPowerBit == GP_MEMBER_EJECT) + { + row["enabled"] = false; + } + else if((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + row["enabled"] = false; + } + } + else + { + // The ban ability is not set. Allow these abilities to be manipulated + if((*ra_it)->mPowerBit == GP_MEMBER_EJECT) + { + row["enabled"] = true; + } + else if((*ra_it)->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + row["enabled"] = true; + } + } + LLScrollListItem* item = ctrl->addElement(row, ADD_BOTTOM, (*ra_it)); if (-1 != check_box_index) @@ -712,6 +763,15 @@ void LLPanelGroupSubTab::buildActionCategory(LLScrollListCtrl* ctrl, check->setTentative(TRUE); } } + + // Regardless of whether or not this ability is allowed by all or some, we want to prevent + // the group managers from accidentally disabling either of the two additional abilities + // tied with GP_GROUP_BAN_ACCESS. + if( (allowed_by_all & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS || + (allowed_by_some & GP_GROUP_BAN_ACCESS) == GP_GROUP_BAN_ACCESS) + { + mHasGroupBanPower = true; + } } } @@ -731,11 +791,8 @@ void LLPanelGroupSubTab::setFooterEnabled(BOOL enable) } } -//////////////////////////// -// LLPanelGroupMembersSubTab -//////////////////////////// - +// LLPanelGroupMembersSubTab ///////////////////////////////////////////// static LLPanelInjector t_panel_group_members_subtab("panel_group_members_subtab"); LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab() @@ -834,6 +891,13 @@ BOOL LLPanelGroupMembersSubTab::postBuildSubTab(LLView* root) mEjectBtn->setEnabled(FALSE); } + mBanBtn = parent->getChild("member_ban", recurse); + if(mBanBtn) + { + mBanBtn->setClickedCallback(onBanMember, this); + mBanBtn->setEnabled(FALSE); + } + return TRUE; } @@ -847,34 +911,6 @@ void LLPanelGroupMembersSubTab::setGroupID(const LLUUID& id) LLPanelGroupSubTab::setGroupID(id); } -void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id) -{ - if(mRolesList) mRolesList->deleteAllItems(); - if(mAssignedMembersList) mAssignedMembersList->deleteAllItems(); - if(mAllowedActionsList) mAllowedActionsList->deleteAllItems(); - - if(mRoleName) mRoleName->clear(); - if(mRoleDescription) mRoleDescription->clear(); - if(mRoleTitle) mRoleTitle->clear(); - - mHasRoleChange = FALSE; - - setFooterEnabled(FALSE); - - LLPanelGroupSubTab::setGroupID(id); -} -void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id) -{ - if(mActionList) mActionList->deleteAllItems(); - if(mActionRoles) mActionRoles->deleteAllItems(); - if(mActionMembers) mActionMembers->deleteAllItems(); - - if(mActionDescription) mActionDescription->clear(); - - LLPanelGroupSubTab::setGroupID(id); -} - - // static void LLPanelGroupMembersSubTab::onMemberSelect(LLUICtrl* ctrl, void* user_data) { @@ -903,7 +939,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() // Build a vector of all selected members, and gather allowed actions. uuid_vec_t selected_members; - U64 allowed_by_all = 0xffffffffffffLL; + U64 allowed_by_all = GP_ALL_POWERS; //0xFFFFffffFFFFffffLL; U64 allowed_by_some = 0; std::vector::iterator itor; @@ -940,8 +976,8 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() LLGroupMgrGroupData::role_list_t::iterator iter = gdatap->mRoles.begin(); LLGroupMgrGroupData::role_list_t::iterator end = gdatap->mRoles.end(); - BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID, - GP_MEMBER_EJECT); + BOOL can_ban_members = gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS); + BOOL can_eject_members = gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT); BOOL member_is_owner = FALSE; for( ; iter != end; ++iter) @@ -988,6 +1024,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() { // Can't remove other owners. cb_enable = FALSE; + can_ban_members = FALSE; break; } } @@ -1007,14 +1044,14 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() } // If anyone selected is in any role besides 'Everyone' then they can't be ejected. - if (role_id.notNull() && (count > 0)) - { + if (role_id.notNull() && (count > 0)) + { can_eject_members = FALSE; - if (role_id == gdatap->mOwnerRole) - { - member_is_owner = TRUE; - } - } + if (role_id == gdatap->mOwnerRole) + { + member_is_owner = TRUE; + } + } LLRoleData rd; if (gdatap->getRoleData(role_id,rd)) @@ -1071,7 +1108,10 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() mAssignedRolesList->setEnabled(TRUE); if (gAgent.isGodlike()) + { can_eject_members = TRUE; + // can_ban_members = TRUE; + } if (!can_eject_members && !member_is_owner) { @@ -1084,10 +1124,41 @@ void LLPanelGroupMembersSubTab::handleMemberSelect() if ( member_data && member_data->isInRole(gdatap->mOwnerRole) ) { can_eject_members = TRUE; + //can_ban_members = TRUE; } } + + } + + // ... or we can eject them because we have all the requisite powers... + if( gAgent.hasPowerInGroup(mGroupID, GP_ROLE_REMOVE_MEMBER) && + !member_is_owner) + { + if( gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_EJECT)) + { + can_eject_members = TRUE; + } + + if( gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + can_ban_members = TRUE; + } } + + uuid_vec_t::const_iterator member_iter = selected_members.begin(); + uuid_vec_t::const_iterator member_end = selected_members.end(); + for ( ; member_iter != member_end; ++member_iter) + { + // Don't count the agent. + if ((*member_iter) == gAgent.getID()) + { + can_eject_members = FALSE; + can_ban_members = FALSE; + } + } + + mBanBtn->setEnabled(can_ban_members); mEjectBtn->setEnabled(can_eject_members); } @@ -1125,61 +1196,26 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata) } void LLPanelGroupMembersSubTab::handleEjectMembers() -{ +{ + //send down an eject message + uuid_vec_t selected_members; + std::vector selection = mMembersList->getAllSelected(); if (selection.empty()) return; - - S32 selection_count = selection.size(); - if (selection_count == 1) - { - LLSD args; - LLUUID selected_avatar = mMembersList->getValue().asUUID(); - std::string fullname = LLSLURL("agent", selected_avatar, "inspect").getSLURLString(); - args["AVATAR_NAME"] = fullname; - LLSD payload; - LLNotificationsUtil::add("EjectGroupMemberWarning", - args, - payload, - boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2)); - } - else - { - LLSD args; - args["COUNT"] = llformat("%d", selection_count); - LLSD payload; - LLNotificationsUtil::add("EjectGroupMembersWarning", - args, - payload, - boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2)); - } -} -bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - if (0 == option) // Eject button + std::vector::iterator itor; + for (itor = selection.begin() ; + itor != selection.end(); ++itor) { - //send down an eject message - uuid_vec_t selected_members; - - std::vector selection = mMembersList->getAllSelected(); - if (selection.empty()) return false; - - std::vector::iterator itor; - for (itor = selection.begin() ; - itor != selection.end(); ++itor) - { - LLUUID member_id = (*itor)->getUUID(); - selected_members.push_back( member_id ); - } - - mMembersList->deleteSelectedItems(); - - sendEjectNotifications(mGroupID, selected_members); - - LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members); + LLUUID member_id = (*itor)->getUUID(); + selected_members.push_back( member_id ); } - return false; + + mMembersList->deleteSelectedItems(); + + sendEjectNotifications(mGroupID, selected_members); + + LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members); } void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members) @@ -1191,7 +1227,9 @@ void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, c for (uuid_vec_t::const_iterator i = selected_members.begin(); i != selected_members.end(); ++i) { LLSD args; - args["AVATAR_NAME"] = LLSLURL("agent", *i, "displayname").getSLURLString(); + // Always show complete name in rights confirmation dialogs + //args["AVATAR_NAME"] = LLSLURL("agent", *i, "displayname").getSLURLString(); + args["AVATAR_NAME"] = LLSLURL("agent", *i, "completename").getSLURLString(); args["GROUP_NAME"] = group_data->mName; LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args)); @@ -1207,12 +1245,11 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, //add that the user is requesting to change the roles for selected //members - U64 powers_all_have = 0xffffffffffffLL; + U64 powers_all_have = GP_ALL_POWERS; U64 powers_some_have = 0; BOOL is_owner_role = ( gdatap->mOwnerRole == role_id ); LLUUID member_id; - std::vector selection = mMembersList->getAllSelected(); if (selection.empty()) @@ -1223,7 +1260,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, for (std::vector::iterator itor = selection.begin() ; itor != selection.end(); ++itor) { - member_id = (*itor)->getUUID(); //see if we requested a change for this member before @@ -1289,7 +1325,6 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id, FALSE); } - // static void LLPanelGroupMembersSubTab::onRoleCheck(LLUICtrl* ctrl, void* user_data) { @@ -1328,6 +1363,15 @@ void LLPanelGroupMembersSubTab::activate() update(GC_ALL); mActivated = true; } + else + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + // Members can be removed outside of this tab, checking changes + if (!gdatap || (gdatap->isMemberDataComplete() && gdatap->mMembers.size() != mMembersList->getItemCount())) + { + update(GC_MEMBER_DATA); + } + } } void LLPanelGroupMembersSubTab::deactivate() @@ -1697,7 +1741,7 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemb // trying to avoid unnecessary hash lookups // FIRE-11350 //if (matchesSearchFilter(av_name.getAccountName())) - if (matchesSearchFilter(av_name.getUserName())) + if (matchesSearchFilter(av_name.getCompleteName())) // { addMemberToList(member); @@ -1731,13 +1775,12 @@ void LLPanelGroupMembersSubTab::updateMembers() return; } - //cleanup list only for first iretation + //cleanup list only for first iteration if(mMemberProgress == gdatap->mMembers.begin()) { mMembersList->deleteAllItems(); } - LLGroupMgrGroupData::member_list_t::iterator end = gdatap->mMembers.end(); LLTimer update_time; @@ -1754,7 +1797,7 @@ void LLPanelGroupMembersSubTab::updateMembers() { // FIRE-11350 //if (matchesSearchFilter(av_name.getAccountName())) - if (matchesSearchFilter(av_name.getUserName())) + if (matchesSearchFilter(av_name.getCompleteName())) // { addMemberToList(mMemberProgress->second); @@ -1806,6 +1849,12 @@ void LLPanelGroupMembersSubTab::updateMembers() handleMemberSelect(); } +void LLPanelGroupMembersSubTab::onBanMember(void* user_data) +{ + LLPanelGroupMembersSubTab* self = static_cast(user_data); + self->handleBanMember(); +} + // [FS:CR] FIRE-12276 void LLPanelGroupMembersSubTab::onExportMembersToXML() { @@ -1824,7 +1873,7 @@ void LLPanelGroupMembersSubTab::onExportMembersToXML() LLAPRFile::tFiletype* file = outfile.getFileHandle(); if (!file) return; - apr_file_printf(file, "Group membership record for %s", gdatap->mName.c_str()); + apr_file_printf(file, "Group membership record for %s (avatar key, avatar name, last online, land contribution)", gdatap->mName.c_str()); LLSD memberlist; for (LLGroupMgrGroupData::member_list_t::const_iterator member_itr = gdatap->mMembers.begin(); @@ -1836,20 +1885,48 @@ void LLPanelGroupMembersSubTab::onExportMembersToXML() /// When the group membership is fully loaded, this works fine as is. LLAvatarName av_name; LLAvatarNameCache::get(member_itr->first, &av_name); - apr_file_printf(file, "\n%s,%s,%s", + apr_file_printf(file, "\n%s,%s,%s,%s", member_itr->first.asString().c_str(), av_name.getCompleteName().c_str(), - member_itr->second->getOnlineStatus().c_str()); + member_itr->second->getOnlineStatus().c_str(), + llformat("%d", member_itr->second->getContribution()).c_str()); } apr_file_printf(file, "\n"); } // [/FS:CR] FIRE-12276 +void LLPanelGroupMembersSubTab::handleBanMember() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } -//////////////////////////// -// LLPanelGroupRolesSubTab -//////////////////////////// + std::vector selection = mMembersList->getAllSelected(); + if(selection.empty()) + { + return; + } + uuid_vec_t ban_ids; + std::vector::iterator itor; + for(itor = selection.begin(); itor != selection.end(); ++itor) + { + LLUUID ban_id = (*itor)->getUUID(); + ban_ids.push_back(ban_id); + + LLGroupBanData ban_data; + gdatap->createBanEntry(ban_id, ban_data); + } + + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_CREATE, ban_ids); + handleEjectMembers(); +} + + +// LLPanelGroupRolesSubTab /////////////////////////////////////////////// static LLPanelInjector t_panel_group_roles_subtab("panel_group_roles_subtab"); LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() @@ -1863,7 +1940,7 @@ LLPanelGroupRolesSubTab::LLPanelGroupRolesSubTab() mMemberVisibleCheck(NULL), mDeleteRoleButton(NULL), mCreateRoleButton(NULL), - + mFirstOpen(TRUE), mHasRoleChange(FALSE) { } @@ -1965,6 +2042,7 @@ void LLPanelGroupRolesSubTab::deactivate() LL_DEBUGS() << "LLPanelGroupRolesSubTab::deactivate()" << LL_ENDL; LLPanelGroupSubTab::deactivate(); + mFirstOpen = FALSE; } bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg) @@ -1972,6 +2050,12 @@ bool LLPanelGroupRolesSubTab::needsApply(std::string& mesg) LL_DEBUGS() << "LLPanelGroupRolesSubTab::needsApply()" << LL_ENDL; LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + LL_WARNS() << "Unable to get group data for group " << mGroupID << LL_ENDL; + return false; + } + return (mHasRoleChange // Text changed in current role || (gdatap && gdatap->pendingRoleChanges())); // Pending role changes in the group @@ -1982,7 +2066,7 @@ bool LLPanelGroupRolesSubTab::apply(std::string& mesg) LL_DEBUGS() << "LLPanelGroupRolesSubTab::apply()" << LL_ENDL; saveRoleChanges(true); - + mFirstOpen = FALSE; LLGroupMgr::getInstance()->sendGroupRoleChanges(mGroupID); notifyObservers(); @@ -2119,14 +2203,17 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) } } - if (!gdatap || !gdatap->isMemberDataComplete()) + if(!mFirstOpen) { - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); - } - - if (!gdatap || !gdatap->isRoleMemberDataComplete()) - { - LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + if (!gdatap || !gdatap->isMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); + } + + if (!gdatap || !gdatap->isRoleMemberDataComplete()) + { + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(mGroupID); + } } if ((GC_ROLE_MEMBER_DATA == gc || GC_MEMBER_DATA == gc) @@ -2142,6 +2229,9 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) void LLPanelGroupRolesSubTab::onRoleSelect(LLUICtrl* ctrl, void* user_data) { LLPanelGroupRolesSubTab* self = static_cast(user_data); + if (!self) + return; + self->handleRoleSelect(); } @@ -2321,41 +2411,116 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force) LLRoleAction* rap = (LLRoleAction*)action_item->getUserdata(); U64 power = rap->mPowerBit; - if (check->get()) + bool isEnablingAbility = check->get(); + LLRoleData rd; + LLSD args; + + if (isEnablingAbility && + !force && + ((GP_ROLE_ASSIGN_MEMBER == power) || (GP_ROLE_CHANGE_ACTIONS == power) )) { - if (!force && ( (GP_ROLE_ASSIGN_MEMBER == power) - || (GP_ROLE_CHANGE_ACTIONS == power) )) + // Uncheck the item, for now. It will be + // checked if they click 'Yes', below. + check->set(FALSE); + + LLRoleData rd; + LLSD args; + + if ( gdatap->getRoleData(role_id, rd) ) { - // Uncheck the item, for now. It will be - // checked if they click 'Yes', below. - check->set(FALSE); - - LLRoleData rd; - LLSD args; - - if ( gdatap->getRoleData(role_id, rd) ) + args["ACTION_NAME"] = rap->mDescription; + args["ROLE_NAME"] = rd.mRoleName; + mHasModal = TRUE; + std::string warning = "AssignDangerousActionWarning"; + if (GP_ROLE_CHANGE_ACTIONS == power) { - args["ACTION_NAME"] = rap->mDescription; - args["ROLE_NAME"] = rd.mRoleName; - mHasModal = TRUE; - std::string warning = "AssignDangerousActionWarning"; - if (GP_ROLE_CHANGE_ACTIONS == power) - { - warning = "AssignDangerousAbilityWarning"; - } - LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check)); - } - else - { - LL_WARNS() << "Unable to look up role information for role id: " - << role_id << LL_ENDL; + warning = "AssignDangerousAbilityWarning"; } + LLNotificationsUtil::add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check)); } else { - gdatap->addRolePower(role_id,power); + LL_WARNS() << "Unable to look up role information for role id: " + << role_id << LL_ENDL; } } + + if(GP_GROUP_BAN_ACCESS == power) + { + std::string warning = isEnablingAbility ? "AssignBanAbilityWarning" : "RemoveBanAbilityWarning"; + + ////////////////////////////////////////////////////////////////////////// + // Get role data for both GP_ROLE_REMOVE_MEMBER and GP_MEMBER_EJECT + // Add description and role name to LLSD + // Pop up dialog saying "Yo, you also granted these other abilities when you did this!" + if ( gdatap->getRoleData(role_id, rd) ) + { + args["ACTION_NAME"] = rap->mDescription; + args["ROLE_NAME"] = rd.mRoleName; + mHasModal = TRUE; + + std::vector all_data = mAllowedActionsList->getAllData(); + std::vector::iterator ad_it = all_data.begin(); + std::vector::iterator ad_end = all_data.end(); + LLRoleAction* adp; + for( ; ad_it != ad_end; ++ad_it) + { + adp = (LLRoleAction*)(*ad_it)->getUserdata(); + if(adp->mPowerBit == GP_MEMBER_EJECT) + { + args["ACTION_NAME_2"] = adp->mDescription; + } + else if(adp->mPowerBit == GP_ROLE_REMOVE_MEMBER) + { + args["ACTION_NAME_3"] = adp->mDescription; + } + } + + LLNotificationsUtil::add(warning, args); + } + else + { + LL_WARNS() << "Unable to look up role information for role id: " + << role_id << LL_ENDL; + } + + ////////////////////////////////////////////////////////////////////////// + + LLGroupMgrGroupData::role_list_t::iterator rit = gdatap->mRoles.find(role_id); + U64 current_role_powers = GP_NO_POWERS; + if (rit != gdatap->mRoles.end()) + { + current_role_powers = ((*rit).second->getRoleData().mRolePowers); + } + + if(isEnablingAbility) + { + power |= (GP_ROLE_REMOVE_MEMBER | GP_MEMBER_EJECT); + current_role_powers |= power; + } + else + { + current_role_powers &= ~GP_GROUP_BAN_ACCESS; + } + + mAllowedActionsList->deleteAllItems(); + buildActionsList( mAllowedActionsList, + current_role_powers, + current_role_powers, + boost::bind(&LLPanelGroupRolesSubTab::handleActionCheck, this, _1, false), + TRUE, + FALSE, + FALSE); + + } + + ////////////////////////////////////////////////////////////////////////// + // Adding non-specific ability to role + ////////////////////////////////////////////////////////////////////////// + if(isEnablingAbility) + { + gdatap->addRolePower(role_id, power); + } else { gdatap->removeRolePower(role_id,power); @@ -2363,6 +2528,7 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLUICtrl* ctrl, bool force) mHasRoleChange = TRUE; notifyObservers(); + } bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check) @@ -2382,7 +2548,6 @@ bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& return false; } - // static void LLPanelGroupRolesSubTab::onPropertiesKey(LLLineEditor* ctrl, void* user_data) { @@ -2560,13 +2725,28 @@ void LLPanelGroupRolesSubTab::saveRoleChanges(bool select_saved_role) mHasRoleChange = FALSE; } } -//////////////////////////// -// LLPanelGroupActionsSubTab -//////////////////////////// +void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id) +{ + if(mRolesList) mRolesList->deleteAllItems(); + if(mAssignedMembersList) mAssignedMembersList->deleteAllItems(); + if(mAllowedActionsList) mAllowedActionsList->deleteAllItems(); + + if(mRoleName) mRoleName->clear(); + if(mRoleDescription) mRoleDescription->clear(); + if(mRoleTitle) mRoleTitle->clear(); + + mHasRoleChange = FALSE; + + setFooterEnabled(FALSE); + + LLPanelGroupSubTab::setGroupID(id); +} + + +// LLPanelGroupActionsSubTab ///////////////////////////////////////////// static LLPanelInjector t_panel_group_actions_subtab("panel_group_actions_subtab"); - LLPanelGroupActionsSubTab::LLPanelGroupActionsSubTab() : LLPanelGroupSubTab() { @@ -2739,34 +2919,299 @@ void LLPanelGroupActionsSubTab::handleActionSelect() } } -void LLPanelGroupRoles::setGroupID(const LLUUID& id) +void LLPanelGroupActionsSubTab::setGroupID(const LLUUID& id) { - LLPanelGroupTab::setGroupID(id); - - LLPanelGroupMembersSubTab* group_members_tab = findChild("members_sub_tab"); - LLPanelGroupRolesSubTab* group_roles_tab = findChild("roles_sub_tab"); - LLPanelGroupActionsSubTab* group_actions_tab = findChild("actions_sub_tab"); + if(mActionList) mActionList->deleteAllItems(); + if(mActionRoles) mActionRoles->deleteAllItems(); + if(mActionMembers) mActionMembers->deleteAllItems(); - if(group_members_tab) group_members_tab->setGroupID(id); - if(group_roles_tab) group_roles_tab->setGroupID(id); - if(group_actions_tab) group_actions_tab->setGroupID(id); + if(mActionDescription) mActionDescription->clear(); - LLButton* button = getChild("member_invite"); - if ( button ) - button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_INVITE)); - // [FS:CR] FIRE-12276 - button = getChild("export_list"); - if (button) - button->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_MEMBER_VISIBLE_IN_DIR)); - // [/FS:CR] - - if(mSubTabContainer) - // FIRE-13501: Activate "Members" tab by default - //mSubTabContainer->selectTab(1); - mSubTabContainer->selectTab(0); - // - - activate(); + LLPanelGroupSubTab::setGroupID(id); } +// LLPanelGroupBanListSubTab ///////////////////////////////////////////// +static LLPanelInjector t_panel_group_ban_subtab("panel_group_banlist_subtab"); +LLPanelGroupBanListSubTab::LLPanelGroupBanListSubTab() + : LLPanelGroupSubTab(), + mBanList(NULL), + mCreateBanButton(NULL), + mDeleteBanButton(NULL) +{} + +BOOL LLPanelGroupBanListSubTab::postBuildSubTab(LLView* root) +{ + LLPanelGroupSubTab::postBuildSubTab(root); + + // Upcast parent so we can ask it for sibling controls. + LLPanelGroupRoles* parent = (LLPanelGroupRoles*)root; + + // Look recursively from the parent to find all our widgets. + bool recurse = true; + + mHeader = parent->getChild("banlist_header", recurse); + mFooter = parent->getChild("banlist_footer", recurse); + + mBanList = parent->getChild("ban_list", recurse); + + mCreateBanButton = parent->getChild("ban_create", recurse); + mDeleteBanButton = parent->getChild("ban_delete", recurse); + mRefreshBanListButton = parent->getChild("ban_refresh", recurse); + mBanCountText = parent->getChild("ban_count", recurse); + + if(!mBanList || !mCreateBanButton || !mDeleteBanButton || !mRefreshBanListButton || !mBanCountText) + return FALSE; + + mBanList->setCommitOnSelectionChange(TRUE); + mBanList->setCommitCallback(onBanEntrySelect, this); + + mCreateBanButton->setClickedCallback(onCreateBanEntry, this); + mCreateBanButton->setEnabled(FALSE); + + mDeleteBanButton->setClickedCallback(onDeleteBanEntry, this); + mDeleteBanButton->setEnabled(FALSE); + + mRefreshBanListButton->setClickedCallback(onRefreshBanList, this); + mRefreshBanListButton->setEnabled(FALSE); + + setBanCount(0); + + // Fix Baker's NameListCtrl un-fix + //mBanList->setOnNameListCompleteCallback(boost::bind(&LLPanelGroupBanListSubTab::onBanListCompleted, this, _1)); + + populateBanList(); + + setFooterEnabled(FALSE); + return TRUE; +} + +void LLPanelGroupBanListSubTab::activate() +{ + LLPanelGroupSubTab::activate(); + + mBanList->deselectAllItems(); + mDeleteBanButton->setEnabled(FALSE); + + LLGroupMgrGroupData * group_datap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if (group_datap) + { + mCreateBanButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS) && + group_datap->mBanList.size() < GB_MAX_BANNED_AGENTS); + setBanCount(group_datap->mBanList.size()); + } + else + { + mCreateBanButton->setEnabled(FALSE); + setBanCount(0); + } + + // BAKER: Should I really request everytime activate() is called? + // Perhaps I should only do it on a force refresh, or if an action on the list happens... + // Because it's not going to live-update the list anyway... You'd have to refresh if you + // wanted to see someone else's additions anyway... + // + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); + + setFooterEnabled(FALSE); + update(GC_ALL); +} + +void LLPanelGroupBanListSubTab::update(LLGroupChange gc) +{ + populateBanList(); +} + +void LLPanelGroupBanListSubTab::draw() +{ + LLPanelGroupSubTab::draw(); + + // BAKER: Might be good to put it here instead of update, maybe.. See how often draw gets hit. + //if( + // populateBanList(); +} + +void LLPanelGroupBanListSubTab::onBanEntrySelect(LLUICtrl* ctrl, void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast(user_data); + if (!self) + return; + + self->handleBanEntrySelect(); +} + +void LLPanelGroupBanListSubTab::handleBanEntrySelect() +{ + if (gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + mDeleteBanButton->setEnabled(TRUE); + } +} + +void LLPanelGroupBanListSubTab::onCreateBanEntry(void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast(user_data); + if (!self) + return; + + self->handleCreateBanEntry(); +} + +void LLPanelGroupBanListSubTab::handleCreateBanEntry() +{ + LLFloaterGroupBulkBan::showForGroup(mGroupID); + //populateBanList(); +} + +void LLPanelGroupBanListSubTab::onDeleteBanEntry(void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast(user_data); + if (!self) + return; + + self->handleDeleteBanEntry(); +} + +void LLPanelGroupBanListSubTab::handleDeleteBanEntry() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } + + std::vector selection = mBanList->getAllSelected(); + if(selection.empty()) + { + return; + } + + bool can_ban_members = false; + if (gAgent.isGodlike() || + gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS)) + { + can_ban_members = true; + } + + // Owners can ban anyone in the group. + LLGroupMgrGroupData::member_list_t::iterator mi = gdatap->mMembers.find(gAgent.getID()); + if (mi != gdatap->mMembers.end()) + { + LLGroupMemberData* member_data = (*mi).second; + if ( member_data && member_data->isInRole(gdatap->mOwnerRole) ) + { + can_ban_members = true; + } + } + + if(!can_ban_members) + return; + + std::vector ban_ids; + std::vector::iterator itor; + for(itor = selection.begin(); itor != selection.end(); ++itor) + { + LLUUID ban_id = (*itor)->getUUID(); + ban_ids.push_back(ban_id); + + gdatap->removeBanEntry(ban_id); + mBanList->removeNameItem(ban_id); + + // Removing an item removes the selection, we shouldn't be able to click + // the button anymore until we reselect another entry. + mDeleteBanButton->setEnabled(FALSE); + } + + // update ban-count related elements + mCreateBanButton->setEnabled(TRUE); + setBanCount(gdatap->mBanList.size()); + + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_POST, mGroupID, LLGroupMgr::BAN_DELETE, ban_ids); +} + +void LLPanelGroupBanListSubTab::onRefreshBanList(void* user_data) +{ + LLPanelGroupBanListSubTab* self = static_cast(user_data); + if (!self) + return; + + self->handleRefreshBanList(); +} + +void LLPanelGroupBanListSubTab::handleRefreshBanList() +{ + mRefreshBanListButton->setEnabled(FALSE); + LLGroupMgr::getInstance()->sendGroupBanRequest(LLGroupMgr::REQUEST_GET, mGroupID); +} + +// Fix Baker's NameListCtrl un-fix +//void LLPanelGroupBanListSubTab::onBanListCompleted(bool isComplete) +//{ +// if(isComplete) +// { +// mRefreshBanListButton->setEnabled(TRUE); +// populateBanList(); +// } +//} +// + +void LLPanelGroupBanListSubTab::setBanCount(U32 ban_count) +{ + LLStringUtil::format_map_t args; + args["[COUNT]"] = llformat("%d", ban_count); + args["[LIMIT]"] = llformat("%d", GB_MAX_BANNED_AGENTS); + mBanCountText->setText(getString("ban_count_template", args)); +} + +void LLPanelGroupBanListSubTab::populateBanList() +{ + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID); + if(!gdatap) + { + LL_WARNS("Groups") << "Unable to get group data for group " << mGroupID << LL_ENDL; + return; + } + + mBanList->deleteAllItems(); + std::map::const_iterator entry = gdatap->mBanList.begin(); + for(; entry != gdatap->mBanList.end(); entry++) + { + LLNameListCtrl::NameItem ban_entry; + ban_entry.value = entry->first; + LLGroupBanData bd = entry->second; + + ban_entry.columns.add().column("name").font.name("SANSSERIF_SMALL").style("NORMAL"); + + // Check out utc_to_pacific_time() + + std::string ban_date_str = bd.mBanDate.toHTTPDateString("%Y/%m/%d"); + time_t utc_time; + utc_time = time_corrected(); + LLSD substitution; + substitution["datetime"] = (S32) utc_time; + LLStringUtil::format (ban_date_str, substitution); + + LL_INFOS("BAKER") << "[BAKER] BAN_DATE: " << bd.mBanDate.toHTTPDateString("%Y/%m/%d") << LL_ENDL; + LL_INFOS("BAKER") << "[BAKER] BAN_DATE_MODIFIED: " << ban_date_str << LL_ENDL; + + //ban_entry.columns.add().column("ban_date").value(ban_date_str.font.name("SANSSERIF_SMALL").style("NORMAL"); + ban_entry.columns.add().column("ban_date").value(bd.mBanDate.toHTTPDateString("%Y/%m/%d")).font.name("SANSSERIF_SMALL").style("NORMAL"); + + mBanList->addNameItemRow(ban_entry); + } + + mRefreshBanListButton->setEnabled(TRUE); + mCreateBanButton->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_GROUP_BAN_ACCESS) && + gdatap->mBanList.size() < GB_MAX_BANNED_AGENTS); + setBanCount(gdatap->mBanList.size()); +} + +void LLPanelGroupBanListSubTab::setGroupID(const LLUUID& id) +{ + if(mBanList) + mBanList->deleteAllItems(); + + setFooterEnabled(FALSE); + LLPanelGroupSubTab::setGroupID(id); +} diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h index 86499fa69f..a174b00657 100755 --- a/indra/newview/llpanelgrouproles.h +++ b/indra/newview/llpanelgrouproles.h @@ -39,11 +39,9 @@ class LLScrollListCtrl; class LLScrollListItem; class LLTextEditor; -// Forward declare for friend usage. -//virtual BOOL LLPanelGroupSubTab::postBuildSubTab(LLView*); - typedef std::map icon_map_t; + class LLPanelGroupRoles : public LLPanelGroupTab { public: @@ -92,6 +90,7 @@ protected: std::string mWantApplyMesg; }; + class LLPanelGroupSubTab : public LLPanelGroupTab { public: @@ -143,10 +142,14 @@ protected: icon_map_t mActionIcons; bool mActivated; - + + bool mHasGroupBanPower; // Used to communicate between action sets due to the dependency between + // GP_GROUP_BAN_ACCESS and GP_EJECT_MEMBER and GP_ROLE_REMOVE_MEMBER + void setOthersVisible(BOOL b); }; + class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab { public: @@ -173,6 +176,10 @@ public: void handleRoleCheck(const LLUUID& role_id, LLRoleMemberChangeType type); + static void onBanMember(void* user_data); + void handleBanMember(); + + void applyMemberChanges(); bool addOwnerCB(const LLSD& notification, const LLSD& response); @@ -209,6 +216,7 @@ protected: LLScrollListCtrl* mAssignedRolesList; LLScrollListCtrl* mAllowedActionsList; LLButton* mEjectBtn; + LLButton* mBanBtn; BOOL mChanged; BOOL mPendingMemberUpdate; @@ -229,6 +237,7 @@ private: void onExportMembersToXML(); }; + class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab { public: @@ -251,7 +260,7 @@ public: static void onActionCheck(LLUICtrl*, void*); bool addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check); - + static void onPropertiesKey(LLLineEditor*, void*); void onDescriptionKeyStroke(LLTextEditor* caller); @@ -270,6 +279,9 @@ public: void saveRoleChanges(bool select_saved_role); virtual void setGroupID(const LLUUID& id); + + BOOL mFirstOpen; + protected: void handleActionCheck(LLUICtrl* ctrl, bool force); LLSD createRoleItem(const LLUUID& role_id, std::string name, std::string title, S32 members); @@ -291,6 +303,7 @@ protected: std::string mRemoveEveryoneTxt; }; + class LLPanelGroupActionsSubTab : public LLPanelGroupSubTab { public: @@ -318,4 +331,47 @@ protected: }; +class LLPanelGroupBanListSubTab : public LLPanelGroupSubTab +{ +public: + LLPanelGroupBanListSubTab(); + virtual ~LLPanelGroupBanListSubTab() {} + + virtual BOOL postBuildSubTab(LLView* root); + + virtual void activate(); + virtual void update(LLGroupChange gc); + virtual void draw(); + + static void onBanEntrySelect(LLUICtrl* ctrl, void* user_data); + void handleBanEntrySelect(); + + static void onCreateBanEntry(void* user_data); + void handleCreateBanEntry(); + + static void onDeleteBanEntry(void* user_data); + void handleDeleteBanEntry(); + + static void onRefreshBanList(void* user_data); + void handleRefreshBanList(); + + // Fix Baker's NameListCtrl un-fix + //void onBanListCompleted(bool isComplete); + +protected: + void setBanCount(U32 ban_count); + void populateBanList(); + +public: + virtual void setGroupID(const LLUUID& id); + +protected: + LLNameListCtrl* mBanList; + LLButton* mCreateBanButton; + LLButton* mDeleteBanButton; + LLButton* mRefreshBanListButton; + LLTextBase* mBanCountText; + +}; + #endif // LL_LLPANELGROUPROLES_H diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 11151575c4..f3e30c70b7 100755 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -663,7 +663,21 @@ void LLPanelLogin::getFields(LLPointer& credential, { // Be lenient in terms of what separators we allow for two-word names // and allow legacy users to login with firstname.lastname + // FIRE-15116: Usernames with underscores don't work on OpenSim + //separator_index = username.find_first_of(" ._"); +#ifdef OPENSIM + if (LLGridManager::getInstance()->isInSecondLife()) + { + separator_index = username.find_first_of(" ._"); + } + else + { + separator_index = username.find_first_of(" ."); + } +#else separator_index = username.find_first_of(" ._"); +#endif + // std::string first = username.substr(0, separator_index); std::string last; if (separator_index != username.npos) @@ -1095,6 +1109,12 @@ void LLPanelLogin::updateServer() // grid changed so show new splash screen (possibly) updateServerCombo(); loadLoginPage(); + + // FIRE-12905: Allow longer passwords in OpenSim +#ifdef OPENSIM + sInstance->getChild("password_edit")->setMaxTextLength(LLGridManager::getInstance()->isInSecondLife() ? 16 : 255); +#endif + // } catch (LLInvalidGridName ex) { diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 5257fd1169..9a633c67be 100755 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -1036,7 +1036,10 @@ void LLPanelPeople::updateButtons() cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected); } - if (!group_tab_active) + // Fix warning about missing gear button on blocklist panel + //if (!group_tab_active) + if (!group_tab_active && cur_tab != BLOCKED_TAB_NAME) + // { cur_panel->getChildView("gear_btn")->setEnabled(multiple_selected); } @@ -1580,6 +1583,17 @@ void LLPanelPeople::onOpen(const LLSD& key) std::string tab_name = key["people_panel_tab_name"]; if (!tab_name.empty()) mTabContainer->selectTabByName(tab_name); + + // Call onOpen for the blocklist panel to select mute if necessary + if (tab_name == "blocked_panel") + { + LLPanel* blocklist_impl_panel = mTabContainer->getCurrentPanel()->findChild("panel_block_list_sidetray"); + if (blocklist_impl_panel) + { + blocklist_impl_panel->onOpen(key); + } + } + // } bool LLPanelPeople::notifyChildren(const LLSD& info) diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index d4b6dfe503..7425a8d267 100755 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -500,8 +500,9 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel, gCacheName->getGroup(parcel->getGroupID(), boost::bind(&LLPanelPlaceInfo::onNameCache, mRegionGroupText, _2)); - gCacheName->getGroup(parcel->getGroupID(), - boost::bind(&LLPanelPlaceInfo::onNameCache, mParcelOwner, _2)); + std::string owner = + LLSLURL("group", parcel->getGroupID(), "inspect").getSLURLString(); + mParcelOwner->setText(owner); } else { diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 0420706f66..449989d8d3 100755 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -200,7 +200,10 @@ public: { if (params.size() > 2) { - const std::string object_name = params[2].asString(); + // FIRE-14987: Cannot mute objects with slashes in their name via V1 chat history + //const std::string object_name = params[2].asString(); + const std::string object_name = LLURI::unescape(params[2].asString()); + // LLMute mute(avatar_id, object_name, LLMute::OBJECT); LLMuteList::getInstance()->add(mute); LLPanelBlockedList::showPanelAndSelect(mute.mID); diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 3264c4ee8f..d543e4c029 100755 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -400,7 +400,10 @@ LLScriptEdCore::LLScriptEdCore( const std::string& sample, const LLHandle& floater_handle, void (*load_callback)(void*), - void (*save_callback)(void*, BOOL), + // FIRE-7514: Script in external editor needs to be saved twice + //void (*save_callback)(void*, BOOL), + void (*save_callback)(void*, BOOL, bool), + // void (*search_replace_callback) (void* userdata), void* userdata, S32 bottom_pad) @@ -620,7 +623,10 @@ void LLScriptEdCore::initMenu() LLMenuItemCallGL* menuItem; menuItem = getChild("Save"); - menuItem->setClickCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE)); + // FIRE-7514: Script in external editor needs to be saved twice + //menuItem->setClickCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE)); + menuItem->setClickCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE, true)); + // menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::hasChanged, this)); menuItem = getChild("Revert All Changes"); @@ -685,8 +691,8 @@ void LLScriptEdCore::initMenu() void LLScriptEdCore::initButtonBar() { - mSaveBtn->setClickedCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE)); - mSaveBtn2->setClickedCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE)); // support extra save button + mSaveBtn->setClickedCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE, true)); + mSaveBtn2->setClickedCallback(boost::bind(&LLScriptEdCore::doSave, this, FALSE, true)); // support extra save button mCutBtn->setClickedCallback(boost::bind(&LLTextEditor::cut, mEditor)); mCopyBtn->setClickedCallback(boost::bind(&LLTextEditor::copy, mEditor)); mPasteBtn->setClickedCallback(boost::bind(&LLTextEditor::paste, mEditor)); @@ -1197,26 +1203,29 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata) self->setHelpPage(self->mFunctions->getSimple()); } -void LLScriptEdCore::doSave( BOOL close_after_save ) +// FIRE-7514: Script in external editor needs to be saved twice +//void LLScriptEdCore::doSave( BOOL close_after_save ) +void LLScriptEdCore::doSave(BOOL close_after_save, bool sync /*= true*/) +// { // NaCl - LSL Preprocessor if (mLSLProc && gSavedSettings.getBOOL("_NACL_LSLPreprocessor")) { LL_INFOS() << "passing to preproc" << LL_ENDL; - mLSLProc->preprocess_script(close_after_save); + mLSLProc->preprocess_script(close_after_save, sync); } else { if( mSaveCallback ) { - mSaveCallback( mUserdata, close_after_save ); + mSaveCallback( mUserdata, close_after_save, sync ); } } // NaCl End } // NaCl - LSL Preprocessor -void LLScriptEdCore::doSaveComplete( void* userdata, BOOL close_after_save ) +void LLScriptEdCore::doSaveComplete( void* userdata, BOOL close_after_save, bool sync) { add( LLStatViewer::LSL_SAVES,1 ); @@ -1224,7 +1233,7 @@ void LLScriptEdCore::doSaveComplete( void* userdata, BOOL close_after_save ) if( mSaveCallback ) { - mSaveCallback( mUserdata, close_after_save ); + mSaveCallback( mUserdata, close_after_save, sync ); } } // NaCl End @@ -1474,7 +1483,10 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata ) std::ofstream fout(filename.c_str()); fout<<(scriptText); fout.close(); - self->mSaveCallback( self->mUserdata, FALSE ); + // FIRE-7514: Script in external editor needs to be saved twice + //self->mSaveCallback( self->mUserdata, FALSE ); + self->mSaveCallback( self->mUserdata, FALSE, true ); + // } } } @@ -1597,8 +1609,14 @@ bool LLScriptEdContainer::onExternalChange(const std::string& filename) } // Disable sync to avoid recursive load->save->load calls. - mScriptEd->doSave(FALSE); - saveIfNeeded(false); + // LSL preprocessor + // Ansariel: Don't call saveIfNeeded directly, as we might have to run the + // preprocessor first. saveIfNeeded will be invoked via callback. Make sure + // to pass sync = false - we don't need to update the external editor in this + // case or the next save will be ignored! + //saveIfNeeded(false); + mScriptEd->doSave(FALSE, false); + // return true; } @@ -1801,11 +1819,17 @@ void LLPreviewLSL::onLoad(void* userdata) } // static -void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save) +// FIRE-7514: Script in external editor needs to be saved twice +//void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save) +void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save, bool sync) +// { LLPreviewLSL* self = (LLPreviewLSL*)userdata; self->mCloseAfterSave = close_after_save; - self->saveIfNeeded(); + // FIRE-7514: Script in external editor needs to be saved twice + //self->saveIfNeeded(); + self->saveIfNeeded(sync); + // } // Save needs to compile the text in the buffer. If the compile @@ -2907,12 +2931,18 @@ void LLLiveLSLEditor::onLoad(void* userdata) } // static -void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save) +// FIRE-7514: Script in external editor needs to be saved twice +//void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save) +void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save, bool sync) +// { LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; self->mCloseAfterSave = close_after_save; - self->saveIfNeeded(); + // FIRE-7514: Script in external editor needs to be saved twice + //self->saveIfNeeded(); + self->saveIfNeeded(sync); + // } diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index d3e2d69325..49885bd0b3 100755 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -77,7 +77,10 @@ protected: const std::string& sample, const LLHandle& floater_handle, void (*load_callback)(void* userdata), - void (*save_callback)(void* userdata, BOOL close_after_save), + // FIRE-7514: Script in external editor needs to be saved twice + //void (*save_callback)(void* userdata, BOOL close_after_save), + void (*save_callback)(void* userdata, BOOL close_after_save, bool sync), + // void (*search_replace_callback)(void* userdata), void* userdata, S32 bottom_pad = 0); // pad below bottom row of buttons @@ -95,13 +98,16 @@ public: void setScriptText(const std::string& text, BOOL is_valid); // NaCL - LSL Preprocessor std::string getScriptText(); - void doSaveComplete(void* userdata, BOOL close_after_save ); + void doSaveComplete(void* userdata, BOOL close_after_save, bool sync); // NaCl End bool loadScriptText(const std::string& filename); bool writeToFile(const std::string& filename, bool unprocessed); void sync(); - void doSave( BOOL close_after_save ); + // FIRE-7514: Script in external editor needs to be saved twice + //void doSave( BOOL close_after_save ); + void doSave(BOOL close_after_save, bool sync = true); + // bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response); bool handleReloadFromServerDialog(const LLSD& notification, const LLSD& response); @@ -155,7 +161,10 @@ private: std::string mSampleText; LLTextEditor* mEditor; void (*mLoadCallback)(void* userdata); - void (*mSaveCallback)(void* userdata, BOOL close_after_save); + // FIRE-7514: Script in external editor needs to be saved twice + //void (*mSaveCallback)(void* userdata, BOOL close_after_save); + void (*mSaveCallback)(void* userdata, BOOL close_after_save, bool sync); + // void (*mSearchReplaceCallback) (void* userdata); void* mUserdata; LLComboBox *mFunctions; @@ -254,7 +263,10 @@ protected: static void onSearchReplace(void* userdata); static void onLoad(void* userdata); - static void onSave(void* userdata, BOOL close_after_save); + // FIRE-7514: Script in external editor needs to be saved twice + //static void onSave(void* userdata, BOOL close_after_save); + static void onSave(void* userdata, BOOL close_after_save, bool sync); + // static void onLoadComplete(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, @@ -327,7 +339,10 @@ private: static void onSearchReplace(void* userdata); static void onLoad(void* userdata); - static void onSave(void* userdata, BOOL close_after_save); + // FIRE-7514: Script in external editor needs to be saved twice + //static void onSave(void* userdata, BOOL close_after_save); + static void onSave(void* userdata, BOOL close_after_save, bool sync); + // static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid, LLAssetType::EType type, diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 7f56abb6ab..10a876f585 100755 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -490,6 +490,9 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vectoraddThisAndNonJointChildren(objects); addAsFamily(objects); + if( isBatchMode() ) + continue; + // Stop the object from moving (this anticipates changes on the // simulator in LLTask::userSelect) object->setVelocity(LLVector3::zero); @@ -498,6 +501,14 @@ LLObjectSelectionHandle LLSelectMgr::selectObjectAndFamily(const std::vectorresetRot(); } + if( isBatchMode() ) + { + mShowSelection = FALSE; + sendSelect(); + return mSelectedObjects; + } + + updateSelectionCenter(); saveSelectedObjectTransform(SELECT_ACTION_TYPE_PICK); updatePointAt(); @@ -1031,6 +1042,13 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject *objectp, LLColor4 const &a return; } + // FIRE-14593: Option to select only copyable objects + if (!objectp->permCopy() && gSavedSettings.getBOOL("FSSelectCopyableOnly")) + { + return; + } + // + // FIRE-304: Option to exclude group owned objects if (objectp->permGroupOwner() && !gSavedSettings.getBOOL("FSSelectIncludeGroupOwned")) { @@ -5336,6 +5354,10 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data node->mInventorySerial = inv_serial; node->mSitName.assign(sit_name); node->mTouchName.assign(touch_name); + + // Fire for any observer interested in object properties + LLSelectMgr::instance().firePropertyReceived( node ); + // } } @@ -6920,6 +6942,12 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) // only select my own objects return FALSE; } + // FIRE-14593: Option to select only copyable objects + if (!object->permCopy() && gSavedSettings.getBOOL("FSSelectCopyableOnly")) + { + return FALSE; + } + // // Can't select orphans if (object->isOrphaned()) return FALSE; @@ -7015,16 +7043,61 @@ S32 LLObjectSelection::getNumNodes() return mList.size(); } +// Fix for crash while selecting objects with derendered child prims +bool LLObjectSelection::checkNode(LLSelectNode* nodep) +{ + if(nodep) + { + if(nodep->getObject()) + { + if(!nodep->getObject()->isDead()) + { + return true; + } + else + { + LL_WARNS("LLObjectSelection") << "skipping dead node object" << LL_ENDL; + } + } + else + { + LL_WARNS("LLObjectSelection") << "skipping NULL node object pointer" << LL_ENDL; + } + mFailedNodesList.push_back(nodep); + } + else + { + LL_WARNS("LLObjectSelection") << "skipping NULL node" << LL_ENDL; + } + + return false; +} + // + void LLObjectSelection::addNode(LLSelectNode *nodep) { - llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + // Fix for crash while selecting objects with derendered child prims + // llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + if(!checkNode(nodep)) + { + return; + } + // + mList.push_front(nodep); mSelectNodeMap[nodep->getObject()] = nodep; } void LLObjectSelection::addNodeAtEnd(LLSelectNode *nodep) { - llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + // Fix for crash while selecting objects with derendered child prims + // llassert_always(nodep->getObject() && !nodep->getObject()->isDead()); + if(!checkNode(nodep)) + { + return; + } + // + mList.push_back(nodep); mSelectNodeMap[nodep->getObject()] = nodep; } @@ -7052,6 +7125,11 @@ void LLObjectSelection::deleteAllNodes() mList.clear(); mSelectNodeMap.clear(); mPrimaryObject = NULL; + + // Fix for crash while selecting objects with derendered child prims + std::for_each(mFailedNodesList.begin(),mFailedNodesList.end(),DeletePointer()); + mFailedNodesList.clear(); + // } LLSelectNode* LLObjectSelection::findNode(LLViewerObject* objectp) diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index a0dbf100db..ed24549961 100755 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -234,6 +234,11 @@ protected: LLPointer mObject; S32 mTESelectMask; S32 mLastTESelected; + +// For const access. Need to check for isDead yourself. +public: + LLViewerObject const* getObject() const { return mObject; } +// }; class LLObjectSelection : public LLRefCount @@ -380,6 +385,11 @@ private: LLPointer mPrimaryObject; std::map, LLSelectNode*> mSelectNodeMap; ESelectType mSelectType; + + // Fix for crash while selecting objects with derendered child prims + list_t mFailedNodesList; + bool checkNode(LLSelectNode* nodep); + // }; typedef LLSafeHandle LLObjectSelectionHandle; @@ -392,7 +402,47 @@ extern template class LLSelectMgr* LLSingleton::getInstance() // For use with getFirstTest() struct LLSelectGetFirstTest; -class LLSelectMgr : public LLEditMenuHandler, public LLSingleton +// To listened into received prop. messages +namespace nd +{ + namespace selection + { + class PropertiesListener + { + public: + virtual void onProperties( LLSelectNode const * ) = 0; + }; + + class PropertiesServer + { + public: + PropertiesServer() + : mBatchMode( false ) + { } + + void registerPropertyListener( nd::selection::PropertiesListener *aP) { mListener.insert( aP ); } + void removePropertyListener( nd::selection::PropertiesListener *aP) { mListener.erase( aP ); } + + void enableBatchMode( ) { mBatchMode = true; } + void disableBatchMode( ) { mBatchMode = false; } + bool isBatchMode() const { return mBatchMode; } + + protected: + void firePropertyReceived( LLSelectNode const *aNode ) + { + for( std::set< nd::selection::PropertiesListener * >::iterator itr = mListener.begin(); itr != mListener.end(); ++itr ) + (*itr)->onProperties( aNode ); + } + + private: + std::set< nd::selection::PropertiesListener * > mListener; + bool mBatchMode; + }; + } +} +// + +class LLSelectMgr : public LLEditMenuHandler, public LLSingleton, public nd::selection::PropertiesServer { public: static BOOL sRectSelectInclusive; // do we need to surround an object to pick it? diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 9022e2100c..4a4c9114ad 100755 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2845,14 +2845,6 @@ void login_show() } LLPanelLogin::show( gViewerWindow->getWindowRectScaled(), login_callback, NULL ); - - // "Did you know about Phoenix mode?" notification, showed once per installation - if (!gSavedSettings.getBOOL("FSVintageLoginInfo")) - { - gSavedSettings.setBOOL("FSVintageLoginInfo", TRUE); - LLNotificationsUtil::add("VintageLoginInfo"); - } - } // Callback for when login screen is closed. Option 0 = connect, option 1 = quit. diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index f3af33fb2e..c6bfa00c3c 100755 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -444,10 +444,11 @@ BOOL LLStatusBar::postBuild() // Hook up and init for filtering mFilterEdit = getChild("search_menu_edit"); mSearchPanel = getChild("menu_search_panel"); + mSearchPanel->setVisible(gSavedSettings.getBOOL("FSMenuSearch")); mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this)); mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this)); collectSearchableItems(); - gSavedSettings.getControl("FSMenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::update, this)); + gSavedSettings.getControl("FSMenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2)); // return TRUE; @@ -608,6 +609,7 @@ void LLStatusBar::setVisibleForMouselook(bool visible) mSGBandwidth->setVisible(visible && showNetStats); mSGPacketLoss->setVisible(visible && showNetStats); mBandwidthButton->setVisible(visible && showNetStats); // FIRE-6287: Clicking on traffic indicator toggles Lag Meter window + mSearchPanel->setVisible(visible && gSavedSettings.getBOOL("FSMenuSearch")); mTimeMediaPanel->setVisible(visible); setBackgroundVisible(visible); } @@ -1525,3 +1527,9 @@ void LLStatusBar::collectSearchableItems() mSearchData->mRootMenu = pItem; collectChildren( gMenuBarView, pItem ); } + +void LLStatusBar::updateMenuSearchVisibility(const LLSD& data) +{ + mSearchPanel->setVisible(data.asBoolean()); + update(); +} diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 0757c50a8d..7cb3a16d21 100755 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -383,6 +383,7 @@ private: nd::statusbar::SearchData *mSearchData; void collectSearchableItems(); + void updateMenuSearchVisibility(const LLSD& data); // }; diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 06b40a2a24..b6a578a0c2 100755 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -45,6 +45,7 @@ //#include "llfloaterimsession.h" #include "fsfloaterim.h" // [FS communication UI] +#include "llavataractions.h" const S32 BOTTOM_PAD = VPAD * 3; const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding @@ -507,6 +508,7 @@ void LLIMToastNotifyPanel::compactButtons() const child_list_t* children = getControlPanel()->getChildList(); S32 offset = 0; + S32 last_bottom = 0; // Fix stacked buttons offset // Children were added by addChild() which uses push_front to insert them into list, // so to get buttons in correct order reverse iterator is used (EXT-5906) for (child_list_t::const_reverse_iterator it = children->rbegin(); it != children->rend(); it++) @@ -514,6 +516,12 @@ void LLIMToastNotifyPanel::compactButtons() LLButton * button = dynamic_cast (*it); if (button != NULL) { + // Fix stacked buttons offset + if (last_bottom != button->getRect().mBottom) + { + offset = 0; + } + // button->setOrigin( offset,button->getRect().mBottom); button->setLeftHPad(2 * HPAD); button->setRightHPad(2 * HPAD); @@ -526,6 +534,8 @@ void LLIMToastNotifyPanel::compactButtons() button->autoResize(); offset += HPAD + button->getRect().getWidth(); button->setFollowsNone(); + // Fix stacked buttons offset + last_bottom = button->getRect().mBottom; } } diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index ac30b635ea..9224ba6b96 100755 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -83,8 +83,9 @@ LLToolBarView::LLToolBarView(const LLToolBarView::Params& p) // Member variables needed for console chat bottom offset //mBottomToolbarPanel(NULL) mBottomToolbarPanel(NULL), - mBottomChatStack(NULL) + mBottomChatStack(NULL), // Member variables needed for console chat bottom offset + mHideBottomOnEmpty(false) // Added to determine if toolbar gets hidden when empty { for (S32 i = 0; i < LLToolBarEnums::TOOLBAR_COUNT; i++) { @@ -128,6 +129,11 @@ BOOL LLToolBarView::postBuild() // Member variable needed for console chat bottom offset mBottomChatStack = findChild("bottom_chat_stack"); + // Added to determine if toolbar gets hidden when empty + std::string current_skin = gSavedSettings.getString("SkinCurrent"); + mHideBottomOnEmpty = (current_skin == "vintage" || current_skin == "latency"); + // + return TRUE; } @@ -603,7 +609,10 @@ void LLToolBarView::draw() for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++) { mToolbars[i]->getParent()->setVisible(mShowToolbars - && (mToolbars[i]->hasButtons() + // FIRE-5141: Nearby chat floater can no longer be resized when all buttons are removed from bottom FUI panel + //&& (mToolbars[i]->hasButtons() + && (((i == LLToolBarEnums::TOOLBAR_BOTTOM && !mHideBottomOnEmpty) ? true : mToolbars[i]->hasButtons()) + // || isToolDragged())); } @@ -629,6 +638,13 @@ void LLToolBarView::draw() void LLToolBarView::startDragTool(S32 x, S32 y, LLToolBarButton* toolbarButton) { + // Do not drag and drop when toolbars are locked + if(gSavedSettings.getBOOL("LockToolbars")) + { + return; + } + // + resetDragTool(toolbarButton); // Flag the tool dragging but don't start it yet @@ -637,6 +653,13 @@ void LLToolBarView::startDragTool(S32 x, S32 y, LLToolBarButton* toolbarButton) BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type) { + // Do not drag and drop when toolbars are locked + if(gSavedSettings.getBOOL("LockToolbars")) + { + return FALSE; + } + // + if (LLToolDragAndDrop::getInstance()->isOverThreshold( x, y )) { if (!gToolBarView->mDragStarted) @@ -670,6 +693,13 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar) { + // Do not drag and drop when toolbars are locked + if(gSavedSettings.getBOOL("LockToolbars")) + { + return FALSE; + } + // + BOOL handled = FALSE; LLInventoryObject* inv_item = static_cast(cargo_data); diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h index e0054e67d7..096c5c7dae 100755 --- a/indra/newview/lltoolbarview.h +++ b/indra/newview/lltoolbarview.h @@ -132,6 +132,9 @@ private: // Member variables needed for console chat bottom offset LLView* mBottomChatStack; // + + // Added to determine if toolbar gets hidden when empty + bool mHideBottomOnEmpty; }; extern LLToolBarView* gToolBarView; diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index a64d027818..3039bac5c1 100755 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -39,6 +39,7 @@ #include "llagentcamera.h" #include "llbutton.h" #include "llviewercontrol.h" +#include "llviewerkeyboard.h"// Mouse movement by Singularity #include "lldrawable.h" #include "lltooltip.h" #include "llhudmanager.h" @@ -314,9 +315,17 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } +static bool right_hold_mouse_walk = false;// Mouse movement by Singularity BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) { + // Mouse movement by Singularity + if (right_hold_mouse_walk) + { + agent_push_forward(KEYSTATE_LEVEL); + } + // + S32 dx = gViewerWindow->getCurrentMouseDX(); S32 dy = gViewerWindow->getCurrentMouseDY(); @@ -450,9 +459,39 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) return TRUE; } +// Mouse movement by Singularity +BOOL LLToolCamera::handleRightMouseDown(S32 x, S32 y, MASK mask) +{ + if (mMouseSteering) + { + agent_push_forward(KEYSTATE_DOWN); + right_hold_mouse_walk = true; + return TRUE; + } + else + { + return FALSE; + } +} +BOOL LLToolCamera::handleRightMouseUp(S32 x, S32 y, MASK mask) +{ + if (mMouseSteering || right_hold_mouse_walk) + { + agent_push_forward(KEYSTATE_UP); + right_hold_mouse_walk = false; + return TRUE; + } + else + { + return FALSE; + } +} +// void LLToolCamera::onMouseCaptureLost() { releaseMouse(); + // Mouse movement by Singularity + handleRightMouseUp(0,0,0); } diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h index b1ac42e33f..d88606cc09 100755 --- a/indra/newview/lltoolfocus.h +++ b/indra/newview/lltoolfocus.h @@ -41,6 +41,8 @@ public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleHover(S32 x, S32 y, MASK mask); + virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);// Mouse movement by Singularity + virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);// Mouse movement by Singularity virtual void onMouseCaptureLost(); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 8d638b2c0b..204247db17 100755 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -384,7 +384,10 @@ BOOL LLToolPie::handleLeftClickPick() } object = (LLViewerObject*)object->getParent(); } - if (object && object == gAgentAvatarp && !gSavedSettings.getBOOL("ClickToWalk")) + // FIRE-15189: Fix ClickToWalk not allowing mouse-walk (behavior change) + //if (object && object == gAgentAvatarp && !gSavedSettings.getBOOL("ClickToWalk")) + if (object && object == gAgentAvatarp) + // { // we left clicked on avatar, switch to focus mode mMouseButtonDown = false; @@ -1296,9 +1299,13 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l if (region) { LLVector3 relPositionObject = region->getPosRegionFromGlobal(hover_object->getPositionGlobal()); - args.clear(); - args["POSITION"] = llformat("<%.02f, %.02f, %.02f>", relPositionObject.mV[VX], relPositionObject.mV[VY], relPositionObject.mV[VZ]); - tooltip_msg.append("\n" + LLTrans::getString("TooltipPosition", args)); + + if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC)) + { + args.clear(); + args["POSITION"] = llformat("<%.02f, %.02f, %.02f>", relPositionObject.mV[VX], relPositionObject.mV[VY], relPositionObject.mV[VZ]); + tooltip_msg.append("\n" + LLTrans::getString("TooltipPosition", args)); + } // Get distance F32 distance = (relPositionObject - region->getPosRegionFromGlobal(gAgent.getPositionGlobal())).magVec(); diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index e7e45a45ce..c6c45d3a0f 100755 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -117,12 +117,16 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); + // FIRE-14593: Option to select only copyable objects + BOOL select_copyable = gSavedSettings.getBOOL("FSSelectCopyableOnly"); // *NOTE: These settings must be cleaned up at bottom of function. if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); gSavedSettings.setBOOL("SelectMovableOnly", FALSE); + // FIRE-14593: Option to select only copyable objects + gSavedSettings.setBOOL("FSSelectCopyableOnly", FALSE); LLSelectMgr::getInstance()->setForceSelection(TRUE); } @@ -257,6 +261,8 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi { gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); gSavedSettings.setBOOL("SelectMovableOnly", select_movable); + // FIRE-14593: Option to select only copyable objects + gSavedSettings.setBOOL("FSSelectCopyableOnly", select_copyable); LLSelectMgr::getInstance()->setForceSelection(FALSE); } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index da47c5c449..dcda17b211 100755 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -176,6 +176,7 @@ #include "fsfloaterteleporthistory.h" #include "fsfloatervoicecontrols.h" #include "fsfloatervolumecontrols.h" +#include "fsfloatervramusage.h" #include "fsfloaterwsassetblacklist.h" #include "fsmoneytracker.h" #include "fspanelclassified.h" @@ -187,6 +188,7 @@ #include "NACLfloaterexploresounds.h" #include "particleeditor.h" #include "quickprefs.h" + // handle secondlife:///app/openfloater/{NAME} URLs class LLFloaterOpenHandler : public LLCommandHandler { @@ -425,6 +427,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("secondary_inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("script_recover", "floater_script_recover.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("sound_explorer", "floater_NACL_explore_sounds.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add( "vram_usage", "floater_fs_vram_usage.xml", static_cast( &LLFloaterReg::build< FSFloaterVRAMUsage >) ); LLFloaterReg::add("ws_asset_blacklist", "floater_asset_blacklist.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::registerControlVariables(); // Make sure visibility and rect controls get preserved when saving diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index e5f1aed9d4..ba0585f8e7 100755 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -251,7 +251,17 @@ public: uuid_vec_t items_to_open; items_to_open.push_back(inventory_id); //inventory_handler is just a stub, because we don't know from who this offer - open_inventory_offer(items_to_open, "inventory_handler"); + // Moved check out of check_offer_throttle + //open_inventory_offer(items_to_open, "inventory_handler"); + if (gSavedSettings.getBOOL("ShowNewInventory")) + { + open_inventory_offer(items_to_open, "inventory_handler"); + } + else if (!items_to_open.empty() && gSavedSettings.getBOOL("ShowInInventory")) + { + LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, items_to_open.back()); + } + // return true; } diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h index ca73212ed1..40802702be 100755 --- a/indra/newview/llviewerkeyboard.h +++ b/indra/newview/llviewerkeyboard.h @@ -113,5 +113,5 @@ private: }; extern LLViewerKeyboard gViewerKeyboard; - +void agent_push_forward(EKeystate s);// Mouse movement by Singularity #endif // LL_LLVIEWERKEYBOARD_H diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 99de73790c..567ad8f245 100755 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2793,12 +2793,14 @@ void derenderObject(bool permanent) { std::string entry_name = ""; std::string region_name; + LLAssetType::EType asset_type; if (objp->isAvatar()) { LLNameValue* firstname = objp->getNVPair("FirstName"); LLNameValue* lastname = objp->getNVPair("LastName"); - entry_name = llformat("%s %s" ,firstname->getString(), lastname->getString()); + entry_name = llformat("%s %s", firstname->getString(), lastname->getString()); + asset_type = LLAssetType::AT_PERSON; } else { @@ -2815,9 +2817,10 @@ void derenderObject(bool permanent) { region_name = region->getName(); } + asset_type = LLAssetType::AT_OBJECT; } - FSWSAssetBlacklist::getInstance()->addNewItemToBlacklist(objp->getID(), entry_name, region_name, LLAssetType::AT_OBJECT); + FSWSAssetBlacklist::getInstance()->addNewItemToBlacklist(objp->getID(), entry_name, region_name, asset_type); } select_mgr->deselectObjectOnly(objp); @@ -7683,25 +7686,44 @@ class LLLandEdit : public view_listener_t class LLMuteParticle : public view_listener_t { + // Blocklist sometimes shows "(waiting)" as avatar name when blocking particle owners + void onAvatarNameCache(const LLUUID& av_id, const LLAvatarName& av_name) + { + LLMute mute(av_id, av_name.getLegacyName(), LLMute::AGENT); + if (LLMuteList::getInstance()->isMuted(mute.mID)) + { + LLMuteList::getInstance()->remove(mute); + } + else + { + LLMuteList::getInstance()->add(mute); + LLPanelBlockedList::showPanelAndSelect(mute.mID); + } + } + // + bool handleEvent(const LLSD& userdata) { LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID; if (id.notNull()) { - std::string name; - gCacheName->getFullName(id, name); + // Blocklist sometimes shows "(waiting)" as avatar name when blocking particle owners + //std::string name; + //gCacheName->getFullName(id, name); - LLMute mute(id, name, LLMute::AGENT); - if (LLMuteList::getInstance()->isMuted(mute.mID)) - { - LLMuteList::getInstance()->remove(mute); - } - else - { - LLMuteList::getInstance()->add(mute); - LLPanelBlockedList::showPanelAndSelect(mute.mID); - } + //LLMute mute(id, name, LLMute::AGENT); + //if (LLMuteList::getInstance()->isMuted(mute.mID)) + //{ + // LLMuteList::getInstance()->remove(mute); + //} + //else + //{ + // LLMuteList::getInstance()->add(mute); + // LLPanelBlockedList::showPanelAndSelect(mute.mID); + //} + LLAvatarNameCache::get(id, boost::bind(&LLMuteParticle::onAvatarNameCache, this, _1, _2)); + // } return true; @@ -8730,7 +8752,7 @@ class LLAdvancedClickRenderProfile: public view_listener_t } }; -void gpu_benchmark(); +F32 gpu_benchmark(); class LLAdvancedClickRenderBenchmark: public view_listener_t { @@ -9047,20 +9069,6 @@ BOOL check_show_xui_names(void *) return gSavedSettings.getBOOL("DebugShowXUINames"); } -// FIRE-304: Option to exclude group owned objects -class FSToolSelectIncludeGroupOwned : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - BOOL cur_val = gSavedSettings.getBOOL("FSSelectIncludeGroupOwned"); - - gSavedSettings.setBOOL("FSSelectIncludeGroupOwned", ! cur_val ); - - return true; - } -}; -// - // Resync Animations class FSToolsResyncAnimations : public view_listener_t { @@ -10655,8 +10663,6 @@ void initialize_menus() commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy)); view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory"); view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction"); - // FIRE-304: Option to exclude group owned objects - view_listener_t::addMenu(new FSToolSelectIncludeGroupOwned(), "Tools.SelectIncludeGroupOwned"); view_listener_t::addMenu(new FSToolsResyncAnimations(), "Tools.ResyncAnimations"); // Resync Animations view_listener_t::addMenu(new FSToolsUndeform(), "Tools.Undeform"); // FIRE-4345: Undeform diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 001cfe0bd0..a79b23d4c0 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -853,6 +853,9 @@ public: } /*virtual*/ void done() { + // FIRE-3234: Don't need a check for ShowNewInventory here; + // This only gets called if the user explicity clicks "Show" or + // AutoAcceptNewInventory and ShowNewInventory are TRUE. open_inventory_offer(mComplete, mFromName); gInventory.removeObserver(this); delete this; @@ -1094,7 +1097,17 @@ protected: else ++it; } - open_inventory_offer(added, ""); + // Moved check out of check_offer_throttle + //open_inventory_offer(added, ""); + if (gSavedSettings.getBOOL("ShowNewInventory")) + { + open_inventory_offer(added, ""); + } + else if (!added.empty() && gSavedSettings.getBOOL("ShowInInventory")) + { + LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, added.back()); + } + // } }; @@ -1108,7 +1121,18 @@ protected: { added.push_back(*it); } - open_inventory_offer(added, "group_offer"); + + // Moved check out of check_offer_throttle + //open_inventory_offer(added, "group_offer"); + if (gSavedSettings.getBOOL("ShowNewInventory")) + { + open_inventory_offer(added, "group_offer"); + } + else if (!added.empty() && gSavedSettings.getBOOL("ShowInInventory")) + { + LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, added.back()); + } + // gInventory.removeObserver(this); delete this; } @@ -1192,12 +1216,10 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) LLChat chat; std::string log_message; - // gSavedSettings to LLCachedControl - // if (!gSavedSettings.getBOOL("ShowNewInventory")) - static LLCachedControl showNewInventory(gSavedSettings, "ShowNewInventory"); - if (!showNewInventory) - // - return false; + // This controls if items should be opened in open_inventory_offer()??? No way! + //if (!gSavedSettings.getBOOL("ShowNewInventory")) + // return false; + // if (check_only) { @@ -1221,7 +1243,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) static LLCachedControl fsOfferThrottleMaxCount(gSavedSettings, "FSOfferThrottleMaxCount"); if (LLStartUp::getStartupState() >= STATE_STARTED //&& throttle_count >= OFFER_THROTTLE_MAX_COUNT) - && throttle_count >= U32(fsOfferThrottleMaxCount)) + && throttle_count >= fsOfferThrottleMaxCount) { if (!throttle_logged) { @@ -1240,7 +1262,6 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) if (!from_name.empty()) { // gSavedSettings to LLCachedControl - // if (gSavedSettings.getBOOL("FSNotifyIncomingObjectSpamFrom")) static LLCachedControl fsNotifyIncomingObjectSpamFrom(gSavedSettings, "FSNotifyIncomingObjectSpamFrom"); if (fsNotifyIncomingObjectSpamFrom) // @@ -1252,7 +1273,6 @@ bool check_offer_throttle(const std::string& from_name, bool check_only) else { // gSavedSettings to LLCachedControl - // if (gSavedSettings.getBOOL("FSNotifyIncomingObjectSpam")) static LLCachedControl fsNotifyIncomingObjectSpam(gSavedSettings, "FSNotifyIncomingObjectSpam"); if (fsNotifyIncomingObjectSpam) // @@ -1422,6 +1442,8 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam const BOOL auto_open = gSavedSettings.getBOOL("ShowInInventory"); // AO: don't open if showininventory is false, otherwise ignore from_name. //gSavedSettings.getBOOL("ShowInInventory") && // don't open if showininventory is false //!from_name.empty(); // don't open if it's not from anyone. + // Don't mess with open inventory panels when ShowInInventory is FALSE + if (auto_open) LLInventoryPanel::openInventoryPanelAndSetSelection(auto_open, obj_id); } } @@ -1476,6 +1498,7 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id, { if(notification->getName() == "ObjectGiveItem" || notification->getName() == "OwnObjectGiveItem" + || notification->getName() == "UserGiveItemLegacy" // FIRE-3832: Silent accept/decline of inventory offers || notification->getName() == "UserGiveItem") { return (notification->getPayload()["from_id"].asUUID() == blocked_id); @@ -1688,6 +1711,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& switch(button) { case IOR_SHOW: + case IOR_SHOW_SILENT: // FIRE-3832: Silent accept/decline of inventory offers // we will want to open this item when it comes back. LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID << LL_ENDL; @@ -1710,7 +1734,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } // [/RLVa:KB] - if (gSavedSettings.getBOOL("ShowOfferedInventory")) + // FIRE-3234: Ask if items should be previewed; + // ShowOfferedInventory is always true anyway - instead there is + // ShowNewInventory that is actually changable by the user! + //if (gSavedSettings.getBOOL("ShowOfferedInventory")) { LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(mObjectID, from_string); open_agent_offer->startFetch(); @@ -1725,7 +1752,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } // Optional V1-like inventory accept messages - if (gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages")) + if (gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages") && button == IOR_SHOW) { send_auto_receive_response(); } @@ -1756,6 +1783,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& // end switch (mIM) case IOR_ACCEPT: + case IOR_ACCEPT_SILENT: // FIRE-3832: Silent accept/decline of inventory offers //don't spam them if they are getting flooded if (check_offer_throttle(mFromName, true)) { @@ -1765,6 +1793,25 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& LLNotificationsUtil::add("SystemMessageTip", args); } + // FIRE-3832: Silent accept/decline of inventory offers + if (mIM == IM_GROUP_NOTICE) + { + opener = new LLOpenTaskGroupOffer; + send_auto_receive_response(); + } + else + { + if (gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages") && button == IOR_ACCEPT) + { + send_auto_receive_response(); + } + if (gSavedSettings.getBOOL("ShowInInventory")) + { + LLInventoryPanel::openInventoryPanelAndSetSelection(TRUE, mObjectID); + } + } + // + break; case IOR_MUTE: @@ -1774,6 +1821,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } // MUTE falls through to decline case IOR_DECLINE: + case IOR_DECLINE_SILENT: // FIRE-3832: Silent accept/decline of inventory offers { { LLStringUtil::format_map_t log_message_args; @@ -1803,7 +1851,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& } // Optional V1-like inventory accept messages - if (gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages")) + if ((gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages") && button == IOR_DECLINE) && mIM == IM_INVENTORY_OFFERED) { send_decline_response(); } @@ -2096,6 +2144,8 @@ void LLOfferInfo::initRespondFunctionMap() mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2); mRespondFunctions["OwnObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2); mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2); + // FIRE-3832: Silent accept/decline of inventory offers + mRespondFunctions["UserGiveItemLegacy"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2); } } @@ -2243,7 +2293,10 @@ void inventory_offer_handler(LLOfferInfo* info) // closes viewer(without responding the notification) p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info)); info->mPersist = true; - p.name = "UserGiveItem"; + // FIRE-3832: Silent accept/decline of inventory offers + //p.name = "UserGiveItem"; + p.name = (gSavedSettings.getBOOL("FSUseLegacyInventoryAcceptMessages") ? "UserGiveItemLegacy" : "UserGiveItem"); + // p.offer_from_agent = true; // Prefetch the item into your local inventory. @@ -2282,7 +2335,7 @@ void inventory_offer_handler(LLOfferInfo* info) } // Show offered inventory also if auto-accept is enabled (FIRE-5101) - if (bAutoAccept && gSavedSettings.getBOOL("ShowOfferedInventory")) + if (bAutoAccept && gSavedSettings.getBOOL("ShowNewInventory")) { LLViewerInventoryCategory* catp = NULL; catp = (LLViewerInventoryCategory*)gInventory.getCategory(info->mObjectID); @@ -3185,6 +3238,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) //args["MESSAGE"] = mes; //LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(LLDate(timestamp))); //make_ui_sound("UISndGroupNotice"); // Group notice sound + if (group_id.isNull()) + { + LL_WARNS() << "Received group notice with null id!" << LL_ENDL; + } gCacheName->get(group_id, true, boost::bind(¬ification_group_name_cb, _2, name, subj, mes, payload, timestamp)); // } @@ -6103,7 +6160,10 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) } else { - LL_WARNS() << "Unknown sim stat identifier: " << stat_id << LL_ENDL; + // Cut down logspam + //LL_WARNS() << "Unknown sim stat identifier: " << stat_id << LL_ENDL; + LL_WARNS_ONCE() << "Unknown sim stat identifier: " << stat_id << LL_ENDL; + // } } @@ -8522,10 +8582,13 @@ void send_lures(const LLSD& notification, const LLSD& response) // Record the offer. { - std::string target_name; - gCacheName->getFullName(target_id, target_name); // for im log filenames + // Show complete name for TP lures + //std::string target_name; + //gCacheName->getFullName(target_id, target_name); // for im log filenames LLSD args; - args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();; + //args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();; + args["TO_NAME"] = LLSLURL("agent", target_id, "completename").getSLURLString(); + // LLSD payload; @@ -9269,8 +9332,32 @@ void invalid_message_callback(LLMessageSystem* msg, void LLOfferInfo::forceResponse(InventoryOfferResponse response) { + // Now this is a hell of piece of... forceResponse() will look for the + // ELEMENT index, and NOT the button index. So if we want to force a + // response of IOR_ACCEPT, we need to pass the correct element + // index of the button. + //LLNotification::Params params("UserGiveItem"); + //params.functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2)); + //LLNotifications::instance().forceResponse(params, response); + S32 element_index; + switch (response) + { + case IOR_ACCEPT: + element_index = 1; + break; + case IOR_DECLINE: + element_index = 2; + break; + case IOR_MUTE: + element_index = 3; + break; + default: + element_index = -1; + break; + } LLNotification::Params params("UserGiveItem"); params.functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2)); - LLNotifications::instance().forceResponse(params, response); + LLNotifications::instance().forceResponse(params, element_index); + // } diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h index 719c10b42f..680d4b13e8 100755 --- a/indra/newview/llviewermessage.h +++ b/indra/newview/llviewermessage.h @@ -60,7 +60,12 @@ enum InventoryOfferResponse IOR_ACCEPT, IOR_DECLINE, IOR_MUTE, - IOR_SHOW + IOR_SHOW, + // FIRE-3832: Silent accept/decline of inventory offers + IOR_ACCEPT_SILENT, + IOR_DECLINE_SILENT, + IOR_SHOW_SILENT + // }; BOOL can_afford_transaction(S32 cost); diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index f7eb7df46c..caf25ce660 100755 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -664,7 +664,8 @@ void LLViewerPartSim::updateSimulation() static LLFrameTimer update_timer; //reset VBO cursor - LLVOPartGroup::sVBSlotCursor = 0; + // Fix particle flashing + //LLVOPartGroup::sVBSlotCursor = 0; const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 1a967437ea..f45db27dc1 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2881,6 +2881,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); capabilityNames.append("GetTexture"); + capabilityNames.append("GroupAPIv1"); capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); capabilityNames.append("HomeLocation"); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index b32b8d2f3a..207e0a6107 100755 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -545,6 +545,10 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem(); sMaxDesiredTextureMem = sMaxTotalTextureMem; //in Bytes, by default and when total used texture memory is small. + // Link threshold factor for lowering bias based on total texture memory to the same value + // textures will be destroyed + static LLCachedControl fsDestroyGLTexturesThreshold(gSavedSettings, "FSDestroyGLTexturesThreshold"); + if (sBoundTextureMemory >= sMaxBoundTextureMem || sTotalTextureMemory >= sMaxTotalTextureMem) { @@ -575,7 +579,11 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity } else if (sDesiredDiscardBias > 0.0f && sBoundTextureMemory < sMaxBoundTextureMem * texmem_lower_bound_scale && - sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale) + // Link threshold factor for lowering bias based on total texture memory to the same value + // textures will be destroyed + //sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale) + sTotalTextureMemory < sMaxTotalTextureMem * fsDestroyGLTexturesThreshold()) + // { // If we are using less texture memory than we should, // scale down the desired discard level diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 621ce700f9..111fa5034c 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -84,6 +84,7 @@ #include "raytrace.h" // newview includes +#include "fscommon.h" #include "llagent.h" #include "llbox.h" #include "llchicletbar.h" @@ -4732,6 +4733,14 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picke while( -1 != err ); // search until the file is not found (i.e., stat() gives an error). LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL; + // Log snapshot filename to local chat history + if (gSavedSettings.getBOOL("FSLogSnapshotsToLocal")) + { + LLStringUtil::format_map_t args; + args["FILENAME"] = filepath; + reportToNearbyChat(LLTrans::getString("SnapshotSavedToDisk", args)); + } + // return image->save(filepath); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index aaf3c0a753..5acdae1f18 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -690,6 +690,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mTyping(FALSE), mMeshValid(FALSE), mVisible(FALSE), + mMutedAsCloud(false), // Show muted avatars as cloud mWindFreq(0.f), mRipplePhase( 0.f ), mBelowWater(FALSE), @@ -2199,6 +2200,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) // attach objects that were waiting for a drawable lazyAttach(); + + // Show muted avatars as cloud + static LLUICachedControl showMutedAvatarsAsCloud("ShowMutedAvatarsAsCloud", false); + mMutedAsCloud = !isSelf() && showMutedAvatarsAsCloud && LLMuteList::instance().isMuted(getID()); + // // animate the character // store off last frame's root position to be consistent with camera position @@ -2593,7 +2599,7 @@ void LLVOAvatar::idleUpdateLoadingEffect() } else { -// [ LL Default Av Clouds ] +// Custom avatar particle cloud // LLPartSysData particle_parameters; // // // fancy particle cloud designed by Brent @@ -2628,15 +2634,18 @@ void LLVOAvatar::idleUpdateLoadingEffect() // Firestorm Clouds if (!isTooComplex()) // do not generate particles for overly-complex avatars - { - if (!isSelf() && LLMuteList::getInstance()->isMuted(getID())) - setParticleSource(sCloudMuted, getID()); - else - setParticleSource(sCloud, getID()); - } - - + { + if (mMutedAsCloud) + { + setParticleSource(sCloudMuted, getID()); + } + else + { + setParticleSource(sCloud, getID()); + } + } } +// } } @@ -3437,6 +3446,13 @@ bool LLVOAvatar::isVisuallyMuted() { bool muted = false; + // FIRE-11783: Always visually mute avatars that are muted + if (!isSelf() && LLMuteList::instance().isMuted(getID())) + { + return true; + } + // + if (!isSelf()) { static LLCachedControl render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions", 0); @@ -3476,31 +3492,33 @@ bool LLVOAvatar::isVisuallyMuted() U32 max_cost = (U32) (max_render_cost*(LLVOAvatar::sLODFactor+0.5)); - muted = LLMuteList::getInstance()->isMuted(getID()) || + muted = /*LLMuteList::getInstance()->isMuted(getID()) ||*/ // FIRE-11783: Always visually mute avatars that are muted (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) || (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f) || (mVisualComplexity > max_cost && max_render_cost > 0); // Could be part of the grand || collection above, but yanked out to make the logic visible - if (!muted) - { - if (sMaxVisible > 0) - { // They are above the visibilty rank - mute them - muted = (mVisibilityRank > sMaxVisible); - } + // FIRE-15074: Render normal imposters properly (Don't tie visual mute to RenderAvatarMaxVisible) + //if (!muted) + //{ + // if (sMaxVisible > 0) + // { // They are above the visibilty rank - mute them + // muted = (mVisibilityRank > sMaxVisible); + // } - // Always draw friends or those in IMs. Needs UI? - if ((render_auto_mute_functions & 0x02) && - (muted || sMaxVisible == 0)) // Don't mute friends or IMs - { - muted = !(LLAvatarTracker::instance().isBuddy(getID())); - if (muted) - { // Not a friend, so they are muted ... are they in an IM? - LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,getID()); - muted = !gIMMgr->hasSession(session_id); - } - } - } + // // Always draw friends or those in IMs. Needs UI? + // if ((render_auto_mute_functions & 0x02) && + // (muted || sMaxVisible == 0)) // Don't mute friends or IMs + // { + // muted = !(LLAvatarTracker::instance().isBuddy(getID())); + // if (muted) + // { // Not a friend, so they are muted ... are they in an IM? + // LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,getID()); + // muted = !gIMMgr->hasSession(session_id); + // } + // } + //} + // // Save visual mute state and set interval for updating const F64 SECONDS_BETWEEN_RENDER_AUTO_MUTE_UPDATES = 1.5; @@ -6553,8 +6571,6 @@ BOOL LLVOAvatar::isVisible() const // Determine if we have enough avatar data to render BOOL LLVOAvatar::getIsCloud() const { - static LLUICachedControl muted_as_cloud("ShowMutedAvatarsAsCloud"); - // Do we have a shape? if ((const_cast(this))->visualParamWeightsAreDefault()) { @@ -6568,10 +6584,12 @@ BOOL LLVOAvatar::getIsCloud() const return TRUE; } - if (muted_as_cloud && !isSelf() && LLMuteList::getInstance()->isMuted(getID())) + // Show muted avatars as cloud + if (mMutedAsCloud) { return TRUE; } + // if (isTooComplex()) { @@ -6602,7 +6620,10 @@ void LLVOAvatar::updateRezzedStatusTimers() startPhase("first_load_" + LLVOAvatar::rezStatusToString(i)); } } - if (rez_status < mLastRezzedStatus) + // Show muted avatars as cloud + //if (rez_status < mLastRezzedStatus) + if (rez_status < mLastRezzedStatus && !mMutedAsCloud) + // { // load level has decreased. start phase timers for higher load levels. for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++) @@ -6765,7 +6786,10 @@ BOOL LLVOAvatar::updateIsFullyLoaded() void LLVOAvatar::updateRuthTimer(bool loading) { - if (isSelf() || !loading) + // Show muted avatars as cloud + //if (isSelf() || !loading) + if (isSelf() || !loading || !mMutedAsCloud) + // { return; } @@ -6827,7 +6851,8 @@ BOOL LLVOAvatar::isFullyLoaded() const // return (mRenderUnloadedAvatar || mFullyLoaded); // [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2) // Changes to LLAppearanceMgr::updateAppearanceFromCOF() expect this function to actually return mFullyLoaded for gAgentAvatarp - return (mRenderUnloadedAvatar && !isSelf()) ||(mFullyLoaded); + //return (mRenderUnloadedAvatar && !isSelf()) ||(mFullyLoaded); + return (mRenderUnloadedAvatar && !isSelf() && !mMutedAsCloud) ||(mFullyLoaded); // Particle clouds! // [/SL:KB] } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 203b028fde..e66fdb8e1f 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -234,6 +234,9 @@ public: private: //aligned members LL_ALIGN_16(LLVector4a mImpostorExtents[2]); + // Show muted avatars as cloud + bool mMutedAsCloud; + //-------------------------------------------------------------------- // Updates //-------------------------------------------------------------------- diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 7d29eaa256..34e00d67da 100755 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -165,6 +165,18 @@ void LLVoiceClient::userAuthorized(const std::string& user_id, const LLUUID &age mVoiceModule->userAuthorized(user_id, agentID); } +void LLVoiceClient::setHidden(bool hidden) +{ + if (mVoiceModule) + { + //mVoiceModule->setHidden(hidden); + #ifdef OPENSIM + mVoiceModule->setHidden(hidden && LLGridManager::getInstance()->isInSecondLife()); + #else + mVoiceModule->setHidden(hidden); + #endif + } +} void LLVoiceClient::terminate() { diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index bcdba2b587..6834af3f98 100755 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -105,6 +105,8 @@ public: virtual void updateSettings()=0; // call after loading settings and whenever they change virtual bool isVoiceWorking() const = 0; // connected to a voice server and voice channel + + virtual void setHidden(bool hidden)=0; // Hides the user from voice. virtual const LLVoiceVersionInfo& getVersion()=0; @@ -363,6 +365,7 @@ public: void setCaptureDevice(const std::string& name); void setRenderDevice(const std::string& name); + void setHidden(bool hidden); const LLVoiceDeviceList& getCaptureDevices(); const LLVoiceDeviceList& getRenderDevices(); diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 6235eaa721..98a169ca87 100755 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -70,6 +70,7 @@ #include "apr_base64.h" #define USE_SESSION_GROUPS 0 +#define VX_NULL_POSITION -2147483648.0 /*The Silence*/ extern LLMenuBarGL* gMenuBarView; extern void handle_voice_morphing_subscribe(); @@ -322,6 +323,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mCaptureBufferRecording(false), mCaptureBufferRecorded(false), mCaptureBufferPlaying(false), + mShutdownComplete(true), mPlayRequestCount(0), mAvatarNameCacheConnection() @@ -376,7 +378,16 @@ void LLVivoxVoiceClient::terminate() if(mConnected) { logout(); - connectorShutdown(); + connectorShutdown(); +#ifdef LL_WINDOWS + int count=0; + while (!mShutdownComplete && 10 > count++) + { + stateMachine(); + _sleep(1000); + } + +#endif closeSocket(); // Need to do this now -- bad things happen if the destructor does it later. cleanUp(); } @@ -475,7 +486,18 @@ bool LLVivoxVoiceClient::writeString(const std::string &str) void LLVivoxVoiceClient::connectorCreate() { std::ostringstream stream; - std::string logpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); + // Set custom Vivox log path everywhere necessary + //std::string logpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); + std::string logpath = gSavedSettings.getString("VivoxLogDirectory"); + if (logpath.empty()) + { + logpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); + } + if (LLStringUtil::endsWith(logpath, gDirUtilp->getDirDelimiter())) + { + logpath = logpath.substr(0, logpath.size() - gDirUtilp->getDirDelimiter().size()); + } + // std::string loglevel = "0"; // Transition to stateConnectorStarted when the connector handle comes back. @@ -483,14 +505,10 @@ void LLVivoxVoiceClient::connectorCreate() std::string savedLogLevel = gSavedSettings.getString("VivoxDebugLevel"); - // Fixing Vivox debug level - //if(savedLogLevel != "-0") if(savedLogLevel != "0") - // { LL_DEBUGS("Voice") << "creating connector with logging enabled" << LL_ENDL; // Fixing Vivox debug level - //loglevel = "0"; loglevel = savedLogLevel; // } @@ -529,6 +547,7 @@ void LLVivoxVoiceClient::connectorShutdown() << "" << "\n\n\n"; + mShutdownComplete = false; mConnectorHandle.clear(); writeString(stream.str()); @@ -805,15 +824,39 @@ void LLVivoxVoiceClient::stateMachine() // vivox executable exists. Build the command line and launch the daemon. LLProcess::Params params; params.executable = exe_path; - // SLIM SDK: these arguments are no longer necessary. -// std::string args = " -p tcp -h -c"; + std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); + std::string shutdown_timeout = gSavedSettings.getString("VivoxShutdownTimeout"); if(loglevel.empty()) { loglevel = "0"; // turn logging off completely } + params.args.add("-ll"); params.args.add(loglevel); + + std::string log_folder = gSavedSettings.getString("VivoxLogDirectory"); + + if (log_folder.empty()) + { + log_folder = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); + } + + // Strip trailing directory delimiter + if (LLStringUtil::endsWith(log_folder, gDirUtilp->getDirDelimiter())) + { + log_folder = log_folder.substr(0, log_folder.size() - gDirUtilp->getDirDelimiter().size()); + } + // + params.args.add("-lf"); + params.args.add(log_folder); + + if(!shutdown_timeout.empty()) + { + params.args.add("-st"); + params.args.add(shutdown_timeout); + } + // Voice in multiple instances; by Latif Khalifa if (gSavedSettings.getBOOL("VoiceMultiInstance")) { @@ -827,6 +870,7 @@ void LLVivoxVoiceClient::stateMachine() } } // + params.cwd = gDirUtilp->getAppRODataDir(); sGatewayPtr = LLProcess::create(params); @@ -1367,7 +1411,7 @@ void LLVivoxVoiceClient::stateMachine() { // Connect to a session by URI sessionCreateSendMessage(mAudioSession, true, false); - } + } notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING); setState(stateJoiningSession); @@ -1543,7 +1587,7 @@ void LLVivoxVoiceClient::stateMachine() // Always reset the terminate request flag when we get here. mSessionTerminateRequested = false; - if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested) + if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested && !LLApp::isExiting()) { // Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state). setState(stateNoChannel); @@ -1586,6 +1630,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateConnectorStopping case stateConnectorStopping: // waiting for connector stop // The handler for the Connector.InitiateShutdown response will transition from here to stateConnectorStopped. + mShutdownComplete = true; break; //MARK: stateConnectorStopped @@ -2351,6 +2396,14 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe #endif } +void LLVivoxVoiceClient::setHidden(bool hidden) +{ + mHidden = hidden; + + sendPositionalUpdate(); + return; +} + void LLVivoxVoiceClient::sendPositionalUpdate(void) { std::ostringstream stream; @@ -2372,14 +2425,23 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void) l = mAvatarRot.getLeftRow(); u = mAvatarRot.getUpRow(); a = mAvatarRot.getFwdRow(); - pos = mAvatarPosition; + + pos = mAvatarPosition; vel = mAvatarVelocity; // SLIM SDK: the old SDK was doing a transform on the passed coordinates that the new one doesn't do anymore. // The old transform is replicated by this function. oldSDKTransform(l, u, a, pos, vel); + + if (mHidden) + { + for (int i=0;i<3;++i) + { + pos.mdV[i] = VX_NULL_POSITION; + } + } - stream + stream << "" << "" << pos.mdV[VX] << "" << "" << pos.mdV[VY] << "" @@ -2443,7 +2505,8 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void) l = earRot.getLeftRow(); u = earRot.getUpRow(); a = earRot.getFwdRow(); - pos = earPosition; + + pos = earPosition; vel = earVelocity; // LL_DEBUGS("Voice") << "Sending listener position " << earPosition << LL_ENDL; @@ -2452,8 +2515,16 @@ void LLVivoxVoiceClient::sendPositionalUpdate(void) // Equal voice volume; by Tigh MacFanatic } // - - stream + + if (mHidden) + { + for (int i=0;i<3;++i) + { + pos.mdV[i] = VX_NULL_POSITION; + } + } + + stream << "" << "" << pos.mdV[VX] << "" << "" << pos.mdV[VY] << "" diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index d6f2bd05b1..99044b34b1 100755 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -726,6 +726,7 @@ private: bool mRenderDeviceDirty; bool mIsInitialized; + bool mShutdownComplete; bool checkParcelChanged(bool update = false); @@ -750,6 +751,7 @@ private: std::string getAudioSessionURI(); std::string getAudioSessionHandle(); + void setHidden(bool hidden); //virtual void sendPositionalUpdate(void); void buildSetCaptureDevice(std::ostringstream &stream); @@ -778,6 +780,7 @@ private: bool mMuteMic; bool mMuteMicDirty; + bool mHidden; //Set to true during teleport to hide the agent's position. // Set to true when the friends list is known to have changed. bool mFriendsListDirty; diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index f90d827827..f54cb639cd 100755 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -49,11 +49,22 @@ const F32 MAX_PART_LIFETIME = 120.f; extern U64MicrosecondsImplicit gFrameTime; LLPointer LLVOPartGroup::sVB = NULL; -S32 LLVOPartGroup::sVBSlotCursor = 0; +// Fix particle flashing +//S32 LLVOPartGroup::sVBSlotCursor = 0; +S32 LLVOPartGroup::sVBSlotFree[]; +S32* LLVOPartGroup::sVBSlotCursor = NULL; +// void LLVOPartGroup::initClass() { - + // Fix particle flashing + for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i) + { + sVBSlotFree[i] = i; + } + + sVBSlotCursor = sVBSlotFree; + // } //static @@ -118,12 +129,21 @@ void LLVOPartGroup::destroyGL() //static S32 LLVOPartGroup::findAvailableVBSlot() { - if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT) + // Fix particle flashing + //if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT) + if (sVBSlotCursor >= sVBSlotFree + LL_MAX_PARTICLE_COUNT) + // { //no more available slots return -1; } - return sVBSlotCursor++; + // Fix particle flashing + //return sVBSlotCursor++; + S32 ret = *sVBSlotCursor; + sVBSlotCursor++; + + return ret; + // } bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) @@ -138,12 +158,27 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) }*/ //allocated (not in free list) - return false; + // Fix particle flashing + //return false; + + while (start < end) + { + if (*start == idx) + { //not allocated (in free list) + return false; + } + ++start; + } + + //allocated (not in free list) + return true; + // } //static void LLVOPartGroup::freeVBSlot(S32 idx) { + // Fix particle flashing /*llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); //llassert(sVBSlotCursor > sVBSlotFree); //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); @@ -153,6 +188,16 @@ void LLVOPartGroup::freeVBSlot(S32 idx) sVBSlotCursor--; *sVBSlotCursor = idx; }*/ + llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); + //llassert(sVBSlotCursor > sVBSlotFree); + //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); + + if (sVBSlotCursor > sVBSlotFree) + { + sVBSlotCursor--; + *sVBSlotCursor = idx; + } + // } LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) @@ -864,7 +909,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLFace* facep = *i; LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); + // Fix particle flashing //if (!facep->isState(LLFace::PARTICLE)) + if (!facep->isState(LLFace::PARTICLE)) + // { //set the indices of this face S32 idx = LLVOPartGroup::findAvailableVBSlot(); if (idx >= 0) @@ -873,7 +921,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) facep->setIndicesIndex(idx*6); facep->setVertexBuffer(LLVOPartGroup::sVB); facep->setPoolType(LLDrawPool::POOL_ALPHA); + // Fix particle flashing //facep->setState(LLFace::PARTICLE); + facep->setState(LLFace::PARTICLE); + // } else { diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index 2ef8b1c848..0b14d2ff48 100755 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -42,7 +42,11 @@ public: //vertex buffer for holding all particles static LLPointer sVB; - static S32 sVBSlotCursor; + // Fix particle flashing + //static S32 sVBSlotCursor; + static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT]; + static S32* sVBSlotCursor; + // static void initClass(); static void restoreGL(); diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index c854e1fc66..313de63e49 100755 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -144,7 +144,10 @@ void LLWaterParamManager::savePreset(const std::string & name) // make an empty llsd LLSD paramsData(LLSD::emptyMap()); - std::string pathName(getUserDir() + LLURI::escape(name) + ".xml"); + // FIRE-10861: Fix Windlight settings order + //std::string pathName(getUserDir() + LLURI::escape(name) + ".xml"); + std::string pathName(getUserDir() + escapeString(name) + ".xml"); + // // fill it with LLSD windlight params paramsData = mParamList[name].getAll(); @@ -348,7 +351,10 @@ bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_fr // remove from file system if requested if (delete_from_disk) { - if (gDirUtilp->deleteFilesInDir(getUserDir(), LLURI::escape(name) + ".xml") < 1) + // FIRE-10861: Fix Windlight settings order + //if (gDirUtilp->deleteFilesInDir(getUserDir(), LLURI::escape(name) + ".xml") < 1) + if (gDirUtilp->deleteFilesInDir(getUserDir(), escapeString(name) + ".xml") < 1) + // { LL_WARNS("WindLight") << "Error removing water preset " << name << " from disk" << LL_ENDL; } @@ -362,7 +368,10 @@ bool LLWaterParamManager::removeParamSet(const std::string& name, bool delete_fr bool LLWaterParamManager::isSystemPreset(const std::string& preset_name) const { // *TODO: file system access is excessive here. - return gDirUtilp->fileExists(getSysDir() + LLURI::escape(preset_name) + ".xml"); + // FIRE-10861: Fix Windlight settings order + //return gDirUtilp->fileExists(getSysDir() + LLURI::escape(preset_name) + ".xml"); + return gDirUtilp->fileExists(getSysDir() + escapeString(preset_name) + ".xml"); + // } void LLWaterParamManager::getPresetNames(preset_name_list_t& presets) const @@ -441,3 +450,20 @@ std::string LLWaterParamManager::getUserDir() { return gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS , "windlight/water", ""); } + +// FIRE-10861: Fix Windlight settings order +// static +std::string LLWaterParamManager::escapeString(const std::string& str) +{ + // Don't use LLURI::escape() because it doesn't encode '-' characters + // which may break handling of some system presets like "A-12AM". + char* curl_str = curl_escape(str.c_str(), str.size()); + std::string escaped_str(curl_str); + curl_free(curl_str); + + LLStringUtil::replaceString(escaped_str, "-", "%2D"); + LLStringUtil::replaceString(escaped_str, ".", "%2E"); + + return escaped_str; +} +// diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h index dc7d41be2a..408987b707 100755 --- a/indra/newview/llwaterparammanager.h +++ b/indra/newview/llwaterparammanager.h @@ -293,6 +293,10 @@ public: F32 getFogDensity(void); LLColor4 getFogColor(void); + // FIRE-10861: Fix Windlight settings order + /// escape string in a way different from LLURI::escape() + static std::string escapeString(const std::string& str); + public: LLWaterParamSet mCurParams; diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index a9a64933b1..b4312f8b4e 100755 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -774,5 +774,11 @@ std::string LLWLParamManager::escapeString(const std::string& str) std::string escaped_str(curl_str); curl_free(curl_str); + // FIRE-10861: Fix Windlight settings order + // And neither does cURL... + LLStringUtil::replaceString(escaped_str, "-", "%2D"); + LLStringUtil::replaceString(escaped_str, ".", "%2E"); + // + return escaped_str; } diff --git a/indra/newview/particleeditor.cpp b/indra/newview/particleeditor.cpp index 31ab7678d9..5bd46077b2 100644 --- a/indra/newview/particleeditor.cpp +++ b/indra/newview/particleeditor.cpp @@ -57,39 +57,39 @@ ParticleEditor::ParticleEditor(const LLSD& key) mObject(0), mParticleScriptInventoryItem(0) { - mPatternMap["drop"]=LLPartSysData::LL_PART_SRC_PATTERN_DROP; - mPatternMap["explode"]=LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE; - mPatternMap["angle"]=LLPartSysData::LL_PART_SRC_PATTERN_ANGLE; - mPatternMap["angle_cone"]=LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; - mPatternMap["angle_cone_empty"]=LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY; + mPatternMap["drop"] = LLPartSysData::LL_PART_SRC_PATTERN_DROP; + mPatternMap["explode"] = LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE; + mPatternMap["angle"] = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE; + mPatternMap["angle_cone"] = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE; + mPatternMap["angle_cone_empty"] = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE_EMPTY; - mScriptPatternMap["drop"]="PSYS_SRC_PATTERN_DROP"; - mScriptPatternMap["explode"]="PSYS_SRC_PATTERN_EXPLODE"; - mScriptPatternMap["angle"]="PSYS_SRC_PATTERN_ANGLE"; - mScriptPatternMap["angle_cone"]="PSYS_SRC_PATTERN_ANGLE_CONE"; - mScriptPatternMap["angle_cone_empty"]="PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY"; + mScriptPatternMap["drop"] = "PSYS_SRC_PATTERN_DROP"; + mScriptPatternMap["explode"] = "PSYS_SRC_PATTERN_EXPLODE"; + mScriptPatternMap["angle"] = "PSYS_SRC_PATTERN_ANGLE"; + mScriptPatternMap["angle_cone"] = "PSYS_SRC_PATTERN_ANGLE_CONE"; + mScriptPatternMap["angle_cone_empty"] = "PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY"; - mBlendMap["blend_one"]=LLPartData::LL_PART_BF_ONE; - mBlendMap["blend_zero"]=LLPartData::LL_PART_BF_ZERO; - mBlendMap["blend_dest_color"]=LLPartData::LL_PART_BF_DEST_COLOR; - mBlendMap["blend_src_color"]=LLPartData::LL_PART_BF_SOURCE_COLOR; - mBlendMap["blend_one_minus_dest_color"]=LLPartData::LL_PART_BF_ONE_MINUS_DEST_COLOR; - mBlendMap["blend_one_minus_src_color"]=LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_COLOR; - mBlendMap["blend_src_alpha"]=LLPartData::LL_PART_BF_SOURCE_ALPHA; - mBlendMap["blend_one_minus_src_alpha"]=LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; + mBlendMap["blend_one"] = LLPartData::LL_PART_BF_ONE; + mBlendMap["blend_zero"] = LLPartData::LL_PART_BF_ZERO; + mBlendMap["blend_dest_color"] = LLPartData::LL_PART_BF_DEST_COLOR; + mBlendMap["blend_src_color"] = LLPartData::LL_PART_BF_SOURCE_COLOR; + mBlendMap["blend_one_minus_dest_color"] = LLPartData::LL_PART_BF_ONE_MINUS_DEST_COLOR; + mBlendMap["blend_one_minus_src_color"] = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_COLOR; + mBlendMap["blend_src_alpha"] = LLPartData::LL_PART_BF_SOURCE_ALPHA; + mBlendMap["blend_one_minus_src_alpha"] = LLPartData::LL_PART_BF_ONE_MINUS_SOURCE_ALPHA; - mScriptBlendMap["blend_one"]="PSYS_PART_BF_ONE"; - mScriptBlendMap["blend_zero"]="PSYS_PART_BF_ZERO"; - mScriptBlendMap["blend_dest_color"]="PSYS_PART_BF_DEST_COLOR"; - mScriptBlendMap["blend_src_color"]="PSYS_PART_BF_SOURCE_COLOR"; - mScriptBlendMap["blend_one_minus_dest_color"]="PSYS_PART_BF_ONE_MINUS_DEST_COLOR"; - mScriptBlendMap["blend_one_minus_src_color"]="PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR"; - mScriptBlendMap["blend_src_alpha"]="PSYS_PART_BF_SOURCE_ALPHA"; - mScriptBlendMap["blend_one_minus_src_alpha"]="PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA"; + mScriptBlendMap["blend_one"] = "PSYS_PART_BF_ONE"; + mScriptBlendMap["blend_zero"] = "PSYS_PART_BF_ZERO"; + mScriptBlendMap["blend_dest_color"] = "PSYS_PART_BF_DEST_COLOR"; + mScriptBlendMap["blend_src_color"] = "PSYS_PART_BF_SOURCE_COLOR"; + mScriptBlendMap["blend_one_minus_dest_color"] = "PSYS_PART_BF_ONE_MINUS_DEST_COLOR"; + mScriptBlendMap["blend_one_minus_src_color"] = "PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR"; + mScriptBlendMap["blend_src_alpha"] = "PSYS_PART_BF_SOURCE_ALPHA"; + mScriptBlendMap["blend_one_minus_src_alpha"] = "PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA"; // I don't really like referencing the particle texture name here, but it's being done // like this all over the viewer, so this is apparently how it's meant to be. -Zi - mDefaultParticleTexture=LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); + mDefaultParticleTexture = LLViewerTextureManager::getFetchedTextureFromFile("pixiesmall.j2c"); } ParticleEditor::~ParticleEditor() @@ -101,117 +101,117 @@ ParticleEditor::~ParticleEditor() BOOL ParticleEditor::postBuild() { - LLPanel* panel=getChild("particle_editor_panel"); + LLPanel* panel = getChild("particle_editor_panel"); - mMainPanel=panel; + mMainPanel = panel; - mPatternTypeCombo=panel->getChild("pattern_type_combo"); - mTexturePicker=panel->getChild("texture_picker"); + mPatternTypeCombo = panel->getChild("pattern_type_combo"); + mTexturePicker = panel->getChild("texture_picker"); - mBurstRateSpinner=panel->getChild("burst_rate_spinner"); - mBurstCountSpinner=panel->getChild("burst_count_spinner"); - mBurstRadiusSpinner=panel->getChild("burst_radius_spinner"); - mAngleBeginSpinner=panel->getChild("angle_begin_spinner"); - mAngleEndSpinner=panel->getChild("angle_end_spinner"); - mBurstSpeedMinSpinner=panel->getChild("burst_speed_min_spinner"); - mBurstSpeedMaxSpinner=panel->getChild("burst_speed_max_spinner"); - mStartAlphaSpinner=panel->getChild("start_alpha_spinner"); - mEndAlphaSpinner=panel->getChild("end_alpha_spinner"); - mScaleStartXSpinner=panel->getChild("scale_start_x_spinner"); - mScaleStartYSpinner=panel->getChild("scale_start_y_spinner"); - mScaleEndXSpinner=panel->getChild("scale_end_x_spinner"); - mScaleEndYSpinner=panel->getChild("scale_end_y_spinner"); - mSourceMaxAgeSpinner=panel->getChild("source_max_age_spinner"); - mParticlesMaxAgeSpinner=panel->getChild("particles_max_age_spinner"); - mStartGlowSpinner=panel->getChild("start_glow_spinner"); - mEndGlowSpinner=panel->getChild("end_glow_spinner"); + mBurstRateSpinner = panel->getChild("burst_rate_spinner"); + mBurstCountSpinner = panel->getChild("burst_count_spinner"); + mBurstRadiusSpinner = panel->getChild("burst_radius_spinner"); + mAngleBeginSpinner = panel->getChild("angle_begin_spinner"); + mAngleEndSpinner = panel->getChild("angle_end_spinner"); + mBurstSpeedMinSpinner = panel->getChild("burst_speed_min_spinner"); + mBurstSpeedMaxSpinner = panel->getChild("burst_speed_max_spinner"); + mStartAlphaSpinner = panel->getChild("start_alpha_spinner"); + mEndAlphaSpinner = panel->getChild("end_alpha_spinner"); + mScaleStartXSpinner = panel->getChild("scale_start_x_spinner"); + mScaleStartYSpinner = panel->getChild("scale_start_y_spinner"); + mScaleEndXSpinner = panel->getChild("scale_end_x_spinner"); + mScaleEndYSpinner = panel->getChild("scale_end_y_spinner"); + mSourceMaxAgeSpinner = panel->getChild("source_max_age_spinner"); + mParticlesMaxAgeSpinner = panel->getChild("particles_max_age_spinner"); + mStartGlowSpinner = panel->getChild("start_glow_spinner"); + mEndGlowSpinner = panel->getChild("end_glow_spinner"); - mBlendFuncSrcCombo=panel->getChild("blend_func_src_combo"); - mBlendFuncDestCombo=panel->getChild("blend_func_dest_combo"); + mBlendFuncSrcCombo = panel->getChild("blend_func_src_combo"); + mBlendFuncDestCombo = panel->getChild("blend_func_dest_combo"); - mBounceCheckBox=panel->getChild("bounce_checkbox"); - mEmissiveCheckBox=panel->getChild("emissive_checkbox"); - mFollowSourceCheckBox=panel->getChild("follow_source_checkbox"); - mFollowVelocityCheckBox=panel->getChild("follow_velocity_checkbox"); - mInterpolateColorCheckBox=panel->getChild("interpolate_color_checkbox"); - mInterpolateScaleCheckBox=panel->getChild("interpolate_scale_checkbox"); - mTargetPositionCheckBox=panel->getChild("target_position_checkbox"); - mTargetLinearCheckBox=panel->getChild("target_linear_checkbox"); - mWindCheckBox=panel->getChild("wind_checkbox"); - mRibbonCheckBox=panel->getChild("ribbon_checkbox"); + mBounceCheckBox = panel->getChild("bounce_checkbox"); + mEmissiveCheckBox = panel->getChild("emissive_checkbox"); + mFollowSourceCheckBox = panel->getChild("follow_source_checkbox"); + mFollowVelocityCheckBox = panel->getChild("follow_velocity_checkbox"); + mInterpolateColorCheckBox = panel->getChild("interpolate_color_checkbox"); + mInterpolateScaleCheckBox = panel->getChild("interpolate_scale_checkbox"); + mTargetPositionCheckBox = panel->getChild("target_position_checkbox"); + mTargetLinearCheckBox = panel->getChild("target_linear_checkbox"); + mWindCheckBox = panel->getChild("wind_checkbox"); + mRibbonCheckBox = panel->getChild("ribbon_checkbox"); - mTargetKeyInput=panel->getChild("target_key_input"); + mTargetKeyInput = panel->getChild("target_key_input"); - mAcellerationXSpinner=panel->getChild("acceleration_x_spinner"); - mAcellerationYSpinner=panel->getChild("acceleration_y_spinner"); - mAcellerationZSpinner=panel->getChild("acceleration_z_spinner"); + mAcellerationXSpinner = panel->getChild("acceleration_x_spinner"); + mAcellerationYSpinner = panel->getChild("acceleration_y_spinner"); + mAcellerationZSpinner = panel->getChild("acceleration_z_spinner"); - mOmegaXSpinner=panel->getChild("omega_x_spinner"); - mOmegaYSpinner=panel->getChild("omega_y_spinner"); - mOmegaZSpinner=panel->getChild("omega_z_spinner"); + mOmegaXSpinner = panel->getChild("omega_x_spinner"); + mOmegaYSpinner = panel->getChild("omega_y_spinner"); + mOmegaZSpinner = panel->getChild("omega_z_spinner"); - mStartColorSelector=panel->getChild("start_color_selector"); - mEndColorSelector=panel->getChild("end_color_selector"); + mStartColorSelector = panel->getChild("start_color_selector"); + mEndColorSelector = panel->getChild("end_color_selector"); - mCopyToLSLButton=panel->getChild("copy_button"); - mCopyToLSLButton->setCommitCallback(boost::bind(&ParticleEditor::onCopyButtonClicked,this)); + mCopyToLSLButton = panel->getChild("copy_button"); + mCopyToLSLButton->setCommitCallback(boost::bind(&ParticleEditor::onCopyButtonClicked, this)); - mInjectScriptButton=panel->getChild("inject_button"); - mInjectScriptButton->setCommitCallback(boost::bind(&ParticleEditor::onInjectButtonClicked,this)); + mInjectScriptButton = panel->getChild("inject_button"); + mInjectScriptButton->setCommitCallback(boost::bind(&ParticleEditor::onInjectButtonClicked, this)); - mClearTargetButton=panel->getChild("clear_target_button"); - mClearTargetButton->setCommitCallback(boost::bind(&ParticleEditor::onClearTargetButtonClicked,this)); + mClearTargetButton = panel->getChild("clear_target_button"); + mClearTargetButton->setCommitCallback(boost::bind(&ParticleEditor::onClearTargetButtonClicked, this)); - mPickTargetButton=panel->getChild("pick_target_button"); - mPickTargetButton->setCommitCallback(boost::bind(&ParticleEditor::onTargetPickerButtonClicked,this)); + mPickTargetButton = panel->getChild("pick_target_button"); + mPickTargetButton->setCommitCallback(boost::bind(&ParticleEditor::onTargetPickerButtonClicked, this)); - mPatternTypeCombo->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mTexturePicker->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mPatternTypeCombo->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mTexturePicker->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); - mBurstRateSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mBurstCountSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mBurstRadiusSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mAngleBeginSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mAngleEndSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mBurstSpeedMinSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mBurstSpeedMaxSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mStartAlphaSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mEndAlphaSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mScaleStartXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mScaleStartYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mScaleEndXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mScaleEndYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mSourceMaxAgeSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mParticlesMaxAgeSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mStartGlowSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mEndGlowSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mBurstRateSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mBurstCountSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mBurstRadiusSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mAngleBeginSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mAngleEndSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mBurstSpeedMinSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mBurstSpeedMaxSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mStartAlphaSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mEndAlphaSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mScaleStartXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mScaleStartYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mScaleEndXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mScaleEndYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mSourceMaxAgeSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mParticlesMaxAgeSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mStartGlowSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mEndGlowSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); - mBlendFuncSrcCombo->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mBlendFuncDestCombo->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mBlendFuncSrcCombo->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mBlendFuncDestCombo->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); - mBounceCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mEmissiveCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mFollowSourceCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mFollowVelocityCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mInterpolateColorCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mInterpolateScaleCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mTargetPositionCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mTargetLinearCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mWindCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mRibbonCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mBounceCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mEmissiveCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mFollowSourceCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mFollowVelocityCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mInterpolateColorCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mInterpolateScaleCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mTargetPositionCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mTargetLinearCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mWindCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mRibbonCheckBox->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); - mTargetKeyInput->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mTargetKeyInput->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); - mAcellerationXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mAcellerationYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mAcellerationZSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mAcellerationXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mAcellerationYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mAcellerationZSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); - mOmegaXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mOmegaYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mOmegaZSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mOmegaXSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mOmegaYSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mOmegaZSpinner->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); - mStartColorSelector->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); - mEndColorSelector->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange,this)); + mStartColorSelector->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); + mEndColorSelector->setCommitCallback(boost::bind(&ParticleEditor::onParameterChange, this)); mStartColorSelector->setCanApplyImmediately(TRUE); mEndColorSelector->setCanApplyImmediately(TRUE); @@ -227,7 +227,7 @@ BOOL ParticleEditor::postBuild() void ParticleEditor::clearParticles() { - if(!mObject) + if (!mObject) return; LL_DEBUGS() << "clearing particles from " << mObject->getID() << LL_ENDL; @@ -237,11 +237,11 @@ void ParticleEditor::clearParticles() void ParticleEditor::updateParticles() { - if(!mObject) + if (!mObject) return; clearParticles(); - LLPointer pss=LLViewerPartSourceScript::createPSS(mObject,mParticles); + LLPointer pss = LLViewerPartSourceScript::createPSS(mObject, mParticles); pss->setOwnerUUID(mObject->getID()); pss->setImage(mTexture); @@ -251,9 +251,9 @@ void ParticleEditor::updateParticles() void ParticleEditor::setObject(LLViewerObject* objectp) { - if(objectp) + if (objectp) { - mObject=objectp; + mObject = objectp; LL_DEBUGS() << "adding particles to " << mObject->getID() << LL_ENDL; @@ -263,59 +263,61 @@ void ParticleEditor::setObject(LLViewerObject* objectp) void ParticleEditor::onParameterChange() { - mParticles.mPattern=mPatternMap[mPatternTypeCombo->getSelectedValue()]; - mParticles.mPartImageID=mTexturePicker->getImageAssetID(); + mParticles.mPattern = mPatternMap[mPatternTypeCombo->getSelectedValue()]; + mParticles.mPartImageID = mTexturePicker->getImageAssetID(); // remember the selected texture here to give updateParticles() a UUID to work with - mTexture=LLViewerTextureManager::getFetchedTexture(mTexturePicker->getImageAssetID()); + mTexture = LLViewerTextureManager::getFetchedTexture(mTexturePicker->getImageAssetID()); - if(mTexture->getID()==IMG_DEFAULT || mTexture->getID().isNull()) - mTexture=mDefaultParticleTexture; + if (mTexture->getID() == IMG_DEFAULT || mTexture->getID().isNull()) + { + mTexture = mDefaultParticleTexture; + } // limit burst rate to 0.01 to avoid internal freeze, script still gets the real value - mParticles.mBurstRate=llmax(0.01f,mBurstRateSpinner->getValueF32()); - mParticles.mBurstPartCount=mBurstCountSpinner->getValue().asInteger(); - mParticles.mBurstRadius=mBurstRadiusSpinner->getValueF32(); - mParticles.mInnerAngle=mAngleBeginSpinner->getValueF32(); - mParticles.mOuterAngle=mAngleEndSpinner->getValueF32(); - mParticles.mBurstSpeedMin=mBurstSpeedMinSpinner->getValueF32(); - mParticles.mBurstSpeedMax=mBurstSpeedMaxSpinner->getValueF32(); + mParticles.mBurstRate = llmax(0.01f, mBurstRateSpinner->getValueF32()); + mParticles.mBurstPartCount = mBurstCountSpinner->getValue().asInteger(); + mParticles.mBurstRadius = mBurstRadiusSpinner->getValueF32(); + mParticles.mInnerAngle = mAngleBeginSpinner->getValueF32(); + mParticles.mOuterAngle = mAngleEndSpinner->getValueF32(); + mParticles.mBurstSpeedMin = mBurstSpeedMinSpinner->getValueF32(); + mParticles.mBurstSpeedMax = mBurstSpeedMaxSpinner->getValueF32(); mParticles.mPartData.setStartAlpha(mStartAlphaSpinner->getValueF32()); mParticles.mPartData.setEndAlpha(mEndAlphaSpinner->getValueF32()); - mParticles.mPartData.setStartScale(mScaleStartXSpinner->getValueF32(),mScaleStartYSpinner->getValueF32()); - mParticles.mPartData.setEndScale(mScaleEndXSpinner->getValueF32(),mScaleEndYSpinner->getValueF32()); - mParticles.mMaxAge=mSourceMaxAgeSpinner->getValueF32(); + mParticles.mPartData.setStartScale(mScaleStartXSpinner->getValueF32(), mScaleStartYSpinner->getValueF32()); + mParticles.mPartData.setEndScale(mScaleEndXSpinner->getValueF32(), mScaleEndYSpinner->getValueF32()); + mParticles.mMaxAge = mSourceMaxAgeSpinner->getValueF32(); mParticles.mPartData.setMaxAge(mParticlesMaxAgeSpinner->getValueF32()); // different way to set values here, ask Linden Lab why -Zi - mParticles.mPartData.mStartGlow=mStartGlowSpinner->getValueF32(); - mParticles.mPartData.mEndGlow=mEndGlowSpinner->getValueF32(); + mParticles.mPartData.mStartGlow = mStartGlowSpinner->getValueF32(); + mParticles.mPartData.mEndGlow = mEndGlowSpinner->getValueF32(); - mParticles.mPartData.mBlendFuncSource=mBlendMap[mBlendFuncSrcCombo->getSelectedValue()]; - mParticles.mPartData.mBlendFuncDest=mBlendMap[mBlendFuncDestCombo->getSelectedValue()]; + mParticles.mPartData.mBlendFuncSource = mBlendMap[mBlendFuncSrcCombo->getSelectedValue()]; + mParticles.mPartData.mBlendFuncDest = mBlendMap[mBlendFuncDestCombo->getSelectedValue()]; - U32 flags=0; - if(mBounceCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_BOUNCE_MASK; - if(mEmissiveCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_EMISSIVE_MASK; - if(mFollowSourceCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_FOLLOW_SRC_MASK; - if(mFollowVelocityCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_FOLLOW_VELOCITY_MASK; - if(mInterpolateColorCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_INTERP_COLOR_MASK; - if(mInterpolateScaleCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_INTERP_SCALE_MASK; - if(mTargetPositionCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_TARGET_POS_MASK; - if(mTargetLinearCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_TARGET_LINEAR_MASK; - if(mWindCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_WIND_MASK; - if(mRibbonCheckBox->getValue().asBoolean()) flags|=LLPartData::LL_PART_RIBBON_MASK; + U32 flags = 0; + if (mBounceCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_BOUNCE_MASK; + if (mEmissiveCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_EMISSIVE_MASK; + if (mFollowSourceCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_FOLLOW_SRC_MASK; + if (mFollowVelocityCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_FOLLOW_VELOCITY_MASK; + if (mInterpolateColorCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_INTERP_COLOR_MASK; + if (mInterpolateScaleCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_INTERP_SCALE_MASK; + if (mTargetPositionCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_TARGET_POS_MASK; + if (mTargetLinearCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_TARGET_LINEAR_MASK; + if (mWindCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_WIND_MASK; + if (mRibbonCheckBox->getValue().asBoolean()) flags |= LLPartData::LL_PART_RIBBON_MASK; mParticles.mPartData.setFlags(flags); - mParticles.mTargetUUID=mTargetKeyInput->getValue().asUUID(); + mParticles.mTargetUUID = mTargetKeyInput->getValue().asUUID(); - mParticles.mPartAccel=LLVector3(mAcellerationXSpinner->getValueF32(),mAcellerationYSpinner->getValueF32(),mAcellerationZSpinner->getValueF32()); - mParticles.mAngularVelocity=LLVector3(mOmegaXSpinner->getValueF32(),mOmegaYSpinner->getValueF32(),mOmegaZSpinner->getValueF32()); + mParticles.mPartAccel = LLVector3(mAcellerationXSpinner->getValueF32(), mAcellerationYSpinner->getValueF32(), mAcellerationZSpinner->getValueF32()); + mParticles.mAngularVelocity = LLVector3(mOmegaXSpinner->getValueF32(), mOmegaYSpinner->getValueF32(), mOmegaZSpinner->getValueF32()); - LLColor4 color=mStartColorSelector->get(); - mParticles.mPartData.setStartColor(LLVector3(color.mV[0],color.mV[1],color.mV[2])); - color=mEndColorSelector->get(); - mParticles.mPartData.setEndColor(LLVector3(color.mV[0],color.mV[1],color.mV[2])); + LLColor4 color = mStartColorSelector->get(); + mParticles.mPartData.setStartColor(LLVector3(color.mV[VX], color.mV[VY], color.mV[VZ])); + color = mEndColorSelector->get(); + mParticles.mPartData.setEndColor(LLVector3(color.mV[VX], color.mV[VY], color.mV[VZ])); updateUI(); updateParticles(); @@ -323,20 +325,20 @@ void ParticleEditor::onParameterChange() void ParticleEditor::updateUI() { - U8 pattern=mPatternMap[mPatternTypeCombo->getValue()]; - BOOL dropPattern=(pattern==LLPartSysData::LL_PART_SRC_PATTERN_DROP); - BOOL explodePattern=(pattern==LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE); - BOOL targetLinear=mTargetLinearCheckBox->getValue(); - BOOL interpolateColor=mInterpolateColorCheckBox->getValue(); - BOOL interpolateScale=mInterpolateScaleCheckBox->getValue(); - BOOL targetEnabled=targetLinear | (mTargetPositionCheckBox->getValue().asBoolean() ? TRUE : FALSE); + U8 pattern = mPatternMap[mPatternTypeCombo->getValue()]; + BOOL dropPattern = (pattern == LLPartSysData::LL_PART_SRC_PATTERN_DROP); + BOOL explodePattern = (pattern == LLPartSysData::LL_PART_SRC_PATTERN_EXPLODE); + BOOL targetLinear = mTargetLinearCheckBox->getValue(); + BOOL interpolateColor = mInterpolateColorCheckBox->getValue(); + BOOL interpolateScale = mInterpolateScaleCheckBox->getValue(); + BOOL targetEnabled = targetLinear | (mTargetPositionCheckBox->getValue().asBoolean() ? TRUE : FALSE); mBurstRadiusSpinner->setEnabled(!(targetLinear | (mFollowSourceCheckBox->getValue().asBoolean() ? TRUE : FALSE) | dropPattern)); mBurstSpeedMinSpinner->setEnabled(!(targetLinear | dropPattern)); mBurstSpeedMaxSpinner->setEnabled(!(targetLinear | dropPattern)); // disabling a color swatch does nothing visually, so we also set alpha - LLColor4 endColor=mEndColorSelector->get(); + LLColor4 endColor = mEndColorSelector->get(); endColor.setAlpha(interpolateColor ? 1.0f : 0.0f); mEndAlphaSpinner->setEnabled(interpolateColor); @@ -380,38 +382,38 @@ void ParticleEditor::onTargetPickerButtonClicked() // static void ParticleEditor::startPicking(void* userdata) { - ParticleEditor* self =(ParticleEditor*) userdata; - LLToolObjPicker::getInstance()->setExitCallback(ParticleEditor::onTargetPicked,self); + ParticleEditor* self = (ParticleEditor*) userdata; + LLToolObjPicker::getInstance()->setExitCallback(ParticleEditor::onTargetPicked, self); LLToolMgr::getInstance()->setTransientTool(LLToolObjPicker::getInstance()); } // static void ParticleEditor::onTargetPicked(void* userdata) { - ParticleEditor* self=(ParticleEditor*) userdata; + ParticleEditor* self = (ParticleEditor*)userdata; - LLUUID picked=LLToolObjPicker::getInstance()->getObjectID(); + LLUUID picked = LLToolObjPicker::getInstance()->getObjectID(); LLToolMgr::getInstance()->clearTransientTool(); self->mPickTargetButton->setEnabled(TRUE); self->mPickTargetButton->setToggleState(FALSE); - if(picked.notNull()) + if (picked.notNull()) { self->mTargetKeyInput->setValue(picked.asString()); self->onParameterChange(); } } -std::string ParticleEditor::lslVector(F32 x,F32 y,F32 z) +std::string ParticleEditor::lslVector(F32 x, F32 y, F32 z) { - return llformat("<%f,%f,%f>",x,y,z); + return llformat("<%f,%f,%f>", x, y, z); } std::string ParticleEditor::lslColor(const LLColor4& color) { - return lslVector(color.mV[0],color.mV[1],color.mV[2]); + return lslVector(color.mV[VX], color.mV[VY], color.mV[VZ]); } std::string ParticleEditor::createScript() @@ -454,67 +456,71 @@ default\n\ }\n\ }\n"; - LLUUID targetKey=mTargetKeyInput->getValue().asUUID(); - std::string keyString="llGetKey()"; + LLUUID targetKey = mTargetKeyInput->getValue().asUUID(); + std::string keyString = "llGetKey()"; - if(!targetKey.isNull() && targetKey!=mObject->getID()) - keyString="(key) \""+targetKey.asString()+"\""; + if (targetKey.notNull() && targetKey != mObject->getID()) + { + keyString="(key) \"" + targetKey.asString() + "\""; + } - LLUUID textureKey=mTexture->getID(); + LLUUID textureKey = mTexture->getID(); std::string textureString; - if(!textureKey.isNull() && textureKey!=IMG_DEFAULT && textureKey!=mDefaultParticleTexture->getID()) - textureString=textureKey.asString(); + if (textureKey.notNull() && textureKey != IMG_DEFAULT && textureKey != mDefaultParticleTexture->getID()) + { + textureString = textureKey.asString(); + } - LLStringUtil::replaceString(script,"[PATTERN]",mScriptPatternMap[mPatternTypeCombo->getValue()]); - LLStringUtil::replaceString(script,"[BURST_RADIUS]",mBurstRadiusSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[ANGLE_BEGIN]",mAngleBeginSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[ANGLE_END]",mAngleEndSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[TARGET_KEY]",keyString); - LLStringUtil::replaceString(script,"[START_COLOR]",lslColor(mStartColorSelector->get())); - LLStringUtil::replaceString(script,"[END_COLOR]",lslColor(mEndColorSelector->get())); - LLStringUtil::replaceString(script,"[START_ALPHA]",mStartAlphaSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[END_ALPHA]",mEndAlphaSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[START_GLOW]",mStartGlowSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[END_GLOW]",mEndGlowSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[START_SCALE]",lslVector(mScaleStartXSpinner->getValueF32(),mScaleStartYSpinner->getValueF32(),0.0f)); - LLStringUtil::replaceString(script,"[END_SCALE]",lslVector(mScaleEndXSpinner->getValueF32(),mScaleEndYSpinner->getValueF32(),0.0f)); - LLStringUtil::replaceString(script,"[TEXTURE]",textureString); - LLStringUtil::replaceString(script,"[SOURCE_MAX_AGE]",mSourceMaxAgeSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[PART_MAX_AGE]",mParticlesMaxAgeSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[BURST_RATE]",mBurstRateSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[BURST_COUNT]",mBurstCountSpinner->getValue()); - LLStringUtil::replaceString(script,"[ACCELERATION]",lslVector(mAcellerationXSpinner->getValueF32(),mAcellerationYSpinner->getValueF32(),mAcellerationZSpinner->getValueF32())); - LLStringUtil::replaceString(script,"[OMEGA]",lslVector(mOmegaXSpinner->getValueF32(),mOmegaYSpinner->getValueF32(),mOmegaZSpinner->getValueF32())); - LLStringUtil::replaceString(script,"[BURST_SPEED_MIN]",mBurstSpeedMinSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[BURST_SPEED_MAX]",mBurstSpeedMaxSpinner->getValue().asString()); - LLStringUtil::replaceString(script,"[BLEND_FUNC_SOURCE]",mScriptBlendMap[mBlendFuncSrcCombo->getValue().asString()]); - LLStringUtil::replaceString(script,"[BLEND_FUNC_DEST]",mScriptBlendMap[mBlendFuncDestCombo->getValue().asString()]); + LLStringUtil::replaceString(script,"[PATTERN]", mScriptPatternMap[mPatternTypeCombo->getValue()]); + LLStringUtil::replaceString(script,"[BURST_RADIUS]", mBurstRadiusSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[ANGLE_BEGIN]", mAngleBeginSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[ANGLE_END]", mAngleEndSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[TARGET_KEY]", keyString); + LLStringUtil::replaceString(script,"[START_COLOR]", lslColor(mStartColorSelector->get())); + LLStringUtil::replaceString(script,"[END_COLOR]", lslColor(mEndColorSelector->get())); + LLStringUtil::replaceString(script,"[START_ALPHA]", mStartAlphaSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[END_ALPHA]", mEndAlphaSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[START_GLOW]", mStartGlowSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[END_GLOW]", mEndGlowSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[START_SCALE]", lslVector(mScaleStartXSpinner->getValueF32(), mScaleStartYSpinner->getValueF32(), 0.0f)); + LLStringUtil::replaceString(script,"[END_SCALE]", lslVector(mScaleEndXSpinner->getValueF32(), mScaleEndYSpinner->getValueF32(), 0.0f)); + LLStringUtil::replaceString(script,"[TEXTURE]", textureString); + LLStringUtil::replaceString(script,"[SOURCE_MAX_AGE]", mSourceMaxAgeSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[PART_MAX_AGE]", mParticlesMaxAgeSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[BURST_RATE]", mBurstRateSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[BURST_COUNT]", mBurstCountSpinner->getValue()); + LLStringUtil::replaceString(script,"[ACCELERATION]", lslVector(mAcellerationXSpinner->getValueF32(), mAcellerationYSpinner->getValueF32(), mAcellerationZSpinner->getValueF32())); + LLStringUtil::replaceString(script,"[OMEGA]", lslVector(mOmegaXSpinner->getValueF32(), mOmegaYSpinner->getValueF32(), mOmegaZSpinner->getValueF32())); + LLStringUtil::replaceString(script,"[BURST_SPEED_MIN]", mBurstSpeedMinSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[BURST_SPEED_MAX]", mBurstSpeedMaxSpinner->getValue().asString()); + LLStringUtil::replaceString(script,"[BLEND_FUNC_SOURCE]", mScriptBlendMap[mBlendFuncSrcCombo->getValue().asString()]); + LLStringUtil::replaceString(script,"[BLEND_FUNC_DEST]", mScriptBlendMap[mBlendFuncDestCombo->getValue().asString()]); - std::string delimiter=" |\n "; + std::string delimiter = " |\n "; std::string flagsString; - if(mBounceCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_BOUNCE_MASK"; - if(mEmissiveCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_EMISSIVE_MASK"; - if(mFollowSourceCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_FOLLOW_SRC_MASK"; - if(mFollowVelocityCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_FOLLOW_VELOCITY_MASK"; - if(mInterpolateColorCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_INTERP_COLOR_MASK"; - if(mInterpolateScaleCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_INTERP_SCALE_MASK"; - if(mTargetLinearCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_TARGET_LINEAR_MASK"; - if(mTargetPositionCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_TARGET_POS_MASK"; - if(mWindCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_WIND_MASK"; - if(mRibbonCheckBox->getValue()) - flagsString+=delimiter+"PSYS_PART_RIBBON_MASK"; + if (mBounceCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_BOUNCE_MASK"; + if (mEmissiveCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_EMISSIVE_MASK"; + if (mFollowSourceCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_FOLLOW_SRC_MASK"; + if (mFollowVelocityCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_FOLLOW_VELOCITY_MASK"; + if (mInterpolateColorCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_INTERP_COLOR_MASK"; + if (mInterpolateScaleCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_INTERP_SCALE_MASK"; + if (mTargetLinearCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_TARGET_LINEAR_MASK"; + if (mTargetPositionCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_TARGET_POS_MASK"; + if (mWindCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_WIND_MASK"; + if (mRibbonCheckBox->getValue()) + flagsString += delimiter + "PSYS_PART_RIBBON_MASK"; - LLStringUtil::replaceString(script,"[FLAGS]",flagsString); + LLStringUtil::replaceString(script, "[FLAGS]", flagsString); LL_DEBUGS() << "\n" << script << LL_ENDL; return script; @@ -522,8 +528,8 @@ default\n\ void ParticleEditor::onCopyButtonClicked() { - std::string script=createScript(); - if(!script.empty()) + std::string script = createScript(); + if (!script.empty()) { getWindow()->copyTextToClipboard(utf8str_to_wstring(script)); LLNotificationsUtil::add("ParticleScriptCopiedToClipboard"); @@ -536,21 +542,23 @@ void ParticleEditor::onInjectButtonClicked() LLUUID categoryID; // first try to find the #Firestorm folder - categoryID=gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); + categoryID = gInventory.findCategoryByName(ROOT_FIRESTORM_FOLDER); // if no #Firestorm folder was found, create one - if(categoryID.isNull()) - categoryID=gInventory.createNewCategory(gInventory.getRootFolderID(),LLFolderType::FT_NONE,ROOT_FIRESTORM_FOLDER); + if (categoryID.isNull()) + { + categoryID = gInventory.createNewCategory(gInventory.getRootFolderID(), LLFolderType::FT_NONE, ROOT_FIRESTORM_FOLDER); + } // if still no #Firestorm folder was found, try to find the default "Scripts" folder - if(categoryID.isNull()) + if (categoryID.isNull()) { - std::string scriptFolderName=LLFolderType::lookup(LLFolderType::FT_LSL_TEXT); + std::string scriptFolderName = LLFolderType::lookup(LLFolderType::FT_LSL_TEXT); gInventory.findCategoryByName(scriptFolderName); } // if still no valid folder found bail out and complain - if(categoryID.isNull()) + if (categoryID.isNull()) { LLNotificationsUtil::add("ParticleScriptFindFolderFailed"); return; @@ -558,21 +566,21 @@ void ParticleEditor::onInjectButtonClicked() // setup permissions LLPermissions perm; - perm.init(gAgent.getID(),gAgent.getID(),LLUUID::null,LLUUID::null); - perm.initMasks(PERM_ALL,PERM_ALL,PERM_ALL,PERM_ALL,PERM_ALL); + perm.init(gAgentID, gAgentID, LLUUID::null, LLUUID::null); + perm.initMasks(PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL, PERM_ALL); // create new script inventory item and wait for it to come back (callback) - LLPointer callback=new ParticleScriptCreationCallback(this); + LLPointer callback = new ParticleScriptCreationCallback(this); create_inventory_item( - gAgent.getID(), - gAgent.getSessionID(), + gAgentID, + gAgentSessionID, categoryID, - LLTransactionID::tnull, - PARTICLE_SCRIPT_NAME, - "", - LLAssetType::AT_LSL_TEXT, + LLTransactionID::tnull, + PARTICLE_SCRIPT_NAME, + "", + LLAssetType::AT_LSL_TEXT, LLInventoryType::IT_LSL, - NOT_WEARABLE, + NOT_WEARABLE, perm.getMaskNextOwner(), callback); @@ -583,34 +591,34 @@ void ParticleEditor::callbackReturned(const LLUUID& inventoryItemID) { setCanClose(TRUE); - if(inventoryItemID.isNull()) + if (inventoryItemID.isNull()) { LLNotificationsUtil::add("ParticleScriptCreationFailed"); return; } - mParticleScriptInventoryItem=gInventory.getItem(inventoryItemID); - if(!mParticleScriptInventoryItem) + mParticleScriptInventoryItem = gInventory.getItem(inventoryItemID); + if (!mParticleScriptInventoryItem) { LLNotificationsUtil::add("ParticleScriptNotFound"); return; } - gInventory.updateItem(mParticleScriptInventoryItem); - gInventory.notifyObservers(); + gInventory.updateItem(mParticleScriptInventoryItem); + gInventory.notifyObservers(); //caps import - std::string url=gAgent.getRegion()->getCapability("UpdateScriptAgent"); + std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent"); - if(!url.empty()) + if (!url.empty()) { - std::string script=createScript(); + std::string script = createScript(); - std::string tempFileName=gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"particle_script.lsltxt"); + std::string tempFileName = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "particle_script.lsltxt"); std::ofstream tempFile; tempFile.open(tempFileName.c_str()); - if(!tempFile.is_open()) + if (!tempFile.is_open()) { LLNotificationsUtil::add("ParticleScriptCreateTempFileFailed"); return; @@ -620,13 +628,13 @@ void ParticleEditor::callbackReturned(const LLUUID& inventoryItemID) tempFile.close(); LLSD body; - body["task_id"]=mObject->getID(); // probably has no effect - body["item_id"]=inventoryItemID; - body["target"]="mono"; - body["is_script_running"]=true; + body["task_id"] = mObject->getID(); // probably has no effect + body["item_id"] = inventoryItemID; + body["target"] = "mono"; + body["is_script_running"] = true; // responder will alert us when the job is done - LLHTTPClient::post(url,body,new ParticleScriptUploadResponder(body,tempFileName,LLAssetType::AT_LSL_TEXT,this)); + LLHTTPClient::post(url, body, new ParticleScriptUploadResponder(body, tempFileName, LLAssetType::AT_LSL_TEXT, this)); mMainPanel->setEnabled(FALSE); setCanClose(FALSE); @@ -643,15 +651,15 @@ void ParticleEditor::scriptInjectReturned(const LLSD& content) setCanClose(TRUE); // play it safe, because some time may have passed - LLViewerObject* object=gObjectList.findObject(mObject->getID()); - if(!object) + LLViewerObject* object = gObjectList.findObject(mObject->getID()); + if (!object) { LL_DEBUGS() << "object went away!" << LL_ENDL; mMainPanel->setEnabled(TRUE); return; } - mObject->saveScript(mParticleScriptInventoryItem,TRUE,FALSE); + mObject->saveScript(mParticleScriptInventoryItem, TRUE, FALSE); LLNotificationsUtil::add("ParticleScriptInjected"); delete this; @@ -661,7 +669,7 @@ void ParticleEditor::scriptInjectReturned(const LLSD& content) ParticleScriptCreationCallback::ParticleScriptCreationCallback(ParticleEditor* editor) { - mEditor=editor; + mEditor = editor; } ParticleScriptCreationCallback::~ParticleScriptCreationCallback() @@ -680,9 +688,9 @@ ParticleScriptUploadResponder::ParticleScriptUploadResponder(const LLSD& post_da LLAssetType::EType asset_type, ParticleEditor* editor ) : - LLUpdateAgentInventoryResponder(post_data,file_name,asset_type) + LLUpdateAgentInventoryResponder(post_data, file_name, asset_type) { - mEditor=editor; + mEditor = editor; } void ParticleScriptUploadResponder::uploadComplete(const LLSD& content) diff --git a/indra/newview/particleeditor.h b/indra/newview/particleeditor.h index 4232adb3bb..befb2618ca 100644 --- a/indra/newview/particleeditor.h +++ b/indra/newview/particleeditor.h @@ -72,7 +72,7 @@ class ParticleEditor : public LLFloater void callbackReturned(const LLUUID& inv_item); void scriptInjectReturned(const LLSD& content); - std::string lslVector(F32 x,F32 y,F32 z); + std::string lslVector(F32 x, F32 y, F32 z); std::string lslColor(const LLColor4& color); LLViewerObject* mObject; @@ -83,11 +83,11 @@ class ParticleEditor : public LLFloater LLPartSysData mParticles; - std::map mPatternMap; - std::map mScriptPatternMap; + std::map mPatternMap; + std::map mScriptPatternMap; - std::map mBlendMap; - std::map mScriptBlendMap; + std::map mBlendMap; + std::map mScriptBlendMap; LLPanel* mMainPanel; diff --git a/indra/newview/piemenu.cpp b/indra/newview/piemenu.cpp index 4b7b19e497..28d43dde08 100644 --- a/indra/newview/piemenu.cpp +++ b/indra/newview/piemenu.cpp @@ -26,20 +26,18 @@ */ #include "llviewerprecompiledheaders.h" -#include "linden_common.h" #include "piemenu.h" #include "pieslice.h" #include "pieseparator.h" #include "llviewercontrol.h" #include "llviewerwindow.h" -#include "v2math.h" // copied from LLMenuGL - Remove these lines over there when finished -const S32 PIE_INNER_SIZE=20; // radius of the inner pie circle -const F32 PIE_POPUP_FACTOR=(F32)1.7f; // pie menu size factor on popup -const F32 PIE_POPUP_TIME=(F32)0.25f; // time to shrink from popup size to regular size -const S32 PIE_OUTER_SIZE=96; // radius of the outer pie circle +const S32 PIE_INNER_SIZE = 20; // radius of the inner pie circle +const F32 PIE_POPUP_FACTOR = 1.7f; // pie menu size factor on popup +const F32 PIE_POPUP_TIME = 0.25f; // time to shrink from popup size to regular size +const S32 PIE_OUTER_SIZE = 96; // radius of the outer pie circle // register the pie menu globally as child widget static LLDefaultChildRegistry::Register r1("pie_menu"); @@ -53,71 +51,109 @@ static PieChildRegistry::Register pie_r3("pie_separator"); #define PIE_DRAW_BOUNDING_BOX 0 // debug // pie slice label text positioning -const S32 PIE_X[] = {64,45, 0,-45,-63,-45, 0, 45}; -const S32 PIE_Y[] = { 0,44,73, 44, 0,-44,-73,-44}; +const S32 PIE_X[] = {64, 45, 0, -45, -63, -45, 0, 45}; +const S32 PIE_Y[] = { 0, 44, 73, 44, 0, -44, -73, -44}; PieMenu::PieMenu(const LLContextMenu::Params& p) : - LLContextMenu(p) + LLContextMenu(p), + mCurrentSegment(-1) { LL_DEBUGS() << "PieMenu::PieMenu()" << LL_ENDL; // radius, so we need this *2 - reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); + reshape(PIE_OUTER_SIZE * 2, PIE_OUTER_SIZE * 2, FALSE); // set up the font for the menu - mFont=LLFontGL::getFont(LLFontDescriptor("SansSerif","Pie",LLFontGL::NORMAL)); - if(!mFont) + mFont = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Pie", LLFontGL::NORMAL)); + if (!mFont) { LL_WARNS() << "Could not find font size for Pie menu, falling back to Small font." << LL_ENDL; - mFont=LLFontGL::getFont(LLFontDescriptor("SansSerif","Small",LLFontGL::NORMAL)); + mFont = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::NORMAL)); } // set slices pointer to our own slices - mSlices=&mMySlices; + mSlices = &mMySlices; // this will be the first click on the menu - mFirstClick=TRUE; + mFirstClick = true; // clean initialisation - mSlice=0; + mSlice = NULL; } -bool PieMenu::addChild(LLView* child,S32 tab_group) +bool PieMenu::addChild(LLView* child, S32 tab_group) { // don't add invalid slices - if(!child) + if (!child) + { return FALSE; + } // add a new slice to the menu mSlices->push_back(child); // tell the view that our menu has changed and reshape it back to correct size LLUICtrl::addChild(child); - reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); + reshape(PIE_OUTER_SIZE * 2, PIE_OUTER_SIZE * 2, FALSE); + return TRUE; } void PieMenu::removeChild(LLView* child) { // remove a slice from the menu - slice_list_t::iterator found_it=std::find(mSlices->begin(),mSlices->end(),child); - if(found_it!=mSlices->end()) + slice_list_t::iterator found_it = std::find(mSlices->begin(), mSlices->end(), child); + if (found_it != mSlices->end()) { mSlices->erase(found_it); } // tell the view that our menu has changed and reshape it back to correct size LLUICtrl::removeChild(child); - reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); + reshape(PIE_OUTER_SIZE * 2, PIE_OUTER_SIZE * 2, FALSE); } -BOOL PieMenu::handleHover(S32 x,S32 y,MASK mask) +BOOL PieMenu::handleHover(S32 x, S32 y, MASK mask) { - // do nothing + // initialize pie scale factor for popup effect + F32 factor = getScaleFactor(); + + // initially, the current segment is marked as invalid + mCurrentSegment = -1; + + // remember to take the UI scaling into account + LLVector2 scale = gViewerWindow->getDisplayScale(); + // move mouse coordinates to be relative to the pie center + LLVector2 mouseVector(x - PIE_OUTER_SIZE / scale.mV[VX], y - PIE_OUTER_SIZE / scale.mV[VY]); + + // get the distance from the center point + F32 distance = mouseVector.length(); + + // check if our mouse pointer is within the pie slice area + if (distance > PIE_INNER_SIZE && (distance < (PIE_OUTER_SIZE * factor) || mFirstClick)) + { + // get the angle of the mouse pointer from the center in radians + F32 angle = acos(mouseVector.mV[VX] / distance); + // if the mouse is below the middle of the pie, reverse the angle + if (mouseVector.mV[VY] < 0) + { + angle = F_PI * 2 - angle; + } + // rotate the angle slightly so the slices' centers are aligned correctly + angle += F_PI / 8; + + // calculate slice number from the angle + mCurrentSegment = (S32) (8.f * angle / (F_PI * 2.f)) % 8; + } + return TRUE; } void PieMenu::show(S32 x, S32 y, LLView* spawning_view) { // if the menu is already there, do nothing - if(getVisible()) + if (getVisible()) + { return; + } + + mCurrentSegment = -1; // play a sound make_ui_sound("UISndPieMenuAppear"); @@ -125,41 +161,49 @@ void PieMenu::show(S32 x, S32 y, LLView* spawning_view) LL_DEBUGS() << "PieMenu::show(): " << x << " " << y << LL_ENDL; // make sure the menu is always the correct size - reshape(PIE_OUTER_SIZE*2,PIE_OUTER_SIZE*2,FALSE); + reshape(PIE_OUTER_SIZE * 2, PIE_OUTER_SIZE * 2, FALSE); // remember our center point - mCenterX=x; - mCenterY=y; + mCenterX = x; + mCenterY = y; // get the 3D view rectangle - LLRect screen=LLMenuGL::sMenuContainer->getMenuRect(); + LLRect screen = LLMenuGL::sMenuContainer->getMenuRect(); // check if the pie menu is out of bounds and move it accordingly - if(x-PIE_OUTER_SIZE<0) - x=PIE_OUTER_SIZE; - else if(x+PIE_OUTER_SIZE>screen.getWidth()) - x=screen.getWidth()-PIE_OUTER_SIZE; + if (x - PIE_OUTER_SIZE < 0) + { + x = PIE_OUTER_SIZE; + } + else if (x + PIE_OUTER_SIZE > screen.getWidth()) + { + x = screen.getWidth() - PIE_OUTER_SIZE; + } - if(y-PIE_OUTER_SIZEscreen.getHeight()) - y=screen.getHeight()-PIE_OUTER_SIZE+screen.mBottom; + if (y - PIE_OUTER_SIZE < screen.mBottom) + { + y = PIE_OUTER_SIZE + screen.mBottom; + } + else if (y + PIE_OUTER_SIZE - screen.mBottom > screen.getHeight()) + { + y = screen.getHeight() - PIE_OUTER_SIZE + screen.mBottom; + } // move the mouse pointer into the center of the menu - LLUI::setMousePositionLocal(getParent(),x,y); + LLUI::setMousePositionLocal(getParent(), x, y); // set our drawing origin to the center of the menu, taking UI scale into account - LLVector2 scale=gViewerWindow->getDisplayScale(); - setOrigin(x-PIE_OUTER_SIZE/scale.mV[VX],y-PIE_OUTER_SIZE/scale.mV[VY]); + LLVector2 scale = gViewerWindow->getDisplayScale(); + setOrigin(x - PIE_OUTER_SIZE / scale.mV[VX], y - PIE_OUTER_SIZE / scale.mV[VY]); // grab mouse control gFocusMgr.setMouseCapture(this); // this was the first click for the menu - mFirstClick=TRUE; + mFirstClick = true; // set up the slices pointer to the menu's own slices - mSlices=&mMySlices; + mSlices = &mMySlices; // reset enable update checks for slices - for (slice_list_t::iterator it = mSlices->begin(); it != mSlices->end(); it++) + for (slice_list_t::iterator it = mSlices->begin(); it != mSlices->end(); ++it) { PieSlice* resetSlice = dynamic_cast(*it); if (resetSlice) @@ -169,8 +213,8 @@ void PieMenu::show(S32 x, S32 y, LLView* spawning_view) } // cleanup - mSlice=0; - mOldSlice=0; + mSlice = NULL; + mOldSlice = NULL; // draw the menu on screen setVisible(TRUE); @@ -180,15 +224,18 @@ void PieMenu::show(S32 x, S32 y, LLView* spawning_view) void PieMenu::hide() { // if the menu is already hidden, do nothing - if(!getVisible()) + if (!getVisible()) + { return; + } // make a sound when hiding make_ui_sound("UISndPieMenuHide"); LL_DEBUGS() << "Clearing selections" << LL_ENDL; - mSlices=&mMySlices; + mCurrentSegment = -1; + mSlices = &mMySlices; #if PIE_POPUP_EFFECT // safety in case the timer was still running mPopupTimer.stop(); @@ -199,7 +246,7 @@ void PieMenu::hide() void PieMenu::setVisible(BOOL visible) { // hide the menu if needed - if(!visible) + if (!visible) { hide(); // clear all menus and temporary selections @@ -207,53 +254,28 @@ void PieMenu::setVisible(BOOL visible) } } -void PieMenu::draw( void ) +void PieMenu::draw() { // save the current OpenGL drawing matrix so we can freely modify it gGL.pushMatrix(); // save the widget's rectangle for later use - LLRect r=getRect(); + LLRect r = getRect(); // initialize pie scale factor for popup effect - F32 factor=1.f; - -#if PIE_POPUP_EFFECT - // set the popup size if this was the first click on the menu - if(mFirstClick) - { - factor=PIE_POPUP_FACTOR; - } - // otherwise check if the popup timer is still running - else if(mPopupTimer.getStarted()) - { - // if the timer ran past the popup time, stop the timer and set the size to 1.0 - F32 elapsedTime=mPopupTimer.getElapsedTimeF32(); - if(elapsedTime>PIE_POPUP_TIME) - { - factor=1.f; - mPopupTimer.stop(); - } - // otherwise calculate the size factor to make the menu shrink over time - else - { - factor=PIE_POPUP_FACTOR-(PIE_POPUP_FACTOR-1.f)*elapsedTime/PIE_POPUP_TIME; - } -// setRect(r); // obsolete? - } -#endif + F32 factor = getScaleFactor(); #if PIE_DRAW_BOUNDING_BOX // draw a bounding box around the menu for debugging purposes - gl_rect_2d(0,r.getHeight(),r.getWidth(),0,LLColor4::white,FALSE); + gl_rect_2d(0, r.getHeight(), r.getWidth(), 0, LLColor4::white, FALSE); #endif // set up pie menu colors - LLColor4 lineColor=LLUIColorTable::instance().getColor("PieMenuLineColor"); - LLColor4 selectedColor=LLUIColorTable::instance().getColor("PieMenuSelectedColor"); - LLColor4 textColor=LLUIColorTable::instance().getColor("PieMenuTextColor"); - LLColor4 bgColor=LLUIColorTable::instance().getColor("PieMenuBgColor"); - LLColor4 borderColor=bgColor % (F32)0.3f; + LLColor4 lineColor = LLUIColorTable::instance().getColor("PieMenuLineColor"); + LLColor4 selectedColor = LLUIColorTable::instance().getColor("PieMenuSelectedColor"); + LLColor4 textColor = LLUIColorTable::instance().getColor("PieMenuTextColor"); + LLColor4 bgColor = LLUIColorTable::instance().getColor("PieMenuBgColor"); + LLColor4 borderColor = bgColor % 0.3f; // if the user wants their own colors, apply them here static LLCachedControl sOverridePieColors(gSavedSettings, "OverridePieColors", false); @@ -261,84 +283,58 @@ void PieMenu::draw( void ) { static LLCachedControl sPieMenuOpacity(gSavedSettings, "PieMenuOpacity"); static LLCachedControl sPieMenuFade(gSavedSettings, "PieMenuFade"); - bgColor=LLUIColorTable::instance().getColor("PieMenuBgColorOverride") % sPieMenuOpacity; - borderColor=bgColor % (1.f - sPieMenuFade); - selectedColor=LLUIColorTable::instance().getColor("PieMenuSelectedColorOverride"); + bgColor = LLUIColorTable::instance().getColor("PieMenuBgColorOverride") % sPieMenuOpacity; + borderColor = bgColor % (1.f - sPieMenuFade); + selectedColor = LLUIColorTable::instance().getColor("PieMenuSelectedColorOverride"); } // on first click, make the menu fade out to indicate "borderless" operation - if(mFirstClick) - borderColor%=0.f; - - // initially, the current segment is marked as invalid - S32 currentSegment=-1; - - // get the current mouse pointer position local to the pie - S32 x,y; - LLUI::getMousePositionLocal(this,&x,&y); - // remember to take the UI scaling into account - LLVector2 scale=gViewerWindow->getDisplayScale(); - // move mouse coordinates to be relative to the pie center - LLVector2 mouseVector(x-PIE_OUTER_SIZE/scale.mV[VX],y-PIE_OUTER_SIZE/scale.mV[VY]); - - // get the distance from the center point - F32 distance=mouseVector.length(); - // check if our mouse pointer is within the pie slice area - if(distance>PIE_INNER_SIZE && (distance<(PIE_OUTER_SIZE*factor) || mFirstClick)) + if (mFirstClick) { - // get the angle of the mouse pointer from the center in radians - F32 angle=acos(mouseVector.mV[VX]/distance); - // if the mouse is below the middle of the pie, reverse the angle - if(mouseVector.mV[VY]<0) - angle=F_PI*2-angle; - // rotate the angle slightly so the slices' centers are aligned correctly - angle+=F_PI/8; - - // calculate slice number from the angle - currentSegment=(S32) (8.f*angle/(F_PI*2.f)) % 8; + borderColor %= 0.f; } // move origin point to the center of our rectangle gGL.translatef(r.getWidth() / 2, r.getHeight() / 2, 0); // draw the general pie background - gl_washer_2d(PIE_OUTER_SIZE*factor,PIE_INNER_SIZE,32,bgColor,borderColor); + gl_washer_2d(PIE_OUTER_SIZE * factor, PIE_INNER_SIZE, 32, bgColor, borderColor); // set up an item list iterator to point at the beginning of the item list slice_list_t::iterator cur_item_iter; - cur_item_iter=mSlices->begin(); + cur_item_iter = mSlices->begin(); // clear current slice pointer - mSlice=0; + mSlice = NULL; // current slice number is 0 - S32 num=0; - BOOL wasAutohide=FALSE; + S32 num = 0; + bool wasAutohide = false; do { // standard item text color - LLColor4 itemColor=textColor; + LLColor4 itemColor = textColor; // clear the label and set up the starting angle to draw in std::string label(""); - F32 segmentStart = F_PI/4.f * (F32)num - F_PI / 8.f; + F32 segmentStart = F_PI / 4.f * (F32)num - F_PI / 8.f; // iterate through the list of slices - if(cur_item_iter!=mSlices->end()) + if (cur_item_iter != mSlices->end()) { // get current slice item - LLView* item=(*cur_item_iter); + LLView* item = (*cur_item_iter); // check if this is a submenu or a normal click slice - PieSlice* currentSlice=dynamic_cast(item); - PieMenu* currentSubmenu=dynamic_cast(item); + PieSlice* currentSlice = dynamic_cast(item); + PieMenu* currentSubmenu = dynamic_cast(item); // advance internally to the next slice item cur_item_iter++; // in case it is regular click slice - if(currentSlice) + if (currentSlice) { // get the slice label and tell the slice to check if it's supposed to be visible - label=currentSlice->getLabel(); + label = currentSlice->getLabel(); currentSlice->updateVisible(); // disable it if it's not visible, pie slices never really disappear BOOL slice_visible = currentSlice->getVisible(); @@ -350,68 +346,81 @@ void PieMenu::draw( void ) } // if the current slice is the start of an autohide chain, clear out previous chains - if(currentSlice->getStartAutohide()) - wasAutohide=FALSE; + if (currentSlice->getStartAutohide()) + { + wasAutohide = false; + } // check if the current slice is part of an autohide chain - if(currentSlice->getAutohide()) + if (currentSlice->getAutohide()) { // if the previous item already won the autohide, skip this item - if(wasAutohide) + if (wasAutohide) + { continue; + } + // look at the next item in the pie - LLView* lookAhead=(*cur_item_iter); + LLView* lookAhead = (*cur_item_iter); // check if this is a normal click slice - PieSlice* lookSlice=dynamic_cast(lookAhead); - if(lookSlice) + PieSlice* lookSlice = dynamic_cast(lookAhead); + if (lookSlice) { // if the next item is part of the current autohide chain as well ... - if(lookSlice->getAutohide() && !lookSlice->getStartAutohide()) + if (lookSlice->getAutohide() && !lookSlice->getStartAutohide()) { // ... it's visible and it's enabled, skip the current one. // the first visible and enabled item in autohide chains wins // this is useful for Sit/Stand toggles lookSlice->updateEnabled(); lookSlice->updateVisible(); - if(lookSlice->getVisible() && lookSlice->getEnabled()) + if (lookSlice->getVisible() && lookSlice->getEnabled()) + { continue; + } + // this item won the autohide contest - wasAutohide=TRUE; + wasAutohide = true; } } } else + { // reset autohide chain - wasAutohide=FALSE; + wasAutohide = false; + } + // check if the slice is currently enabled currentSlice->updateEnabled(); - if(!currentSlice->getEnabled()) + if (!currentSlice->getEnabled()) { LL_DEBUGS() << label << " is disabled" << LL_ENDL; // fade the item color alpha to mark the item as disabled - itemColor%=(F32)0.3f; + itemColor %= 0.3f; } } // if it's a submenu just get the label - else if(currentSubmenu) - label=currentSubmenu->getLabel(); + else if (currentSubmenu) + { + label = currentSubmenu->getLabel(); + } // if it's a slice or submenu, the mouse pointer is over the same segment as our counter and the item is enabled - if((currentSlice || currentSubmenu) && (currentSegment==num) && item->getEnabled()) + if ((currentSlice || currentSubmenu) && (mCurrentSegment == num) && item->getEnabled()) { // memorize the currently highlighted slice for later - mSlice=item; + mSlice = item; // if we highlighted a different slice than before, we must play a sound - if(mOldSlice!=mSlice) + if (mOldSlice != mSlice) { // get the appropriate UI sound and play it - char soundNum='0'+num; - std::string soundName="UISndPieMenuSliceHighlight"; - soundName+=soundNum; + char soundNum = '0' + num; + std::string soundName = "UISndPieMenuSliceHighlight"; + soundName += soundNum; make_ui_sound(soundName.c_str()); // remember which slice we highlighted last, so we only play the sound once - mOldSlice=mSlice; + mOldSlice = mSlice; } // draw the currently highlighted pie slice @@ -434,12 +443,14 @@ void PieMenu::draw( void ) // next slice num++; } - while(num<8); // do this until the menu is full + while (num < 8); // do this until the menu is full // draw inner and outer circle, outer only if it was not the first click - if(!mFirstClick) + if (!mFirstClick) + { gl_washer_2d(PIE_OUTER_SIZE * factor, PIE_OUTER_SIZE * factor - 2.f, 32, lineColor, borderColor); - gl_washer_2d(PIE_INNER_SIZE+1,PIE_INNER_SIZE-1,16,borderColor,lineColor); + } + gl_washer_2d(PIE_INNER_SIZE + 1, PIE_INNER_SIZE - 1, 16, borderColor, lineColor); // restore OpenGL drawing matrix gGL.popMatrix(); @@ -451,8 +462,10 @@ void PieMenu::draw( void ) BOOL PieMenu::appendContextSubMenu(PieMenu* menu) { LL_DEBUGS() << "PieMenu::appendContextSubMenu()" << LL_ENDL; - if(!menu) + if (!menu) + { return FALSE; + } LL_DEBUGS() << "PieMenu::appendContextSubMenu() appending " << menu->getLabel() << " to " << getLabel() << LL_ENDL; @@ -460,28 +473,29 @@ BOOL PieMenu::appendContextSubMenu(PieMenu* menu) mSlices->push_back(menu); // tell the view that our menu has changed LLUICtrl::addChild(menu); + return TRUE; } -BOOL PieMenu::handleMouseUp(S32 x,S32 y,MASK mask) +BOOL PieMenu::handleMouseUp(S32 x, S32 y, MASK mask) { // left and right mouse buttons both do the same thing currently - return handleMouseButtonUp(x,y,mask); + return handleMouseButtonUp(x, y, mask); } -BOOL PieMenu::handleRightMouseUp(S32 x,S32 y,MASK mask) +BOOL PieMenu::handleRightMouseUp(S32 x, S32 y, MASK mask) { // left and right mouse buttons both do the same thing currently - return handleMouseButtonUp(x,y,mask); + return handleMouseButtonUp(x, y, mask); } // left and right mouse buttons both do the same thing currently -BOOL PieMenu::handleMouseButtonUp(S32 x,S32 y,MASK mask) +BOOL PieMenu::handleMouseButtonUp(S32 x, S32 y, MASK mask) { // if this was the first click and no slice is highlighted (no borderless click), start the popup timer - if(mFirstClick && !mSlice) + if (mFirstClick && !mSlice) { - mFirstClick=FALSE; + mFirstClick = false; #if PIE_POPUP_EFFECT mPopupTimer.start(); #endif @@ -489,11 +503,11 @@ BOOL PieMenu::handleMouseButtonUp(S32 x,S32 y,MASK mask) else { // default to invisible - BOOL visible=FALSE; + BOOL visible = FALSE; // get the current selected slice and check if this is a regular click slice - PieSlice* currentSlice=dynamic_cast(mSlice); - if(currentSlice) + PieSlice* currentSlice = dynamic_cast(mSlice); + if (currentSlice) { // if so, click it and make a sound make_ui_sound("UISndClickRelease"); @@ -502,15 +516,15 @@ BOOL PieMenu::handleMouseButtonUp(S32 x,S32 y,MASK mask) else { // check if this was a submenu - PieMenu* currentSubmenu=dynamic_cast(mSlice); - if(currentSubmenu) + PieMenu* currentSubmenu = dynamic_cast(mSlice); + if (currentSubmenu) { // if so, remember we clicked the menu already at least once - mFirstClick=FALSE; + mFirstClick = false; // swap out the list of items for the ones in the submenu - mSlices=¤tSubmenu->mMySlices; + mSlices = ¤tSubmenu->mMySlices; // reset enable update checks for slices - for (slice_list_t::iterator it = mSlices->begin(); it != mSlices->end(); it++) + for (slice_list_t::iterator it = mSlices->begin(); it != mSlices->end(); ++it) { PieSlice* resetSlice = dynamic_cast(*it); if (resetSlice) @@ -519,7 +533,7 @@ BOOL PieMenu::handleMouseButtonUp(S32 x,S32 y,MASK mask) } } // the menu stays visible - visible=TRUE; + visible = TRUE; #if PIE_POPUP_EFFECT // restart the popup timer mPopupTimer.reset(); @@ -533,9 +547,44 @@ BOOL PieMenu::handleMouseButtonUp(S32 x,S32 y,MASK mask) setVisible(visible); } // release mouse capture after the first click if we still have it grabbed - if(hasMouseCapture()) + if (hasMouseCapture()) + { gFocusMgr.setMouseCapture(NULL); + } // give control back to the system - return LLView::handleMouseUp(x,y,mask); + return LLView::handleMouseUp(x, y, mask); } + +F32 PieMenu::getScaleFactor() +{ + // initialize pie scale factor for popup effect + F32 factor = 1.f; + +#if PIE_POPUP_EFFECT + // set the popup size if this was the first click on the menu + if (mFirstClick) + { + factor = PIE_POPUP_FACTOR; + } + // otherwise check if the popup timer is still running + else if (mPopupTimer.getStarted()) + { + // if the timer ran past the popup time, stop the timer and set the size to 1.0 + F32 elapsedTime = mPopupTimer.getElapsedTimeF32(); + if (elapsedTime > PIE_POPUP_TIME) + { + factor = 1.f; + mPopupTimer.stop(); + } + // otherwise calculate the size factor to make the menu shrink over time + else + { + factor = PIE_POPUP_FACTOR - (PIE_POPUP_FACTOR - 1.f) * elapsedTime / PIE_POPUP_TIME; + } +// setRect(r); // obsolete? + } + + return factor; +#endif +} \ No newline at end of file diff --git a/indra/newview/piemenu.h b/indra/newview/piemenu.h index 3b1096c9b6..d986f740b1 100644 --- a/indra/newview/piemenu.h +++ b/indra/newview/piemenu.h @@ -45,7 +45,7 @@ class PieMenu : public LLContextMenu Params() { - visible=false; + visible = false; } }; @@ -57,7 +57,7 @@ class PieMenu : public LLContextMenu /*virtual*/ void setVisible(BOOL visible); // adding and removing "child" slices to the pie - /*virtual*/ bool addChild(LLView* child,S32 tab_group=0); + /*virtual*/ bool addChild(LLView* child, S32 tab_group = 0); /*virtual*/ void removeChild(LLView* child); /*virtual*/ BOOL handleHover(S32 x,S32 y,MASK mask); @@ -90,7 +90,7 @@ class PieMenu : public LLContextMenu protected: // general mouse button handling - BOOL handleMouseButtonUp(S32 x,S32 y,MASK mask); + BOOL handleMouseButtonUp(S32 x, S32 y, MASK mask); // font used for the menu const LLFontGL* mFont; // currently highlighted item, must be tested if it's a slice or submenu @@ -104,7 +104,11 @@ class PieMenu : public LLContextMenu S32 mCenterX; S32 mCenterY; // this is TRUE when the first mouseclick came to display the menu, used for borderless menu - BOOL mFirstClick; + bool mFirstClick; + + F32 getScaleFactor(); + + S32 mCurrentSegment; }; #endif // PIEMENU_H diff --git a/indra/newview/pieseparator.cpp b/indra/newview/pieseparator.cpp index a1621417e7..b20cdca5fc 100644 --- a/indra/newview/pieseparator.cpp +++ b/indra/newview/pieseparator.cpp @@ -26,7 +26,6 @@ */ #include "llviewerprecompiledheaders.h" -#include "linden_common.h" #include "pieseparator.h" @@ -40,5 +39,5 @@ PieSeparator::PieSeparator(const PieSeparator::Params& p) : // pick up parameters from the XUI definition PieSeparator::Params::Params() { - name="pie_separator"; + name = "pie_separator"; } diff --git a/indra/newview/pieseparator.h b/indra/newview/pieseparator.h index 376fa0c334..17c0e059f8 100644 --- a/indra/newview/pieseparator.h +++ b/indra/newview/pieseparator.h @@ -28,7 +28,6 @@ #ifndef PIESEPARATOR_H #define PIESEPARATOR_H -#include "llinitparam.h" #include "lluictrl.h" // a pie slice that does nothing and is not highlighting by mouse hover diff --git a/indra/newview/pieslice.cpp b/indra/newview/pieslice.cpp index 5a1a336a02..c4041aada2 100644 --- a/indra/newview/pieslice.cpp +++ b/indra/newview/pieslice.cpp @@ -47,9 +47,9 @@ PieSlice::Params::Params() : on_click("on_click"), on_visible("on_visible"), on_enable("on_enable"), - start_autohide("start_autohide",FALSE), - autohide("autohide",FALSE), - check_enable_once("check_enable_once",FALSE) + start_autohide("start_autohide", FALSE), + autohide("autohide", FALSE), + check_enable_once("check_enable_once", FALSE) { } @@ -57,7 +57,7 @@ PieSlice::Params::Params() : void PieSlice::initFromParams(const Params& p) { // add a callback if on_click is provided - if(p.on_click.isProvided()) + if (p.on_click.isProvided()) { setCommitCallback(initCommitCallback(p.on_click)); } @@ -87,12 +87,12 @@ void PieSlice::initFromParams(const Params& p) // call this to make the menu update its "enabled" status void PieSlice::updateEnabled() { - if(mDoUpdateEnabled && mEnableSignal.num_slots()>0) + if (mDoUpdateEnabled && mEnableSignal.num_slots() > 0) { - bool enabled=mEnableSignal(this,LLSD()); - if(mEnabledControlVariable) + bool enabled = mEnableSignal(this, LLSD()); + if (mEnabledControlVariable) { - if(!enabled) + if (!enabled) { // callback overrides control variable; this will call setEnabled() mEnabledControlVariable->set(false); @@ -110,9 +110,9 @@ void PieSlice::updateEnabled() // call this to make the menu update its "visible" status void PieSlice::updateVisible() { - if(mVisibleSignal.num_slots()>0) + if (mVisibleSignal.num_slots() > 0) { - bool visible=mVisibleSignal(this,LLSD()); + bool visible = mVisibleSignal(this, LLSD()); setVisible(visible); } } @@ -138,7 +138,7 @@ std::string PieSlice::getLabel() const // accessor void PieSlice::setLabel(const std::string newLabel) { - mLabel=newLabel; + mLabel = newLabel; } // accessor diff --git a/indra/newview/pieslice.h b/indra/newview/pieslice.h index e20784372d..692016b3df 100644 --- a/indra/newview/pieslice.h +++ b/indra/newview/pieslice.h @@ -28,9 +28,6 @@ #ifndef PIESLICE_H #define PIESLICE_H -#include - -#include "llinitparam.h" #include "lluictrl.h" // A slice in the pie. Does nothing by itself, just stores the function and diff --git a/indra/newview/quickprefs.cpp b/indra/newview/quickprefs.cpp index 46ef93150b..f098389d6c 100644 --- a/indra/newview/quickprefs.cpp +++ b/indra/newview/quickprefs.cpp @@ -1402,6 +1402,12 @@ void FloaterQuickPrefs::onValuesChanged() return; } + // don't crash when we try to update values without having a control selected + if(mSelectedControl=="") + { + return; + } + // remember the current and possibly new control names std::string old_control_name=mSelectedControl; std::string new_control_name=mControlNameCombo->getValue(); diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp index 3fa5ad31cd..18d4df4aff 100644 --- a/indra/newview/rlvcommon.cpp +++ b/indra/newview/rlvcommon.cpp @@ -357,6 +357,12 @@ void RlvStrings::setCustomString(const std::string& strStringName, const std::st bool RlvUtil::m_fForceTp = false; +std::string escape_for_regex(const std::string& str) +{ + using namespace boost; + return regex_replace(str, regex("[.^$|()\\[\\]{}*+?\\\\]"), "\\\\&", match_default|format_sed); +} + // Checked: 2009-07-04 (RLVa-1.0.0a) | Modified: RLVa-1.0.0a void RlvUtil::filterLocation(std::string& strUTF8Text) { @@ -364,12 +370,12 @@ void RlvUtil::filterLocation(std::string& strUTF8Text) LLWorld::region_list_t regions = LLWorld::getInstance()->getRegionList(); const std::string& strHiddenRegion = RlvStrings::getString(RLV_STRING_HIDDEN_REGION); for (LLWorld::region_list_t::const_iterator itRegion = regions.begin(); itRegion != regions.end(); ++itRegion) - boost::replace_all_regex(strUTF8Text, boost::regex("\\b" + (*itRegion)->getName() + "\\b", boost::regex::icase), strHiddenRegion); + boost::replace_all_regex(strUTF8Text, boost::regex("\\b" + escape_for_regex((*itRegion)->getName()) + "\\b", boost::regex::icase), strHiddenRegion); // Filter any mention of the parcel name LLViewerParcelMgr* pParcelMgr = LLViewerParcelMgr::getInstance(); if (pParcelMgr) - boost::replace_all_regex(strUTF8Text, boost::regex("\\b" + pParcelMgr->getAgentParcelName() + "\\b", boost::regex::icase), RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL)); + boost::replace_all_regex(strUTF8Text, boost::regex("\\b" + escape_for_regex(pParcelMgr->getAgentParcelName()) + "\\b", boost::regex::icase), RlvStrings::getString(RLV_STRING_HIDDEN_PARCEL)); } // Checked: 2010-12-08 (RLVa-1.2.2c) | Modified: RLVa-1.2.2c @@ -382,7 +388,7 @@ void RlvUtil::filterNames(std::string& strUTF8Text, bool fFilterLegacy) LLAvatarName avName; if (LLAvatarNameCache::get(idAgents[idxAgent], &avName)) { - const std::string& strDisplayName = avName.getDisplayName(); + const std::string& strDisplayName = escape_for_regex(avName.getDisplayName()); bool fFilterDisplay = (strDisplayName.length() > 2); const std::string& strLegacyName = avName.getLegacyName(); fFilterLegacy &= (strLegacyName.length() > 2); diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp index dbc908fbd3..0f1b06becd 100644 --- a/indra/newview/rlvhandler.cpp +++ b/indra/newview/rlvhandler.cpp @@ -2033,14 +2033,16 @@ ERlvCmdRet RlvHandler::onGetAttach(const RlvCommand& rlvCmd, std::string& strRep { const LLViewerJointAttachment* pAttachPt = itAttach->second; // FIRE-11848 @getattach includes the LSL bridge - if (pAttachPt->getName() == FS_BRIDGE_ATTACHMENT_POINT_NAME) + if (pAttachPt->getName() == "Bridge") { continue; } // FIRE-11848 if ( (0 == idxAttachPt) || (itAttach->first == idxAttachPt) ) { - bool fWorn = (pAttachPt->getNumObjects() > 0) && + // Ansa: Do not include the bridge when checking for number of objects + S32 bridge_correct = (pAttachPt->getName() == FS_BRIDGE_ATTACHMENT_POINT_NAME && FSLSLBridge::instance().isBridgeValid()) ? 1 : 0; + bool fWorn = ((pAttachPt->getNumObjects() - bridge_correct) > 0) && ( (!RlvSettings::getHideLockedAttach()) || (RlvForceWear::isForceDetachable(pAttachPt, true, rlvCmd.getObjectID())) ); strReply.push_back( (fWorn) ? '1' : '0' ); } @@ -2064,7 +2066,7 @@ ERlvCmdRet RlvHandler::onGetAttachNames(const RlvCommand& rlvCmd, std::string& s { const LLViewerJointAttachment* pAttachPt = itAttach->second; // FIRE-11848 @getattach includes the LSL bridge - if (pAttachPt->getName() == FS_BRIDGE_ATTACHMENT_POINT_NAME) + if (pAttachPt->getName() == "Bridge") { continue; } @@ -2075,7 +2077,11 @@ ERlvCmdRet RlvHandler::onGetAttachNames(const RlvCommand& rlvCmd, std::string& s switch (rlvCmd.getBehaviourType()) { case RLV_BHVR_GETATTACHNAMES: // Every attachment point that has an attached object - fAdd = (pAttachPt->getNumObjects() > 0); + // Ansa: Do not include the bridge when checking for number of objects + { + S32 bridge_correct = ((pAttachPt->getName() == FS_BRIDGE_ATTACHMENT_POINT_NAME && FSLSLBridge::instance().isBridgeValid()) ? 1 : 0); + fAdd = ((pAttachPt->getNumObjects() - bridge_correct) > 0); + } break; case RLV_BHVR_GETADDATTACHNAMES: // Every attachment point that can be attached to (wear replace OR wear add) fAdd = (gRlvAttachmentLocks.canAttach(pAttachPt) & RLV_WEAR); diff --git a/indra/newview/roles_constants.h b/indra/newview/roles_constants.h index effd15ea72..8fd7978fa1 100755 --- a/indra/newview/roles_constants.h +++ b/indra/newview/roles_constants.h @@ -53,98 +53,100 @@ enum LLRoleChangeType // KNOWN HOLES: use these for any single bit powers you need // bit 0x1 << 46 -// bit 0x1 << 49 and above +// bit 0x1 << 52 and above // These powers were removed to make group roles simpler // bit 0x1 << 41 (GP_ACCOUNTING_VIEW) // bit 0x1 << 46 (GP_PROPOSAL_VIEW) const U64 GP_NO_POWERS = 0x0; -const U64 GP_ALL_POWERS = 0xFFFFFFFFFFFFFFFFLL; +const U64 GP_ALL_POWERS = 0xFFFFffffFFFFffffLL; // Membership -const U64 GP_MEMBER_INVITE = 0x1 << 1; // Invite member -const U64 GP_MEMBER_EJECT = 0x1 << 2; // Eject member from group -const U64 GP_MEMBER_OPTIONS = 0x1 << 3; // Toggle "Open enrollment" and change "Signup Fee" -const U64 GP_MEMBER_VISIBLE_IN_DIR = 0x1LL << 47; +const U64 GP_MEMBER_INVITE = 0x1LL << 1; // Invite member +const U64 GP_MEMBER_EJECT = 0x1LL << 2; // Eject member from group +const U64 GP_MEMBER_OPTIONS = 0x1LL << 3; // Toggle "Open enrollment" and change "Signup Fee" +const U64 GP_MEMBER_VISIBLE_IN_DIR = 0x1LL << 47; // Roles -const U64 GP_ROLE_CREATE = 0x1 << 4; // Create new roles -const U64 GP_ROLE_DELETE = 0x1 << 5; // Delete roles -const U64 GP_ROLE_PROPERTIES = 0x1 << 6; // Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?) -const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED = 0x1 << 7; // Assign Member to a Role that the assigner is in -const U64 GP_ROLE_ASSIGN_MEMBER = 0x1 << 8; // Assign Member to Role -const U64 GP_ROLE_REMOVE_MEMBER = 0x1 << 9; // Remove Member from Role -const U64 GP_ROLE_CHANGE_ACTIONS = 0x1 << 10; // Change actions a role can perform +const U64 GP_ROLE_CREATE = 0x1LL << 4; // Create new roles +const U64 GP_ROLE_DELETE = 0x1LL << 5; // Delete roles +const U64 GP_ROLE_PROPERTIES = 0x1LL << 6; // Change Role Names, Titles, and Descriptions (Of roles the user is in, only, or any role in group?) +const U64 GP_ROLE_ASSIGN_MEMBER_LIMITED = 0x1LL << 7; // Assign Member to a Role that the assigner is in +const U64 GP_ROLE_ASSIGN_MEMBER = 0x1LL << 8; // Assign Member to Role +const U64 GP_ROLE_REMOVE_MEMBER = 0x1LL << 9; // Remove Member from Role +const U64 GP_ROLE_CHANGE_ACTIONS = 0x1LL << 10; // Change actions a role can perform // Group Identity -const U64 GP_GROUP_CHANGE_IDENTITY = 0x1 << 11; // Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes +const U64 GP_GROUP_CHANGE_IDENTITY = 0x1LL << 11; // Charter, insignia, 'Show In Group List', 'Publish on the web', 'Mature', all 'Show Member In Group Profile' checkboxes // Parcel Management -const U64 GP_LAND_DEED = 0x1 << 12; // Deed Land and Buy Land for Group -const U64 GP_LAND_RELEASE = 0x1 << 13; // Release Land (to Gov. Linden) -const U64 GP_LAND_SET_SALE_INFO = 0x1 << 14; // Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land") -const U64 GP_LAND_DIVIDE_JOIN = 0x1 << 15; // Divide and Join Parcels +const U64 GP_LAND_DEED = 0x1LL << 12; // Deed Land and Buy Land for Group +const U64 GP_LAND_RELEASE = 0x1LL << 13; // Release Land (to Gov. Linden) +const U64 GP_LAND_SET_SALE_INFO = 0x1LL << 14; // Set for sale info (Toggle "For Sale", Set Price, Set Target, Toggle "Sell objects with the land") +const U64 GP_LAND_DIVIDE_JOIN = 0x1LL << 15; // Divide and Join Parcels // Parcel Identity -const U64 GP_LAND_FIND_PLACES = 0x1 << 17; // Toggle "Show in Find Places" and Set Category. -const U64 GP_LAND_CHANGE_IDENTITY = 0x1 << 18; // Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox -const U64 GP_LAND_SET_LANDING_POINT = 0x1 << 19; // Set Landing Point +const U64 GP_LAND_FIND_PLACES = 0x1LL << 17; // Toggle "Show in Find Places" and Set Category. +const U64 GP_LAND_CHANGE_IDENTITY = 0x1LL << 18; // Change Parcel Identity: Parcel Name, Parcel Description, Snapshot, 'Publish on the web', and 'Mature' checkbox +const U64 GP_LAND_SET_LANDING_POINT = 0x1LL << 19; // Set Landing Point // Parcel Settings -const U64 GP_LAND_CHANGE_MEDIA = 0x1 << 20; // Change Media Settings -const U64 GP_LAND_EDIT = 0x1 << 21; // Toggle Edit Land -const U64 GP_LAND_OPTIONS = 0x1 << 22; // Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes +const U64 GP_LAND_CHANGE_MEDIA = 0x1LL << 20; // Change Media Settings +const U64 GP_LAND_EDIT = 0x1LL << 21; // Toggle Edit Land +const U64 GP_LAND_OPTIONS = 0x1LL << 22; // Toggle Set Home Point, Fly, Outside Scripts, Create/Edit Objects, Landmark, and Damage checkboxes // Parcel Powers -const U64 GP_LAND_ALLOW_EDIT_LAND = 0x1 << 23; // Bypass Edit Land Restriction -const U64 GP_LAND_ALLOW_FLY = 0x1 << 24; // Bypass Fly Restriction -const U64 GP_LAND_ALLOW_CREATE = 0x1 << 25; // Bypass Create/Edit Objects Restriction -const U64 GP_LAND_ALLOW_LANDMARK = 0x1 << 26; // Bypass Landmark Restriction -const U64 GP_LAND_ALLOW_SET_HOME = 0x1 << 28; // Bypass Set Home Point Restriction -const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land - +const U64 GP_LAND_ALLOW_EDIT_LAND = 0x1LL << 23; // Bypass Edit Land Restriction +const U64 GP_LAND_ALLOW_FLY = 0x1LL << 24; // Bypass Fly Restriction +const U64 GP_LAND_ALLOW_CREATE = 0x1LL << 25; // Bypass Create/Edit Objects Restriction +const U64 GP_LAND_ALLOW_LANDMARK = 0x1LL << 26; // Bypass Landmark Restriction +const U64 GP_LAND_ALLOW_SET_HOME = 0x1LL << 28; // Bypass Set Home Point Restriction +const U64 GP_LAND_ALLOW_HOLD_EVENT = 0x1LL << 41; // Allowed to hold events on group-owned land // Parcel Access -const U64 GP_LAND_MANAGE_ALLOWED = 0x1 << 29; // Manage Allowed List -const U64 GP_LAND_MANAGE_BANNED = 0x1 << 30; // Manage Banned List -const U64 GP_LAND_MANAGE_PASSES = 0x1LL << 31; // Change Sell Pass Settings -const U64 GP_LAND_ADMIN = 0x1LL << 32; // Eject and Freeze Users on the land +const U64 GP_LAND_MANAGE_ALLOWED = 0x1LL << 29; // Manage Allowed List +const U64 GP_LAND_MANAGE_BANNED = 0x1LL << 30; // Manage Banned List +const U64 GP_LAND_MANAGE_PASSES = 0x1LL << 31; // Change Sell Pass Settings +const U64 GP_LAND_ADMIN = 0x1LL << 32; // Eject and Freeze Users on the land // Parcel Content -const U64 GP_LAND_RETURN_GROUP_SET = 0x1LL << 33; // Return objects on parcel that are set to group -const U64 GP_LAND_RETURN_NON_GROUP = 0x1LL << 34; // Return objects on parcel that are not set to group -const U64 GP_LAND_RETURN_GROUP_OWNED= 0x1LL << 48; // Return objects on parcel that are owned by the group +const U64 GP_LAND_RETURN_GROUP_SET = 0x1LL << 33; // Return objects on parcel that are set to group +const U64 GP_LAND_RETURN_NON_GROUP = 0x1LL << 34; // Return objects on parcel that are not set to group +const U64 GP_LAND_RETURN_GROUP_OWNED = 0x1LL << 48; // Return objects on parcel that are owned by the group // Select a power-bit based on an object's relationship to a parcel. const U64 GP_LAND_RETURN = GP_LAND_RETURN_GROUP_OWNED | GP_LAND_RETURN_GROUP_SET | GP_LAND_RETURN_NON_GROUP; -const U64 GP_LAND_GARDENING = 0x1LL << 35; // Parcel Gardening - plant and move linden trees +const U64 GP_LAND_GARDENING = 0x1LL << 35; // Parcel Gardening - plant and move linden trees // Object Management -const U64 GP_OBJECT_DEED = 0x1LL << 36; // Deed Object -const U64 GP_OBJECT_MANIPULATE = 0x1LL << 38; // Manipulate Group Owned Objects (Move, Copy, Mod) -const U64 GP_OBJECT_SET_SALE = 0x1LL << 39; // Set Group Owned Object for Sale +const U64 GP_OBJECT_DEED = 0x1LL << 36; // Deed Object +const U64 GP_OBJECT_MANIPULATE = 0x1LL << 38; // Manipulate Group Owned Objects (Move, Copy, Mod) +const U64 GP_OBJECT_SET_SALE = 0x1LL << 39; // Set Group Owned Object for Sale // Accounting -const U64 GP_ACCOUNTING_ACCOUNTABLE = 0x1LL << 40; // Pay Group Liabilities and Receive Group Dividends +const U64 GP_ACCOUNTING_ACCOUNTABLE = 0x1LL << 40; // Pay Group Liabilities and Receive Group Dividends // Notices -const U64 GP_NOTICES_SEND = 0x1LL << 42; // Send Notices -const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice History +const U64 GP_NOTICES_SEND = 0x1LL << 42; // Send Notices +const U64 GP_NOTICES_RECEIVE = 0x1LL << 43; // Receive Notices and View Notice History // Proposals // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: -const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal +const U64 GP_PROPOSAL_START = 0x1LL << 44; // Start Proposal // TODO: _DEPRECATED suffix as part of vote removal - DEV-24856: -const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal +const U64 GP_PROPOSAL_VOTE = 0x1LL << 45; // Vote on Proposal // Group chat moderation related -const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session -const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk -const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session +const U64 GP_SESSION_JOIN = 0x1LL << 16; //can join session +const U64 GP_SESSION_VOICE = 0x1LL << 27; //can hear/talk +const U64 GP_SESSION_MODERATOR = 0x1LL << 37; //can mute people's session + +// Group Banning +const U64 GP_GROUP_BAN_ACCESS = 0x1LL << 51; // Allows access to ban / un-ban agents from a group. const U64 GP_DEFAULT_MEMBER = GP_ACCOUNTING_ACCOUNTABLE | GP_LAND_ALLOW_SET_HOME diff --git a/indra/newview/sanitycheck.cpp b/indra/newview/sanitycheck.cpp index d376a8d0f7..422e5c9e44 100644 --- a/indra/newview/sanitycheck.cpp +++ b/indra/newview/sanitycheck.cpp @@ -44,9 +44,9 @@ void SanityCheck::init() f(SanityCheck* s) : chk(s) {}; virtual void apply(const std::string& name, LLControlVariable* control) { - if(control->getSanityType()!=SANITY_TYPE_NONE) + if (control->getSanityType() != SANITY_TYPE_NONE) { - control->getSanitySignal()->connect(boost::bind(&SanityCheck::onSanity,_1)); + control->getSanitySignal()->connect(boost::bind(&SanityCheck::onSanity, _1)); SanityCheck::instance().onSanity(control); } } @@ -59,26 +59,26 @@ void SanityCheck::init() // static void SanityCheck::onSanity(LLControlVariable* controlp) { - static LLControlVariable* lastControl=NULL; + static LLControlVariable* lastControl = NULL; - if(controlp->isSane()) + if (controlp->isSane()) return; - if(controlp==lastControl) + if (controlp == lastControl) return; - lastControl=controlp; + lastControl = controlp; - std::string checkType="SanityCheck"+gSavedSettings.sanityTypeEnumToString(controlp->getSanityType()); - std::vector sanityValues=controlp->getSanityValues(); + std::string checkType = "SanityCheck" + gSavedSettings.sanityTypeEnumToString(controlp->getSanityType()); + std::vector sanityValues = controlp->getSanityValues(); LLSD args; LLStringUtil::format_map_t map; - map["VALUE_1"]=sanityValues[0].asString(); - map["VALUE_2"]=sanityValues[1].asString(); - map["CONTROL_NAME"]=controlp->getName(); - args["SANITY_MESSAGE"]=LLTrans::getString(checkType,map); - args["SANITY_COMMENT"]=controlp->getSanityComment(); - args["CURRENT_VALUE"]=controlp->getValue().asString(); - LLNotificationsUtil::add("SanityCheck",args); + map["VALUE_1"] = sanityValues[0].asString(); + map["VALUE_2"] = sanityValues[1].asString(); + map["CONTROL_NAME"] = controlp->getName(); + args["SANITY_MESSAGE"] = LLTrans::getString(checkType,map); + args["SANITY_COMMENT"] = controlp->getSanityComment(); + args["CURRENT_VALUE"] = controlp->getValue().asString(); + LLNotificationsUtil::add("SanityCheck", args); } diff --git a/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml b/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml index 34150e97cd..72fe9b1e8b 100644 --- a/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml +++ b/indra/newview/skins/ansastorm/xui/en/panel_toolbar_view.xml @@ -253,7 +253,6 @@ - + diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml index 72817c6106..f231420431 100755 --- a/indra/newview/skins/default/xui/da/notifications.xml +++ b/indra/newview/skins/default/xui/da/notifications.xml @@ -1346,10 +1346,24 @@ Prøv igen om lidt. [ITEM_SLURL]
+ diff --git a/indra/newview/skins/default/xui/en/floater_pay.xml b/indra/newview/skins/default/xui/en/floater_pay.xml index 39ce0afd64..b28e934c61 100755 --- a/indra/newview/skins/default/xui/en/floater_pay.xml +++ b/indra/newview/skins/default/xui/en/floater_pay.xml @@ -19,6 +19,7 @@
+ + + diff --git a/indra/newview/skins/default/xui/en/floater_window_size.xml b/indra/newview/skins/default/xui/en/floater_window_size.xml index e8c7c94e67..d715f086ac 100755 --- a/indra/newview/skins/default/xui/en/floater_window_size.xml +++ b/indra/newview/skins/default/xui/en/floater_window_size.xml @@ -37,41 +37,49 @@ name="item2" value="1024 x 768" /> + value="1360 x 768" /> + + - + + + Use Keyboard Shortcuts: + + + + diff --git a/indra/newview/skins/default/xui/en/panel_preferences_firestorm.xml b/indra/newview/skins/default/xui/en/panel_preferences_firestorm.xml index a08b8805e0..97feb54a7a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_firestorm.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_firestorm.xml @@ -875,8 +875,8 @@ name="PhoenixBeamPrev_rainbow" label="" scale_image="true" - image_color="White" - image_color_disabled="White" + image_color="SL-White" + image_color_disabled="SL-White" image_selected="beam_rainbow.png" image_unselected="beam_rainbow.png" image_hover_selected="beam_rainbow.png" @@ -992,8 +992,8 @@ height="80" name="PhoenixBeamPrev_Phoenix" label="" - image_color="White" - image_color_disabled="White" + image_color="SL-White" + image_color_disabled="SL-White" scale_image="true" image_selected="beam_phoenix.png" image_unselected="beam_phoenix.png" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml index 49c31494ae..e690dfaf19 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml @@ -19,7 +19,7 @@ right="-1" name="tabs" tab_min_width="50" - tab_position="top" > + tab_position="top"> + name="tab-view"> + top_pad="10"> Automatically pose avatar during (select one or more): + + + + + + + + + (requires restart) + + + + + + + + + + + + top="10" + left="20" /> @@ -202,7 +329,7 @@ label="Show avatar in Mouselook" layout="topleft" left_delta="10" - top_pad="2" + top_pad="8" name="first_person_avatar_visible" width="256" /> Mouselook mouse sensitivity: @@ -321,7 +448,7 @@ left_pad="5" max_val="15" name="mouse_sensitivity" - top_delta="-1" + top_delta="1" width="145" /> + name="tab-movement"> + top_pad="8"/> + + - + - - Camera options: - - - - - - - - - - - - - + label="Map & Minimap" + name="tab-maps"> - (requires restart) - - - - - - - - - - - - - diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 79b2a73b93..bedeb179e3 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -55,7 +55,7 @@ layout="topleft" left="30" name="clear_cache" - top_pad="10" + top_pad="8" width="145"> @@ -82,7 +82,7 @@ layout="topleft" left="30" name="online_searchresults" - top_pad="10" + top_pad="8" width="350" /> + + @@ -292,7 +302,7 @@ left="30" name="UseLegacyIMLogNames" tool_tip="If enabled, the legacy file name format for transcripts (User Name) will be used instead of new format (user_name)." - top_pad="3" + top_pad="2" height="16" width="350" /> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_skins.xml b/indra/newview/skins/default/xui/en/panel_preferences_skins.xml index 2b95352833..5e97705f0a 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_skins.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_skins.xml @@ -11,8 +11,8 @@ name="skin_panel"> @@ -605,7 +605,7 @@ image_unselected="SplitButtonRight_Off" > @@ -623,7 +623,7 @@ image_overlay="phoenix_18" > diff --git a/indra/newview/skins/latency/xui/pl/floater_about_land.xml b/indra/newview/skins/latency/xui/pl/floater_about_land.xml index 9e75c71ca4..fe33c56d1b 100644 --- a/indra/newview/skins/latency/xui/pl/floater_about_land.xml +++ b/indra/newview/skins/latency/xui/pl/floater_about_land.xml @@ -7,10 +7,10 @@ minuta - [SECONDS] sekundy + [SECONDS] sekund - pozostały + pozostało @@ -24,7 +24,7 @@ Obszar - Numer aukcji: [ID] + ID aukcji: [ID] Musisz zaakceptować zakup by móc modyfikować tą działkę. @@ -50,9 +50,6 @@ Nie wybrano działki. - - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] - Numer identyfikacyjny UUID działki nie został rozpoznany. @@ -68,15 +65,9 @@ Typ: - - Mainland / Homestead - Rodzaj: - - Adult - Właściciel: @@ -97,7 +88,7 @@ Na sprzedaż: - Nie + Nie na sprzedaż Cena: [PRICE]L$ ([PRICE_PER_SQM]L$/m²). @@ -129,7 +120,7 @@