diff options
154 files changed, 1394 insertions, 662 deletions
diff --git a/autobuild.xml b/autobuild.xml index 803e479078..f81fe4eaa1 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3830,9 +3830,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <array> <string>-G</string> <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string> - <string>-DUNATTENDED:BOOL=ON</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> <string>-DUSE_KDU=FALSE</string> + <string>-DOPENAL:BOOL=ON</string> </array> </map> <key>name</key> @@ -3903,6 +3903,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string> <string>-DUNATTENDED:BOOL=ON</string> <string>-DINSTALL_PROPRIETARY=FALSE</string> <string>-DUSE_KDU=FALSE</string> + <string>-DOPENAL:BOOL=ON</string> </array> </map> <key>name</key> diff --git a/doc/contributions.txt b/doc/contributions.txt index 8047c7cbe0..7c1986530d 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -258,6 +258,8 @@ Beansy Twine Benja Kepler VWR-746 Benjamin Bigdipper +Beq Janus + BUG-227094 Beth Walcher Bezilon Kasei Biancaluce Robbiani @@ -829,6 +831,7 @@ Khyota Wulluf Kimar Coba Kithrak Kirkorian Kitty Barnett + BUG-228665 VWR-19699 STORM-288 STORM-799 @@ -1444,6 +1447,8 @@ Thickbrick Sleaford STORM-956 STORM-1147 STORM-1325 +Thoys Pan + SL-12396 Thraxis Epsilon SVC-371 VWR-383 diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 82cd5d62e8..aeadfdd626 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -67,6 +67,10 @@ if(WINDOWS) set(release_files ${release_files} fmod.dll) endif (FMODSTUDIO) + if (OPENAL) + list(APPEND release_files openal32.dll alut.dll) + endif (OPENAL) + #******************************* # Copy MS C runtime dlls, required for packaging. # *TODO - Adapt this to support VC9 diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake index 25163d0322..1741dc111f 100644 --- a/indra/cmake/DirectX.cmake +++ b/indra/cmake/DirectX.cmake @@ -1,8 +1,15 @@ # -*- cmake -*- if (WINDOWS) + if(ADDRESS_SIZE EQUAL 32) + set(PROGRAMFILES_x86 $ENV{PROGRAMFILES}) + else(ADDRESS_SIZE EQUAL 32) + set(PROGRAMFILES_x86 $ENV{PROGRAMFILES\(X86\)}) + endif(ADDRESS_SIZE EQUAL 32) + find_path(DIRECTX_INCLUDE_DIR dxdiag.h "$ENV{DXSDK_DIR}/Include" + "${PROGRAMFILES_x86}/Windows Kits/8.1/Include/um" "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include" "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Include" "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include" @@ -26,6 +33,7 @@ if (WINDOWS) find_path(DIRECTX_LIBRARY_DIR dxguid.lib "$ENV{DXSDK_DIR}/Lib/x86" + "${PROGRAMFILES_x86}/Windows Kits/8.1/Lib/winv6.3/um/x86" "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Lib/x86" "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Lib/x86" "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86" diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index 8b628a058e..558ede7bf6 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -60,6 +60,10 @@ if (FMODSTUDIO) endif (FMODSTUDIO) if (OPENAL) + include_directories( + ${OPENAL_LIBRARIES} + ) + list(APPEND llaudio_SOURCE_FILES llaudioengine_openal.cpp lllistener_openal.cpp diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index a38d8291fa..3bdd0302ee 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -55,7 +55,7 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title) { mWindGen = NULL; - LLAudioEngine::init(num_channels, userdata); + LLAudioEngine::init(num_channels, userdata, app_title); if(!alutInit(NULL, NULL)) { diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 0f76ff23ea..6978b8d08b 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -1010,8 +1010,8 @@ CURLcode HttpOpRequest::curlSslCtxCallback(CURL *curl, void *sslctx, void *userd if (op->mCallbackSSLVerify) { SSL_CTX * ctx = (SSL_CTX *)sslctx; - // disable any default verification for server certs - SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + // verification for ssl certs + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); // set the verification callback. SSL_CTX_set_cert_verify_callback(ctx, sslCertVerifyCallback, userdata); // the calls are void diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 222f3cf235..27abf39537 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -46,10 +46,10 @@ class LLRotation; // of this writing, July 08, 2010) about getting it implemented before you resort to // LLVector3/LLVector4. ///////////////////////////////// -class LLVector4a; +struct LLVector4a; LL_ALIGN_PREFIX(16) -class LLVector4a +struct LLVector4a { public: @@ -92,6 +92,7 @@ public: // CONSTRUCTORS //////////////////////////////////// + //LLVector4a is plain data which should never have a default constructor or destructor(malloc&free won't trigger it) LLVector4a() { //DO NOT INITIALIZE -- The overhead is completely unnecessary ll_assert_aligned(this,16); diff --git a/indra/llmessage/llteleportflags.h b/indra/llmessage/llteleportflags.h index b3fcad036e..fd1e702832 100644 --- a/indra/llmessage/llteleportflags.h +++ b/indra/llmessage/llteleportflags.h @@ -44,6 +44,8 @@ const U32 TELEPORT_FLAGS_VIA_REGION_ID = 1 << 12; const U32 TELEPORT_FLAGS_IS_FLYING = 1 << 13; const U32 TELEPORT_FLAGS_SHOW_RESET_HOME = 1 << 14; const U32 TELEPORT_FLAGS_FORCE_REDIRECT = 1 << 15; // used to force a redirect to some random location - used when kicking someone from land. +const U32 TELEPORT_FLAGS_VIA_GLOBAL_COORDS = 1 << 16; +const U32 TELEPORT_FLAGS_WITHIN_REGION = 1 << 17; const U32 TELEPORT_FLAGS_MASK_VIA = TELEPORT_FLAGS_VIA_LURE | TELEPORT_FLAGS_VIA_LANDMARK diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 623f570cef..962b8e9bb5 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -655,6 +655,37 @@ void LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*) { updateLayout(getRect().getWidth(),getRect().getHeight()); } + +// virtual +void LLAccordionCtrl::onUpdateScrollToChild(const LLUICtrl *cntrl) +{ + if (mScrollbar && mScrollbar->getVisible()) + { + // same as scrollToShowRect + LLRect rect; + cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this); + + // Translate to parent coordinatess to check if we are in visible rectangle + rect.translate(getRect().mLeft, getRect().mBottom); + + if (!getRect().contains(rect)) + { + // for accordition's scroll, height is in pixels + // Back to local coords and calculate position for scroller + S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom; + S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop; + + S32 scroll_pos = llclamp(mScrollbar->getDocPos(), + bottom, // min vertical scroll + top); // max vertical scroll + + mScrollbar->setDocPos(scroll_pos); + } + } + + LLUICtrl::onUpdateScrollToChild(cntrl); +} + void LLAccordionCtrl::onOpen (const LLSD& key) { for(size_t i=0;i<mAccordionTabs.size();++i) diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h index 1fe64c472e..b38a76d27f 100644 --- a/indra/llui/llaccordionctrl.h +++ b/indra/llui/llaccordionctrl.h @@ -111,6 +111,7 @@ public: void draw(); void onScrollPosChangeCallback(S32, LLScrollbar*); + virtual void onUpdateScrollToChild(const LLUICtrl * cntrl); void onOpen (const LLSD& key); S32 notifyParent(const LLSD& info); diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 1034a21905..098621b543 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -452,6 +452,35 @@ void LLAccordionCtrlTab::onVisibilityChange(BOOL new_visibility) notifyParent(LLSD().with("child_visibility_change", new_visibility)); } +// virtual +void LLAccordionCtrlTab::onUpdateScrollToChild(const LLUICtrl *cntrl) +{ + if (mScrollbar && mScrollbar->getVisible()) + { + LLRect rect; + cntrl->localRectToOtherView(cntrl->getLocalRect(), &rect, this); + + // Translate to parent coordinatess to check if we are in visible rectangle + rect.translate(getRect().mLeft, getRect().mBottom); + + if (!getRect().contains(rect)) + { + // for accordition's scroll, height is in pixels + // Back to local coords and calculate position for scroller + S32 bottom = mScrollbar->getDocPos() - rect.mBottom + getRect().mBottom; + S32 top = mScrollbar->getDocPos() - rect.mTop + getRect().mTop; + + S32 scroll_pos = llclamp(mScrollbar->getDocPos(), + bottom, // min vertical scroll + top); // max vertical scroll + + mScrollbar->setDocPos(scroll_pos); + } + } + + LLUICtrl::onUpdateScrollToChild(cntrl); +} + BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask) { if(mCollapsible && mHeaderVisible && mCanOpenClose) diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 0263bce4be..2c72e8c036 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -159,6 +159,7 @@ public: * Raises notifyParent event with "child_visibility_change" = new_visibility */ void onVisibilityChange(BOOL new_visibility); + virtual void onUpdateScrollToChild(const LLUICtrl * cntrl); // Changes expand/collapse state and triggers expand/collapse callbacks virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); diff --git a/indra/llui/llbadgeowner.cpp b/indra/llui/llbadgeowner.cpp index 0557cd4375..5f11c383ef 100644 --- a/indra/llui/llbadgeowner.cpp +++ b/indra/llui/llbadgeowner.cpp @@ -56,6 +56,14 @@ void LLBadgeOwner::initBadgeParams(const LLBadge::Params& p) } } +void LLBadgeOwner::reshapeBadge(const LLRect& new_rect) +{ + if (mBadge) + { + mBadge->setShape(new_rect); + } +} + void LLBadgeOwner::setBadgeVisibility(bool visible) { if (mBadge) diff --git a/indra/llui/llbadgeowner.h b/indra/llui/llbadgeowner.h index 01ed95f3a3..4ce208fa0d 100644 --- a/indra/llui/llbadgeowner.h +++ b/indra/llui/llbadgeowner.h @@ -46,6 +46,7 @@ public: bool hasBadgeHolderParent() const { return mHasBadgeHolderParent; }; void setBadgeVisibility(bool visible); void setDrawBadgeAtTop(bool draw_at_top); + void reshapeBadge(const LLRect& new_rect); private: diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index c7f0326ed4..52dc908655 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -514,6 +514,14 @@ S32 LLComboBox::getCurrentIndex() const return -1; } +void LLComboBox::setEnabledByValue(const LLSD& value, BOOL enabled) +{ + LLScrollListItem *found = mList->getItem(value); + if (found) + { + found->setEnabled(enabled); + } +} void LLComboBox::createLineEditor(const LLComboBox::Params& p) { diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 7d38c051a5..4af3313162 100644 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -158,6 +158,8 @@ public: BOOL setCurrentByIndex( S32 index ); S32 getCurrentIndex() const; + void setEnabledByValue(const LLSD& value, BOOL enabled); + void createLineEditor(const Params&); //======================================================================== diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 6bb5e6c02e..c175034d75 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -241,6 +241,8 @@ public: void dumpSelectionInformation(); virtual S32 notify(const LLSD& info) ; + + void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; } bool useLabelSuffix() { return mUseLabelSuffix; } virtual void updateMenu(); diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 70304cdfd2..1badd54fca 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -2151,6 +2151,7 @@ void LLLineEditor::clear() void LLLineEditor::onTabInto() { selectAll(); + LLUICtrl::onTabInto(); } //virtual diff --git a/indra/llui/llmultisliderctrl.cpp b/indra/llui/llmultisliderctrl.cpp index 20e2b569f1..b3df7c154b 100644 --- a/indra/llui/llmultisliderctrl.cpp +++ b/indra/llui/llmultisliderctrl.cpp @@ -509,6 +509,7 @@ void LLMultiSliderCtrl::onTabInto() { mEditor->onTabInto(); } + LLF32UICtrl::onTabInto(); } void LLMultiSliderCtrl::reportInvalidData() diff --git a/indra/llui/llsliderctrl.cpp b/indra/llui/llsliderctrl.cpp index 3b89a8ca63..d80a434f22 100644 --- a/indra/llui/llsliderctrl.cpp +++ b/indra/llui/llsliderctrl.cpp @@ -479,6 +479,7 @@ void LLSliderCtrl::onTabInto() { mEditor->onTabInto(); } + LLF32UICtrl::onTabInto(); } void LLSliderCtrl::reportInvalidData() diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index ce3fc29d32..ee78b82429 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -442,7 +442,8 @@ void LLSpinCtrl::setAllowEdit(BOOL allow_edit) void LLSpinCtrl::onTabInto() { - mEditor->onTabInto(); + mEditor->onTabInto(); + LLF32UICtrl::onTabInto(); } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 83b851eed2..30bf938591 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1017,7 +1017,38 @@ BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) // handle triple click if (!mTripleClickTimer.hasExpired()) { - selectAll(); + S32 real_line = getLineNumFromDocIndex(mCursorPos, false); + S32 line_start = -1; + S32 line_end = -1; + for (line_list_t::const_iterator it = mLineInfoList.begin(), end_it = mLineInfoList.end(); + it != end_it; + ++it) + { + if (it->mLineNum < real_line) + { + continue; + } + if (it->mLineNum > real_line) + { + break; + } + if (line_start == -1) + { + line_start = it->mDocIndexStart; + } + line_end = it->mDocIndexEnd; + line_end = llclamp(line_end, 0, getLength()); + } + + if (line_start == -1) + { + return TRUE; + } + + mSelectionEnd = line_start; + mSelectionStart = line_end; + setCursorPos(line_start); + return TRUE; } diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index c98da0d410..544a76e8d5 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -721,8 +721,9 @@ void LLUICtrl::resetDirty() } // virtual -void LLUICtrl::onTabInto() +void LLUICtrl::onTabInto() { + onUpdateScrollToChild(this); } // virtual diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 593c8b12fc..d81e2cd494 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -641,6 +641,16 @@ void LLView::onVisibilityChange ( BOOL new_visibility ) } // virtual +void LLView::onUpdateScrollToChild(const LLUICtrl * cntrl) +{ + LLView* parent_view = getParent(); + if (parent_view) + { + parent_view->onUpdateScrollToChild(cntrl); + } +} + +// virtual void LLView::translate(S32 x, S32 y) { mRect.translate(x, y); diff --git a/indra/llui/llview.h b/indra/llui/llview.h index db81900aaf..5c91c37d3c 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -301,6 +301,7 @@ public: virtual BOOL setLabelArg( const std::string& key, const LLStringExplicit& text ); virtual void onVisibilityChange ( BOOL new_visibility ); + virtual void onUpdateScrollToChild(const LLUICtrl * cntrl); void pushVisible(BOOL visible) { mLastVisible = mVisible; setVisible(visible); } void popVisible() { setVisible(mLastVisible); } diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 33fa186a2e..b3a014058a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1627,6 +1627,10 @@ if (WINDOWS) # causes those systems to run in a Windows 8 compatibility mode, which works. LIST(APPEND viewer_SOURCE_FILES windows.manifest) endif (ADDRESS_SIZE EQUAL 64) + + if (OPENAL) + LIST(APPEND viewer_LIBRARIES ${OPENAL_LIBRARIES}) + endif (OPENAL) endif (WINDOWS) # Add the xui files. This is handy for searching for xui elements @@ -1728,6 +1732,12 @@ if (FMODSTUDIO) endif (FMODSTUDIO) set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") + +if (HAVOK OR HAVOK_TPV) + set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_HAVOK") +endif (HAVOK OR HAVOK_TPV) + +# progress view disables/enables icons based on available packages set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) @@ -1851,6 +1861,13 @@ if (WINDOWS) ) endif (FMODSTUDIO) + if (OPENAL) + list(APPEND COPY_INPUT_DEPENDENCIES + ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/OpenAL32.dll + ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/alut.dll + ) + endif (OPENAL) + add_custom_command( OUTPUT ${CMAKE_CFG_INTDIR}/copy_touched.bat COMMAND ${PYTHON_EXECUTABLE} @@ -1861,6 +1878,7 @@ if (WINDOWS) --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" "--fmodstudio=${FMODSTUDIO}" + "--openal=${OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -1923,6 +1941,7 @@ if (WINDOWS) --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" "--fmodstudio=${FMODSTUDIO}" + "--openal=${OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2069,6 +2088,7 @@ if (LINUX) --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" "--fmodstudio=${FMODSTUDIO}" + "--openal=${OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2096,6 +2116,7 @@ if (LINUX) --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" "--fmodstudio=${FMODSTUDIO}" + "--openal=${OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2173,6 +2194,7 @@ if (DARWIN) --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" "--fmodstudio=${FMODSTUDIO}" + "--openal=${OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER} @@ -2208,6 +2230,7 @@ if (DARWIN) --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" "--fmodstudio=${FMODSTUDIO}" + "--openal=${OPENAL}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index dfc3c7b89d..62ae6ed5cd 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14420,7 +14420,7 @@ <key>VoiceCallsFriendsOnly</key> <map> <key>Comment</key> - <string>Only accept voice calls from residents on your friends list</string> + <string>(Deprecated) Only accept voice calls from residents on your friends list</string> <key>Persist</key> <integer>1</integer> <key>Type</key> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 8f4ca6c633..3d77ac43e5 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -220,6 +220,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>VoiceCallsFriendsOnly</key> + <map> + <key>Comment</key> + <string>Only accept voice calls and receive IMs from residents on your friends list</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>VoiceEffectDefault</key> <map> <key>Comment</key> @@ -392,6 +403,17 @@ <key>Value</key> <string></string> </map> + <key>FavoritesFolder</key> + <map> + <key>Comment</key> + <string>User's chosen folder which will be shown in the Favorites tab (UUID)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string></string> + </map> <key>SnapshotBaseDir</key> <map> <key>Comment</key> diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index f3df79fb6b..166c2d67c8 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -867,9 +867,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp) if (mRegionp != regionp) { - std::string ip = regionp->getHost().getString(); - LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() - << " located at " << ip << LL_ENDL; + LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() << LL_ENDL; if (mRegionp) { // We've changed regions, we're now going to change our agent coordinate frame. diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 9e65409256..672104dd70 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -354,6 +354,18 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) resetPanDiff(); resetOrbitDiff(); mHUDTargetZoom = 1.f; + + if (LLSelectMgr::getInstance()->mAllowSelectAvatar) + { + // resetting camera also resets position overrides in debug mode 'AllowSelectAvatar' + LLObjectSelectionHandle selected_handle = LLSelectMgr::getInstance()->getSelection(); + if (selected_handle->getObjectCount() == 1 + && selected_handle->getFirstObject() != NULL + && selected_handle->getFirstObject()->isAvatar()) + { + LLSelectMgr::getInstance()->resetObjectOverrides(selected_handle); + } + } } // Allow camera to be moved somewhere other than behind avatar. diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 47fde299c7..a2b7362608 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -294,6 +294,7 @@ struct AttachmentInfo std::vector<AttachmentInfo> info{ AttachmentInfo(metadata.logFilePathname, "text/plain"), AttachmentInfo(metadata.userSettingsPathname, "text/xml"), + AttachmentInfo(metadata.accountSettingsPathname, "text/xml"), AttachmentInfo(metadata.staticDebugPathname, "text/xml") }; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d2b7c9d85e..fb9782a505 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3140,8 +3140,9 @@ LLSD LLAppViewer::getViewerInfo() const info["POSITION"] = ll_sd_from_vector3d(pos); info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos)); info["REGION"] = gAgent.getRegion()->getName(); - info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName(); - info["HOSTIP"] = gAgent.getRegion()->getHost().getString(); + + boost::regex regex("\\.(secondlife|lindenlab)\\..*"); + info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getHost().getHostName(), regex, ""); info["SERVER_VERSION"] = gLastVersionChannel; LLSLURL slurl; LLAgentUI::buildSLURL(slurl); @@ -4009,6 +4010,7 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q void LLAppViewer::userQuit() { + LL_INFOS() << "User requested quit" << LL_ENDL; if (gDisconnected || !gViewerWindow || !gViewerWindow->getProgressView() @@ -4866,13 +4868,14 @@ void LLAppViewer::idle() { return; } + + gViewerWindow->updateUI(); + if (gTeleportDisplay) { return; } - gViewerWindow->updateUI(); - /////////////////////////////////////// // Agent and camera movement // diff --git a/indra/newview/llappviewerlistener.cpp b/indra/newview/llappviewerlistener.cpp index 94250f1fc2..2380a8ebf0 100644 --- a/indra/newview/llappviewerlistener.cpp +++ b/indra/newview/llappviewerlistener.cpp @@ -52,10 +52,12 @@ LLAppViewerListener::LLAppViewerListener(const LLAppViewerGetter& getter): void LLAppViewerListener::requestQuit(const LLSD& event) { + LL_INFOS() << "Listener requested quit" << LL_ENDL; mAppViewerGetter()->requestQuit(); } void LLAppViewerListener::forceQuit(const LLSD& event) { + LL_INFOS() << "Listener requested force quit" << LL_ENDL; mAppViewerGetter()->forceQuit(); } diff --git a/indra/newview/llappviewermacosx-for-objc.h b/indra/newview/llappviewermacosx-for-objc.h index 37e8a3917a..79c3efff91 100644 --- a/indra/newview/llappviewermacosx-for-objc.h +++ b/indra/newview/llappviewermacosx-for-objc.h @@ -41,6 +41,7 @@ struct CrashMetadata { std::string logFilePathname; std::string userSettingsPathname; + std::string accountSettingsPathname; std::string staticDebugPathname; std::string OSInfo; std::string agentFullname; diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 3111540a13..662164af2d 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -199,10 +199,11 @@ CrashMetadataSingleton::CrashMetadataSingleton() else { LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL; - logFilePathname = get_metadata(info, "SLLog"); - userSettingsPathname = get_metadata(info, "SettingsFilename"); - OSInfo = get_metadata(info, "OSInfo"); - agentFullname = get_metadata(info, "LoginName"); + logFilePathname = get_metadata(info, "SLLog"); + userSettingsPathname = get_metadata(info, "SettingsFilename"); + accountSettingsPathname = get_metadata(info, "PerAccountSettingsFilename"); + OSInfo = get_metadata(info, "OSInfo"); + agentFullname = get_metadata(info, "LoginName"); // Translate underscores back to spaces LLStringUtil::replaceChar(agentFullname, '_', ' '); regionName = get_metadata(info, "CurrentRegion"); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index d208e135bb..293f86f170 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -139,6 +139,9 @@ namespace { // user name, when we have it sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname())); + + sBugSplatSender->sendAdditionalFile( + WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "settings_per_account.xml"))); } // LL_ERRS message, when there is one diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index dedb06c945..8d89455cd4 100644 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -1092,6 +1092,10 @@ void LLScriptChiclet::onMenuItemClicked(const LLSD& user_data) { LLScriptFloaterManager::instance().removeNotification(getSessionId()); } + else if ("close all" == action) + { + LLIMWellWindow::getInstance()->closeAll(); + } } void LLScriptChiclet::createPopupMenu() diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp index 5539fa75dd..9430bb3ca3 100644 --- a/indra/newview/llconversationlog.cpp +++ b/indra/newview/llconversationlog.cpp @@ -482,6 +482,10 @@ bool LLConversationLog::saveToFile(const std::string& filename) conv_it->getSessionID().toString(conversation_id); conv_it->getParticipantID().toString(participant_id); + bool is_adhoc = (conv_it->getConversationType() == LLIMModel::LLIMSession::ADHOC_SESSION); + std::string conv_name = is_adhoc ? conv_it->getConversationName() : LLURI::escape(conv_it->getConversationName()); + std::string file_name = is_adhoc ? conv_it->getHistoryFileName() : LLURI::escape(conv_it->getHistoryFileName()); + // examples of two file entries // [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe| // [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a| @@ -490,10 +494,10 @@ bool LLConversationLog::saveToFile(const std::string& filename) (S32)conv_it->getConversationType(), (S32)0, (S32)conv_it->hasOfflineMessages(), - LLURI::escape(conv_it->getConversationName()).c_str(), + conv_name.c_str(), participant_id.c_str(), conversation_id.c_str(), - LLURI::escape(conv_it->getHistoryFileName()).c_str()); + file_name.c_str()); } fclose(fp); return true; @@ -541,14 +545,18 @@ bool LLConversationLog::loadFromFile(const std::string& filename) conv_id_buffer, history_file_name); + bool is_adhoc = ((SessionType)stype == LLIMModel::LLIMSession::ADHOC_SESSION); + std::string conv_name = is_adhoc ? conv_name_buffer : LLURI::unescape(conv_name_buffer); + std::string file_name = is_adhoc ? history_file_name : LLURI::unescape(history_file_name); + ConversationParams params; params.time(LLUnits::Seconds::fromValue(time)) .conversation_type((SessionType)stype) .has_offline_ims(has_offline_ims) - .conversation_name(LLURI::unescape(conv_name_buffer)) + .conversation_name(conv_name) .participant_id(LLUUID(part_id_buffer)) .session_id(LLUUID(conv_id_buffer)) - .history_filename(LLURI::unescape(history_file_name)); + .history_filename(file_name); LLConversation conversation(params); diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 4eb9a4151d..b8562e9077 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -138,24 +138,24 @@ public: PASS_POST_BUMP, PASS_MATERIAL, PASS_MATERIAL_ALPHA, - PASS_MATERIAL_ALPHA_MASK, + PASS_MATERIAL_ALPHA_MASK, // Diffuse texture used as alpha mask PASS_MATERIAL_ALPHA_EMISSIVE, PASS_SPECMAP, PASS_SPECMAP_BLEND, - PASS_SPECMAP_MASK, + PASS_SPECMAP_MASK, // Diffuse texture used as alpha mask and specular texture(map) PASS_SPECMAP_EMISSIVE, PASS_NORMMAP, PASS_NORMMAP_BLEND, - PASS_NORMMAP_MASK, + PASS_NORMMAP_MASK, // Diffuse texture used as alpha mask and normal map PASS_NORMMAP_EMISSIVE, PASS_NORMSPEC, PASS_NORMSPEC_BLEND, - PASS_NORMSPEC_MASK, + PASS_NORMSPEC_MASK, // Diffuse texture used as alpha mask with normal and specular map PASS_NORMSPEC_EMISSIVE, PASS_GLOW, PASS_ALPHA, PASS_ALPHA_MASK, - PASS_FULLBRIGHT_ALPHA_MASK, + PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright PASS_ALPHA_INVISIBLE, NUM_RENDER_TYPES, }; diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index da0467315f..4ee08e869a 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -314,11 +314,15 @@ void LLDrawPoolAlpha::render(S32 pass) LLVertexBuffer::MAP_TEXCOORD0); pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); - pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + // Material alpha mask gGL.diffuseColor4f(0, 0, 1, 1); pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushBatches(LLRenderPass::PASS_NORMMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushBatches(LLRenderPass::PASS_SPECMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushBatches(LLRenderPass::PASS_NORMSPEC_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); + pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); gGL.diffuseColor4f(0, 1, 0, 1); pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE); diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 789a254389..f3e922ce8e 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -1741,11 +1741,16 @@ void LLDrawPoolAvatar::getRiggedGeometry( LLVolume* volume, const LLVolumeFace& vol_face) { - face->setGeomIndex(0); - face->setIndicesIndex(0); - - //rigged faces do not batch textures - face->setTextureIndex(255); + face->setGeomIndex(0); + face->setIndicesIndex(0); + + if (face->getTextureIndex() != FACE_DO_NOT_BATCH_TEXTURES) + { + face->setDrawInfo(NULL); + } + + //rigged faces do not batch textures + face->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable()) { diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 18ea184da6..36832d85fd 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -153,7 +153,7 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) } mTEOffset = -1; - mTextureIndex = 255; + mTextureIndex = FACE_DO_NOT_BATCH_TEXTURES; setDrawable(drawablep); mVObjp = objp; @@ -184,6 +184,7 @@ void LLFace::destroy() if(mTexture[i].notNull()) { mTexture[i]->removeFace(i, this) ; + mTexture[i] = NULL; } } @@ -203,7 +204,6 @@ void LLFace::destroy() { mDrawPoolp->removeFace(this); } - mDrawPoolp = NULL; } @@ -212,7 +212,7 @@ void LLFace::destroy() delete mTextureMatrix; mTextureMatrix = NULL; - if (mDrawablep.notNull()) + if (mDrawablep) { LLSpatialGroup* group = mDrawablep->getSpatialGroup(); if (group) @@ -224,7 +224,7 @@ void LLFace::destroy() } setDrawInfo(NULL); - + mDrawablep = NULL; mVObjp = NULL; } @@ -456,13 +456,13 @@ void LLFace::setTextureIndex(U8 index) { mTextureIndex = index; - if (mTextureIndex != 255) + if (mTextureIndex != FACE_DO_NOT_BATCH_TEXTURES) { mDrawablep->setState(LLDrawable::REBUILD_POSITION); } else { - if (mDrawInfo && mDrawInfo->mTextureList.size() <= 1) + if (mDrawInfo && !mDrawInfo->mTextureList.empty()) { LL_ERRS() << "Face with no texture index references indexed texture draw info." << LL_ENDL; } @@ -535,7 +535,7 @@ void LLFace::updateCenterAgent() void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) { - if (mDrawablep->getSpatialGroup() == NULL) + if (mDrawablep == NULL || mDrawablep->getSpatialGroup() == NULL) { return; } @@ -543,7 +543,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) mDrawablep->getSpatialGroup()->rebuildGeom(); mDrawablep->getSpatialGroup()->rebuildMesh(); - if(mDrawablep.isNull() || mVertexBuffer.isNull()) + if(mVertexBuffer.isNull()) { return; } @@ -1539,7 +1539,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); - U8 index = mTextureIndex < 255 ? mTextureIndex : 0; + U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0; S32 val = 0; U8* vp = (U8*) &val; @@ -2072,7 +2072,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLVector4a texIdx; - S32 index = mTextureIndex < 255 ? mTextureIndex : 0; + S32 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0; F32 val = 0.f; S32* vp = (S32*) &val; @@ -2673,7 +2673,7 @@ S32 LLFace::renderElements(const U16 *index_array) const S32 LLFace::renderIndexed() { - if(mDrawablep.isNull() || mDrawPoolp == NULL) + if(mDrawablep == NULL || mDrawPoolp == NULL) { return 0; } diff --git a/indra/newview/llface.h b/indra/newview/llface.h index c74d4e3fa8..3611539ff8 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -52,6 +52,7 @@ class LLDrawInfo; const F32 MIN_ALPHA_SIZE = 1024.f; const F32 MIN_TEX_ANIM_SIZE = 512.f; +const U8 FACE_DO_NOT_BATCH_TEXTURES = 255; class LLFace : public LLTrace::MemTrackableNonVirtual<LLFace, 16> { @@ -279,8 +280,13 @@ private: LLXformMatrix* mXform; LLPointer<LLViewerTexture> mTexture[LLRender::NUM_TEXTURE_CHANNELS]; - - LLPointer<LLDrawable> mDrawablep; + + // mDrawablep is not supposed to be null, don't use LLPointer because + // mDrawablep owns LLFace and LLPointer is a good way to either cause a + // memory leak or a 'delete each other' situation if something deletes + // drawable wrongly. + LLDrawable* mDrawablep; + // LLViewerObject technically owns drawable, but also it should be strictly managed LLPointer<LLViewerObject> mVObjp; S32 mTEOffset; diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index 91436e52fe..25348474a1 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -74,7 +74,6 @@ public: void onClickBuy(); void onClickCancel(); - void onClickErrorWeb(); }; LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key) @@ -132,7 +131,6 @@ BOOL LLFloaterBuyCurrencyUI::postBuild() getChild<LLUICtrl>("buy_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickBuy, this)); getChild<LLUICtrl>("cancel_btn")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickCancel, this)); - getChild<LLUICtrl>("error_web")->setCommitCallback( boost::bind(&LLFloaterBuyCurrencyUI::onClickErrorWeb, this)); center(); @@ -173,7 +171,6 @@ void LLFloaterBuyCurrencyUI::updateUI() // hide most widgets - we'll turn them on as needed next getChildView("info_buying")->setVisible(FALSE); - getChildView("info_cannot_buy")->setVisible(FALSE); getChildView("info_need_more")->setVisible(FALSE); getChildView("purchase_warning_repurchase")->setVisible(FALSE); getChildView("purchase_warning_notenough")->setVisible(FALSE); @@ -183,32 +180,16 @@ void LLFloaterBuyCurrencyUI::updateUI() if (hasError) { // display an error from the server - getChildView("normal_background")->setVisible(FALSE); - getChildView("error_background")->setVisible(TRUE); - getChildView("info_cannot_buy")->setVisible(TRUE); - getChildView("cannot_buy_message")->setVisible(TRUE); - getChildView("balance_label")->setVisible(FALSE); - getChildView("balance_amount")->setVisible(FALSE); - getChildView("buying_label")->setVisible(FALSE); - getChildView("buying_amount")->setVisible(FALSE); - getChildView("total_label")->setVisible(FALSE); - getChildView("total_amount")->setVisible(FALSE); - - LLTextBox* message = getChild<LLTextBox>("cannot_buy_message"); - if (message) - { - message->setText(mManager.errorMessage()); - } - - getChildView("error_web")->setVisible( !mManager.errorURI().empty()); + LLSD args; + args["TITLE"] = getString("info_cannot_buy"); + args["MESSAGE"] = mManager.errorMessage(); + LLNotificationsUtil::add("CouldNotBuyCurrency", args); + closeFloater(); } else { // display the main Buy L$ interface getChildView("normal_background")->setVisible(TRUE); - getChildView("error_background")->setVisible(FALSE); - getChildView("cannot_buy_message")->setVisible(FALSE); - getChildView("error_web")->setVisible(FALSE); if (mHasTarget) { @@ -278,14 +259,6 @@ void LLFloaterBuyCurrencyUI::onClickCancel() LLStatusBar::sendMoneyBalanceRequest(); } -void LLFloaterBuyCurrencyUI::onClickErrorWeb() -{ - LLWeb::loadURL(mManager.errorURI()); - closeFloater(); - // Update L$ balance - LLStatusBar::sendMoneyBalanceRequest(); -} - // static void LLFloaterBuyCurrency::buyCurrency() { diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index 44725cab70..dd2baacb7e 100644 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -84,10 +84,7 @@ BOOL LLFloaterConversationPreview::postBuild() file = "chat"; } mChatHistoryFileName = file; - if (mIsGroup) - { - mChatHistoryFileName += GROUP_CHAT_SUFFIX; - } + LLStringUtil::format_map_t args; args["[NAME]"] = name; std::string title = getString("Title", args); diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 696f748613..028c922a4d 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -35,6 +35,7 @@ #include "llagent.h" #include "llbutton.h" +#include "llcheckboxctrl.h" #include "llcombobox.h" #include "lldrawable.h" #include "lldrawpoolavatar.h" @@ -115,8 +116,14 @@ BOOL LLFloaterImagePreview::postBuild() mSculptedPreview = new LLImagePreviewSculpted(256, 256); mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f); - if (mRawImagep->getWidth() * mRawImagep->getHeight () <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF) - getChildView("lossless_check")->setEnabled(TRUE); + if (mRawImagep->getWidth() * mRawImagep->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF) + { + // We want "lossless_check" to be unchecked when it is disabled, regardless of + // LosslessJ2CUpload state, so only assign control when enabling checkbox + LLCheckBoxCtrl* check_box = getChild<LLCheckBoxCtrl>("lossless_check"); + check_box->setEnabled(TRUE); + check_box->setControlVariable(gSavedSettings.getControl("LosslessJ2CUpload")); + } } else { diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index 21420b122b..bd834b4260 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -455,7 +455,7 @@ void LLFloaterIMContainer::idleUpdate() while (current_participant_model != end_participant_model) { LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model); - participant_model->setModeratorOptionsVisible(is_moderator && participant_model->getUUID() != gAgentID); + participant_model->setModeratorOptionsVisible(is_moderator); participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID); current_participant_model++; @@ -1409,12 +1409,21 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v { return is_single_select; } - - // Beyond that point, if only the user agent is selected, everything is disabled - if (is_single_select && (single_id == gAgentID)) - { - return false; - } + + bool is_moderator_option = ("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item); + + // Beyond that point, if only the user agent is selected, everything is disabled + if (is_single_select && (single_id == gAgentID)) + { + if (is_moderator_option) + { + return enableModerateContextMenuItem(item, true); + } + else + { + return false; + } + } // If the user agent is selected with others, everything is disabled for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id) @@ -1480,11 +1489,11 @@ bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_v { return canBanSelectedMember(single_id); } - else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item)) - { - // *TODO : get that out of here... - return enableModerateContextMenuItem(item); - } + else if (is_moderator_option) + { + // *TODO : get that out of here... + return enableModerateContextMenuItem(item); + } // By default, options that not explicitely disabled are enabled return true; @@ -1854,7 +1863,7 @@ LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParti return LLUICtrlFactory::create<LLConversationViewParticipant>(params); } -bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata) +bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata, bool is_self) { // only group moderators can perform actions related to this "enable callback" if (!isGroupModerator()) @@ -1874,7 +1883,7 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user { return voice_channel; } - else if ("can_mute" == userdata) + else if (("can_mute" == userdata) && !is_self) { return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID()); } @@ -1884,7 +1893,7 @@ bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& user } // The last invoke is used to check whether the "can_allow_text_chat" will enabled - return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID()); + return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID()) && !is_self; } bool LLFloaterIMContainer::isGroupModerator() diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 78b3572111..0f7d0a557e 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -164,7 +164,7 @@ private: void doToSelectedGroup(const LLSD& userdata); static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response); - bool enableModerateContextMenuItem(const std::string& userdata); + bool enableModerateContextMenuItem(const std::string& userdata, bool is_self = false); LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp); LLSpeakerMgr * getSpeakerMgrForSelectedParticipant(); bool isGroupModerator(); diff --git a/indra/newview/llfloaterloadprefpreset.cpp b/indra/newview/llfloaterloadprefpreset.cpp index fa17a9d40e..f89daf3e04 100644 --- a/indra/newview/llfloaterloadprefpreset.cpp +++ b/indra/newview/llfloaterloadprefpreset.cpp @@ -66,6 +66,11 @@ void LLFloaterLoadPrefPreset::onOpen(const LLSD& key) EDefaultOptions option = DEFAULT_TOP; LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option); + std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive"); + if (!preset_graphic_active.empty()) + { + combo->setSimple(preset_graphic_active); + } } void LLFloaterLoadPrefPreset::onPresetsListChange() @@ -74,6 +79,11 @@ void LLFloaterLoadPrefPreset::onPresetsListChange() EDefaultOptions option = DEFAULT_TOP; LLPresetsManager::getInstance()->setPresetNamesInComboBox(mSubdirectory, combo, option); + std::string preset_graphic_active = gSavedSettings.getString("PresetGraphicActive"); + if (!preset_graphic_active.empty()) + { + combo->setSimple(preset_graphic_active); + } } void LLFloaterLoadPrefPreset::onBtnCancel() diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp index 3968f43485..649a107d74 100644 --- a/indra/newview/llfloaterperms.cpp +++ b/indra/newview/llfloaterperms.cpp @@ -178,7 +178,6 @@ void LLFloaterPermsDefault::sendInitialPerms() if(!mCapSent) { updateCap(); - setCapSent(true); } } @@ -240,7 +239,7 @@ void LLFloaterPermsDefault::updateCapCoro(std::string url) { const std::string& reason = status.toString(); // Do not display the same error more than once in a row - if (reason != previousReason) + if ((reason != previousReason) && mCapSent) { previousReason = reason; LLSD args; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 81f4b2234c..712b41848c 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1094,6 +1094,7 @@ void LLFloaterPreference::onBtnCancel(const LLSD& userdata) if (userdata.asString() == "closeadvanced") { LLFloaterReg::hideInstance("prefs_graphics_advanced"); + updateMaxComplexity(); } else { @@ -1926,6 +1927,8 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im getChildView("log_path_button")->setEnabled(TRUE); getChildView("chat_font_size")->setEnabled(TRUE); getChildView("conversation_log_combo")->setEnabled(TRUE); + getChild<LLUICtrl>("voice_call_friends_only_check")->setEnabled(TRUE); + getChild<LLUICtrl>("voice_call_friends_only_check")->setValue(gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly")); } @@ -2034,6 +2037,14 @@ void LLFloaterPreference::updateMaxComplexity() LLAvatarComplexityControls::updateMax( getChild<LLSliderCtrl>("IndirectMaxComplexity"), getChild<LLTextBox>("IndirectMaxComplexityText")); + + LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance<LLFloaterPreferenceGraphicsAdvanced>("prefs_graphics_advanced"); + if (floater_graphics_advanced) + { + LLAvatarComplexityControls::updateMax( + floater_graphics_advanced->getChild<LLSliderCtrl>("IndirectMaxComplexity"), + floater_graphics_advanced->getChild<LLTextBox>("IndirectMaxComplexityText")); + } } bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map) @@ -2081,6 +2092,14 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity() LLAvatarComplexityControls::updateMax( getChild<LLSliderCtrl>("IndirectMaxComplexity"), getChild<LLTextBox>("IndirectMaxComplexityText")); + + LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences"); + if (floater_preferences) + { + LLAvatarComplexityControls::updateMax( + floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"), + floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText")); + } } void LLFloaterPreference::onChangeMaturity() @@ -2554,9 +2573,13 @@ void LLPanelPreference::showMultipleViewersWarning(LLUICtrl* checkbox, const LLS void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value) { - if (checkbox && checkbox->getValue()) + if (checkbox) { - LLNotificationsUtil::add("FriendsAndGroupsOnly"); + gSavedPerAccountSettings.setBOOL("VoiceCallsFriendsOnly", checkbox->getValue().asBoolean()); + if (checkbox->getValue()) + { + LLNotificationsUtil::add("FriendsAndGroupsOnly"); + } } } @@ -2659,7 +2682,6 @@ class LLPanelPreferencePrivacy : public LLPanelPreference public: LLPanelPreferencePrivacy() { - mAccountIndependentSettings.push_back("VoiceCallsFriendsOnly"); mAccountIndependentSettings.push_back("AutoDisengageMic"); } diff --git a/indra/newview/llfloatersaveprefpreset.cpp b/indra/newview/llfloatersaveprefpreset.cpp index 5f3cf9d95b..dd47d02bfa 100644 --- a/indra/newview/llfloatersaveprefpreset.cpp +++ b/indra/newview/llfloatersaveprefpreset.cpp @@ -86,7 +86,10 @@ void LLFloaterSavePrefPreset::onBtnSave() { std::string name = mPresetCombo->getSimple(); - if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (name == PRESETS_DEFAULT)) + std::string upper_name(name); + LLStringUtil::toUpper(upper_name); + + if ((name == LLTrans::getString(PRESETS_DEFAULT)) || (upper_name == PRESETS_DEFAULT_UPPER)) { LLNotificationsUtil::add("DefaultPresetNotSaved"); } diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index dbf7639539..d96014bd72 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -947,7 +947,7 @@ static void formatDateString(std::string &date_string) // static void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) { - LL_DEBUGS() << "LLGroupMgr::processGroupMembersReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupMembersReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); if (gAgent.getID() != agent_id) @@ -1053,7 +1053,7 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data) //static void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) { - LL_DEBUGS() << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupPropertiesReply" << LL_ENDL; if (!msg) { LL_ERRS() << "Can't access the messaging system" << LL_ENDL; @@ -1119,13 +1119,22 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data) group_datap->mGroupPropertiesDataComplete = true; group_datap->mChanged = TRUE; + properties_request_map_t::iterator request = LLGroupMgr::getInstance()->mPropRequests.find(group_id); + if (request != LLGroupMgr::getInstance()->mPropRequests.end()) + { + LLGroupMgr::getInstance()->mPropRequests.erase(request); + } + else + { + LL_DEBUGS("GrpMgr") << "GroupPropertyResponse received with no pending request. Response was slow." << LL_ENDL; + } LLGroupMgr::getInstance()->notifyObservers(GC_PROPERTIES); } // static void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) { - LL_DEBUGS() << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleDataReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); if (gAgent.getID() != agent_id) @@ -1186,7 +1195,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) - LL_DEBUGS() << "Adding role data: " << name << " {" << role_id << "}" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "Adding role data: " << name << " {" << role_id << "}" << LL_ENDL; LLGroupRoleData* rd = new LLGroupRoleData(role_id,name,title,desc,powers,member_count); group_datap->mRoles[role_id] = rd; } @@ -1210,7 +1219,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data) // static void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) { - LL_DEBUGS() << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupRoleMembersReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); if (gAgent.getID() != agent_id) @@ -1271,7 +1280,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) if (rd && md) { - LL_DEBUGS() << "Adding role-member pair: " << role_id << ", " << member_id << LL_ENDL; + LL_DEBUGS("GrpMgr") << "Adding role-member pair: " << role_id << ", " << member_id << LL_ENDL; rd->addMember(member_id); md->addRole(role_id,rd); } @@ -1323,7 +1332,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data) // static void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data) { - LL_DEBUGS() << "LLGroupMgr::processGroupTitlesReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::processGroupTitlesReply" << LL_ENDL; LLUUID agent_id; msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); if (gAgent.getID() != agent_id) @@ -1356,7 +1365,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data) if (!title.mTitle.empty()) { - LL_DEBUGS() << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr adding title: " << title.mTitle << ", " << title.mRoleID << ", " << (title.mSelected ? 'Y' : 'N') << LL_ENDL; group_datap->mTitles.push_back(title); } } @@ -1368,7 +1377,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data) // static void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data) { - LL_DEBUGS() << "processEjectGroupMemberReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "processEjectGroupMemberReply" << LL_ENDL; LLUUID group_id; msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id); BOOL success; @@ -1384,7 +1393,7 @@ void LLGroupMgr::processEjectGroupMemberReply(LLMessageSystem* msg, void ** data // static void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data) { - LL_DEBUGS() << "processJoinGroupReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "processJoinGroupReply" << LL_ENDL; LLUUID group_id; BOOL success; msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id); @@ -1404,7 +1413,7 @@ void LLGroupMgr::processJoinGroupReply(LLMessageSystem* msg, void ** data) // static void LLGroupMgr::processLeaveGroupReply(LLMessageSystem* msg, void ** data) { - LL_DEBUGS() << "processLeaveGroupReply" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "processLeaveGroupReply" << LL_ENDL; LLUUID group_id; BOOL success; msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group_id); @@ -1488,6 +1497,28 @@ LLGroupMgrGroupData* LLGroupMgr::createGroupData(const LLUUID& id) return group_datap; } +bool LLGroupMgr::hasPendingPropertyRequest(const LLUUID & id) +{ + properties_request_map_t::iterator existing_req = LLGroupMgr::getInstance()->mPropRequests.find(id); + if (existing_req != LLGroupMgr::getInstance()->mPropRequests.end()) + { + if (gFrameTime - existing_req->second < MIN_GROUP_PROPERTY_REQUEST_FREQ) + { + return true; + } + else + { + LLGroupMgr::getInstance()->mPropRequests.erase(existing_req); + } + } + return false; +} + +void LLGroupMgr::addPendingPropertyRequest(const LLUUID& id) +{ + LLGroupMgr::getInstance()->mPropRequests[id] = gFrameTime; +} + void LLGroupMgr::notifyObservers(LLGroupChange gc) { for (group_map_t::iterator gi = mGroups.begin(); gi != mGroups.end(); ++gi) @@ -1566,10 +1597,17 @@ void LLGroupMgr::addGroup(LLGroupMgrGroupData* group_datap) void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupPropertiesRequest" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest" << LL_ENDL; // This will happen when we get the reply //LLGroupMgrGroupData* group_datap = createGroupData(group_id); - + + if (LLGroupMgr::getInstance()->hasPendingPropertyRequest(group_id)) + { + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupPropertiesRequest suppressed repeat for " << group_id << LL_ENDL; + return; + } + LLGroupMgr::getInstance()->addPendingPropertyRequest(group_id); + LLMessageSystem* msg = gMessageSystem; msg->newMessage("GroupProfileRequest"); msg->nextBlock("AgentData"); @@ -1582,7 +1620,7 @@ void LLGroupMgr::sendGroupPropertiesRequest(const LLUUID& group_id) void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupMembersRequest" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupMembersRequest" << LL_ENDL; LLGroupMgrGroupData* group_datap = createGroupData(group_id); if (group_datap->mMemberRequestID.isNull()) { @@ -1604,7 +1642,7 @@ void LLGroupMgr::sendGroupMembersRequest(const LLUUID& group_id) void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupRoleDataRequest" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleDataRequest" << LL_ENDL; LLGroupMgrGroupData* group_datap = createGroupData(group_id); if (group_datap->mRoleDataRequestID.isNull()) { @@ -1625,7 +1663,7 @@ void LLGroupMgr::sendGroupRoleDataRequest(const LLUUID& group_id) void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupRoleMembersRequest" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleMembersRequest" << LL_ENDL; LLGroupMgrGroupData* group_datap = createGroupData(group_id); if (group_datap->mRoleMembersRequestID.isNull()) @@ -1635,7 +1673,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id) || !group_datap->isRoleDataComplete()) { // *TODO: KLW FIXME: Should we start a member or role data request? - LL_INFOS() << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N") + LL_INFOS("GrpMgr") << " Pending: " << (group_datap->mPendingRoleMemberRequest ? "Y" : "N") << " MemberDataComplete: " << (group_datap->mMemberDataComplete ? "Y" : "N") << " RoleDataComplete: " << (group_datap->mRoleDataComplete ? "Y" : "N") << LL_ENDL; group_datap->mPendingRoleMemberRequest = TRUE; @@ -1659,7 +1697,7 @@ void LLGroupMgr::sendGroupRoleMembersRequest(const LLUUID& group_id) void LLGroupMgr::sendGroupTitlesRequest(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupTitlesRequest" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupTitlesRequest" << LL_ENDL; LLGroupMgrGroupData* group_datap = createGroupData(group_id); group_datap->mTitles.clear(); @@ -1678,7 +1716,7 @@ void LLGroupMgr::sendGroupTitlesRequest(const LLUUID& group_id) void LLGroupMgr::sendGroupTitleUpdate(const LLUUID& group_id, const LLUUID& title_role_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupTitleUpdate" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupTitleUpdate" << LL_ENDL; LLMessageSystem* msg = gMessageSystem; msg->newMessage("GroupTitleUpdate"); @@ -1737,7 +1775,7 @@ void LLGroupMgr::sendCreateGroupRequest(const std::string& name, void LLGroupMgr::sendUpdateGroupInfo(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendUpdateGroupInfo" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendUpdateGroupInfo" << LL_ENDL; LLGroupMgrGroupData* group_datap = createGroupData(group_id); LLMessageSystem* msg = gMessageSystem; @@ -1766,7 +1804,7 @@ void LLGroupMgr::sendUpdateGroupInfo(const LLUUID& group_id) void LLGroupMgr::sendGroupRoleMemberChanges(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupRoleMemberChanges" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleMemberChanges" << LL_ENDL; LLGroupMgrGroupData* group_datap = createGroupData(group_id); if (group_datap->mRoleMemberChanges.empty()) return; @@ -2313,7 +2351,7 @@ void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::sendGroupRoleChanges" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::sendGroupRoleChanges" << LL_ENDL; LLGroupMgrGroupData* group_datap = getGroupData(group_id); if (group_datap && group_datap->pendingRoleChanges()) @@ -2328,7 +2366,7 @@ void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id) void LLGroupMgr::cancelGroupRoleChanges(const LLUUID& group_id) { - LL_DEBUGS() << "LLGroupMgr::cancelGroupRoleChanges" << LL_ENDL; + LL_DEBUGS("GrpMgr") << "LLGroupMgr::cancelGroupRoleChanges" << LL_ENDL; LLGroupMgrGroupData* group_datap = getGroupData(group_id); if (group_datap) group_datap->cancelRoleChanges(); @@ -2362,7 +2400,7 @@ bool LLGroupMgr::parseRoleActions(const std::string& xml_filename) std::string action_set_name; if (action_set->getAttributeString("name", action_set_name)) { - LL_DEBUGS() << "Loading action set " << action_set_name << LL_ENDL; + LL_DEBUGS("GrpMgr") << "Loading action set " << action_set_name << LL_ENDL; role_action_data->mName = action_set_name; } else @@ -2403,7 +2441,7 @@ bool LLGroupMgr::parseRoleActions(const std::string& xml_filename) std::string action_name; if (action->getAttributeString("name", action_name)) { - LL_DEBUGS() << "Loading action " << action_name << LL_ENDL; + LL_DEBUGS("GrpMgr") << "Loading action " << action_name << LL_ENDL; role_action->mName = action_name; } else diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index cf9735e38a..0d25e8fb22 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -448,6 +448,8 @@ private: void notifyObserver(const LLUUID& group_id, LLGroupChange gc); void addGroup(LLGroupMgrGroupData* group_datap); LLGroupMgrGroupData* createGroupData(const LLUUID &id); + bool hasPendingPropertyRequest(const LLUUID& id); + void addPendingPropertyRequest(const LLUUID& id); typedef std::multimap<LLUUID,LLGroupMgrObserver*> observer_multimap_t; observer_multimap_t mObservers; @@ -455,6 +457,10 @@ private: typedef std::map<LLUUID, LLGroupMgrGroupData*> group_map_t; group_map_t mGroups; + const U64MicrosecondsImplicit MIN_GROUP_PROPERTY_REQUEST_FREQ = 100000;//100ms between requests should be enough to avoid spamming. + typedef std::map<LLUUID, U64MicrosecondsImplicit> properties_request_map_t; + properties_request_map_t mPropRequests; + typedef std::set<LLParticularGroupObserver*> observer_set_t; typedef std::map<LLUUID,observer_set_t> observer_map_t; observer_map_t mParticularObservers; diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 81d862a827..0701b07856 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -415,7 +415,8 @@ void LLHUDNameTag::clearString() void LLHUDNameTag::addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style, - const LLFontGL* font) + const LLFontGL* font, + const bool use_ellipses) { LLWString wline = utf8str_to_wstring(text_utf8); if (!wline.empty()) @@ -432,18 +433,49 @@ void LLHUDNameTag::addLine(const std::string &text_utf8, tokenizer tokens(wline, sep); tokenizer::iterator iter = tokens.begin(); - while (iter != tokens.end()) - { - U32 line_length = 0; - do - { - F32 max_pixels = HUD_TEXT_MAX_WIDTH; - S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); - LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); - mTextSegments.push_back(segment); - line_length += segment_length; - } - while (line_length != iter->size()); + const F32 max_pixels = HUD_TEXT_MAX_WIDTH; + while (iter != tokens.end()) + { + U32 line_length = 0; + if (use_ellipses) + { + // "QualityAssuranceAssuresQuality 1" will end up like "QualityAssuranceAssuresQual..." + // "QualityAssurance AssuresQuality 1" will be split into two lines "QualityAssurance" and "AssuresQuality 1" + do + { + S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::ONLY_WORD_BOUNDARIES); + if (segment_length == 0) + { + // First word in segment (not nessesary first line) does not fit, need to draw "...". + // Use four dots for ellipsis width to generate padding + const LLWString dots_pad(utf8str_to_wstring(std::string("...."))); + S32 elipses_width = font->getWidthF32(dots_pad.c_str()); + segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels - elipses_width, wline.length(), LLFontGL::ANYWHERE); + const LLWString dots(utf8str_to_wstring(std::string("..."))); + LLHUDTextSegment segment(iter->substr(line_length, segment_length) + dots, style, color, font); + mTextSegments.push_back(segment); + break; // consider it to be complete + } + else + { + LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); + mTextSegments.push_back(segment); + line_length += segment_length; + } + } while (line_length != iter->size()); + } + else + { + // "QualityAssuranceAssuresQuality 1" will be split into two lines "QualityAssuranceAssuresQualit" and "y 1" + // "QualityAssurance AssuresQuality 1" will be split into two lines "QualityAssurance" and "AssuresQuality" + do + { + S32 segment_length = font->maxDrawableChars(iter->substr(line_length).c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE); + LLHUDTextSegment segment(iter->substr(line_length, segment_length), style, color, font); + mTextSegments.push_back(segment); + line_length += segment_length; + } while (line_length != iter->size()); + } ++iter; } } diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 38a4f18415..20272a8232 100644 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -92,7 +92,7 @@ public: void clearString(); // Add text a line at a time, allowing custom formatting - void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL); + void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL, const bool use_ellipses = false); // For bubble chat, set the part above the chat text void setLabel(const std::string& label_utf8); diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 6da7bbe263..0d2553fd55 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -450,7 +450,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, || (dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id)); BOOL is_owned_by_me = FALSE; BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true; - BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly"); + BOOL accept_im_from_only_friend = gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly"); BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT && LLMuteList::getInstance()->isLinden(name); @@ -1164,7 +1164,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, { return; } - else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL)) + else if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL)) { return; } diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index d5142a4496..d17bb982e1 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -515,6 +515,7 @@ LLIMModel::LLIMModel() { addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1)); addNewMsgCallback(boost::bind(&on_new_message, _1)); + LLCallDialogManager::instance(); } LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg) @@ -2683,7 +2684,7 @@ void LLIMMgr::addMessage( } bool skip_message = false; bool from_linden = LLMuteList::getInstance()->isLinden(from); - if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden) + if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden) { // Evaluate if we need to skip this message when that setting is true (default is false) skip_message = (LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL); // Skip non friends... @@ -2742,7 +2743,7 @@ void LLIMMgr::addMessage( } //Play sound for new conversations - if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)) + if (!skip_message & !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)) { make_ui_sound("UISndNewIncomingIMSession"); } @@ -3072,7 +3073,7 @@ void LLIMMgr::inviteToSession( if (voice_invite) { bool isRejectGroupCall = (gSavedSettings.getBOOL("VoiceCallsRejectGroup") && (notify_box_type == "VoiceInviteGroup")); - bool isRejectNonFriendCall = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)); + bool isRejectNonFriendCall = (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)); if (isRejectGroupCall || isRejectNonFriendCall || gAgent.isDoNotDisturb()) { if (gAgent.isDoNotDisturb() && !isRejectGroupCall && !isRejectNonFriendCall) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 657c65c68d..03123689c5 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -138,6 +138,35 @@ bool isMarketplaceSendAction(const std::string& action) return ("send_to_marketplace" == action); } +bool isPanelActive(const std::string& panel_name) +{ + LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); + return (active_panel && (active_panel->getName() == panel_name)); +} + +bool isParentSystemFolder(const LLInventoryModel* model, const LLUUID& folder_id) +{ + if (!model || folder_id.isNull()) return false; + + LLViewerInventoryCategory* cat = model->getCategory(folder_id); + if (cat) + { + if (cat->getPreferredType() == LLFolderType::FT_ROOT_INVENTORY) + { + return false; + } + if (LLFolderType::lookupIsProtectedType(cat->getPreferredType())) + { + return true; + } + else + { + return isParentSystemFolder(model, cat->getParentUUID()); + } + } + return false; +} + // Used by LLFolderBridge as callback for directory fetching recursion class LLRightClickInventoryFetchDescendentsObserver : public LLInventoryFetchDescendentsObserver { @@ -888,8 +917,7 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Properties")); } - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel && (active_panel->getName() != "All Items")) + if (!isPanelActive("All Items")) { items.push_back(std::string("Show in Main Panel")); } @@ -980,7 +1008,7 @@ void LLInvFVBridge::addDeleteContextMenuOptions(menuentry_vec_t &items, items.push_back(std::string("Delete")); - if (!isItemRemovable()) + if (!isItemRemovable() || isPanelActive("Favorite Items")) { disabled_items.push_back(std::string("Delete")); } @@ -4010,6 +4038,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back(std::string("New Clothes")); disabled_items.push_back(std::string("New Body Parts")); disabled_items.push_back(std::string("upload_def")); + disabled_items.push_back(std::string("Set Favorites folder")); } if (favorites == mUUID) { @@ -4037,6 +4066,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back(std::string("New Clothes")); disabled_items.push_back(std::string("New Body Parts")); disabled_items.push_back(std::string("upload_def")); + disabled_items.push_back(std::string("Set Favorites folder")); } if (marketplace_listings_id == mUUID) { @@ -4045,14 +4075,14 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items disabled_items.push_back(std::string("Cut")); disabled_items.push_back(std::string("Delete")); } + + if (isPanelActive("Favorite Items")) + { + disabled_items.push_back(std::string("Delete")); + } if(trash_id == mUUID) { - bool is_recent_panel = false; - LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(FALSE); - if (active_panel && (active_panel->getName() == "Recent Items")) - { - is_recent_panel = true; - } + bool is_recent_panel = isPanelActive("Recent Items"); // This is the trash. items.push_back(std::string("Empty Trash")); @@ -4102,6 +4132,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items items.push_back(std::string("New Settings")); items.push_back(std::string("upload_def")); + if (!LLFolderType::lookupIsProtectedType(getPreferredType()) && !isParentSystemFolder(model, mUUID)) + { + items.push_back(std::string("Set Favorites folder")); + } if (!LLEnvironment::instance().isInventoryEnabled()) { disabled_items.push_back("New Settings"); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 745b953996..72013f7396 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -192,10 +192,15 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const // when applying a filter, matching folders get their contents downloaded first // but make sure we are not interfering with pre-download if (isNotDefault() - && !gInventory.isCategoryComplete(folder_id) && LLStartUp::getStartupState() > STATE_WEARABLES_WAIT) - { - LLInventoryModelBackgroundFetch::instance().start(folder_id); + { + LLViewerInventoryCategory* cat = gInventory.getCategory(folder_id); + if (!cat || (cat->getVersion() == LLViewerInventoryCategory::VERSION_UNKNOWN)) + { + // At the moment background fetch only cares about VERSION_UNKNOWN, + // so do not check isCategoryComplete that compares descendant count + LLInventoryModelBackgroundFetch::instance().start(folder_id); + } } // Marketplace folder filtering @@ -287,21 +292,34 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent // Pass if this item's type is of the correct filter type if (filterTypes & FILTERTYPE_OBJECT) { - - // If it has no type, pass it, unless it's a link. - if (object_type == LLInventoryType::IT_NONE) - { - if (object && object->getIsLinkType()) - { - return FALSE; - } - } - else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) - { - return FALSE; - } + switch (object_type) + { + case LLInventoryType::IT_NONE: + // If it has no type, pass it, unless it's a link. + if (object && object->getIsLinkType()) + { + return FALSE; + } + break; + case LLInventoryType::IT_UNKNOWN: + { + // Unknows are only shown when we show every type. + // Unknows are 255 and won't fit in 64 bits. + if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL) + { + return FALSE; + } + break; + } + default: + if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) + { + return FALSE; + } + break; + } } - + if(filterTypes & FILTERTYPE_WORN) { if (!get_is_item_worn(object_id)) @@ -426,18 +444,32 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) cons // Pass if this item's type is of the correct filter type if (filterTypes & FILTERTYPE_OBJECT) { - // If it has no type, pass it, unless it's a link. - if (object_type == LLInventoryType::IT_NONE) - { - if (item && item->getIsLinkType()) - { - return false; - } - } - else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) - { - return false; - } + switch (object_type) + { + case LLInventoryType::IT_NONE: + // If it has no type, pass it, unless it's a link. + if (item && item->getIsLinkType()) + { + return FALSE; + } + break; + case LLInventoryType::IT_UNKNOWN: + { + // Unknows are only shown when we show every type. + // Unknows are 255 and won't fit in 64 bits. + if (mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL) + { + return FALSE; + } + break; + } + default: + if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0)) + { + return FALSE; + } + break; + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 17e80dca89..a44a54632c 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -542,6 +542,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType:: cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder")); break; } + case LLFolderType::FT_FAVORITE: + { + cat_id = LLUUID(gSavedPerAccountSettings.getString("FavoritesFolder")); + break; + } default: break; } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index c6075b4066..26f1b61fe6 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -179,6 +179,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) : mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this)); mCommitCallbackRegistrar.add("Inventory.Share", boost::bind(&LLAvatarActions::shareWithAvatars, this)); mCommitCallbackRegistrar.add("Inventory.FileUploadLocation", boost::bind(&LLInventoryPanel::fileUploadLocation, this, _2)); + mCommitCallbackRegistrar.add("Inventory.SetFavoritesFolder", boost::bind(&LLInventoryPanel::setFavoritesFolder, this, _2)); } LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id ) @@ -1374,6 +1375,11 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata) } } +void LLInventoryPanel::setFavoritesFolder(const LLSD& userdata) +{ + gSavedPerAccountSettings.setString("FavoritesFolder", LLFolderBridge::sSelf.get()->getUUID().asString()); +} + void LLInventoryPanel::purgeSelectedItems() { if (!mFolderRoot.get()) return; @@ -1753,43 +1759,98 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params) mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER; } -/************************************************************************/ -/* Asset Pre-Filtered Inventory Panel related class */ -/* Exchanges filter's flexibility for speed of generation and */ -/* improved performance */ -/************************************************************************/ -class LLAssetFilteredInventoryPanel : public LLInventoryPanel +static LLDefaultChildRegistry::Register<LLInventoryFavoriteItemsPanel> t_favorites_inventory_panel("favorites_inventory_panel"); + +LLInventoryFavoriteItemsPanel::LLInventoryFavoriteItemsPanel(const Params& params) + : LLInventoryPanel(params) { -public: - struct Params - : public LLInitParam::Block<Params, LLInventoryPanel::Params> + std::string ctrl_name = "FavoritesFolder"; + if (gSavedPerAccountSettings.controlExists(ctrl_name)) { - Mandatory<std::string> filter_asset_type; + LLPointer<LLControlVariable> cntrl_ptr = gSavedPerAccountSettings.getControl(ctrl_name); + if (cntrl_ptr.notNull()) + { + mFolderChangedSignal = cntrl_ptr->getCommitSignal()->connect(boost::bind(&LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder, this)); + } + } +} - Params() : filter_asset_type("filter_asset_type") {} - }; +void LLInventoryFavoriteItemsPanel::setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb) +{ + if (mFolderRoot.get()) + { + mFolderRoot.get()->setSelectCallback(cb); + mSelectionCallback = cb; + } +} - void initFromParams(const Params& p); -protected: - LLAssetFilteredInventoryPanel(const Params& p) : LLInventoryPanel(p) {} - friend class LLUICtrlFactory; -public: - ~LLAssetFilteredInventoryPanel() {} +void LLInventoryFavoriteItemsPanel::initFromParams(const Params& p) +{ + Params fav_params(p); + fav_params.start_folder.id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE); + LLInventoryPanel::initFromParams(fav_params); + updateFavoritesRootFolder(); +} - /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, - EDragAndDropType cargo_type, - void* cargo_data, - EAcceptance* accept, - std::string& tooltip_msg) override; +void LLInventoryFavoriteItemsPanel::updateFavoritesRootFolder() +{ + const LLUUID& folder_id = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_FAVORITE); -protected: - /*virtual*/ LLFolderViewItem* buildNewViews(const LLUUID& id) override; - /*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override; + bool is_favorites_set = (folder_id != gInventory.findCategoryUUIDForTypeInRoot(LLFolderType::FT_FAVORITE, true, gInventory.getRootFolderID())); -private: - LLAssetType::EType mAssetType; -}; + if (!is_favorites_set || folder_id != getRootFolderID()) + { + LLUUID root_id = folder_id; + if (mFolderRoot.get()) + { + removeItemID(getRootFolderID()); + mFolderRoot.get()->destroyView(); + } + + mCommitCallbackRegistrar.pushScope(); + { + LLFolderView* folder_view = createFolderRoot(root_id); + mFolderRoot = folder_view->getHandle(); + + addItemID(root_id, mFolderRoot.get()); + + + LLRect scroller_view_rect = getRect(); + scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom); + LLScrollContainer::Params scroller_params(mParams.scroll()); + scroller_params.rect(scroller_view_rect); + + if (mScroller) + { + removeChild(mScroller); + delete mScroller; + mScroller = NULL; + } + mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params); + addChild(mScroller); + mScroller->addChild(mFolderRoot.get()); + mFolderRoot.get()->setScrollContainer(mScroller); + mFolderRoot.get()->setFollowsAll(); + mFolderRoot.get()->addChild(mFolderRoot.get()->mStatusTextBox); + + if (!mSelectionCallback.empty()) + { + mFolderRoot.get()->setSelectCallback(mSelectionCallback); + } + } + mCommitCallbackRegistrar.popScope(); + mFolderRoot.get()->setCallbackRegistrar(&mCommitCallbackRegistrar); + if (is_favorites_set) + { + buildNewViews(folder_id); + } + mFolderRoot.get()->setShowEmptyMessage(!is_favorites_set); + } +} +/************************************************************************/ +/* Asset Pre-Filtered Inventory Panel related class */ +/************************************************************************/ void LLAssetFilteredInventoryPanel::initFromParams(const Params& p) { diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index b55eb2b828..eda5479cb4 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -214,6 +214,7 @@ public: void doCreate(const LLSD& userdata); bool beginIMSession(); void fileUploadLocation(const LLSD& userdata); + void setFavoritesFolder(const LLSD& userdata); void purgeSelectedItems(); bool attachObject(const LLSD& userdata); static void idle(void* user_data); @@ -338,4 +339,63 @@ private: bool mViewsInitialized; // Views have been generated }; + +class LLInventoryFavoriteItemsPanel : public LLInventoryPanel +{ +public: + struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params> + {}; + + void initFromParams(const Params& p); + bool isSelectionRemovable() { return false; } + void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb); + +protected: + LLInventoryFavoriteItemsPanel(const Params& params); + ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); } + void updateFavoritesRootFolder(); + + boost::signals2::connection mFolderChangedSignal; + boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback; + friend class LLUICtrlFactory; +}; + +/************************************************************************/ +/* Asset Pre-Filtered Inventory Panel related class */ +/* Exchanges filter's flexibility for speed of generation and */ +/* improved performance */ +/************************************************************************/ + +class LLAssetFilteredInventoryPanel : public LLInventoryPanel +{ +public: + struct Params + : public LLInitParam::Block<Params, LLInventoryPanel::Params> + { + Mandatory<std::string> filter_asset_type; + + Params() : filter_asset_type("filter_asset_type") {} + }; + + void initFromParams(const Params& p); +protected: + LLAssetFilteredInventoryPanel(const Params& p) : LLInventoryPanel(p) {} + friend class LLUICtrlFactory; +public: + ~LLAssetFilteredInventoryPanel() {} + + /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, + EDragAndDropType cargo_type, + void* cargo_data, + EAcceptance* accept, + std::string& tooltip_msg) override; + +protected: + /*virtual*/ LLFolderViewItem* buildNewViews(const LLUUID& id) override; + /*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override; + +private: + LLAssetType::EType mAssetType; +}; + #endif // LL_LLINVENTORYPANEL_H diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 0c64531783..354f5a453b 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -761,8 +761,8 @@ bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group) { std::string file_name; gCacheName->getGroupName(avatar_id, file_name); - file_name = makeLogFileName(file_name); - return isTranscriptFileFound(makeLogFileName(file_name)); + file_name = makeLogFileName(file_name + GROUP_CHAT_SUFFIX); + return isTranscriptFileFound(file_name); } return false; } diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 1fce158eb4..66f747956d 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1553,7 +1553,7 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) if (!zero) { //attempt to parse - if (physicsShapeReceived(mesh_id, buffer, size)) + if (physicsShapeReceived(mesh_id, buffer, size) == MESH_OK) { delete[] buffer; return true; @@ -1647,7 +1647,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c LLMeshRepository::sCacheBytesRead += bytes; ++LLMeshRepository::sCacheReads; file.read(buffer, bytes); - if (headerReceived(mesh_params, buffer, bytes)) + if (headerReceived(mesh_params, buffer, bytes) == MESH_OK) { // Found mesh in VFS cache return true; @@ -1794,7 +1794,7 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, return retval; } -bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) +EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size) { const LLUUID mesh_id = mesh_params.getSculptID(); LLSD header; @@ -1802,30 +1802,39 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat U32 header_size = 0; if (data_size > 0) { - std::string res_str((char*) data, data_size); + std::istringstream stream; + try + { + std::string res_str((char*)data, data_size); - std::string deprecated_header("<? LLSD/Binary ?>"); + std::string deprecated_header("<? LLSD/Binary ?>"); - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size()+1, data_size); - header_size = deprecated_header.size()+1; - } - data_size = res_str.size(); + if (res_str.substr(0, deprecated_header.size()) == deprecated_header) + { + res_str = res_str.substr(deprecated_header.size() + 1, data_size); + header_size = deprecated_header.size() + 1; + } + data_size = res_str.size(); - std::istringstream stream(res_str); + stream.str(res_str); + } + catch (std::bad_alloc&) + { + // out of memory, we won't be able to process this mesh + return MESH_OUT_OF_MEMORY; + } if (!LLSDSerialize::fromBinary(header, stream, data_size)) { LL_WARNS(LOG_MESH) << "Mesh header parse error. Not a valid mesh asset! ID: " << mesh_id << LL_ENDL; - return false; + return MESH_PARSE_FAILURE; } if (!header.isMap()) { LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL; - return false; + return MESH_INVALID; } if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION) @@ -1871,7 +1880,7 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat } } - return true; + return MESH_OK; } EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size) @@ -1916,18 +1925,25 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat if (data_size > 0) { - std::string res_str((char*) data, data_size); - - std::istringstream stream(res_str); + try + { + std::string res_str((char*)data, data_size); + std::istringstream stream(res_str); - U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size); - if (uzip_result != LLUZipHelper::ZR_OK) - { - LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id - << " uzip result" << uzip_result - << LL_ENDL; - return false; - } + U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id + << " uzip result" << uzip_result + << LL_ENDL; + return false; + } + } + catch (std::bad_alloc&) + { + LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL; + return false; + } } { @@ -1949,19 +1965,26 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 LLSD decomp; if (data_size > 0) - { - std::string res_str((char*) data, data_size); - - std::istringstream stream(res_str); + { + try + { + std::string res_str((char*)data, data_size); + std::istringstream stream(res_str); - U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size); - if (uzip_result != LLUZipHelper::ZR_OK) - { - LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id - << " uzip result: " << uzip_result - << LL_ENDL; - return false; - } + U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id + << " uzip result: " << uzip_result + << LL_ENDL; + return false; + } + } + catch (std::bad_alloc&) + { + LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL; + return false; + } } { @@ -1976,7 +1999,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 return true; } -bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size) +EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size) { LLSD physics_shape; @@ -1993,8 +2016,19 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH); LLPointer<LLVolume> volume = new LLVolume(volume_params,0); - std::string mesh_string((char*) data, data_size); - std::istringstream stream(mesh_string); + + std::istringstream stream; + try + { + std::string mesh_string((char*)data, data_size); + stream.str(mesh_string); + } + catch (std::bad_alloc&) + { + // out of memory, we won't be able to process this mesh + delete d; + return MESH_OUT_OF_MEMORY; + } if (volume->unpackVolumeFaces(stream, data_size)) { @@ -2033,7 +2067,7 @@ bool LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 LLMutexLock lock(mMutex); mDecompositionQ.push_back(d); } - return true; + return MESH_OK; } LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data, LLVector3& scale, bool upload_textures, @@ -3142,15 +3176,21 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b U8 * data, S32 data_size) { LLUUID mesh_id = mMeshParams.getSculptID(); - bool success = (! MESH_HEADER_PROCESS_FAILED) - && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong - && gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size); + bool success = (!MESH_HEADER_PROCESS_FAILED) + && ((data != NULL) == (data_size > 0)); // if we have data but no size or have size but no data, something is wrong; llassert(success); + EMeshProcessingResult res = MESH_UNKNOWN; + if (success) + { + res = gMeshRepo.mThread->headerReceived(mMeshParams, data, data_size); + success = (res == MESH_OK); + } if (! success) { // *TODO: Get real reason for parse failure here. Might we want to retry? LL_WARNS(LOG_MESH) << "Unable to parse mesh header. ID: " << mesh_id - << ", Unknown reason. Not retrying." + << ", Size: " << data_size + << ", Reason: " << res << " Not retrying." << LL_ENDL; // Can't get the header so none of the LODs will be available @@ -3430,7 +3470,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3 { if ((!MESH_PHYS_SHAPE_PROCESS_FAILED) && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong - && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size)) + && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size) == MESH_OK) { // good fetch from sim, write to VFS for caching LLVFile file(gVFS, mMeshID, LLAssetType::AT_MESH, LLVFile::WRITE); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index bba0c9f2cb..9a627dabcb 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -57,6 +57,8 @@ typedef enum e_mesh_processing_result_enum MESH_NO_DATA = 1, MESH_OUT_OF_MEMORY, MESH_HTTP_REQUEST_FAILED, + MESH_PARSE_FAILURE, + MESH_INVALID, MESH_UNKNOWN } EMeshProcessingResult; @@ -336,11 +338,11 @@ public: bool fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry = true); bool fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry = true); - bool headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); + EMeshProcessingResult headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size); EMeshProcessingResult lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size); bool skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 data_size); bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size); - bool physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); + EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size); LLSD& getMeshHeader(const LLUUID& mesh_id); void notifyLoadedMeshes(); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 852ba846ff..272e7ae351 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1047,6 +1047,7 @@ void LLOutfitGallery::updateSnapshotFolderObserver() void LLOutfitGallery::refreshOutfit(const LLUUID& category_id) { LLViewerInventoryCategory* category = gInventory.getCategory(category_id); + if (category) { bool photo_loaded = false; LLInventoryModel::cat_array_t sub_cat_array; diff --git a/indra/newview/llpanelexperiences.cpp b/indra/newview/llpanelexperiences.cpp index 37981b36a9..91d3b523fb 100644 --- a/indra/newview/llpanelexperiences.cpp +++ b/indra/newview/llpanelexperiences.cpp @@ -93,9 +93,20 @@ void LLPanelExperiences::setExperienceList( const LLSD& experiences ) item->init(public_key); mExperiencesList->addItem(item, public_key); + + const LLSD& experience_details = LLExperienceCache::instance().get(public_key); + if (experience_details.isUndefined()) + { + LLExperienceCache::instance().get(public_key, boost::bind(&LLPanelExperiences::sortExperiencesList, this)); + } } - mExperiencesList->sort(); + sortExperiencesList(); +} + +void LLPanelExperiences::sortExperiencesList() +{ + mExperiencesList->sort(); } void LLPanelExperiences::getExperienceIdsList(std::vector<LLUUID>& result) diff --git a/indra/newview/llpanelexperiences.h b/indra/newview/llpanelexperiences.h index f29fdfdecb..9d5afd1a6a 100644 --- a/indra/newview/llpanelexperiences.h +++ b/indra/newview/llpanelexperiences.h @@ -60,6 +60,8 @@ public: void setExperienceList(const LLSD& experiences); void getExperienceIdsList(std::vector<LLUUID>& result); + void sortExperiencesList(); + LLExperienceItem* getSelectedExperienceItem(); void removeExperiences( const LLSD& ids ); void removeExperience( const LLUUID& id); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 5742b5ad1a..f127325ced 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1109,6 +1109,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) bool enabled = (editable && isIdenticalPlanarTexgen()); childSetValue("checkbox planar align", align_planar && enabled); + childSetVisible("checkbox planar align", enabled); childSetEnabled("checkbox planar align", enabled); childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1); diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 02cd22c307..89682d9576 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -188,6 +188,16 @@ BOOL LLPanelMainInventory::postBuild() worn_filter.markDefault(); mWornItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mWornItemsPanel, _1, _2)); } + + mFavoriteItemsPanel = getChild<LLInventoryFavoriteItemsPanel>("Favorite Items"); + if (mFavoriteItemsPanel) + { + LLInventoryFilter& recent_filter = mFavoriteItemsPanel->getFilter(); + recent_filter.setEmptyLookupMessage("InventoryFavoritItemsNotSelected"); + recent_filter.markDefault(); + mFavoriteItemsPanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mFavoriteItemsPanel, _1, _2)); + } + mSearchTypeCombo = getChild<LLComboBox>("search_type"); if(mSearchTypeCombo) { @@ -1403,7 +1413,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) } if (command_name == "delete") { - return getActivePanel()->isSelectionRemovable(); + return getActivePanel()->isSelectionRemovable() && (getActivePanel() != mFavoriteItemsPanel); } if (command_name == "save_texture") { diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h index a6bdee233d..c0b4a7b6fc 100644 --- a/indra/newview/llpanelmaininventory.h +++ b/indra/newview/llpanelmaininventory.h @@ -37,6 +37,7 @@ class LLComboBox; class LLFolderViewItem; class LLInventoryPanel; +class LLInventoryFavoriteItemsPanel; class LLSaveFolderState; class LLFilterEditor; class LLTabContainer; @@ -136,6 +137,7 @@ private: LLHandle<LLFloater> mFinderHandle; LLInventoryPanel* mActivePanel; LLInventoryPanel* mWornItemsPanel; + LLInventoryFavoriteItemsPanel* mFavoriteItemsPanel; bool mResortActivePanel; LLSaveFolderState* mSavedFolderState; std::string mFilterText; diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp index cea7054d6a..7a6631448b 100644 --- a/indra/newview/llpanelmarketplaceinboxinventory.cpp +++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp @@ -36,12 +36,15 @@ #include "llpanellandmarks.h" #include "llplacesinventorybridge.h" #include "llviewerfoldertype.h" +#include "llsdserialize.h" #define DEBUGGING_FRESHNESS 0 const LLColor4U DEFAULT_WHITE(255, 255, 255); +const std::string NEW_INBOX_FILENAME("inbox_new_items.xml"); + // // statics // @@ -57,7 +60,9 @@ static LLDefaultChildRegistry::Register<LLInboxFolderViewItem> r3("inbox_folder_ LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p) : LLInventoryPanel(p) -{} +{ + LLInboxNewItemsStorage::getInstance()->load(); +} LLInboxInventoryPanel::~LLInboxInventoryPanel() {} @@ -127,7 +132,7 @@ void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item) } // Compute freshness if our parent is the root folder for the inbox - if (mParentFolder == mRoot) + if ((mParentFolder == mRoot) && !mFresh) { computeFreshness(); } @@ -145,6 +150,12 @@ void LLInboxFolderViewFolder::draw() setBadgeVisibility(mFresh); LLFolderViewFolder::draw(); + + if (mFresh) + { + reshapeBadge(getRect()); + } + } BOOL LLInboxFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask ) @@ -167,11 +178,12 @@ void LLInboxFolderViewFolder::selectItem() void LLInboxFolderViewFolder::computeFreshness() { + LLFolderViewModelItemInventory* view_model = static_cast<LLFolderViewModelItemInventory*>(getViewModelItem()); const U32 last_expansion_utc = gSavedPerAccountSettings.getU32("LastInventoryInboxActivity"); if (last_expansion_utc > 0) { - mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc); + mFresh = (view_model->getCreationDate() > last_expansion_utc) || LLInboxNewItemsStorage::getInstance()->isItemFresh(view_model->getUUID()); #if DEBUGGING_FRESHNESS if (mFresh) @@ -184,6 +196,11 @@ void LLInboxFolderViewFolder::computeFreshness() { mFresh = true; } + + if (mFresh) + { + LLInboxNewItemsStorage::getInstance()->addFreshItem(view_model->getUUID()); + } } void LLInboxFolderViewFolder::deFreshify() @@ -191,6 +208,7 @@ void LLInboxFolderViewFolder::deFreshify() mFresh = false; gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); + LLInboxNewItemsStorage::getInstance()->removeItem(static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getUUID()); } // @@ -271,5 +289,55 @@ void LLInboxFolderViewItem::deFreshify() gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected()); } +LLInboxNewItemsStorage::LLInboxNewItemsStorage() +{ +} + +// static +void LLInboxNewItemsStorage::destroyClass() +{ + LLInboxNewItemsStorage::getInstance()->saveNewItemsIds(); +} + +void LLInboxNewItemsStorage::saveNewItemsIds() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, NEW_INBOX_FILENAME); + if (!filename.empty()) + { + LLSD uuids_data; + for (std::set<LLUUID>::const_iterator it = mNewItemsIDs.begin(); it != mNewItemsIDs.end(); it++) + { + uuids_data.append((*it)); + } + llofstream file; + file.open(filename.c_str()); + if ( file.is_open() ) + { + LLSDSerialize::toPrettyXML(uuids_data, file); + file.close(); + } + } +} + +void LLInboxNewItemsStorage::load() +{ + std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, NEW_INBOX_FILENAME); + if (!filename.empty()) + { + llifstream in_file; + in_file.open(filename.c_str()); + + LLSD uuids_data; + if (in_file.is_open()) + { + LLSDSerialize::fromXML(uuids_data, in_file); + in_file.close(); + for (LLSD::array_iterator i = uuids_data.beginArray(); i != uuids_data.endArray(); ++i) + { + mNewItemsIDs.insert((*i).asUUID()); + } + } + } +} // eof diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h index 0b27818c95..3e508e801b 100644 --- a/indra/newview/llpanelmarketplaceinboxinventory.h +++ b/indra/newview/llpanelmarketplaceinboxinventory.h @@ -113,4 +113,23 @@ protected: bool mFresh; }; +class LLInboxNewItemsStorage : public LLSingleton<LLInboxNewItemsStorage> + , public LLDestroyClass<LLInboxNewItemsStorage> +{ + LLSINGLETON(LLInboxNewItemsStorage); + LOG_CLASS(LLInboxNewItemsStorage); +public: + static void destroyClass(); + void saveNewItemsIds(); + + void load(); + + void addFreshItem(const LLUUID& id) { mNewItemsIDs.insert(id); } + void removeItem(const LLUUID& id) { mNewItemsIDs.erase(id); } + bool isItemFresh(const LLUUID& id) { return (mNewItemsIDs.find(id) != mNewItemsIDs.end()); } + +private: + std::set<LLUUID> mNewItemsIDs; +}; + #endif //LL_INBOXINVENTORYPANEL_H diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 8019335f97..8fff52ca4e 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -55,6 +55,7 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() : mMyOutfitsPanel(NULL), mCurrentOutfitPanel(NULL), mActivePanel(NULL), + mAppearanceTabs(NULL), mInitialized(false) { gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this)); @@ -312,6 +313,7 @@ void LLPanelOutfitsInventory::initTabPanels() void LLPanelOutfitsInventory::onTabChange() { + if (!mAppearanceTabs) return; mActivePanel = dynamic_cast<LLPanelAppearanceTab*>(mAppearanceTabs->getCurrentPanel()); if (!mActivePanel) return; diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 55c84815aa..67cd23d2ee 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -73,6 +73,7 @@ bool get_hud_matrices(glh::matrix4f &proj, glh::matrix4f &model); const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels[] = { ZOOM_NONE, ZOOM_MEDIUM }; const int LLPanelPrimMediaControls::kNumZoomLevels = 2; +const F32 EXCEEDING_ZOOM_DISTANCE = 0.5f; // // LLPanelPrimMediaControls // @@ -93,6 +94,7 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() : mZoomObjectID(LLUUID::null), mZoomObjectFace(0), mVolumeSliderVisible(0), + mZoomedCameraPos(), mWindowShade(NULL), mHideImmediately(false), mSecureURL(false), @@ -256,7 +258,7 @@ void LLPanelPrimMediaControls::focusOnTarget() LLViewerMediaImpl* media_impl = getTargetMediaImpl(); if(media_impl) { - if(!media_impl->hasFocus()) + if (!media_impl->hasFocus() || isZoomDistExceeding()) { // The current target doesn't have media focus -- focus on it. LLViewerObject* objectp = getTargetObject(); @@ -307,7 +309,8 @@ void LLPanelPrimMediaControls::updateShape() bool can_navigate = parcel->getMediaAllowNavigate(); bool enabled = false; - bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace); + bool is_zoomed = (mCurrentZoom != ZOOM_NONE) && (mTargetObjectID == mZoomObjectID) && (mTargetObjectFace == mZoomObjectFace) && !isZoomDistExceeding(); + // There is no such thing as "has_focus" being different from normal controls set // anymore (as of user feedback from bri 10/09). So we cheat here and force 'has_focus' // to 'true' (or, actually, we use a setting) @@ -1141,7 +1144,7 @@ void LLPanelPrimMediaControls::updateZoom() if (zoom_padding > 0.0f) { // since we only zoom into medium for now, always set zoom_in constraint to true - LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding, true); + mZoomedCameraPos = LLViewerMediaFocus::setCameraZoom(getTargetObject(), mTargetObjectNormal, zoom_padding, true); } // Remember the object ID/face we zoomed into, so we can update the zoom icon appropriately @@ -1401,6 +1404,10 @@ bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible() return mVolumeSliderVisible > 0; } +bool LLPanelPrimMediaControls::isZoomDistExceeding() +{ + return (gAgentCamera.getCameraPositionGlobal() - mZoomedCameraPos).normalize() >= EXCEEDING_ZOOM_DISTANCE; +} void LLPanelPrimMediaControls::clearFaceOnFade() { diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index d4301aaf7c..86fc036553 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -119,6 +119,8 @@ private: void showVolumeSlider(); void hideVolumeSlider(); bool shouldVolumeSliderBeVisible(); + + bool isZoomDistExceeding(); static void onScrollUp(void* user_data); static void onScrollUpHeld(void* user_data); @@ -183,6 +185,8 @@ private: F32 mZoomMediumPadding; F32 mZoomFarPadding; S32 mTopWorldViewAvoidZone; + + LLVector3d mZoomedCameraPos; LLUICtrl *mMediaPanelScroll; LLButton *mScrollUpCtrl; diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp index a23830e8e1..1c14acd843 100644 --- a/indra/newview/llplacesinventorypanel.cpp +++ b/indra/newview/llplacesinventorypanel.cpp @@ -43,9 +43,8 @@ static LLDefaultChildRegistry::Register<LLPlacesInventoryPanel> r("places_invent static const LLPlacesInventoryBridgeBuilder PLACES_INVENTORY_BUILDER; LLPlacesInventoryPanel::LLPlacesInventoryPanel(const Params& p) : - LLInventoryPanel(p), + LLAssetFilteredInventoryPanel(p), mSavedFolderState(NULL) - { mInvFVBridgeBuilder = &PLACES_INVENTORY_BUILDER; mSavedFolderState = new LLSaveFolderState(); diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h index 27d9b83bd1..5629438415 100644 --- a/indra/newview/llplacesinventorypanel.h +++ b/indra/newview/llplacesinventorypanel.h @@ -32,14 +32,16 @@ class LLLandmarksPanel; class LLFolderView; -class LLPlacesInventoryPanel : public LLInventoryPanel +class LLPlacesInventoryPanel : public LLAssetFilteredInventoryPanel { public: struct Params - : public LLInitParam::Block<Params, LLInventoryPanel::Params> + : public LLInitParam::Block<Params, LLAssetFilteredInventoryPanel::Params> { Params() - {} + { + filter_asset_type = "landmark"; + } }; LLPlacesInventoryPanel(const Params& p); diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h index d5b384ceb9..0de30e9e01 100644 --- a/indra/newview/llpresetsmanager.h +++ b/indra/newview/llpresetsmanager.h @@ -33,6 +33,7 @@ #include <map> static const std::string PRESETS_DEFAULT = "Default"; +static const std::string PRESETS_DEFAULT_UPPER = "DEFAULT"; static const std::string PRESETS_DIR = "presets"; static const std::string PRESETS_GRAPHIC = "graphic"; static const std::string PRESETS_CAMERA = "camera"; diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index e9feae3457..3e3ab3a676 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -404,28 +404,30 @@ void LLProgressView::initLogos() // with no internal paddings so it gets additional padding icon_width = 77; icon_height = 21; - S32 pad_y = 4; + S32 pad_fmod_y = 4; texture_start_x++; loadLogo(temp_str + "fmod_logo.png", image_codec, - LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y), + LLRect(texture_start_x, texture_start_y + pad_fmod_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_fmod_y), default_clip, default_clip); texture_start_x += icon_width + default_pad + 1; -#endif +#endif //LL_FMODSTUDIO +#ifdef LL_HAVOK // original image size is 342x113, central element is on a larger side // plus internal padding, so it gets slightly more height than desired 32 icon_width = 88; icon_height = 29; - pad_y = -1; + S32 pad_havok_y = -1; loadLogo(temp_str + "havok_logo.png", image_codec, - LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y), + LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y), default_clip, default_clip); texture_start_x += icon_width + default_pad; +#endif //LL_HAVOK // 108x41 icon_width = 74; @@ -545,6 +547,7 @@ void LLProgressView::onCancelButtonClicked(void*) // cancel is pressed while teleporting inside region (EXT-4911) if (LLStartUp::getStartupState() < STATE_STARTED) { + LL_INFOS() << "User requesting quit during login" << LL_ENDL; LLAppViewer::instance()->requestQuit(); } else diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 55e49100c3..8e52480644 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -78,16 +78,14 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert, BIO * pem_bio = BIO_new_mem_buf((void*)pem_cert.c_str(), pem_cert.length()); if(pem_bio == NULL) { - LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL; - LLTHROW(LLInvalidCertificate(LLSD::emptyMap())); + LL_ERRS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL; } mCert = NULL; PEM_read_bio_X509(pem_bio, &mCert, 0, NULL); BIO_free(pem_bio); if (!mCert) { - LL_WARNS("SECAPI") << "Could not decode certificate to x509." << LL_ENDL; - LLTHROW(LLInvalidCertificate(LLSD::emptyMap())); + LL_ERRS("SECAPI") << "Could not decode certificate to x509." << LL_ENDL; } } diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 56068b3bbb..9fd5eb28c1 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -303,6 +303,27 @@ void LLSelectMgr::updateEffects() } } +void LLSelectMgr::resetObjectOverrides() +{ + resetObjectOverrides(getSelection()); +} + +void LLSelectMgr::resetObjectOverrides(LLObjectSelectionHandle selected_handle) +{ + struct f : public LLSelectedNodeFunctor + { + virtual bool apply(LLSelectNode* node) + { + node->mLastPositionLocal.setVec(0, 0, 0); + node->mLastRotation = LLQuaternion(); + node->mLastScale.setVec(0, 0, 0); + return true; + } + } func; + + selected_handle->applyToNodes(&func); +} + void LLSelectMgr::overrideObjectUpdates() { //override any position updates from simulator on objects being edited @@ -5130,18 +5151,27 @@ void LLSelectMgr::sendListToRegions(LLObjectSelectionHandle selected_handle, bool link_operation = message_name == "ObjectLink"; - //clear update override data (allow next update through) - struct f : public LLSelectedNodeFunctor - { - virtual bool apply(LLSelectNode* node) - { - node->mLastPositionLocal.setVec(0,0,0); - node->mLastRotation = LLQuaternion(); - node->mLastScale.setVec(0,0,0); - return true; - } - } func; - selected_handle->applyToNodes(&func); + if (mAllowSelectAvatar) + { + if (selected_handle->getObjectCount() == 1 + && selected_handle->getFirstObject() != NULL + && selected_handle->getFirstObject()->isAvatar()) + { + // Server doesn't move avatars at the moment, it is a local debug feature, + // but server does update position regularly, so do not drop mLastPositionLocal + // Position override for avatar gets reset in LLAgentCamera::resetView(). + } + else + { + // drop mLastPositionLocal (allow next update through) + resetObjectOverrides(selected_handle); + } + } + else + { + //clear update override data (allow next update through) + resetObjectOverrides(selected_handle); + } std::queue<LLSelectNode*> nodes_to_send; @@ -6851,51 +6881,26 @@ void LLSelectMgr::pauseAssociatedAvatars() mSelectedObjects->mSelectType = getSelectTypeForObject(object); - bool is_attached = false; - if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && - isAgentAvatarValid()) + LLVOAvatar* parent_av = NULL; + if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT) { // Selection can be obsolete, confirm that this is an attachment - LLViewerObject* parent = (LLViewerObject*)object->getParent(); - while (parent != NULL) - { - if (parent->isAvatar()) - { - is_attached = true; - break; - } - else - { - parent = (LLViewerObject*)parent->getParent(); - } - } + // and find parent avatar + parent_av = object->getAvatarAncestor(); } - - if (is_attached) + // Can be both an attachment and animated object + if (parent_av) { - if (object->isAnimatedObject()) - { - // Is an animated object attachment. - // Pause both the control avatar and the avatar it's attached to. - if (object->getControlAvatar()) - { - mPauseRequests.push_back(object->getControlAvatar()->requestPause()); - } - mPauseRequests.push_back(gAgentAvatarp->requestPause()); - } - else - { - // Is a regular attachment. Pause the avatar it's attached to. - mPauseRequests.push_back(gAgentAvatarp->requestPause()); - } + // It's an attachment. Pause the avatar it's attached to. + mPauseRequests.push_back(parent_av->requestPause()); } - else if (object && object->isAnimatedObject() && object->getControlAvatar()) + + if (object->isAnimatedObject() && object->getControlAvatar()) { - // Is a non-attached animated object. Pause the control avatar. + // It's an animated object. Pause the control avatar. mPauseRequests.push_back(object->getControlAvatar()->requestPause()); } - } } diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 3bed484b58..75d11dd06b 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -458,6 +458,13 @@ public: void clearSelections(); void update(); void updateEffects(); // Update HUD effects + + // When we edit object's position/rotation/scale we set local + // overrides and ignore any updates (override received valeus). + // When we send data to server, we send local values and reset + // overrides + void resetObjectOverrides(); + void resetObjectOverrides(LLObjectSelectionHandle selected_handle); void overrideObjectUpdates(); // Returns the previous value of mForceSelection diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 77bbcdada6..2cdba4d9ba 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3448,7 +3448,7 @@ public: U8 index = facep->getTextureIndex(); if (facep->mDrawInfo) { - if (index < 255) + if (index < FACE_DO_NOT_BATCH_TEXTURES) { if (facep->mDrawInfo->mTextureList.size() <= index) { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 4c54d44ac5..0a8ff4b339 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -917,9 +917,9 @@ bool idle_startup() } // Set PerAccountSettingsFile to the default value. - gSavedSettings.setString("PerAccountSettingsFile", - gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, - LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount"))); + std::string settings_per_account = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, LLAppViewer::instance()->getSettingsFilename("Default", "PerAccount")); + gSavedSettings.setString("PerAccountSettingsFile", settings_per_account); + gDebugInfo["PerAccountSettingsFilename"] = settings_per_account; // Note: can't store warnings files per account because some come up before login @@ -1105,6 +1105,8 @@ bool idle_startup() // Its either downloading or declined. // If optional was skipped this case shouldn't // be reached. + + LL_INFOS() << "Forcing a quit due to update." << LL_ENDL; LLLoginInstance::getInstance()->disconnect(); LLAppViewer::instance()->forceQuit(); } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 6a0464c657..de7551d2fe 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -139,17 +139,17 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { - if ( mBakeTextureEnabled && mModeSelector->getSelectedIndex() != 2) + if ( mBakeTextureEnabled && mModeSelector->getValue().asInteger() != 2) { - mModeSelector->setSelectedIndex(2, 0); + mModeSelector->selectByValue(2); onModeSelect(0,this); } } else { - if (mModeSelector->getSelectedIndex() == 2) + if (mModeSelector->getValue().asInteger() == 2) { - mModeSelector->setSelectedIndex(0, 0); + mModeSelector->selectByValue(0); onModeSelect(0,this); } @@ -346,7 +346,7 @@ BOOL LLFloaterTexturePicker::postBuild() } mTentativeLabel = getChild<LLTextBox>("Multiple"); - mResolutionLabel = getChild<LLTextBox>("unknown"); + mResolutionLabel = getChild<LLTextBox>("size_lbl"); childSetAction("Default",LLFloaterTexturePicker::onBtnSetToDefault,this); @@ -362,9 +362,9 @@ BOOL LLFloaterTexturePicker::postBuild() mInventoryPanel = getChild<LLInventoryPanel>("inventory panel"); - mModeSelector = getChild<LLRadioGroup>("mode_selection"); + mModeSelector = getChild<LLComboBox>("mode_selection"); mModeSelector->setCommitCallback(onModeSelect, this); - mModeSelector->setSelectedIndex(0, 0); + mModeSelector->selectByValue(0); if(mInventoryPanel) { @@ -755,7 +755,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata) { LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata; - int index = self->mModeSelector->getSelectedIndex(); + int index = self->mModeSelector->getValue().asInteger(); self->getChild<LLButton>("Default")->setVisible(index == 0 ? TRUE : FALSE); self->getChild<LLButton>("Blank")->setVisible(index == 0 ? TRUE : FALSE); @@ -1082,7 +1082,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string ) void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled) { - mModeSelector->setIndexEnabled(1,enabled); + mModeSelector->setEnabledByValue(1, enabled); } void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) @@ -1090,18 +1090,18 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled) BOOL changed = (enabled != mBakeTextureEnabled); mBakeTextureEnabled = enabled; - mModeSelector->setIndexEnabled(2, enabled); + mModeSelector->setEnabledByValue(2, enabled); - if (!mBakeTextureEnabled && (mModeSelector->getSelectedIndex() == 2)) + if (!mBakeTextureEnabled && (mModeSelector->getValue().asInteger() == 2)) { - mModeSelector->setSelectedIndex(0, 0); + mModeSelector->selectByValue(0); } if (changed && mBakeTextureEnabled && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID)) { - if (mModeSelector->getSelectedIndex() != 2) + if (mModeSelector->getValue().asInteger() != 2) { - mModeSelector->setSelectedIndex(2, 0); + mModeSelector->selectByValue(2); } } onModeSelect(0, this); diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index b2a34a37c4..c705c34e21 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -36,7 +36,6 @@ #include "llstring.h" #include "lluictrl.h" #include "llpermissionsflags.h" -#include "llradiogroup.h" #include "lltextbox.h" // for params #include "llviewerinventory.h" #include "llviewborder.h" // for params @@ -44,7 +43,7 @@ #include "llviewertexture.h" #include "llwindow.h" -class LLButton; +class LLComboBox; class LLFloaterTexturePicker; class LLInventoryItem; class LLViewerFetchedTexture; @@ -367,7 +366,7 @@ protected: LLSaveFolderState mSavedFolderState; BOOL mSelectedItemPinned; - LLRadioGroup* mModeSelector; + LLComboBox* mModeSelector; LLScrollListCtrl* mLocalScrollCtrl; private: diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index a4806ceaf6..f01b374db1 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -142,8 +142,9 @@ BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask) // call the base class to propogate info to sim LLTool::handleMouseDown(x, y, mask); - - if (!gAgent.leftButtonGrabbed()) + + // leftButtonGrabbed() checks if controls are reserved by scripts, but does not take masks into account + if (!gAgent.leftButtonGrabbed() || ((mask & DEFAULT_GRAB_MASK) != 0 && !gAgentCamera.cameraMouselook())) { // can grab transparent objects (how touch event propagates, scripters rely on this) gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE); diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 02ed5c26d7..ce0de0f946 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -44,6 +44,7 @@ class LLPickInfo; void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, const LLVector3 &grab_offset); void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick); +const MASK DEFAULT_GRAB_MASK = MASK_CONTROL; /** * LLToolGrabBase contains most of the semantics of LLToolGrab. It's just that diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index f499c34ca4..12346f16d7 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -1449,7 +1449,7 @@ LLTool* LLToolPie::getOverrideTool(MASK mask) { if (gSavedSettings.getBOOL("EnableGrab")) { - if (mask == MASK_CONTROL) + if (mask == DEFAULT_GRAB_MASK) { return LLToolGrab::getInstance(); } diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index 71ae7bfbc3..10099eda5b 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -205,8 +205,9 @@ bool LLViewerMediaFocus::getFocus() } // This function selects an ideal viewing distance based on the focused object, pick normal, and padding value -void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only) +LLVector3d LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only) { + LLVector3d camera_pos; if (object) { gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); @@ -254,7 +255,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, distance += depth * 0.5; // Finally animate the camera to this new position and focal point - LLVector3d camera_pos, target_pos; + LLVector3d target_pos; // The target lookat position is the center of the selection (in global coords) target_pos = center; // Target look-from (camera) position is "distance" away from the target along the normal @@ -287,7 +288,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, if (zoom_in_only && (dist_vec_squared(gAgentCamera.getCameraPositionGlobal(), target_pos) < dist_vec_squared(camera_pos, target_pos))) { - return; + return camera_pos; } gAgentCamera.setCameraPosAndFocusGlobal(camera_pos, target_pos, object->getID() ); @@ -298,6 +299,7 @@ void LLViewerMediaFocus::setCameraZoom(LLViewerObject* object, LLVector3 normal, // If we have no object, focus back on the avatar. gAgentCamera.setFocusOnAvatar(TRUE, ANIMATE); } + return camera_pos; } void LLViewerMediaFocus::onFocusReceived() { diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h index fa469c36e3..effd08a559 100644 --- a/indra/newview/llviewermediafocus.h +++ b/indra/newview/llviewermediafocus.h @@ -63,7 +63,7 @@ public: void update(); - static void setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only = false); + static LLVector3d setCameraZoom(LLViewerObject* object, LLVector3 normal, F32 padding_factor, bool zoom_in_only = false); static F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth); bool isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face); diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 0cdd447fcd..5a8110cd57 100644 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -52,6 +52,7 @@ mMediaParcelLocalID(0) LLMessageSystem* msg = gMessageSystem; msg->setHandlerFunc("ParcelMediaCommandMessage", parcelMediaCommandMessageHandler ); msg->setHandlerFunc("ParcelMediaUpdate", parcelMediaUpdateHandler ); + LLViewerParcelMediaAutoPlay::instance(); } LLViewerParcelMedia::~LLViewerParcelMedia() diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e67826454b..2ca045b0c9 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3144,7 +3144,7 @@ void LLViewerRegion::setCapabilitiesReceived(bool received) { mCapabilitiesReceivedSignal(getRegionID()); - //LLFloaterPermsDefault::sendInitialPerms(); + LLFloaterPermsDefault::sendInitialPerms(); // This is a single-shot signal. Forget callbacks to save resources. mCapabilitiesReceivedSignal.disconnect_all_slots(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 1fbb32ac5e..1e72e2266b 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1396,6 +1396,7 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window) void LLViewerWindow::handleQuit(LLWindow *window) { + LL_INFOS() << "Window forced quit" << LL_ENDL; LLAppViewer::instance()->forceQuit(); } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d567623ac0..786d4aacb7 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2414,6 +2414,7 @@ S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) } static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE("Avatar Update"); +static LLTrace::BlockTimerStatHandle FTM_AVATAR_UPDATE_COMPLEXITY("Avatar Update Complexity"); static LLTrace::BlockTimerStatHandle FTM_JOINT_UPDATE("Update Joints"); //------------------------------------------------------------------------ @@ -2463,7 +2464,6 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } // Update should be happening max once per frame. - const S32 upd_freq = 4; // force update every upd_freq frames. if ((mLastAnimExtents[0]==LLVector3())|| (mLastAnimExtents[1])==LLVector3()) { @@ -2471,6 +2471,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } else { + const S32 upd_freq = 4; // force update every upd_freq frames. mNeedsExtentUpdate = ((LLDrawable::getCurrentFrame()+mID.mData[0])%upd_freq==0); } @@ -2555,7 +2556,40 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) } idleUpdateNameTag( mLastRootPos ); - idleUpdateRenderComplexity(); + + // Complexity has stale mechanics, but updates still can be very rapid + // so spread avatar complexity calculations over frames to lesen load from + // rapid updates and to make sure all avatars are not calculated at once. + S32 compl_upd_freq = 20; + if (isControlAvatar()) + { + // animeshes do not (or won't) have impostors nor change outfis, + // no need for high frequency + compl_upd_freq = 100; + } + else if (mLastRezzedStatus <= 0) //cloud or init + { + compl_upd_freq = 60; + } + else if (isSelf()) + { + compl_upd_freq = 5; + } + else if (mLastRezzedStatus == 1) //'grey', not fully loaded + { + compl_upd_freq = 40; + } + else if (isInMuteList()) //cheap, buffers value from search + { + compl_upd_freq = 100; + } + + if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0) + { + LL_RECORD_BLOCK_TIME(FTM_AVATAR_UPDATE_COMPLEXITY); + idleUpdateRenderComplexity(); + } + idleUpdateDebugInfo(); } void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled) @@ -2866,7 +2900,10 @@ F32 LLVOAvatar::calcMorphAmount() void LLVOAvatar::idleUpdateLipSync(bool voice_enabled) { // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync - if ( voice_enabled && (LLVoiceClient::getInstance()->lipSyncEnabled()) && LLVoiceClient::getInstance()->getIsSpeaking( mID ) ) + if ( voice_enabled + && mLastRezzedStatus > 0 // no point updating lip-sync for clouds + && (LLVoiceClient::getInstance()->lipSyncEnabled()) + && LLVoiceClient::getInstance()->getIsSpeaking( mID ) ) { F32 ooh_morph_amount = 0.0f; F32 aah_morph_amount = 0.0f; @@ -3214,7 +3251,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) std::string title_str = title->getString(); LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR); addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall()); + LLFontGL::getFontSansSerifSmall(), true); } static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames", true); @@ -3234,7 +3271,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) if (show_display_names) { addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerif()); + LLFontGL::getFontSansSerif(), true); } // Suppress SLID display if display name matches exactly (ugh) if (show_usernames && !av_name.isDisplayNameDefault()) @@ -3242,14 +3279,14 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) // *HACK: Desaturate the color LLColor4 username_color = name_tag_color * 0.83f; addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL, - LLFontGL::getFontSansSerifSmall()); + LLFontGL::getFontSansSerifSmall(), true); } } else { const LLFontGL* font = LLFontGL::getFontSansSerif(); std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() ); - addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font); + addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font, true); } mNameAway = is_away; @@ -3341,7 +3378,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) } } -void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font) +void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses) { llassert(mNameText); if (mVisibleChat) @@ -3350,7 +3387,7 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, } else { - mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font); + mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses); } mNameIsSet |= !line.empty(); } @@ -3900,6 +3937,11 @@ void LLVOAvatar::computeUpdatePeriod() { //background avatars are REALLY slow updating impostors mUpdatePeriod = 16; } + else if (mLastRezzedStatus <= 0) + { + // Don't update cloud avatars too often + mUpdatePeriod = 8; + } else if ( shouldImpostor(3) ) { //back 25% of max visible avatars are slow updating impostors mUpdatePeriod = 8; @@ -4286,15 +4328,15 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // Set mUpdatePeriod and visible based on distance and other criteria. //-------------------------------------------------------------------- computeUpdatePeriod(); - visible = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0 ? TRUE : FALSE; + bool needs_update = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0; //-------------------------------------------------------------------- - // Early out if not visible and not self + // Early out if does not need update and not self // don't early out for your own avatar, as we rely on your animations playing reliably // for example, the "turn around" animation when entering customize avatar needs to trigger // even when your avatar is offscreen //-------------------------------------------------------------------- - if (!visible && !isSelf()) + if (!needs_update && !isSelf()) { updateMotions(LLCharacter::HIDDEN_UPDATE); return FALSE; @@ -4343,12 +4385,17 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) mSpeed = speed; // update animations - if (mSpecialRenderMode == 1) // Animation Preview + if (!visible) + { + updateMotions(LLCharacter::HIDDEN_UPDATE); + } + else if (mSpecialRenderMode == 1) // Animation Preview { updateMotions(LLCharacter::FORCE_UPDATE); } else { + // Might be better to do HIDDEN_UPDATE if cloud updateMotions(LLCharacter::NORMAL_UPDATE); } @@ -4376,10 +4423,13 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) // Update child joints as needed. mRoot->updateWorldMatrixChildren(); - // System avatar mesh vertices need to be reskinned. - mNeedsSkin = TRUE; + if (visible) + { + // System avatar mesh vertices need to be reskinned. + mNeedsSkin = TRUE; + } - return TRUE; + return visible; } //----------------------------------------------------------------------------- @@ -10142,7 +10192,10 @@ void LLVOAvatar::idleUpdateRenderComplexity() // Render Complexity calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed +} +void LLVOAvatar::idleUpdateDebugInfo() +{ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO)) { std::string info_line; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index ca6ac5c902..71a81c2e3d 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -284,8 +284,9 @@ public: static void invalidateNameTag(const LLUUID& agent_id); // force all name tags to rebuild, useful when display names turned on/off static void invalidateNameTags(); - void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font); + void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses = false); void idleUpdateRenderComplexity(); + void idleUpdateDebugInfo(); void accountRenderComplexityForObject(const LLViewerObject *attached_object, const F32 max_attachment_complexity, LLVOVolume::texture_cost_t& textures, diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 16b27fd144..aea12380e8 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -2667,11 +2667,6 @@ void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch) { gAgentCamera.changeCameraToCustomizeAvatar(); } - -#if 0 - gAgentAvatarp->clearVisualParamWeights(); - gAgentAvatarp->idleUpdateAppearanceAnimation(); -#endif gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh. diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a6500d1399..99622c6312 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4585,8 +4585,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { U8 mode = mat->getDiffuseAlphaMode(); - if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE || - mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE) + if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE + || mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE + || (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && mat->getAlphaMaskCutoff() == 0)) { ignore_alpha = true; } @@ -5100,7 +5101,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } - if (index < 255 && idx >= 0) + if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) { if (mat || draw_vec[idx]->mMaterial) { //can't batch textures when materials are present (yet) @@ -5146,7 +5147,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); - if (index < 255 && index >= draw_vec[idx]->mTextureList.size()) + if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size()) { draw_vec[idx]->mTextureList.resize(index+1); draw_vec[idx]->mTextureList[index] = tex; @@ -5233,7 +5234,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mDrawMode = LLRender::TRIANGLE_STRIP; } - if (index < 255) + if (index < FACE_DO_NOT_BATCH_TEXTURES) { //initialize texture list for texture batching draw_info->mTextureList.resize(index+1); draw_info->mTextureList[index] = tex; @@ -6365,7 +6366,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //face has no texture index facep->mDrawInfo = NULL; - facep->setTextureIndex(255); + facep->setTextureIndex(FACE_DO_NOT_BATCH_TEXTURES); if (geom_count + facep->getGeomCount() > max_vertices) { //cut batches on geom count too big @@ -6429,7 +6430,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace facep->setGeomIndex(index_offset); facep->setVertexBuffer(buffer); - if (batch_textures && facep->getTextureIndex() == 255) + if (batch_textures && facep->getTextureIndex() == FACE_DO_NOT_BATCH_TEXTURES) { LL_ERRS() << "Invalid texture index." << LL_ENDL; } diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 8e2539606b..32c8ce66a0 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -240,16 +240,16 @@ void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle, if (!status) { + mImpl->setHttpStatus(status); + LLSD errordata = status.getErrorData(); + mImpl->mErrorCertData = errordata; + if ((status.toULong() != CURLE_SSL_PEER_CERTIFICATE) && (status.toULong() != CURLE_SSL_CACERT)) { // if we have a curl error that's not already been handled - // (a non cert error), then generate the error message as + // (a non cert error), then generate the warning message as // appropriate - mImpl->setHttpStatus(status); - LLSD errordata = status.getErrorData(); - mImpl->mErrorCertData = errordata; - LL_WARNS() << "LLXMLRPCTransaction error " << status.toHex() << ": " << status.toString() << LL_ENDL; LL_WARNS() << "LLXMLRPCTransaction request URI: " diff --git a/indra/newview/skins/default/xui/da/floater_buy_currency.xml b/indra/newview/skins/default/xui/da/floater_buy_currency.xml index 3c0428b2b0..b7ac181dd4 100644 --- a/indra/newview/skins/default/xui/da/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/da/floater_buy_currency.xml @@ -60,8 +60,7 @@ objektet. </text> <button label="Køb nu" name="buy_btn"/> <button label="Annullér" name="cancel_btn"/> - <text name="info_cannot_buy"> + <floater.string name="info_cannot_buy"> Kan ikke købe - </text> - <button label="Fortsæt til web" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_buy_currency.xml b/indra/newview/skins/default/xui/de/floater_buy_currency.xml index 65926c088c..eb94df1cad 100644 --- a/indra/newview/skins/default/xui/de/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/de/floater_buy_currency.xml @@ -59,8 +59,7 @@ </text> <button label="Jetzt kaufen" name="buy_btn"/> <button label="Abbrechen" name="cancel_btn"/> - <text name="info_cannot_buy"> + <floater.string name="info_cannot_buy"> Kaufabbruch - </text> - <button label="Weiter zur Kontoseite" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml index b818a7d480..81b093b8c2 100644 --- a/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/de/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> Mehrere Texturen </text> - <radio_group name="mode_selection"> - <radio_item label="Inventar" name="inventory" value="0"/> - <radio_item label="Lokal" name="local" value="1"/> - <radio_item label="Backen" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - Größe: [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Inventar" name="inventory" value="0"/> + <combo_box.item label="Lokal" name="local" value="1"/> + </combo_box> <button label="Standard" label_selected="Standard" name="Default"/> <button label="Leer" label_selected="Leer" name="Blank"/> <button label="Keine" label_selected="Keine" name="None"/> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml index e0aa9fe4a9..16fdb69509 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Freunde immer darstellen" name="AlwaysRenderFriends"/> <button label="Ausnahmen..." name="RenderExceptionsButton"/> - <button label="Einstellungen als Voreinstellung speichern..." name="PrefSaveButton"/> - <button label="Voreinstellung laden..." name="PrefLoadButton"/> + <button label="Einstellungen als Voreinstellung speichern" name="PrefSaveButton" width="235" left="5"/> + <button label="Voreinstellung laden" name="PrefLoadButton" width="120"/> min_val="0.125" - <button label="Voreinstellung löschen..." name="PrefDeleteButton"/> - <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults"/> + <button label="Voreinstellung löschen" name="PrefDeleteButton" width="130"/> + <button label="Auf empfohlene Einstellungen zurücksetzen" name="Defaults" width="248"/> <button label="Erweiterte Einstellungen..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml index 1435b7f87d..a8509cabac 100644 --- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml @@ -35,5 +35,5 @@ <text name="Proxy Settings:"> Proxy-Einstellungen: </text> - <button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy"/> + <button label="Proxy-Einstellungen ändern" label_selected="Durchsuchen" name="set_proxy" width="160"/> </panel> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index a1dd179765..b2d9e53039 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -123,8 +123,8 @@ No parcel selected. </panel.string> <panel.string name="time_stamp_template"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] - </panel.string> + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] + </panel.string> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml index 553c5d51d0..061af1b67c 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml @@ -13,6 +13,10 @@ name="buy_currency"> Buy L$ [LINDENS] for approx. [LOCALAMOUNT] </floater.string> + <floater.string + name="info_cannot_buy"> + Unable to Buy + </floater.string> <icon height="215" image_name="Linden_Dollar_Background" @@ -286,42 +290,4 @@ Re-enter amount to see the latest exchange rate. left_pad="10" name="cancel_btn" width="90"/> - <icon - height="215" - image_name="Linden_Dollar_Alert" - layout="topleft" - left="0" - name="error_background" - top="15" - use_draw_context_alpha="false" - width="350"/> - <text - type="string" - font="SansSerifHuge" - left="165" - width="360" - height="25" - top="25" - name="info_cannot_buy"> - Unable to Buy - </text> - <text - type="string" - width="176" - height="125" - top="60" - left="165" - word_wrap="true" - follows="bottom|right" - name="cannot_buy_message"> - </text> - <button - follows="bottom|left" - height="20" - label="Continue to the Web" - layout="topleft" - left="170" - name="error_web" - top="200" - width="160"/> </floater> diff --git a/indra/newview/skins/default/xui/en/floater_image_preview.xml b/indra/newview/skins/default/xui/en/floater_image_preview.xml index 3daff1a132..773d9aafc9 100644 --- a/indra/newview/skins/default/xui/en/floater_image_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_image_preview.xml @@ -120,8 +120,8 @@ Try saving image as 24 bit Targa (.tga). </text> <check_box - control_name="LosslessJ2CUpload" enabled="false" + initial_value="false" follows="bottom|left" height="16" label="Use lossless compression" diff --git a/indra/newview/skins/default/xui/en/floater_inspect.xml b/indra/newview/skins/default/xui/en/floater_inspect.xml index 63334e2b24..802a6649c8 100644 --- a/indra/newview/skins/default/xui/en/floater_inspect.xml +++ b/indra/newview/skins/default/xui/en/floater_inspect.xml @@ -13,7 +13,7 @@ width="400"> <floater.string name="timeStamp"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] </floater.string> <scroll_list bottom="268" diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index a52d0a95d6..3a66911389 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -48,42 +48,28 @@ </text> <!-- mode selector --> - <radio_group + <combo_box control_name="mode_selection" height="20" layout="topleft" - left="0" - top_pad="80" + left="6" + top_pad="77" name="mode_selection" - follows="left|top"> - <radio_item + follows="left|top" + width="120"> + <combo_box.item label="Inventory" name="inventory" - top_delta="20" - layout="topleft" - height="16" - left="0" - value="0" - width="70" /> - <radio_item + value="0" /> + <combo_box.item label="Local" - left_pad="0" - layout="topleft" - top_delta="0" - height="16" name="local" - value="1" - width="50" /> - <radio_item + value="1" /> + <combo_box.item label="Bake" - left_pad="0" - layout="topleft" - top_delta="0" - height="16" name="bake" - value="2" - width="50" /> - </radio_group> + value="2" /> + </combo_box> <!-- --> <text @@ -92,21 +78,9 @@ follows="left|top" height="14" layout="topleft" - left_delta="12" + left="8" name="size_lbl" top_pad="4"> - Size: - </text> - - <text - type="string" - length="1" - follows="left|top" - height="14" - layout="topleft" - left_delta="0" - name="unknown" - top_pad="4"> [DIMENSIONS] </text> <!-- middle: inventory mode --> @@ -149,8 +123,8 @@ image_selected="eye_button_active.tga" image_unselected="eye_button_inactive.tga" layout="topleft" - left_delta="-80" - top_delta="-10" + left="18" + top_delta="-23" name="Pipette" width="28" /> <text @@ -329,7 +303,7 @@ layout="topleft" label="OK" label_selected="OK" layout="topleft" - left="95" + left="176" top="-30" name="Select" width="100" /> @@ -352,5 +326,5 @@ layout="topleft" left="6" name="apply_immediate_check" top_delta="0" - width="120" /> + width="150" /> </floater> diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml index 76df0abdfd..d88c267a95 100644 --- a/indra/newview/skins/default/xui/en/fonts.xml +++ b/indra/newview/skins/default/xui/en/fonts.xml @@ -12,6 +12,7 @@ <file>msyh.ttc</file> <file load_collection="true">Cambria.ttc</file> <file>malgun.ttf</file> + <file>micross.ttf</file> </os> <os name="Mac"> <file>ヒラギノ角ゴシック W3.ttc</file> @@ -25,6 +26,7 @@ <file>华文细黑.ttf</file> <file>PingFang.ttc</file> <file>STIXGeneral.otf</file> + <file>Thonburi.ttc</file> </os> </font> diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml index 9aa84c1bac..adefa261aa 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory.xml @@ -393,6 +393,13 @@ parameter="model" /> </menu_item_call> </menu> + <menu_item_call + label="Use as Favorites folder" + layout="topleft" + name="Set Favorites folder"> + <menu_item_call.on_click + function="Inventory.SetFavoritesFolder"/> + </menu_item_call> <menu label="Change Type" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml index db29d9cebc..49e52ebb8d 100644 --- a/indra/newview/skins/default/xui/en/menu_script_chiclet.xml +++ b/indra/newview/skins/default/xui/en/menu_script_chiclet.xml @@ -16,4 +16,12 @@ function="ScriptChiclet.Action" parameter="end" /> </menu_item_call> + <menu_item_call + label="Close All Dialogs" + layout="topleft" + name="Close All"> + <menu_item_call.on_click + function="ScriptChiclet.Action" + parameter="close all" /> + </menu_item_call> </menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 873b95926b..c7ab26bc22 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -56,7 +56,8 @@ </menu_item_call> <menu_item_call label="Places..." - name="Places"> + name="Places" + shortcut="control|L"> <menu_item_call.on_click function="Floater.ToggleOrBringToFront" parameter="places" /> @@ -85,11 +86,22 @@ <menu_item_separator/> <menu_item_call label="Camera Controls..." - name="Camera Controls"> + name="Camera Controls" + shortcut="control|K"> <menu_item_call.on_click function="Floater.ToggleOrBringToFront" parameter="camera" /> </menu_item_call> + <menu_item_call + label="Hover Height" + name="HoverHeight" + shortcut="alt|control|H" + visible="false"> + <menu_item_call.on_click + function="HoverHeight"/> + <menu_item_call.on_enable + function="Edit.EnableHoverHeight"/> + </menu_item_call> <menu create_jump_keys="true" label="Movement" @@ -150,7 +162,8 @@ </menu_item_check> <menu_item_call label="Stop Animating Me" - name="Stop Animating My Avatar"> + name="Stop Animating My Avatar" + shortcut="alt|shift|A"> <menu_item_call.on_click function="Tools.StopAllAnimations" /> </menu_item_call> @@ -458,7 +471,8 @@ </menu_item_check> <menu_item_call label="Events" - name="Events"> + name="Events" + shortcut="control|E"> <menu_item_call.on_click function="Advanced.ShowURL" parameter="https://secondlife.com/my/community/events"/> @@ -647,7 +661,8 @@ tear_off="true"> <menu_item_check label="Sunrise" - name="Sunrise"> + name="Sunrise" + shortcut="control|shift|O"> <menu_item_check.on_click function="World.EnvSettings" parameter="sunrise" /> @@ -679,7 +694,8 @@ </menu_item_check> <menu_item_check label="Midnight" - name="Midnight"> + name="Midnight" + shortcut="control|shift|Z"> <menu_item_check.on_click function="World.EnvSettings" parameter="midnight" /> @@ -1317,7 +1333,8 @@ function="World.EnvPreset" <menu_item_call label="Model..." layout="topleft" - name="Upload Model"> + name="Upload Model" + shortcut="alt|control|U"> <menu_item_call.on_click function="File.UploadModel" parameter="" /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 32ae56e3af..32a801e1a3 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1343,6 +1343,18 @@ You must agree to the Second Life Terms and Conditions, Privacy Policy, and Term <notification icon="alertmodal.tga" + name="CouldNotBuyCurrency" + type="alertmodal"> +[TITLE] +[MESSAGE] + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" name="CouldNotPutOnOutfit" type="alertmodal"> Could not put on outfit. diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index 13986c4030..87035e5cd3 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -41,7 +41,7 @@ </string> <string name="acquired_date"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] </string> <!-- Texture names for rating icons --> <string diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index d77fbdec0a..2745b9d302 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -117,20 +117,32 @@ name="Recent Items" show_item_link_overlays="true" width="290" /> - <inventory_panel - name="Worn Items" - label="WORN" - show_empty_message="false" - follows="all" - layout="topleft" - width="290" - bg_opaque_color="DkGray2" - bg_alpha_color="DkGray2" - background_visible="true" - border="false" - bevel_style="none" - scroll.reserve_scroll_corner="false"> - </inventory_panel> + <inventory_panel + name="Worn Items" + label="WORN" + show_empty_message="false" + follows="all" + layout="topleft" + width="290" + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + scroll.reserve_scroll_corner="false"/> + <favorites_inventory_panel + name="Favorite Items" + label="FAVORITES" + show_empty_message="false" + follows="all" + layout="topleft" + width="290" + bg_opaque_color="DkGray2" + bg_alpha_color="DkGray2" + background_visible="true" + border="false" + bevel_style="none" + scroll.reserve_scroll_corner="false"/> </tab_container> <layout_stack animate="false" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index eeb930485e..6c8cc9d39a 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -30,7 +30,6 @@ tab_height="30" tab_position="top" halign="center" - hide_scroll_arrows="true" top="8" width="315"> <panel diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml index ece6c95080..c023cb036e 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml @@ -52,7 +52,7 @@ </check_box> <check_box - control_name="VoiceCallsFriendsOnly" + enabled="false" height="16" label="Only friends and groups can call or IM me" layout="topleft" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index c2defdd772..65b9a64111 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -514,12 +514,12 @@ follows="left|top" height="23" is_toggle="true" - label="Input/Output devices" + label="Voice Input/Output devices" layout="topleft" left="20" top_pad="6" name="device_settings_btn" - width="190"> + width="230"> </button> <panel layout="topleft" diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index 2a1eb425ed..1777a0db05 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -32,7 +32,7 @@ width="333"> top="5" follows="left|top|right" layout="topleft" - width="303" + width="307" height="33" name="panel_currentlook" > @@ -118,14 +118,14 @@ width="333"> name="Filter" search_button_visible="true" top_pad="10" - width="303" /> + width="307" /> <panel class="panel_outfits_inventory" filename="panel_outfits_inventory.xml" name="panel_outfits_inventory" height="493" min_height="410" - width="320" + width="325" visible="false" left="0" tab_group="1" diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index acb6f5b42a..9a68479d05 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -33,7 +33,7 @@ </panel.string> <panel.string name="acquiredDate"> - [wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] + [wkday,datetime,slt] [mth,datetime,slt] [day,datetime,slt] [hour,datetime,slt]:[min,datetime,slt]:[second,datetime,slt] [year,datetime,slt] </panel.string> <panel.string name="origin_inventory"> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 1bfac6aeb7..73ee8332cc 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -28,7 +28,7 @@ <string name="BuildConfig">Build Configuration [BUILD_CONFIG]</string> <string name="AboutPosition"> -You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> ([HOSTIP]) +You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at <nolink>[HOSTNAME]</nolink> SLURL: <nolink>[SLURL]</nolink> (global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1]) [SERVER_VERSION] @@ -2295,6 +2295,7 @@ For AI Character: Get the closest navigable point to the point provided. <!-- inventory --> <string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string> <string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string> + <string name="InventoryFavoritItemsNotSelected">Click "Use as Favorites folder" on a folder of your choice. You can choose a different folder at any time. System folders cannot be used for Favorites.</string> <string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string> <string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string> <string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string> diff --git a/indra/newview/skins/default/xui/es/floater_buy_currency.xml b/indra/newview/skins/default/xui/es/floater_buy_currency.xml index dbff3fcf0e..086150dd57 100644 --- a/indra/newview/skins/default/xui/es/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/es/floater_buy_currency.xml @@ -60,8 +60,7 @@ no el objeto. </text> <button label="Comprar ahora" name="buy_btn"/> <button label="Cancelar" name="cancel_btn"/> - <text name="info_cannot_buy" left="150" font="SansSerifBig"> + <floater.string name="info_cannot_buy"> No se pudo hacer la compra - </text> - <button label="Ir a la web" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml index 2e409ef69c..a77dd99af0 100644 --- a/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/es/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> Texturas múltiples </text> - <radio_group name="mode_selection"> - <radio_item label="Inventario" name="inventory" value="0"/> - <radio_item label="Local" name="local" value="1"/> - <radio_item label="Hornear" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - Tamaño: [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Inventario" name="inventory" value="0"/> + <combo_box.item label="Local" name="local" value="1"/> + </combo_box> <button label="Por defecto" label_selected="Por defecto" name="Default" width="84"/> <button label="Blanca" label_selected="Blanca" name="Blank"/> <button label="Ninguna" label_selected="Ninguna" left="90" name="None"/> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml index 007101b8fe..0ba676898f 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml @@ -28,5 +28,5 @@ <check_box label="Mostrar la selección de cuadrícula al iniciar sesión" name="show_grid_selection_check"/> <check_box label="Mostrar el menú Avanzado" name="show_advanced_menu_check"/> <check_box label="Mostrar el menú Desarrollar" name="show_develop_menu_check"/> - <button label="Permisos de creación predeterminados" name="default_creation_permissions"/> + <button label="Permisos de creación predeterminados" name="default_creation_permissions" width="235"/> </panel> diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml index 816c698548..47815d0296 100644 --- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Renderizar siempre los amigos" name="AlwaysRenderFriends"/> <button label="Excepciones..." name="RenderExceptionsButton"/> - <button label="Guardar configuración como valor predefinido..." name="PrefSaveButton"/> - <button label="Cargar predefinido..." name="PrefLoadButton"/> + <button label="Guardar configuración como valor predefinido" name="PrefSaveButton" width="260" left="5"/> + <button label="Cargar predefinido" name="PrefLoadButton" left_pad="7"/> min_val="0.125" - <button label="Eliminar predefinido..." name="PrefDeleteButton"/> - <button label="Restablecer la configuración recomendada" name="Defaults"/> + <button label="Eliminar predefinido" name="PrefDeleteButton" width="117" left_pad="7"/> + <button label="Restablecer la configuración recomendada" name="Defaults" width="248"/> <button label="Configuración avanzada..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml index c295172abf..55b0d1825a 100644 --- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml @@ -60,8 +60,7 @@ le Lindex... </text> <button label="Acheter" name="buy_btn"/> <button label="Annuler" name="cancel_btn"/> - <text name="info_cannot_buy" left="160" width="200"> + <floater.string name="info_cannot_buy" left="160" width="200"> Achat impossible - </text> - <button label="Accéder au Web" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml index 2925727b48..a4de7954c5 100644 --- a/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/fr/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> Textures multiples </text> - <radio_group name="mode_selection"> - <radio_item label="Inventaire" name="inventory" value="0"/> - <radio_item label="Local" name="local" value="1"/> - <radio_item label="Figer" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - Taille : [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Inventaire" name="inventory" value="0"/> + <combo_box.item label="Local" name="local" value="1"/> + </combo_box> <button label="Défaut" label_selected="Défaut" name="Default" width="60"/> <button label="Vierge" label_selected="Vierge" name="Blank" width="60"/> <button label="Aucune" label_selected="Aucune" left="68" name="None" width="60"/> diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml index 7117ace7e1..46d6305290 100644 --- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Toujours effectuer le rendu des amis" name="AlwaysRenderFriends"/> <button label="Exceptions..." name="RenderExceptionsButton"/> - <button label="Enregistrer les paramètres comme préréglage..." name="PrefSaveButton"/> - <button label="Charger un préréglage..." name="PrefLoadButton"/> + <button label="Enregistrer les paramètres comme préréglage" name="PrefSaveButton" width="260" /> + <button label="Charger un préréglage" name="PrefLoadButton" width="132"/> min_val="0,125" - <button label="Supprimer un préréglage..." name="PrefDeleteButton"/> - <button label="Réinitialiser les paramètres recommandés" name="Defaults"/> + <button label="Supprimer un préréglage" name="PrefDeleteButton" width="148" top_delta="30" left_pad="-220"/> + <button label="Réinitialiser les paramètres recommandés" name="Defaults" width="255" top_delta="35"/> <button label="Paramètres avancés" name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency.xml b/indra/newview/skins/default/xui/it/floater_buy_currency.xml index 53a2057455..522d26373e 100644 --- a/indra/newview/skins/default/xui/it/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/it/floater_buy_currency.xml @@ -60,8 +60,7 @@ l'oggetto. </text> <button label="Acquista" name="buy_btn"/> <button label="Annulla" name="cancel_btn"/> - <text name="info_cannot_buy" left="160" font="SansSerifBig"> + <floater.string name="info_cannot_buy" left="160" font="SansSerifBig"> Non in grado di acquistare - </text> - <button label="Continua sul Web" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml index 2e4644cef3..f857bfe49f 100644 --- a/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/it/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> Texture multiple </text> - <radio_group name="mode_selection"> - <radio_item label="Inventario" name="inventory" value="0"/> - <radio_item label="Locale" name="local" value="1"/> - <radio_item label="Effettua il bake" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - Dimensioni: [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Inventario" name="inventory" value="0"/> + <combo_box.item label="Locale" name="local" value="1"/> + </combo_box> <button label="Default" label_selected="Default" name="Default"/> <button label="Vuoto" label_selected="Vuoto" name="Blank"/> <button label="Niente" label_selected="Niente" name="None"/> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml index f3ca9fafb3..c7739b8472 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml @@ -32,10 +32,10 @@ </text> <check_box initial_value="true" label="Esegui sempre il rendering degli amici" name="AlwaysRenderFriends"/> <button label="Eccezioni..." name="RenderExceptionsButton"/> - <button label="Salva impostazioni come valori predefiniti..." name="PrefSaveButton"/> - <button label="Carica valore predefinito..." name="PrefLoadButton"/> + <button label="Salva impostazioni come valori predefiniti" name="PrefSaveButton" width="240" left="4"/> + <button label="Carica valore predefinito" name="PrefLoadButton" width="145" left_pad="7"/> min_val="0.125" - <button label="Elimina valore predefinito..." name="PrefDeleteButton"/> + <button label="Elimina valore predefinito" name="PrefDeleteButton" width="148" left_pad="7"/> <button label="Ripristina impostazioni consigliate" name="Defaults"/> <button label="Impostazioni avanzate..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml index aa3ff53f4a..c9d90539e1 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_setup.xml @@ -35,5 +35,5 @@ <text name="Proxy Settings:"> Impostazioni proxy: </text> - <button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy"/> + <button label="Regola impostazioni proxy" label_selected="Sfoglia" name="set_proxy" width="160"/> </panel> diff --git a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml index a472f163e3..ac2db917cc 100644 --- a/indra/newview/skins/default/xui/ja/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/ja/floater_buy_currency.xml @@ -59,8 +59,7 @@ </text> <button label="購入する" name="buy_btn"/> <button label="取り消し" name="cancel_btn"/> - <text name="info_cannot_buy"> + <floater.string name="info_cannot_buy"> 購入できません - </text> - <button label="Web サイトに移動" name="error_web" width="140"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml index 05e7bfefd2..1221702e9b 100644 --- a/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/ja/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> 複数のテクスチャ </text> - <radio_group name="mode_selection"> - <radio_item label="インベントリ" name="inventory" value="0"/> - <radio_item label="ローカル" name="local" value="1"/> - <radio_item label="構築(ベーク)" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - サイズ: [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="インベントリ" name="inventory" value="0"/> + <combo_box.item label="ローカル" name="local" value="1"/> + </combo_box> <button label="デフォルト" label_selected="デフォルト" name="Default"/> <button label="ブランク" label_selected="ブランク" name="Blank"/> <button label="なし" label_selected="なし" name="None"/> diff --git a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml index 72167e0d3c..a1d703a15a 100644 --- a/indra/newview/skins/default/xui/pl/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/pl/floater_buy_currency.xml @@ -50,8 +50,7 @@ </text> <button label="Kup teraz" name="buy_btn" /> <button label="Anuluj" name="cancel_btn" /> - <text name="info_cannot_buy"> + <floater.string name="info_cannot_buy"> Nie można kupić - </text> - <button label="Odwiedź stronę WWW" name="error_web" /> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml index 8ac158b462..2425213160 100644 --- a/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/pl/floater_texture_ctrl.xml @@ -9,13 +9,10 @@ <text name="Multiple"> Wiele tekstur </text> - <radio_group name="mode_selection"> - <radio_item label="Szafa" name="inventory" /> - <radio_item label="Lokalna" name="local" /> - </radio_group> - <text name="unknown"> - Rozm.: [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Szafa" name="inventory" /> + <combo_box.item label="Lokalna" name="local" /> + </combo_box> <button label="Domyślna" label_selected="Domyślna" name="Default" /> <button label="Pusta" label_selected="Pusta" name="Blank" /> <button label="Przezrocz." label_selected="Przezrocz." name="None" /> diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml index 513400954b..c740b90472 100644 --- a/indra/newview/skins/default/xui/pt/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/pt/floater_buy_currency.xml @@ -59,8 +59,7 @@ </text> <button label="Comprar já!" name="buy_btn"/> <button label="Fechar" name="cancel_btn"/> - <text name="info_cannot_buy" font="SansSerifBig"> + <floater.string name="info_cannot_buy"> Transação incompleta - </text> - <button label="Prosseguir para a web" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml index d06c16d8c8..d3eec114e2 100644 --- a/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/pt/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> Multiplas texturas </text> - <radio_group name="mode_selection"> - <radio_item label="Inventário" name="inventory" value="0"/> - <radio_item label="Local" name="local" value="1"/> - <radio_item label="Assar" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - Tamanho: [DIMENSÕES] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Inventário" name="inventory" value="0"/> + <combo_box.item label="Local" name="local" value="1"/> + </combo_box> <button label="Padrão" label_selected="Padrão" name="Default"/> <button label="Branco" label_selected="Branco" name="Blank"/> <button label="Nenhum" label_selected="Nenhum" name="None"/> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml index a0f4ea4ed5..d387c4c869 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml @@ -33,10 +33,10 @@ rápido </text> <check_box initial_value="true" label="Sempre renderizar amigos" name="AlwaysRenderFriends"/> <button label="Exceções..." name="RenderExceptionsButton"/> - <button label="Salvar configurações como predefinição..." name="PrefSaveButton"/> - <button label="Carregar predefinição..." name="PrefLoadButton"/> + <button label="Salvar configurações como predefinição" name="PrefSaveButton" width="235" left="5"/> + <button label="Carregar predefinição" name="PrefLoadButton" width="130" left_pad="8"/> min_val="0.125" - <button label="Excluir predefinição..." name="PrefDeleteButton"/> - <button label="Redefinir para configurações recomendadas" left="110" name="Defaults"/> + <button label="Excluir predefinição" name="PrefDeleteButton" width="122" left_pad="8"/> + <button label="Redefinir para configurações recomendadas" name="Defaults" width="255"/> <button label="Configurações avançadas..." name="AdvancedSettings"/> </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml index 03536f28c3..56fc225bc0 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml @@ -35,5 +35,5 @@ <text name="Proxy Settings:"> Configurações de proxy: </text> - <button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy"/> + <button label="Ajustar configurações de proxy" label_selected="Procurar" name="set_proxy" width="180"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml index 87e8bd524e..ef55ce58d4 100644 --- a/indra/newview/skins/default/xui/ru/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/ru/floater_buy_currency.xml @@ -59,8 +59,7 @@ </text> <button label="Приобрести" name="buy_btn"/> <button label="Отмена" name="cancel_btn"/> - <text name="info_cannot_buy"> + <floater.string name="info_cannot_buy"> Нельзя купить - </text> - <button label="Продолжить в Интернете" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml index c56657b86b..d4323e5c34 100644 --- a/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/ru/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> Несколько текстур </text> - <radio_group name="mode_selection"> - <radio_item label="Инвентарь" name="inventory" value="0"/> - <radio_item label="Локально" name="local" value="1"/> - <radio_item label="Зафиксировать" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - Размер: [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Инвентарь" name="inventory" value="0"/> + <combo_box.item label="Локально" name="local" value="1"/> + </combo_box> <button label="По умолчанию" label_selected="По умолчанию" name="Default"/> <button label="Очистить" label_selected="Очистить" name="Blank"/> <button label="Нет" label_selected="Нет" name="None"/> diff --git a/indra/newview/skins/default/xui/ru/notifications.xml b/indra/newview/skins/default/xui/ru/notifications.xml index 517c4db278..f3d52aacb9 100644 --- a/indra/newview/skins/default/xui/ru/notifications.xml +++ b/indra/newview/skins/default/xui/ru/notifications.xml @@ -1612,22 +1612,22 @@ [DOWNLOAD_PATH]. </notification> <notification name="RequiredUpdate"> - Для входа необходима версия \[VERSION]. + Для входа необходима версия [VERSION]. Скачайте обновление с веб-сайта https://secondlife.com/support/downloads/ <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="PauseForUpdate"> - Для входа необходима версия \[VERSION]. + Для входа необходима версия [VERSION]. Нажмите OK для загрузки и установки. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="OptionalUpdateReady"> - Версия \[VERSION] загружена и готова к установке. + Версия [VERSION] загружена и готова к установке. Нажмите OK для установки. <usetemplate name="okbutton" yestext="OK"/> </notification> <notification name="PromptOptionalUpdate"> - Версия \[VERSION] загружена и готова к установке. + Версия [VERSION] загружена и готова к установке. Продолжить? <usetemplate canceltext="Не сейчас" name="yesnocancelbuttons" notext="Пропустить" yestext="Установить"/> </notification> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml index dd0cf8e172..79d5cb7960 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_advanced.xml @@ -28,5 +28,5 @@ <check_box label="Выбор сетки при входе" name="show_grid_selection_check"/> <check_box label="Показывать расширенное меню" name="show_advanced_menu_check"/> <check_box label="Показать меню разработчика" name="show_develop_menu_check"/> - <button label="Стандартные разрешения на создание" name="default_creation_permissions"/> + <button label="Стандартные разрешения на создание" name="default_creation_permissions" width="235"/> </panel> diff --git a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml index 4524fb4d43..f392a1f0b7 100644 --- a/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/ru/panel_preferences_graphics1.xml @@ -32,7 +32,7 @@ </text> <check_box initial_value="true" label="Всегда рисовать друзей" name="AlwaysRenderFriends"/> <button label="Исключения..." name="RenderExceptionsButton"/> - <button label="Сохранить настройки как пресет..." name="PrefSaveButton"/> + <button label="Сохранить настройки как пресет..." name="PrefSaveButton" width="210"/> <button label="Загрузить пресет..." name="PrefLoadButton"/> min_val="0,125" <button label="Удалить пресет..." name="PrefDeleteButton"/> diff --git a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml index d90985dcff..33c4b2287f 100644 --- a/indra/newview/skins/default/xui/tr/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/tr/floater_buy_currency.xml @@ -59,8 +59,7 @@ </text> <button label="Şimdi Satın Al" name="buy_btn"/> <button label="İptal" name="cancel_btn"/> - <text name="info_cannot_buy"> + <floater.string name="info_cannot_buy"> Satın Alınamıyor - </text> - <button label="Web'e devam et" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml index 1a16709127..0389cdcbe5 100644 --- a/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/tr/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> Birden çok doku </text> - <radio_group name="mode_selection"> - <radio_item label="Envanter" name="inventory" value="0"/> - <radio_item label="Yerel" name="local" value="1"/> - <radio_item label="Kurut" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - Büyüklük: [DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="Envanter" name="inventory" value="0"/> + <combo_box.item label="Yerel" name="local" value="1"/> + </combo_box> <button label="Varsayılan" label_selected="Varsayılan" name="Default"/> <button label="Boş" label_selected="Boş" name="Blank"/> <button label="Hiçbiri" label_selected="Hiçbiri" name="None"/> diff --git a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml index fcf2800728..41c8c26ccc 100644 --- a/indra/newview/skins/default/xui/zh/floater_buy_currency.xml +++ b/indra/newview/skins/default/xui/zh/floater_buy_currency.xml @@ -59,8 +59,7 @@ </text> <button label="立即購買" name="buy_btn"/> <button label="取消" name="cancel_btn"/> - <text name="info_cannot_buy"> + <floater.string name="info_cannot_buy"> 無法購買 - </text> - <button label="繼續到網頁" name="error_web"/> + </floater.string> </floater> diff --git a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml index 881ca40338..6fc3e1129b 100644 --- a/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/zh/floater_texture_ctrl.xml @@ -9,14 +9,10 @@ <text name="Multiple"> 多重材質 </text> - <radio_group name="mode_selection"> - <radio_item label="收納區" name="inventory" value="0"/> - <radio_item label="本地" name="local" value="1"/> - <radio_item label="確定產出" name="bake" value="2"/> - </radio_group> - <text name="unknown"> - 尺寸:[DIMENSIONS] - </text> + <combo_box name="mode_selection"> + <combo_box.item label="收納區" name="inventory" value="0"/> + <combo_box.item label="本地" name="local" value="1"/> + </combo_box> <button label="預設" label_selected="預設" name="Default"/> <button label="空白" label_selected="空白" name="Blank"/> <button label="無" label_selected="無" name="None"/> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index b385717dbe..e79b45f2b0 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -523,6 +523,11 @@ class WindowsManifest(ViewerManifest): else: self.path("fmod.dll") + if self.args['openal'] == 'ON': + # Get openal dll + self.path("OpenAL32.dll") + self.path("alut.dll") + # For textures self.path("openjpeg.dll") @@ -1539,7 +1544,6 @@ class Linux_i686_Manifest(LinuxManifest): print "Skipping libfmod.so - not found" pass - # Vivox runtimes with self.prefix(src=relpkgdir, dst="bin"): self.path("SLVoice") @@ -1564,10 +1568,12 @@ class Linux_x86_64_Manifest(LinuxManifest): ################################################################ if __name__ == "__main__": + # fmodstudio and openal can be used simultaneously and controled by environment extra_arguments = [ dict(name='bugsplat', description="""BugSplat database to which to post crashes, if BugSplat crash reporting is desired""", default=''), dict(name='fmodstudio', description="""Indication if fmod studio libraries are needed""", default='OFF'), + dict(name='openal', description="""Indication openal libraries are needed""", default='OFF'), ] try: main(extra=extra_arguments) |